Cómo inicializar matrices bidimensionales en Fortran
-
02-10-2019 - |
Pregunta
En C se puede inicializar fácilmente una matriz usando la sintaxis de llaves, si no recuerdo mal:
int* a = new int[] { 1, 2, 3, 4 };
¿Cómo se puede hacer lo mismo en Fortran para matrices bidimensionales cuando se desea inicializar una matriz con los valores de ensayo específicos para los propósitos matemáticos? (Sin tener que doblemente índice de cada elemento en estados separados)
La matriz se define por cualquiera
real, dimension(3, 3) :: a
o
real, dimension(:), allocatable :: a
Solución
Se puede hacer que el uso de reshape y intrínsecos forma . Algo así como:
INTEGER, DIMENSION(3, 3) :: array
array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))
Pero recuerde el orden de columnas-importante. La matriz será
1 4 7
2 5 8
3 6 9
después de la remodelación.
Así que para obtener:
1 2 3
4 5 6
7 8 9
transposición intrínseca:
array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))
Por ejemplo más general (matriz 2D asignable con diferentes dimensiones), uno necesidades tamaño intrínseca:
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
Otros consejos
Para (rango> 1) matrices multidimensionales, la forma en Fortran para difiere de inicialización de la solución C, porque en C matrices multidimensionales son sólo matrices de matrices de etc.
En Fortran, cada rango corresponde a un atributo diferente del tipo de datos modificado. Pero sólo hay un constructor de matrices, Ranking-1 matrices. A partir de estas dos razones, la inicialización a través de array constructor requiere la función intrínseco RESHAPE
.
Además de lo que ya ha sido contestada, hay una manera más directa de entrar en el valor de una matriz por fila en cambio, como por la columna: reshape tiene un ORDER
argumento opcional que puede ser usado para modificar el orden de llenar el elemento de la matriz multidimensional con las entradas de la constructor array.
Por ejemplo, en el caso del ejemplo de la primera respuesta, se podría escribir:
INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, &
4, 5, 6, &
7, 8, 9 /), &
shape(array), order=(/2,1/) )
obtener el llenado de la matriz matriz exactamente en el orden que se muestra por las líneas de código.
Las fuerzas array (/2, 1/)
la (2)
índice de la columna de tener precedencia sobre la (1)
índice de la fila, dando el efecto deseado.
inicialización de la matriz se puede hacer en la cuenta de declaración de matriz en sí, 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 aceptada por el compilador (G95 tratado, gfortran). Resulta que la shape
de
(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
es 9
y no 3 3
!