我正在使用2D网格中具有两个变量f(x,y)的一组函数。网格中每个点的函数本身只能采用有限集合中的值。我需要列举我可以构造的所有可能的函数。
特别是,函数定义为矩阵,第ith个第j个元素告诉我在x_i,y_j处求值的函数的值。
我希望能够创建所有可能的矩阵。我知道这类矩阵的总数为nf ^(nx * ny),其中nf是函数可以在一个点中采用的值的数量,而nx,ny是x和y网格中的点的数量。因此,我的测试将使用少量的网格点。
谢谢
我试图通过枚举树中的所有分支并使用递归来表达问题,但是无法创建矩阵作为输出。
答案 0 :(得分:1)
这是您想要的吗?
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
我将返回一个生成器,您可以轻松地对其进行迭代而不会实现,因为收集它可能会占用过多的内存。当然,对于小型数据,您可以collect
进行处理,其额外好处是它将成为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]
答案 1 :(得分:0)
这是我对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]]