Выделить несколько массивов с одной формой - PullRequest
0 голосов
/ 06 июня 2018

Я выделяю несколько массивов ранга 3, чтобы они были в точности одинаковой формы, и мне интересно, возможно ли указать форму только один раз.Например, в настоящее время я делаю:

program main
   implicit none
   integer :: long_name_dimension_1 = 3
   integer :: long_name_dimension_2 = 5
   integer :: long_name_dimension_3 = 8

   real, allocatable, dimension(:,:,:) :: A, B, C

   allocate(A(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3), &
            B(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3), &
            C(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3))

end program main

Это неудобно печатать, и сложно сразу увидеть, что эти массивы имеют одинаковую форму.Я мог бы использовать mold или source после выделения первого массива, например:

allocate(A(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3))
allocate(B, source=A)
allocate(C, mold=A)

, но мне это тоже не очень нравится - возможно, потому что, на мой взгляд, это должен быть один оператор allocate.

Я ищу синтаксис, такой как:

allocate( SHAPE :: (long_name_dimension_1,long_name_dimension_2,long_name_dimension_3), &
   A, B, C)

, который мне не удалось найти.Существует ли такой синтаксис (или что-то подобное)?

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Ну, есть синтаксис для оператора allocate в последнем (2015) стандарте Fortran:

allocate statement in Fortran 2015

Форма должна следовать за каждым Выделение Термин в Выделение-список , поэтому нет никакой синтаксической структуры для объявления одной общей формы для всех переменных, кроме как с параметрами SOURCE или MOLD.

Я мог бы использовать mold или source после выделения первого массива, но мне это тоже не очень нравится - возможно, потому что, на мой взгляд, это должен быть один оператор allocate.

На самом деле вы не можете определить форму массива и ссылаться на него в одном выражении.Далее в этой же главе говорится:

source-expr не должен размещаться в операторе ALLOCATE, в котором он появляется;он также не должен зависеть от значения, границ, параметров отложенного типа, статуса выделения или статуса ассоциации любого allocate-object в этом операторе.

Итак, суммируя,то, что вам больше всего нужно, это то, что вам не нравится:

allocate(A(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3))
allocate(B, C, mold=A)

Или source = A, если вы хотите скопировать содержимое A.


Редактировать:

Как насчет этого:

allocate(A, B, C, mold=reshape([integer ::], &
[long_name_dimension_1,long_name_dimension_2,long_name_dimension_3])

Я только что проверил в Intel Fortran и подтвердил, что он работает.Кажется странным, что массив нулевого размера может иметь любую форму.Я твердо верю, что это не стандартно.

0 голосов
/ 06 июня 2018

Fortran не поддерживает выделение нескольких массивов так, как вы бы этого хотели.Вы почти застряли с опциями mold и source оператора allocate.Вы можете написать

allocate(A(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3))
allocate(B,C,mold=A)

, что экономит несколько нажатий клавиш.Вы можете сэкономить еще несколько, написав

allocate(A(long_name_dimension_1,long_name_dimension_2,long_name_dimension_3))
A = 1
B = A
C = A

, хотя это устанавливает значения элементов B и C, а также их формы.

Я редактировал кодчтобы разобраться с проблемой @evets, поднятой в комментарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...