Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用fortran生成可能组合的矩阵_Fortran - Fatal编程技术网

使用fortran生成可能组合的矩阵

使用fortran生成可能组合的矩阵,fortran,Fortran,我有一个数组X(9,2),我想用所有可能的组合生成另一个数组B(512,9) 我想做9个do循环,但我希望有一个更有效的方法 这就是我所拥有的 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

我有一个数组X(9,2),我想用所有可能的组合生成另一个数组B(512,9)

我想做9个do循环,但我希望有一个更有效的方法

这就是我所拥有的

    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
这样有什么问题吗?有更好的方法吗


谢谢

确实有更好的办法。例如,请参阅,-特别是笛卡尔乘积示例和文件
n-tuple.c
。尽管是C语言,但代码始终使用数组和引用参数,因此可以毫无困难地转换为Fortran,只需将索引更改为从1开始,而不是从0开始。他使用的方法是使用索引数组向上计数。

你应该通过如下方式循环B的元素(我有一个打印语句而不是赋值…):


据我所见,这与您的原始代码的结果相同,但更紧凑,适用于任何元组大小和索引范围。

我认为这也可以实现

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 

谢谢西蒙!我不懂c,得到一些fortran代码有什么变化吗?我没有遇到任何适合fortran的代码。不过,从C语言翻译过来一点也不难。您需要将
for
循环更改为
while
循环,将
++
运算符从
x++
更改为
x=x+1
等。但是,否则Fortran子例程看起来与C非常相似。您几乎可以通过尝试使用Fortran编译器编译C并修复编译器逐个报告。您可以找到一本很好的C for Fortran程序员入门(快速)指南。解释代码总是好的。只有代码的答案是不受欢迎的,尤其是当它们超过几行时。我知道这里还有其他答案没有太多解释,但它们都很古老,没有多少投票权。
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 
  character *70 ofil
  ofil='allcomb.txt'
  write(*,*)'feed n and m (Note: n or m larger than 20 takes time)'
  read(*,*) n,m
  write(*,*)'feed file name to store results'
  read(*,*) ofil
  call combin(n,m,ofil)
  write(*,*)'Over'
  end
  !---------------------------------------------------------------
  subroutine combin(n,m,ofil)
  ! Generates all ncm combinatins
  parameter (mx=20)! mx is maximum dimension
  Integer a(mx),b(mx),c
  double precision ncm,ic
  character *70 ofil
  open(15,file=ofil)
  ncm=1
    do i=1,m
    a(i)=i ! a is least indexed combination
    b(i)=n-m+i ! b is maximum indexed combination
    ncm=ncm*b(i)/i ! total possible combinations
    enddo
  write (15,*) (a(i),i=1,m)! Initial (least indexed) combination
  incmpl=1
  ic=1
  ! --------------------------------------------------------------
  do while (incmpl.ne.0 .and.int(ic).lt.ncm)
  incm=0
    do i=1,m
    incm=incm+(b(i)-a(i))
    enddo
  incmpl=incm
  a(m)=a(m)+1
    do i=1,m
    ii=m-i+1
      if(a(ii).gt.b(ii)) then
      a(ii-1)=a(ii-1)+1
         do j=ii,m
         a(j)=a(j-1)+1
         enddo
      endif
    enddo
  ic=ic+1
  write(15,*)(a(k),k=1,m)
  enddo ! end do while loop
  ! --------------------------------------------------------------
  close(15)
  return
  end