Frage

In C können Sie ein Array mit der geschweiften Klammern Syntax leicht initialisieren, wenn ich mich richtig erinnere:

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

Wie kann man das gleiche in Fortran für zweidimensionalen Arrays tun, wenn Sie eine Matrix mit spezifischen Testwerten für mathematische Zwecke initialisieren wollen? (Ohne jedes Element auf separaten Aussagen doppelt Index)

Das Array ist entweder definiert durch

real, dimension(3, 3) :: a

oder

real, dimension(:), allocatable :: a
War es hilfreich?

Lösung

Das können Sie mit reshape und Form intrinsics. So etwas wie:

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

Aber denken Sie daran, den Spalte-Großauftrag. Das Array wird

1   4   7
2   5   8
3   6   9

nach dem Umformen.

So zu erhalten:

1   2   3
4   5   6
7   8   9

Sie müssen transponieren Eigen:

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

Für allgemeinere Beispiel (zuweisbaren 2D-Array mit unterschiedlichen Dimensionen), man braucht Größe intrinsischen:

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

Andere Tipps

Für multidimensionale (Rang> 1) Arrays, die Fortran Weg zur Initialisierung unterscheidet sich von der C-Lösung, weil in C multidimensionalen Arrays sind nur Arrays von Arrays von etc.

In Fortran, die jeweils Rang entspricht ein anderes Attribut des modifizierten Datentypen. Aber es ist nur ein Array Konstruktor für Rang-1-Arrays. Aus diesen beiden Gründen Initialisierung durch Array-Konstruktor erfordert die RESHAPE intrisic Funktion.

Zusätzlich zu dem, was bereits beantwortet worden ist, gibt es einen direkteren Weg, um den Wert einer Matrix durch Zeilen statt, wie durch Spalte Eingabe: reshape hat ein optionales Argument ORDER, die verwendet werden können, um die Reihenfolge der Befüllung des Elements zu modifizieren, der mehrdimensionalen Array mit den Einträgen des Arrays Konstruktor.

Zum Beispiel im Fall des Beispiels in der ersten Antwort, könnte man schreiben:

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

, um die Füllung der Matrix-Array erhalten werden genau in der Reihenfolge, die durch die Codezeilen dargestellt.

Die Array (/2, 1/) Kräfte der Spaltenindex (2) zu Vorrang auf dem Zeilenindex (1) haben, um den gewünschten Effekt.

Array Initialisierung kann sich in der Anordnung Deklarationsanweisung erfolgen, wie unten dargestellt:

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

Es überrascht mich, dass

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

ist nicht akzeptiert durch den Compiler (versucht g95, gfortran). Es stellt sich heraus, dass der shape von (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) ist 9 und nicht 3 3!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top