1

配列 X(9,2) があり、考えられるすべての組み合わせで別の配列 B(512,9) を生成したいと考えています。

do ループを 9 回やろうと思ったのですが、もっと効率的な方法を期待していました。

これは私が持っているものです

    do i1=1, 2
    do i2=1, 2
        do i3=1,2
            do i4=1,2
                do i5=1,2
                    do i6=1,2
                        do i7=1,2
                            do i8=i,2
                                do i9=1,2
                                    B(row, col) = X(1,i1)
                                    col = col + 1
                                    B(row, col) = X(2,i2)
                                    col = col + 1
                                    B(row, col) = X(3,i3)
                                    col = col + 1
                                    B(row, col) = X(4,i4)
                                    col = col + 1
                                    B(row, col) = X(5,i5)
                                    col = col + 1
                                    B(row, col) = X(6,i6)
                                    col = col + 1
                                    B(row, col) = X(7,i7)
                                    col = col + 1
                                    B(row, col) = X(8,i8)
                                    col = col + 1
                                    B(row, col) = X(9,i9)
                                    col = 1
                                    row = row + 1
                                end do
                            end do
                        end do
                    end do
                end do
            end do
        end do
    end do
end do

この方法で何か問題がありますか?これを行うより良い方法はありますか?

ありがとう!

4

4 に答える 4

1

次のように B の要素をループすることで、ループを逆にする必要があります (代入の代わりに print ステートメントがあります...)。

 program test
  implicit none

  integer, parameter :: nn = 9, imax = 2
  integer :: row, col, ii
  integer :: indices(nn)

  indices(:) = 1
  do row = 1, imax**nn
    do col = 1, nn
      print "(A,I0,A,I0,A,I0,A,I0,A)", "B(", row, ",", col, ") = X(",&
          & col, ",", indices(col), ")"
      !B(row, col) = X(col, indices(col))
    end do
    indices(nn) = indices(nn) + 1
    ii = nn
    do while (ii > 1 .and. indices(ii) > imax)
      indices(ii) = 1
      indices(ii-1) = indices(ii-1) + 1
      ii = ii - 1
    end do
  end do

end program test

私が見る限り、これは元のコードと同じ結果をもたらしますが、はるかにコンパクトで、あらゆるタプル サイズとインデックス範囲で機能します。

于 2013-01-29T08:44:02.827 に答える
1

私はこれもトリックを行うと思います

ncol = 9
B = 0
tot = 2**ncol
do n = 1, ncol
   div = 2**n
   step = tot/div
   do m = 0, div-1
      fr = 1 + m*step
      to = fr + step
      B(fr:to,n) = X(n, 1+mod(m,2))
   end do
end do

do n = 1, tot
     write(*,*) (B(n,i), i=1,ncol)
end do 
于 2013-01-29T12:35:28.093 に答える
0

実はもっと良い方法があります。たとえば、Martin Broadhurst の組み合わせアルゴリズム、特にデカルト積の例とファイルを参照してくださいn-tuple.c。C 言語であるにもかかわらず、コードは配列と参照パラメーターを使用しているため、インデックスを 0 ではなく 1 から開始するように変更する以外は問題なく Fortran に変換できました。

于 2013-01-29T00:08:45.443 に答える