[英]MATLAB: Multiply 2D matrix with 3D matrix within cell arrays
I have a constant 2D double matrix mat1
. 我有一个恒定的二维双矩阵mat1
。 I also have a 2D cell array mat2
where every cell contains a 2D or 3D double matrix. 我也有一个2D单元阵列mat2
,其中每个单元都包含一个2D或3D双矩阵。 These double matrices have the same number of rows and columns as mat1
. 这些双矩阵具有与mat1
相同的行数和列mat1
。 I need to dot multiply (.*) mat1
with every slice of each double matrix within mat2
. 我需要在mat2
的每个双mat1
矩阵的每个切片上点乘(。*) mat1
。 The result needs to be another cell array results
with the same size as mat2
, whereby the contatining double matrices must equal the double matrices of mat2
in terms of size. 结果需要是另一个大小与mat2
相同的单元格数组results
,因此,在大小上,有条件的双重矩阵必须等于mat2
的双重矩阵。
Here's my code to generate mat1
and mat2
for illustrating purposes. 这是我生成mat1
和mat2
代码,用于说明目的。 I am struggling at the point where the multiplication should take place. 我正在努力进行乘法。
rowCells = 5;
colCells = 3;
rowTimeSeries = 300;
colTimeSeries = 5;
slices = [1;10];
% Create 2D double matrix
mat1 = rand(rowTimeSeries, colTimeSeries);
% Create 2D cell matrix comprisiong 2D and/or 3D double matrices
mat2 = cell(rowCells,colCells);
for c = 1:colCells
for r = 1:rowCells
slice = randsample(slices, 1, true);
mat2{r,c} = rand(rowTimeSeries, colTimeSeries, slice);
end
end
% Multiply (.*) mat1 with mat2 (every slice)
results = cell(rowCells,colCells);
for c = 1:colCells
for r = 1:rowCells
results{r,c} = ... % I am struggling here!!!
end
end
You could use bsxfun
to remove the need for your custom function multiply2D3D
, it works in a similar way! 你可以使用bsxfun
删除需要您自定义函数multiply2D3D
,它的工作原理类似的方式! Updated code: 更新的代码:
results = cell(rowCells,colCells);
for c = 1:colCells
for r = 1:rowCells
results{r,c} = bsxfun(@times, mat1, mat2{r,c});
end
end
This will work for 2D and 3D matrices where the number of rows and cols is the same in each of your "slices", so it should work in your case. 这将适用于2D和3D矩阵,其中每个“切片”中的行数和列数均相同,因此它应适用于您的情况。
You also don't need to loop over the rows and the columns of your cell array separately. 您也不需要分别遍历单元格数组的行和列。 This loop has the same number of iterations, but it is one loop not two, so the code is a little more streamlined: 这个循环具有相同的迭代次数,但是它是一个循环而不是两个循环,因此代码更加精简了:
results = cell(size(mat2));
for n = 1:numel(mat2) % Loop over every element of mat2. numel(mat2) = rowCells*colCells
results{n} = bsxfun(@times, mat1, mat2{n});
end
I had almost the exact same answer as Wolfie but he beat me to it. 我得到的答案几乎与沃尔夫完全相同,但他击败了我。
Anyway, here is a one liner that I think is slightly nicer: 无论如何,这是一个我认为稍微好一点的班轮:
nR = rowCells; % Number of Rows
nC = colCells; % Number of Cols
results = arrayfun(@(I) bsxfun(@times, mat1, mat2{I}), reshape(1:nR*nC,[],nC), 'un',0);
This uses arrayfun
to perform the loop indexing and bsxfun
for the multiplications. 这使用arrayfun
执行循环索引,并使用bsxfun
进行乘法。
A few advantages 一些优点
1) Specifying 'UniformOutput'
( 'un'
) in arrayfun
returns a cell array so the results
variable is also a cell array and doesn't need to be initialised (in contrast to using loops). 1)在arrayfun
指定'UniformOutput'
( 'un'
) arrayfun
返回单元格数组,因此results
变量也是单元格数组,不需要初始化(与使用循环相反)。
2) The dimensions of the indexes determine the dimensions of results
at the output, so they can match what you like. 2)索引的维度确定输出results
的维度,因此它们可以匹配您喜欢的维度。
3) The single line can be used directly as an input argument to a function. 3)单行可以直接用作函数的输入参数。
Disadvantage 坏处
1) Can run slower than using for
loops as Wolfie pointed out in the comments. 1)正如Wolfie在评论中指出的, 运行速度可能比使用for
循环慢 。
One solution I came up with is to outsource the multiplication of a 2D with a 3D matrix into a function. 我想到的一种解决方案是将2D与3D矩阵的乘法外包给一个函数。 However, I am curious to know whether this is the most efficient way to solve this problem? 但是,我很想知道这是否是解决此问题的最有效方法?
rowCells = 5;
colCells = 3;
rowTimeSeries = 300;
colTimeSeries = 5;
slices = [1;10];
% Create 2D double matrix
mat1 = rand(rowTimeSeries, colTimeSeries);
% Create 2D cell matrix comprisiong 2D and/or 3D double matrices
mat2 = cell(rowCells,colCells);
for c = 1:colCells
for r = 1:rowCells
slice = randsample(slices, 1, true);
mat2{r,c} = rand(rowTimeSeries, colTimeSeries, slice);
end
end
% Multiply (.*) mat1 with mat2 (every slice)
results = cell(rowCells,colCells);
for c = 1:colCells
for r = 1:rowCells
results{r,c} = multiply2D3D(mat1, mat2{r,c});
end
end
function vout = multiply2D3D(mat2D, mat3D)
%MULTIPLY2D3D multiplies a 2D double matrix with every slice of a 3D
% double matrix.
%
% INPUTs:
% mat2D:
% 2D double matrix
%
% mat3D:
% 3D double matrix where the third dimension is equal or greater than 1.
%
% OUTPUT:
% vout:
% 3D double matrix with the same size as mat3D. Every slice in vout
% is the result of a multiplication of mat2D with every individual slice
% of mat3D.
[rows, cols, slices] = size(mat3D);
vout = zeros(rows, cols, slices);
for s = 1 : slices
vout(:,:,s) = mat2D .* mat3D(:,:,s);
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.