Reputation: 7922
I have a vector w
containing n
elements. I do not know n
in advance.
I want to generate an n
-dimensional grid g
whose values range from grid_min
to grid_max
and obtain the "dimension-wise" product of w
and g
.
How can I do this for an arbitrary n
?
For simplicity, let's say that grid_min = 0
and grid_max = 5
.
Case: 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
Case: 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
Now suppose a user passes in the vector w
and we do not know how many elements (n
) it contains. How can I create the grid and obtain the product?
Upvotes: 5
Views: 494
Reputation: 112689
%// 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);
How this works:
The grid (variable gg
) is generated with 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
, and the results are summed along the n+1
-th dimension.
Edit:
Following @Divakar's insightful comment, the last line can be replaced by
sz_gg = size(gg);
result = zeros(sz_gg(1:end-1));
result(:) = reshape(gg,[],numel(w))*w(:);
which results in a significant speedup, because Matlab is even better at matrix multiplication than at bsxfun
(see for example here and here).
Upvotes: 8