Как инициализировать двумерные массивы в Фортране - PullRequest
28 голосов
/ 14 сентября 2010

В C вы можете легко инициализировать массив, используя синтаксис фигурных скобок, если я правильно помню:

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

Как вы можете сделать то же самое в Fortran для двумерных массивов, когда вы хотите инициализировать матрицу с конкретными тестовыми значениями для математических целей? (Без необходимости вдвойне индексировать каждый элемент в отдельных операторах)

Массив определяется либо

real, dimension(3, 3) :: a

или

real, dimension(:), allocatable :: a

Ответы [ 3 ]

48 голосов
/ 14 сентября 2010

Вы можете сделать это, используя изменить форму и shape встроенные.Что-то вроде:

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

Но запомните порядок в столбцах.Массив будет

1   4   7
2   5   8
3   6   9

после изменения формы.

Таким образом, чтобы получить:

1   2   3
4   5   6
7   8   9

вам также необходимо transpose intrinsic:

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

Для более общего примера (выделяемый двумерный массив с разными размерами) требуется размер свойственный:

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
18 голосов
/ 01 мая 2016

Для многомерных массивов (ранг> 1) способ инициализации Фортрана отличается от решения C, поскольку в C многомерные массивы являются просто массивами массивов и т. Д.

В Fortran каждый ранг соответствует отдельномуатрибут измененного типа данных.Но есть только один конструктор массива для массивов ранга 1.По этим двум причинам для инициализации через конструктор массива требуется встроенная функция RESHAPE.

В дополнение к тому, что уже было получено, существует более прямой способ ввода значения матрицы по строке, а неУ column: reshape есть необязательный аргумент ORDER, который можно использовать для изменения порядка заполнения элемента многомерного массива записями конструктора массива.

Например, в случае примера вВ первом ответе можно было бы написать:

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

, получая заполнение матричного массива точно в порядке, указанном строками кода.

Массив (/2, 1/) вызывает индекс столбца(2) иметь приоритет над индексом строки (1), давая желаемый эффект.

6 голосов
/ 23 июня 2014

Инициализация массива может быть выполнена в самом объявлении массива, как показано ниже:

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

Меня удивляет, что

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

это не , принятый компилятором (пробовал g95, gfortran). Оказывается, что shape из (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) - это 9, а не 3 3!

...