在matlab中生成具有一般维数的网格
Generating a grid in matlab with a general number of dimensions
问题
我有一个包含 n
个元素的向量 w
。我事先不知道n
。
我想生成一个n
维的网格g
,其值范围从grid_min
到grid_max
,并得到[=的"dimension-wise"乘积12=] 和 g
。
如何为任意 n
执行此操作?
例子
为简单起见,假设 grid_min = 0
和 grid_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
)。如何创建网格并获取产品?
%// 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);
这是如何工作的:
用ndgrid
, using as output a comma-separated list of n
elements obtained from a cell array. The resulting n
-dimensional arrays (gg{1}
, gg{2}
etc) are contatenated along the n+1
-th dimension (using cat
), which turns gg
into an n+1
-dimensional array. The vector w
is reshaped into the n+1
-th dimension (shiftdim
), multiplied by gg
using bsxfun
生成网格(变量gg
),结果沿第n+1
维求和。
编辑:
根据@Divakar 富有洞察力的评论,最后一行可以替换为
sz_gg = size(gg);
result = zeros(sz_gg(1:end-1));
result(:) = reshape(gg,[],numel(w))*w(:);
这会导致显着的加速,因为 Matlab 在矩阵乘法方面比 bsxfun
更好(参见示例 here and here)。
问题
我有一个包含 n
个元素的向量 w
。我事先不知道n
。
我想生成一个n
维的网格g
,其值范围从grid_min
到grid_max
,并得到[=的"dimension-wise"乘积12=] 和 g
。
如何为任意 n
执行此操作?
例子
为简单起见,假设 grid_min = 0
和 grid_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
)。如何创建网格并获取产品?
%// 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);
这是如何工作的:
用ndgrid
, using as output a comma-separated list of n
elements obtained from a cell array. The resulting n
-dimensional arrays (gg{1}
, gg{2}
etc) are contatenated along the n+1
-th dimension (using cat
), which turns gg
into an n+1
-dimensional array. The vector w
is reshaped into the n+1
-th dimension (shiftdim
), multiplied by gg
using bsxfun
生成网格(变量gg
),结果沿第n+1
维求和。
编辑:
根据@Divakar 富有洞察力的评论,最后一行可以替换为
sz_gg = size(gg);
result = zeros(sz_gg(1:end-1));
result(:) = reshape(gg,[],numel(w))*w(:);
这会导致显着的加速,因为 Matlab 在矩阵乘法方面比 bsxfun
更好(参见示例 here and here)。