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