salto resueltos programación problemas manejo linea ciclo arreglos archivos arrays fortran array-initialize

arrays - resueltos - Cómo inicializar matrices bidimensionales en Fortran



problemas resueltos de programación en fortran 95 pdf (3)

La inicialización de la matriz se puede hacer en la declaración de declaración de la matriz, como se muestra a continuación:

program test real:: x(3) = (/1,2,3/) real:: y(3,3) = reshape((/1,2,3,4,5,6,7,8,9/), (/3,3/)) integer:: i(3,2,2) = reshape((/1,2,3,4,5,6,7,8,9,10,11,12/), (/3,2,2/)) end program test

Me sorprende que

real:: y(3,3) = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)

No es aceptado por el compilador (probado g95, gfortran). Resulta que la shape de (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) es 9 y no 3 3 !

En C puedes inicializar fácilmente una matriz usando la sintaxis de llaves, si recuerdo correctamente:

int* a = new int[] { 1, 2, 3, 4 };

¿Cómo puede hacer lo mismo en Fortran para matrices bidimensionales cuando desea inicializar una matriz con valores de prueba específicos para propósitos matemáticos? (Sin tener que indexar doblemente cada elemento en declaraciones separadas)

La matriz está definida por

real, dimension(3, 3) :: a

o

real, dimension(:), allocatable :: a


Para matrices multidimensionales (rango> 1), la forma de inicialización de Fortran difiere de la solución C porque en C las matrices multidimensionales son solo matrices de matrices de etc.

En Fortran, cada rango corresponde a un atributo diferente del tipo de datos modificado. Pero solo hay un constructor de matrices, para las matrices de rango 1. Por estas dos razones, la inicialización a través del constructor de arreglos requiere la función RESHAPE .

Además de lo que ya se ha respondido, hay una forma más directa de ingresar el valor de una matriz por fila en lugar de por columna: remodelar tiene un argumento opcional ORDER que puede usarse para modificar el orden de llenado del elemento de lo multidimensional. array con las entradas del constructor de array.

Por ejemplo, en el caso del ejemplo en la primera respuesta, uno podría escribir:

INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, & 4, 5, 6, & 7, 8, 9 /), & shape(array), order=(/2,1/) )

obteniendo el relleno de la matriz matricial exactamente en el orden mostrado por las líneas de código.

La matriz (/2, 1/) obliga a que el índice de la columna (2) tenga prioridad sobre el índice de la fila (1) , dando el efecto deseado.


Puedes hacer eso usando reshape y reshape shape intrínsecos. Algo como:

INTEGER, DIMENSION(3, 3) :: array array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))

Pero recuerda el orden de la columna principal. La matriz será

1 4 7 2 5 8 3 6 9

después de remodelar.

Así que para obtener:

1 2 3 4 5 6 7 8 9

También necesita transpose intrínseca:

array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))

Para un ejemplo más general (matriz 2D asignable con diferentes dimensiones), se necesita un size intrínseco:

PROGRAM main IMPLICIT NONE INTEGER, DIMENSION(:, :), ALLOCATABLE :: array ALLOCATE (array(2, 3)) array = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /), & (/ size(array, 2), size(array, 1) /))) DEALLOCATE (array) END PROGRAM main