Question

En C, vous pouvez facilement initialiser un tableau en utilisant la syntaxe des accolades, si je me souviens bien:

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

Comment pouvez-vous faire la même chose dans Fortran pour les tableaux en deux dimensions lorsque vous souhaitez initialiser une matrice avec des valeurs de test spécifiques à des fins mathématiques? (Sans avoir à indexer doublement tous les éléments sur les états séparés)

Le réseau est soit définie par

real, dimension(3, 3) :: a

ou

real, dimension(:), allocatable :: a
Était-ce utile?

La solution

Vous pouvez le faire en utilisant Reshape et les valeurs intrinsèques de forme. Quelque chose comme:

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

Mais rappelez-vous l'ordre des colonnes-major. Le tableau sera

1   4   7
2   5   8
3   6   9

après le formage.

Donc, pour obtenir:

1   2   3
4   5   6
7   8   9

vous devez également intrinsèque Transpose:

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

Par exemple plus générale (tableau allouable 2D avec des dimensions différentes), on a besoin de taille intrinsèque:

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

Autres conseils

Pour les tableaux multidimensionnels (rang 1>), la façon dont Fortran diffère d'initialisation de la solution C, car dans des tableaux multidimensionnels C ne sont que des tableaux de tableaux de etc.

Fortran, chacun correspond à un rang attribut différent du type de données modifié. Mais il n'y a qu'un seul constructeur de tableau, pour les tableaux de rang 1. A partir de ces deux raisons, l'initialisation par le constructeur de tableau nécessite la fonction RESHAPE intrisic.

En plus de ce qui a déjà reçu une réponse, il est d'une manière plus directe d'entrer la valeur d'une matrice ligne par ligne au lieu que par colonne: reshape a un argument optionnel ORDER qui peut être utilisé pour modifier l'ordre de remplissage de l'élément du tableau multidimensionnel avec les entrées du constructeur de tableau.

Par exemple, dans le cas de l'exemple dans la première réponse, on pourrait écrire:

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

obtenir le remplissage de la matrice de la matrice exactement dans l'ordre indiqué par les lignes de code.

Les forces de (/2, 1/) de réseau l'indice de colonne de (2) d'avoir priorité sur l'index de ligne (1), ce qui donne l'effet recherché.

initialisation Array peut être fait dans la déclaration de déclaration de tableau lui-même, comme indiqué ci-dessous:

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

Il me surprend que

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

pas accepté par le compilateur (essayé G95, gfortran). Il se trouve que le shape de (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) est 9 et non 3 3!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top