Рекурсивный N-вложенный цикл

Учтите, что у вас есть квадратная матрица M(N,N) и вы хотите просуммировать все пары, такие что:

M(i,j)*M(i+1,j)+M(i,j)*M(i,j+1)

для этого проще всего вычислить:

INTEGER i,j,N, SUMT
INTEGER M(100,100), c(101)

N=100
SUMT = 0
do j=1,N   
  c(j) = j
end do
c(N+1)=1

do j=1,N   
   do i=1,N
      SUMT = SUMT + M(i,j)*M(c(i+1),j)+M(i,j)*M(i,c(j*1))
   end do 
end do

ПРИМЕЧАНИЕ. c — это быстрый способ применить периодическое граничное условие.

В моей задаче для трехмерной системы {M(N,N,N)} я должен сделать следующее:

M(i,j,k)*M(i+1,j,k)+M(i,j,k)*M(i,j+1,k)+M(i,j,k)*M(i,j,k+1)

Итак, код:

INTEGER i,j,k,N, SUMT
INTEGER M(100,100), c(101)
SUMT = 0
do j=1,N   
  c(j) = j
end do

c(N+1)=1 
N=100

do j=1,N   
   do i=1,N
      SUMT = SUMT +M(i,j,k)*M(c(i+1),j,k)+M(i,j,k)*M(i,c(j+1),k)+M(i,j,k)*M(i,j,c(k+1))
   end do 
end do

На данный момент мой вопрос:

Есть ли способ вычислить эту проблему с вложенными циклами, такой размер матрицы M является параметром? Я имею в виду, я мог бы сделать:

INTEGER i,j,k,l,m,n,....
INTEGER N, SUMT, D
PARAMETER (N=100)
PARAMETER (D=3) !DIMENSION

INTEGER M(N**D), c(N+1)

if (dim=1) then
  do i=1,N
else if (dim=2) then
  do j=1,N
    do i=1,N
else if (dim=3) then
  do k=1,N
    do j=1,N
       do i=1,N
 ....

но вы думаете о более элегантном решении на фортране 77?

Я думал о доступе к матрице M с dim D, как если бы она имела только одно измерение с пробелами N ** D, но я думаю, что если применить инструкции if внутри предела контроля N, это будет работать очень медленно. Любая хорошая идея, или я должен рассмотреть неприятные циклы if-do?


person Learning from masters    schedule 16.11.2015    source источник
comment
Если вы заботитесь об элегантности или краткости, забудьте Fortran 77, это 2015 год. Но я не вижу проблемы. Зачем нужны все три ветки, если это параметр? Компилятор все равно отбросит их при оптимизации.   -  person Vladimir F    schedule 16.11.2015


Ответы (1)


Я не знаю фортран и не уверен, что это вам нужно, но вот некоторый псевдокод, который может помочь

INTEGER N, D, m
INTEGER I(D)     ! indices in each dimension
do j=1,N**D      ! loop over whole matrix
  m = j          
  do k=1,D           ! for each dimension
    I(k) = MOD(m,N)  ! get index in dimension k
    m = m / N        ! and move to next most-significant "register"
  end do
  ! now you have an array of indices for this item
  ! do stuff here
end do

например D=3, N=100 означает, что j изменяется от 1 до 1000000
I последовательно становится массивом [1,1,1], [2,1,1], [3,1,1], ... [100,100,100]

person Sanjay Manohar    schedule 16.11.2015