2010-11-01 2 views
9

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

integer myarray :: (maxdim, nr) 

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

ответ

16

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

В качестве первого шага, идти вперед и записать фактическую DO -loop:

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) /) 

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

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

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

5  10 
    50 

Конструктор массива просто расширяющихся 1-мерный массив, сглаживающий любые вложенные массивные конструкции. Мы можем фактически отказаться от второго набора (/ /) для упрощения. Поскольку все уже в правильном порядке, мы можем использовать встроенный 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 
+7

Обратите внимание, что это справедливо и для записи 'myarray_implicit = Reshape ((/ ((I, I = 1, MAXDIM), J = 1, NR) /), shape (myarray_implicit)) ' , чтобы избежать явного ввода размеров вашей матрицы. – Markus

6

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

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

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

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

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