matlab 填充数组[副本]的通用算法

bvn4nwqk  于 12个月前  发布在  Matlab
关注(0)|答案(1)|浏览(194)

此问题已在此处有答案

Generate a matrix containing all combinations of elements from n vectors (Cartesian product)(4个答案)
上个月关门了。
我有一个代码,它适用于3维,但我希望能够动态地指定维度的数量。有一个函数nchoosek,但它创建了一个非重复元素的数组。
这是我的3D代码:

energy_band=70;
count=1;
for i=-energy_band:energy_band
    for j=-energy_band:energy_band
        for z=-energy_band:energy_band
          out(1,count)=i;
          out(2,count)=j;
          out(3,count)=z;
          count=count+1;
       end
   end
end

我们需要一个类似的算法,但对于任意数量的维度。例如,当我需要创建一个4维数组时,代码如下所示:

for i=-energy_band:energy_band %array formation cycle with energy shifts in the range from -1.75 eV to 1.75 eV
            for j=-energy_band:energy_band
                for z=-energy_band:energy_band
                    for k=-energy_band:energy_band
                        out(1,count)=i;
                        out(2,count)=j;
                        out(3,count)=z;
                        out(4,count)=k;
                        count=count+1;
                    end
                end
            end
        end

目前我正在用下面的函数解决这个问题,但正如你所看到的,这里没有普适性:

function out=energy_array(matrix_version,energy_band)
count=1;
switch matrix_version
    case 1
        for i=-energy_band:energy_band %array formation cycle with energy shifts in the range from -1.75 eV to 1.75 eV
            out(1,count)=i;
            count=count+1;
        end
    case 2
        for i=-energy_band:energy_band %array formation cycle with energy shifts in the range from -1.75 eV to 1.75 eV
            for j=-energy_band:energy_band
                out(1,count)=i;
                out(2,count)=j;
                count=count+1;
            end
        end
    case 3
        for i=-energy_band:energy_band %array formation cycle with energy shifts in the range from -1.75 eV to 1.75 eV
            for j=-energy_band:energy_band
                for z=-energy_band:energy_band
                    out(1,count)=i;
                    out(2,count)=j;
                    out(3,count)=z;
                    count=count+1;
                end
            end
        end
    case 4
        for i=-energy_band:energy_band %array formation cycle with energy shifts in the range from -1.75 eV to 1.75 eV
            for j=-energy_band:energy_band
                for z=-energy_band:energy_band
                    for k=-energy_band:energy_band
                        out(1,count)=i;
                        out(2,count)=j;
                        out(3,count)=z;
                        out(4,count)=k;
                        count=count+1;
                    end
                end
            end
        end
    case 5
        for i=-energy_band:energy_band %array formation cycle with energy shifts in the range from -1.75 eV to 1.75 eV
            for j=-energy_band:energy_band
                for z=-energy_band:energy_band
                    for k=-energy_band:energy_band
                        for l=-energy_band:energy_band
                            out(1,count)=i;
                            out(2,count)=j;
                            out(3,count)=z;
                            out(4,count)=k;
                            out(5,count)=l;
                            count=count+1;
                        end
                    end
                end
            end
        end
end

我如何才能更优雅地实现这一点,而不需要详细说明所有不同的情况?

m4pnthwp

m4pnthwp1#

您可以使用ndgrid创建这样的数组。该函数为所需数组的每一列输出一个单独的数组,因此我们需要应用一些技巧来收集任意数量的输出并将它们连接为矩阵的列:

function out = energy_array(matrix_version, energy_band)
   arrays = cell(matrix_version,1);
   range = -energy_band:energy_band;
   inputs = repmat({range}, matrix_version, 1);
   [arrays{:}] = ndgrid(inputs{:});
   arrays = cellfun(@(x) x(:).', arrays, 'UniformOutput', false);
   out = cat(2, arrays{:});
end

arrays是一个单元阵列,输出数量为ndgrid。这是接收可变数量的输出参数的技巧。
inputs是一个单元数组,其输入参数为ndgridinputs{:}是单元数组中的值的逗号分隔列表,这意味着每个元素都是一个单独的参数。
在调用ndgrid之后,arrays包含一组matrix_version数组,每个数组的维数为matrix_version。我们需要将它们转换为列向量,您可以将arrays{i} = arrays{i}(:)转换为每个i。这就是cellfun行的作用。最后,我们将得到的数组连接成一个矩阵。
[Note:this是一个更好的解决方案,我保留了这个以防止删除。

相关问题