Esto es un poco complicado; Me gustaría recibir cualquier comentario sobre cómo mejorar la claridad de la pregunta.Asignar matriz dinámica con dimensiones interdependientes
Ok, decir que tengo una matriz:
real, allocatable :: A(:,:,:)
y quiero asignarlo antes de usarlo. ¿Es posible que el tamaño de la tercera dimensión dependa del tamaño de la segunda dimensión?
E.g.
do i=1,n
allocate(A(3,i,i**2))
end do
Obviamente, lo anterior no funciona. Me gustaría terminar con una matriz (o un conjunto de matrices) con la forma (s)
(3,1,1), (3,2,4), (3,3,9), ... (3, n, n^2)
donde el tamaño de la tercera dimensión es el cuadrado del tamaño de la segunda dimensión.
Mi regla para el tamaño de la dimensión dependiente es un poco más complicada, pero si la cuadratura es posible, puedo hacer el resto.
¿Esto es posible? Si es así, ¿cómo podría implementarlo en Fortran?
¿Qué devolvería shape(A)
? Eso puede ser interesante.
Mi otra alternativa es asignar al tamaño máximo requerido, y tenga cuidado de usar sólo ciertos elementos en los cálculos, es decir
allocate(A(3,n,n**2))
pesar de que no soy difícil para arriba en la memoria en el momento, Me gustaría tener buenas prácticas de programación. Este es un problema interesante de todos modos.
Gracias.
EDIT:
¿Qué hay de tener el tamaño de una dimensión depende del valor de un elemento en otra dimensión?
En la respuesta por debajo del tamaño de la matriz en ambas dimensiones dependía del índice de B. Me gustaría algo en la línea de
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
Se obtiene lo que quiero decir? Pero el programa falla cuando trata de asignar las variables ya asignadas, p. cuando i=1
asigna data(1)%cell(1)
, y luego intenta asignar data(1)%cell(2)
... uh oh. Lo que quiero es algo así como:
Cada data(i)
tiene una gran variedad lev(j)
de los valores, con j
que va desde 1 hasta n, y para cada valor lev(j)
tenemos un tamaño de cell
lev
^2. Tenga en cuenta que estos cell
son únicos para cada data(i)
y cada lev
, y que el tamaño de ese particular cell
depende del valor lev
correspondiente, y posiblemente el correspondiente data(i)
también.
¿Debo usar un tipo derivado en un tipo derivado?
Para que lo sepas, el tipo de matriz que estás buscando se llama matriz "dentada", como matriz "rectangular". IRO-bot a continuación tiene la respuesta correcta; en Fortran los arreglos solos son siempre rectangulares, pero puedes usar tipos definidos para crear tu propia estructura. –
"Jagged" ... hey, eso tiene sentido, pictóricamente. "... puedes usar tipos definidos para crear tu propia estructura". De Verdad? Entonces, si quiero una matriz cuya forma aumenta hasta la mitad, luego disminuye, o sigue la secuencia de Fibonacci, o es completamente aleatoria, eso es posible sin demasiado esfuerzo ... ¡genial! –
@SamuelTan Además edité mi respuesta con código actualizado para resolver su nuevo problema. Compara los dos códigos para ver lo que estabas haciendo mal. – milancurcic