我有一个恒定的二维双矩阵mat1。我也有一个2D单元阵列mat2,其中每个单元包含一个2D或3D双矩阵。这些双矩阵的行数和列数与mat1相同。我需要点乘(.*) mat1与每一个双矩阵在mat2中的每一片。结果需要另一个单元格阵列results,其大小与mat2相同,因此,控制双矩阵的大小必须等于mat2的双矩阵。
下面是我的代码,用于生成mat1和mat2,以便于说明。我正在为应该进行乘法的时刻而奋斗。
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发布于 2017-04-26 12:57:04
您可以使用bsxfun来消除对自定义函数multiply2D3D的需求,它以类似的方式工作!更新代码:
results = cell(rowCells,colCells);
for c = 1:colCells
for r = 1:rowCells
results{r,c} = bsxfun(@times, mat1, mat2{r,c});
end
end这将适用于2D和3D矩阵,在每个“切片”中行数和cols数是相同的,因此在您的情况下应该可以工作。
您也不需要分别遍历单元格数组的行和列。这个循环有相同的迭代次数,但它是一个循环而不是两个循环,因此代码稍微简化了一点:
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发布于 2017-04-26 13:09:37
我的答案和沃尔菲几乎完全一样,但他比我强。
总之,这里有一条我认为稍微好一点的衬垫:
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);这使用arrayfun来执行循环索引和乘法的bsxfun。
几个优点
1)在'UniformOutput' ('un')中指定arrayfun返回单元数组,因此results变量也是单元数组,不需要初始化(与使用循环不同)。
2)索引的维数决定了输出时results的维数,因此它们可以匹配您喜欢的内容。
3)单行可直接用作函数的输入参数。
Disadvantage
( 1) Can run slower比使用for循环(如Wolfie在注释中所指出的那样)更重要。
发布于 2017-04-26 12:40:52
我想出的一种解决方案是将带有三维矩阵的2D乘法输出到函数中。不过,我很想知道这是否解决这个问题最有效的方法?
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
endhttps://stackoverflow.com/questions/43633782
复制相似问题