Jak zainicjować tablice dwuwymiarowe w Fortran
W C można łatwo zainicjować tablicę używając składni nawiasów klamrowych, jeśli dobrze pamiętam:
int* a = new int[] { 1, 2, 3, 4 };
Jak można zrobić to samo w Fortran dla tablic dwuwymiarowych, jeśli chcesz zainicjować macierz z określonymi wartościami testowymi dla celów matematycznych? (Bez konieczności podwójnego indeksowania każdego elementu na osobnych instrukcjach)
Tablica jest albo zdefiniowana przez
real, dimension(3, 3) :: a
Lub
real, dimension(:), allocatable :: a
3 answers
Możesz to zrobić używając reshapei shape. Coś w stylu:
INTEGER, DIMENSION(3, 3) :: array
array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))
Ale pamiętaj o kolejności kolumn. Tablica będzie
1 4 7
2 5 8
3 6 9
Po przekształceniu.
Więc dostać:
1 2 3
4 5 6
7 8 9
Potrzebujesz też transponować wewnętrznie:
array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))
Dla bardziej ogólnego przykładu (alokowana tablica 2D o różnych wymiarach), trzeba Rozmiar :
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-21 19:56:40
Dla tablic wielowymiarowych (rank>1) Sposób inicjalizacji Fortran różni się od rozwiązania C, ponieważ w C tablice wielowymiarowe są tylko tablicami tablic itd.
W Fortran, każda ranga odpowiada innemu atrybutowi zmodyfikowanego typu danych. Ale jest tylko jeden konstruktor tablicy dla tablic rank-1. Z tych dwóch powodów inicjalizacja za pomocą konstruktora tablicy wymaga funkcji intryzycznej RESHAPE
.
Oprócz tego, na co już udzielono odpowiedzi, istnieje bardziej bezpośredni sposób wprowadzania wartości macierzy wierszem zamiast kolumną: reshape ma opcjonalny argument ORDER
, który może być użyty do zmiany kolejności wypełniania elementu wielowymiarowej tablicy wpisami konstruktora tablicy.
Na przykład w przypadku przykładu w pierwszej odpowiedzi można by napisać:
INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, &
4, 5, 6, &
7, 8, 9 /), &
shape(array), order=(/2,1/) )
Uzyskanie wypełnienia macierzy dokładnie w kolejności wskazanej przez linie kodu.
Tablica (/2, 1/)
siły indeks Kolumny (2)
ma pierwszeństwo przed indeksem wiersza (1)
, dając pożądany efekt.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-10 16:22:06
Inicjalizacja tablicy może być wykonana w samej deklaracji array, 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
Dziwi mnie, że
real:: y(3,3) = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
Jest nie akceptowane przez kompilator(wypróbowane g95, gfortran). Okazuje się, że shape
z
(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
jest 9
a nie 3 3
!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-23 07:07:49