Неявная инициализация массива цикла do

Я хочу инициализировать массив одной строкой с помощью неявного цикла do. Однако я всегда получаю ошибку синтаксиса или формы. Может ли кто-нибудь помочь мне исправить следующую конструкцию?

integer myarray :: (maxdim, nr)

myarray(1:maxdim,nr) = (/ (/i,i=1,maxdim/),nr /)

person tarrasch    schedule 01.11.2010    source источник


Ответы (2)


Вы инициализируете массив с MAXDIM строками и NR столбцами, и похоже, что каждый столбец содержит целые числа от 1 до MAXDIM.

В качестве первого шага напишите настоящий DO-цикл:

do j=1,NR
    do i=1,MAXDIM
        myarray(i,j) = i
    end do
end do

Сверните внутренний цикл в структуру неявного цикла:

do j = 1,NR
    myarray(1:MAXDIM,j) = (/ (i, i=1,MAXDIM) /)
end do

Однако когда мы пытаемся свернуть внешний цикл, происходит нечто странное:

myarray = (/ ((/ (i, i=1,MAXDIM) /), j=1,NR) /)

Теперь я получаю ошибку несовместимости рангов, как и вы. Поскольку я тоже не очень хорошо разбираюсь в неявных циклах выполнения, я посмотрел на внутренние результаты shape для конструктора массива:

print *, shape(myarray)
print *, shape((/ ((/ (i, i=1,MAXDIM) /), j=1,NR) /))

Это распечатывает

   5      10
  50

Конструктор массива просто расширяет одномерный массив, сглаживая любые вложенные конструкции массива. На самом деле мы можем отбросить второй набор (/ /) для упрощения. Поскольку все уже в правильном порядке, мы можем использовать встроенную функцию reshape, чтобы обеспечить правильный ранг. Моя полная тестовая программа тогда:

program sotest
    implicit none

    integer, parameter :: MAXDIM = 5
    integer, parameter :: NR     = 10

    integer :: i
    integer :: j
    integer :: myarray(MAXDIM, NR)
    integer :: myarray_implicit(MAXDIM, NR)

    do j = 1,NR
        do i = 1,MAXDIM
            myarray(i,j) = i
        end do
    end do 

    myarray_implicit = reshape((/ ((i,i=1,MAXDIM), j=1,NR) /), (/ MAXDIM, NR /))

    print *, all(myarray == myarray_implicit)
 end program sotest
person Tim Whitcomb    schedule 01.11.2010
comment
Обратите внимание, что также допустимо писать myarray_implicit = reshape((/ ((i,i=1,MAXDIM), j=1,NR) /), shape(myarray_implicit)), чтобы избежать повторного ввода размеров вашей матрицы. - person Markus; 10.06.2013
comment
Странно, что нельзя неявно инициализировать двумерный массив. Я чувствую, что это должно быть ошибкой в ​​Fortran, а не функцией. (Благодаря десятилетнему опыту работы с Fortran я привыкаю к ​​этому....) - person jvriesem; 15.05.2018

Неявный цикл do создаст только вектор, поэтому вам придется изменить его форму. Что-то вроде этого:

integer, dimension(m,n) :: myarray
integer :: ix, jx
...
myarray = reshape( [ (ix, ix = 1, m*n) ], [ m, n ] )

или, возможно, вам нужен более сложный вложенный цикл с подразумеваемым выполнением:

myarray = reshape( [ ((ix+jx, ix = 1, m), jx = 1, n) ], [ m, n ] )

Обратите внимание, что я использую соглашение Fortran2003 [ ] для разграничения конструкций массивов, а не (/ /). Обратите также внимание, что вы должны объявить подразумеваемые индексные переменные цикла do.

person High Performance Mark    schedule 01.11.2010