2010-09-14 8 views
22

W C można łatwo zainicjować tablicę używając składni nawiasów klamrowych, jeśli dobrze pamiętam:Jak zainicjować tablice dwuwymiarowe w Fortran

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

Jak można zrobić to samo w Fortran dla dwuwymiarowy tablice, gdy chcesz zainicjować macierz z określonymi wartościami testowymi dla celów matematycznych? (Bez konieczności podwójnie indeks każdy element na osobnych sprawozdań)

Tablica jest też zdefiniowany przez

real, dimension(3, 3) :: a 

lub

real, dimension(:), allocatable :: a 

Odpowiedz

42

Można to zrobić za pomocą reshape i shape intrinsics. Coś jak:

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

Ale pamiętaj o kolejności kolumna-major. Po zmianie kształtu macierz będzie miała postać

1 4 7 
2 5 8 
3 6 9 

.

Tak, aby uzyskać:

1 2 3 
4 5 6 
7 8 9 

trzeba także transpose wewnętrznej:

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

Dla bardziej ogólny przykład (allocatable 2D tablicy z różnymi wymiarami), trzeba size wewnętrznej:

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 
+12

1) Większość kompilatorów akceptuje teraz notację Fortran 2003 [], aby zainicjować tablice, zamiast nieco nieprzyjemnego (/ /). 2) Dla prostych przypadków możesz pominąć transpozycję, podając wartości w kolumnie głównej: array = reshape ([1, 4, 7, 2, 5, 8, 3, 6, 9], kształt (tablica)) –

+0

Zapomniałem wspomnieć, że musimy pracować w Fortranie 90. –

4

Inicjację macierzy można wykonać w tablicy d Samo stwierdzenie EKLARACJA, jak pokazano poniżej:

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 

Zaskakuje mnie, że

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

jest nie akceptowane przez kompilator (próbował G95, gfortran). Okazuje się, że shape z 0124868984108178052510 jest, a nie !

13

wielowymiarowej (stopień> 1), macierze, Fortran sposób inicjalizacji różni się od rozwiązania C, ponieważ w C wielowymiarowe tablice są tylko układy tablic itp

FORTRAN każda pozycja odpowiada innemu atrybutu zmodyfikowanego typu danych. Ale istnieje tylko jeden konstruktor tablicowy dla macierzy rank-1. Z tych dwóch powodów inicjalizacja za pomocą konstruktora tablic wymaga funkcji intrisic RESHAPE.

Oprócz tego, co już zostało udzielone, istnieje bardziej bezpośredni sposób wprowadzania wartości macierzy po wierszu, jak w kolumnie: zmiana kształtu ma opcjonalny argument ORDER, który może być użyty do modyfikacji kolejności wypełniania element wielowymiarowej tablicy z wpisami konstruktora tablicowego.

Na przykład, w tym przykładzie w pierwszej odpowiedzi, jeden może napisać:

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

uzyskania wypełnienia macierzy matrycy dokładnie w podanej kolejności przez linie kodu.

Macierz (/2, 1/) wymusza na indeksie (2) indeks kolumny, który ma pierwszeństwo względem indeksu wiersza (1), podając pożądany efekt.

Powiązane problemy