Comment initialiser les tableaux bidimensionnels dans Fortran

EN C, vous pouvez facilement initialiser un tableau en utilisant la syntaxe curly braces, si je me souviens bien:

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

Comment faire la même chose dans Fortran pour les tableaux bidimensionnels quand vous souhaitez initialiser une matrice avec des valeurs de test spécifiques à des fins mathématiques? (Sans avoir à indexer doublement chaque élément sur des énoncés séparés)

Le tableau est défini par

real, dimension(3, 3) :: a

ou

real, dimension(:), allocatable :: a
27
demandé sur Fludlu McBorry 2010-09-14 15:12:30

3 réponses

vous pouvez faire cela en utilisant carré et forme intrinsèques. Quelque chose comme:

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

Mais n'oubliez pas la colonne ordre majeur. Le tableau sera

1   4   7
2   5   8
3   6   9

après le remodelage.

Donc, pour obtenir:

1   2   3
4   5   6
7   8   9

vous avez aussi besoin de transposer intrinsèque:

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

pour un exemple plus général (tableau 2D allocable 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
44
répondu Wildcat 2016-10-21 19:56:40

pour les tableaux multidimensionnels (rang>1), la méthode Fortran pour l'initialisation diffère de la solution C parce que dans C les tableaux multidimensionnels sont juste des tableaux de tableaux de etc.

dans Fortran, chaque rang correspond à un attribut différent du type de données modifié. Mais il n'y a qu'un constructeur de tableaux, pour les tableaux de rang 1. Pour ces deux raisons, l'initialisation par le constructeur de tableaux nécessite le RESHAPE propre fonction.

En plus de ce qui a déjà a été répondu, il y a une façon plus directe d'entrer la valeur d'une matrice par ligne plutôt 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 de la matrice de constructeur.

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 exactement dans l'ordre indiqué par les lignes de code.

array (/2, 1/) force l'index des colonnes (2) pour avoir la préséance sur la ligne d'index (1), donnant l'effet désiré.

14
répondu GiorgioP 2017-09-10 16:22:06

l'initialisation du tableau peut être faite dans la déclaration du tableau elle-même, comme suit:

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

Ça m'étonne que

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

accepté par le compilateur (essayé g95, gfortran). Il s'avère que le shape de (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)9 et non 3 3!

5
répondu Sourav Mukherjee 2014-06-23 07:07:49