Выделение массивов одинакового размера

Я хотел бы выделить массив B одинаковой формы и иметь те же нижние и верхние границы, что и другой массив A. Например, я мог бы использовать

allocate(B(lbound(A,1):ubound(A,1), lbound(A,2):ubound(A,2), lbound(A,3):ubound(A,3)))

Но не только это неэлегантно, но и становится очень раздражающим для массивов (даже) более высоких измерений.

Я надеялся на что-то большее, чем

allocate(B(shape(A)))

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

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

Ответ 1

Начиная с Fortran 2008, теперь существует необязательный аргумент MOLD:

ALLOCATE(B, MOLD=A)

Спецификатор MOLD = работает почти так же, как SOURCE =. Если вы укажете MOLD =, а source_expr - переменная, ее значение не обязательно должно быть определено. Кроме того, MOLD = не копирует значение source_expr в назначаемую переменную.

Источник: IBM Fortran Ref

Ответ 2

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

#define DIMS3D(my_array) lbound(my_array,1):ubound(my_array,1),lbound(my_array,2):ubound(my_array,2),lbound(my_array,3):ubound(my_array,3)

allocate(B(DIMS3D(A)))

не забудьте скомпилировать, например. параметр -cpp (gfortran)

Если вы используете Fortran 2003 или выше, вы можете использовать исходный аргумент:

allocate(B, source=A)

но это также скопирует элементы A в B.

Ответ 3

Если вы делаете это много и считаете его слишком уродливым, вы можете написать свою собственную подпрограмму, чтобы позаботиться об этом, copy_dims (template, new_array), инкапсулируя строку исходного кода, которую вы показываете. Вы могли бы даже создать общий интерфейс, чтобы он мог обрабатывать массивы нескольких рангов - см. как написать оболочку для "allocate" для примера этой концепции.