下面的函数应该做你想做的,我想。它尽可能简单,以包含数据集基数的rank 1数组作为输入,并返回一个rank 2数组,每个数据集一列,包含该集的索引。表达式1 + mod((i-1)/rep, N)
表示整数序列1,2,...,N
的第012个元素,每个元素重复rep
次。
! (requires explicit interface)
pure function cartprod(v) result(cp)
integer, intent(in) :: v(1:)
integer :: cp(product(v), size(v,1))
integer :: i, j, p, rep
p = product(v)
do j = 1, size(v,1)
rep = p/product(v(1:j))
do i = 1, p
cp(i,j) = 1 + mod((i-1)/rep, v(j))
enddo
enddo
end function
假设你如下定义的动态长度矢量,可以直接获得的组合的基质:
module dynamic_vector
implicit none
type :: d_vector
integer, allocatable :: val(:)
end type
contains
pure function combvec(v) result(cv)
type(d_vector), intent(in) :: v(1:)
integer, allocatable :: cv(:,:)
integer :: i, j, prod, rep, len, sizes(size(v,1))
len = size(v,1)
! Determine sizes of the vectors, loop is necessary because we may not
! reference v%val if v is an array and val is allocatable.
do i = 1, len
sizes(i) = size(v(i)%val,1)
enddo
prod = product(sizes)
! Allocate and fill the output matrix
allocate(cv(prod, len))
do j = 1, len
rep = prod/product(sizes(1:j))
do i = 1, prod
cv(i,j) = v(j)%val(1 + mod((i-1)/rep, sizes(j)))
enddo
enddo
end function
end module
甲短的测试程序:
program test
use dynamic_vector
implicit none
type(d_vector) :: foo(2)
integer :: i, bar(:,:)
allocatable :: bar
allocate(foo(1)%val, source = [1,2])
allocate(foo(2)%val, source = [3,4,5])
bar = combvec(foo)
write(*,'(2(I0,X))') (bar(i,:), i = 1, 6)
end program
结果:
1 3
1 4
1 5
2 3
2 4
2 5
@bdecaf,我猜这是ve可用于创建稀疏矩阵的矩阵。类似于MATLAB中的sparse(vector1,vector2,values,size1,size2)'(我看你是一个MATLAB的人) –
是啊,在想这个 - 这就是为什么我删掉了评论。 – bdecaf
但是要回到你所问的问题叫做[笛卡儿积](http://en.wikipedia.org/wiki/Cartesian_product)。搜索它会导致许多结果,包括SO:[使用fortran生成可能组合的矩阵](http://stackoverflow.com/questions/14572966/generate-a-matrix-of-possible-combinations-using-fortran) – bdecaf