This is a bit complicated; I'd welcome any comments on how to improve the clarity of the question.
Ok, say I have an array:
real, allocatable :: A(:,:,:)
and I want to allocate it before I use it. Is it possible for the size of third dimension to depend on the size of the second dimension?
E.g.
do i=1,n
allocate(A(3,i,i**2))
end do
Obviously the above doesn't work. I'd like to end up with an array (or a set of arrays) with the shape(s)
(3,1,1), (3,2,4), (3,3,9), ... (3, n, n^2)
where the size of the third dimension is the square of the size of the second dimension.
My rule for the size of the dependent dimension is a bit more complicated, but if squaring is possible I can do the rest.
Is this possible? If so, how might I implement it in Fortran?
What would shape(A)
return? That would be interesting.
My other alternative is to allocate to the maximum size required, and be careful to only use certain elements in calculations, i.e.
allocate(A(3,n,n**2))
Even though I'm not hard up on memory at the moment, I'd like to have good programming practices. This is an interesting problem anyway.
Thank you.
EDIT:
What about having the size of a dimension depend on the value of an element in another dimension?
In the answer below the size of array in both dimensions depended on the index of B. I'd like something along the lines of
type myarray
real :: coord(3)
integer,allocatable :: lev(:)
integer, allocatable :: cell(:)
endtype myarray
type(myarray), allocatable :: data
allocate(data(m))
allocate(data%lev(n))
forall (j=1:n) !simple now, for argument's sake
lev(j)=j
endforall
! I was thinking of using a FORALL loop here, but the errors returned
! suggested that the compiler (gfortran) didn't expect IF blocks and ALLOCATE
! statements in a FORALL block
do i=1,m
do j=1,n
allocate(data(i)%cell(lev(j)**2))
enddo
enddo
You get what I mean? But the program falls over as it tries to allocate already allocated variables, e.g. when i=1
it allocates data(1)%cell(1)
, and then tries to allocate data(1)%cell(2)
...uh oh. What I want is something like:
Each data(i)
has an array lev(j)
of values, with j
running from 1 to n, and for each lev(j)
value we have a cell
of size lev
^2. Note that these cell
's are unique for each data(i)
and each lev
, and that the size of that particular cell
depends on the corresponding lev
value, and possibly the corresponding data(i)
too.
Would I have to use a derived type within a derived type?