Performance 朱莉娅:有没有办法用离散集合中的条目来枚举所有大小为m×n的矩阵?

Performance 朱莉娅:有没有办法用离散集合中的条目来枚举所有大小为m×n的矩阵?,performance,matrix,julia,permutation,Performance,Matrix,Julia,Permutation,我正在处理一组二维网格中两个变量f(x,y)的函数。网格中每个点的函数本身只能从有限集中获取值。我需要列举我能构造的所有可能的函数 特别是,函数定义为矩阵,其中第i个第j个元素告诉我在x_i,y_j处计算的函数值 我希望能够创建所有可能的矩阵。我知道这样的矩阵的总数是nf^(nx*ny),其中nf是函数在一个点上可以接受的值的数量,nx,ny是x和y的网格中的点的数量。因此,我的测试将使用少量的网格点 多谢各位 我试图将问题表示为枚举树中的所有分支并使用递归,但无法创建矩阵作为输出。这是您想要的

我正在处理一组二维网格中两个变量f(x,y)的函数。网格中每个点的函数本身只能从有限集中获取值。我需要列举我能构造的所有可能的函数

特别是,函数定义为矩阵,其中第i个第j个元素告诉我在x_i,y_j处计算的函数值

我希望能够创建所有可能的矩阵。我知道这样的矩阵的总数是nf^(nx*ny),其中nf是函数在一个点上可以接受的值的数量,nx,ny是x和y的网格中的点的数量。因此,我的测试将使用少量的网格点

多谢各位


我试图将问题表示为枚举树中的所有分支并使用递归,但无法创建矩阵作为输出。

这是您想要的吗

function funs(fs)
    nf = length(fs)
    @assert length(unique(size.(fs))) == 1
    nx,ny = size(fs[1])
    sigs = Iterators.product(ntuple(i -> 1:nf, nx*ny)...)
    ([fs[sig[i+(j-1)*nx]][nx,ny] for i in 1:nx, j in 1:ny] for sig in sigs)
end
我返回了一个生成器,您可以轻松地迭代它而不必具体化,因为收集它可能会占用太多内存。当然,对于小数据,您可以
收集
它,另外的好处是它将是一个
nx*ny
维度数组,允许您轻松地对不同维度进行切片

以下是一个例子:

julia> fs = [fill(1,2,2), fill(2,2,2), fill(3,2,2)]
3-element Array{Array{Int64,2},1}:
 [1 1; 1 1]
 [2 2; 2 2]
 [3 3; 3 3]

julia> funs(fs)
Base.Generator{Base.Iterators.ProductIterator{NTuple{4,UnitRange{Int64}}},getfield(Main, Symbol("##46#49")){Array{Array{Int64,2},1},Int64,Int64}}(getfield(Main, Symbol("##46#49")){Array{Array{Int64,2},1},Int64,Int64}(Array{Int64,2}[[1 1; 1 1], [2 2; 2 2], [3 3; 3 3]], 2, 2), Base.Iterators.ProductIterator{NTuple{4,UnitRange{Int64}}}((1:3, 1:3, 1:3, 1:3)))

julia> collect(funs(fs))
3×3×3×3 Array{Array{Int64,2},4}:
[:, :, 1, 1] =
 [1 1; 1 1]  [1 1; 2 1]  [1 1; 3 1]
 [2 1; 1 1]  [2 1; 2 1]  [2 1; 3 1]
 [3 1; 1 1]  [3 1; 2 1]  [3 1; 3 1]

[:, :, 2, 1] =
 [1 2; 1 1]  [1 2; 2 1]  [1 2; 3 1]
 [2 2; 1 1]  [2 2; 2 1]  [2 2; 3 1]
 [3 2; 1 1]  [3 2; 2 1]  [3 2; 3 1]

[:, :, 3, 1] =
 [1 3; 1 1]  [1 3; 2 1]  [1 3; 3 1]
 [2 3; 1 1]  [2 3; 2 1]  [2 3; 3 1]
 [3 3; 1 1]  [3 3; 2 1]  [3 3; 3 1]

[:, :, 1, 2] =
 [1 1; 1 2]  [1 1; 2 2]  [1 1; 3 2]
 [2 1; 1 2]  [2 1; 2 2]  [2 1; 3 2]
 [3 1; 1 2]  [3 1; 2 2]  [3 1; 3 2]

[:, :, 2, 2] =
 [1 2; 1 2]  [1 2; 2 2]  [1 2; 3 2]
 [2 2; 1 2]  [2 2; 2 2]  [2 2; 3 2]
 [3 2; 1 2]  [3 2; 2 2]  [3 2; 3 2]

[:, :, 3, 2] =
 [1 3; 1 2]  [1 3; 2 2]  [1 3; 3 2]
 [2 3; 1 2]  [2 3; 2 2]  [2 3; 3 2]
 [3 3; 1 2]  [3 3; 2 2]  [3 3; 3 2]

[:, :, 1, 3] =
 [1 1; 1 3]  [1 1; 2 3]  [1 1; 3 3]
 [2 1; 1 3]  [2 1; 2 3]  [2 1; 3 3]
 [3 1; 1 3]  [3 1; 2 3]  [3 1; 3 3]

[:, :, 2, 3] =
 [1 2; 1 3]  [1 2; 2 3]  [1 2; 3 3]
 [2 2; 1 3]  [2 2; 2 3]  [2 2; 3 3]
 [3 2; 1 3]  [3 2; 2 3]  [3 2; 3 3]

[:, :, 3, 3] =
 [1 3; 1 3]  [1 3; 2 3]  [1 3; 3 3]
 [2 3; 1 3]  [2 3; 2 3]  [2 3; 3 3]
 [3 3; 1 3]  [3 3; 2 3]  [3 3; 3 3]

以下是我对OP的理解:

function all_functions(finite_set, nx, ny)
  I = Iterators.product(fill(finite_set, nx*ny)...)
  (reshape(collect(i), (nx,ny)) for i in I)
end
在行动中:

julia>fs = (0,1,2,3)
julia>collect(Iterators.take(all_functions(fs, 2, 2), 8))
Array{Int64,2}[[0 0; 0 0], [1 0; 0 0], [2 0; 0 0], [3 0; 0 0], [0 0; 1 0], [1 0; 1 0], [2 0; 1 0], [3 0; 1 0]]