在matlab中生成具有一般维数的网格

Posted

技术标签:

【中文标题】在matlab中生成具有一般维数的网格【英文标题】:Generating a grid in matlab with a general number of dimensions 【发布时间】:2015-03-21 04:16:42 【问题描述】:

问题

我有一个向量 w 包含 n 元素。我事先不知道n

我想生成一个n维网格g,其值范围从grid_mingrid_max,并获得wg的“维数”乘积。

如何为任意n 执行此操作?


示例

为简单起见,假设grid_min = 0grid_max = 5

案例:n=1

>> w = [0.75];
>> g = 0:5

ans =

     0     1     2     3     4     5

>> w * g

ans =

         0    0.7500    1.5000    2.2500    3.0000    3.7500

案例:n=2

>> w = [0.1, 0.2];
>> [g1, g2] = meshgrid(0:5, 0:5)

g1 =

     0     1     2     3     4     5
     0     1     2     3     4     5
     0     1     2     3     4     5
     0     1     2     3     4     5
     0     1     2     3     4     5
     0     1     2     3     4     5


g2 =

     0     0     0     0     0     0
     1     1     1     1     1     1
     2     2     2     2     2     2
     3     3     3     3     3     3
     4     4     4     4     4     4
     5     5     5     5     5     5

>> w(1) * g1 + w(2) * g2

ans =

         0    0.1000    0.2000    0.3000    0.4000    0.5000
    0.2000    0.3000    0.4000    0.5000    0.6000    0.7000
    0.4000    0.5000    0.6000    0.7000    0.8000    0.9000
    0.6000    0.7000    0.8000    0.9000    1.0000    1.1000
    0.8000    0.9000    1.0000    1.1000    1.2000    1.3000
    1.0000    1.1000    1.2000    1.3000    1.4000    1.5000

现在假设用户传入向量w,我们不知道它包含多少元素(n)。如何创建网格并获取产品?

【问题讨论】:

对如此清晰表达的问题表示敬意 如果您遇到“大”n 的内存问题(无论如何,这似乎很快就会爆炸......)如果您采取 Luis,您可能会更进一步>' 方法并将其修改为仅生成 n ggs 之一,并在排列时将其汇总到 for-loop 中。 【参考方案1】:
%// Data:
grid_min = 0;
grid_max = 5;
w = [.1 .2 .3];

%// Let's go:    
n = numel(w);
gg = cell(1,n);
[gg:] = ndgrid(grid_min:grid_max);
gg = cat(n+1, gg:);
result = sum(bsxfun(@times, gg, shiftdim(w(:), -n)), n+1);

这是如何工作的

网格(变量gg)是使用ndgrid 生成的,使用从元胞数组中获得的n 元素中的comma-separated list 作为输出。生成的n 维数组(gg1gg2 等)沿n+1 维(使用cat)连接,这会将gg 转换为n+1 维数组。向量w 被重新整形为n+1-th 维度(shiftdim),使用bsxfun 乘以gg,结果沿n+1-th 维度求和。

编辑:

根据@Divakar 富有洞察力的评论,最后一行可以替换为

sz_gg = size(gg);
result = zeros(sz_gg(1:end-1));
result(:) = reshape(gg,[],numel(w))*w(:);

这会导致显着的加速,因为 Matlab 在矩阵乘法方面甚至比bsxfun 更好(参见例如here 和here)。

【讨论】:

这些张量乘法真的应该是内置的!顺便说一句:更改答案不是一个好主意,因为这更自然,但作为旁注:对于n==2,由于meshgridndgrid,它实际上是OP 问题的转置。我很确定ndgrid 是他真正想要的。 sz_gg = size(gg); result = zeros(sz_gg(1:end-1)); result(:) = reshape(gg,[],numel(w))*w(:); 似乎内存效率更高,并且显示出良好的加速。 @knedlsepp 好点!正如你所说,我想我会保持原样 @Divakar 不错的选择!但是,它似乎并没有加快多少。但我只用tictoc进行了测试 @Divakar:Octave 的 JIT 似乎不太好,所以 ideone 分析不会给出最好的结果,但在我的机器上,this for-approach 对于大 n 甚至会更快。 (虽然不那么漂亮。)

以上是关于在matlab中生成具有一般维数的网格的主要内容,如果未能解决你的问题,请参考以下文章

matlab中怎样计算一个矩阵中每个数的平方

如何在 Matlab 中生成两个具有给定相关系数的 Weibull 随机向量?

如何在Matlab中生成具有对数正态分布和指定几何平均数和几何标准差的随机数

创建具有可变维数的 C++ 向量

在 Matlab 中生成矩阵的所有可能组合

Matlab3-D 网格中 2-D 选择的插值