Come inizializzare gli array bidimensionali in Fortran
-
02-10-2019 - |
Domanda
In C si può facilmente inizializzare un array utilizzando la sintassi parentesi graffe, se non ricordo male:
int* a = new int[] { 1, 2, 3, 4 };
Come si può fare lo stesso in Fortran per array bidimensionali quando si desidera inizializzare una matrice con valori di test specifici per scopi matematici? (Senza dover doppiamente indice ogni elemento di dichiarazioni separate)
La matrice può essere definito sia da
real, dimension(3, 3) :: a
o
real, dimension(:), allocatable :: a
Soluzione
È possibile farlo utilizzando rimodellare e intrinseche forma . Qualcosa di simile:
INTEGER, DIMENSION(3, 3) :: array
array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))
Ma ricordate l'ordine delle colonne-major. La matrice sarà
1 4 7
2 5 8
3 6 9
dopo rimodellare.
Quindi, per ottenere:
1 2 3
4 5 6
7 8 9
trasporre intrinseca:
array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))
Per esempio più generale (array allocatable 2D con dimensioni diverse), uno esigenze dimensioni intrinseca:
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
Altri suggerimenti
Per rango (> 1) array multidimensionali, il modo per Fortran differisce inizializzazione della soluzione C perché in C array multidimensionali sono solo array di array di etc.
In FORTRAN, ognuno corrisponde ad un rango diverso attributo del tipo di dati modificati. Ma c'è solo un costruttore di array per rango-1 array. Da queste due ragioni, inizializzazione attraverso costruttore matrice richiede la funzione intrinseci RESHAPE
.
In aggiunta a quanto già risposto, c'è un modo più diretto inserendo il valore di una matrice per righe invece come per colonna: rimodellazione ha un ORDER
argomento opzionale che può essere usata per modificare l'ordine di riempimento dell'elemento della matrice multidimensionale con le voci del costruttore matrice.
Ad esempio, nel caso dell'esempio nella prima risposta, si potrebbe scrivere:
INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, &
4, 5, 6, &
7, 8, 9 /), &
shape(array), order=(/2,1/) )
ottenere il riempimento della matrice esattamente nell'ordine indicato dalle linee di codice.
Le forze matrice (/2, 1/)
l'indice di colonna (2)
avere la precedenza sulla (1)
indice di riga, dando l'effetto desiderato.
inizializzazione array può essere realizzata in comunicazione dichiarazione matrice stessa, come illustrato di seguito:
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
Mi sorprende che
real:: y(3,3) = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
non accettato dal compilatore (G95 provato, gfortran). Si scopre che la shape
di
(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
è 9
e non 3 3
!