[英]MATLAB: Multiply 2D matrix with 3D matrix within cell arrays
我有一個恆定的二維雙矩陣mat1
。 我也有一個2D單元陣列mat2
,其中每個單元都包含一個2D或3D雙矩陣。 這些雙矩陣具有與mat1
相同的行數和列mat1
。 我需要在mat2
的每個雙mat1
矩陣的每個切片上點乘(。*) mat1
。 結果需要是另一個大小與mat2
相同的單元格數組results
,因此,在大小上,有條件的雙重矩陣必須等於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
你可以使用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矩陣,其中每個“切片”中的行數和列數均相同,因此它應適用於您的情況。
您也不需要分別遍歷單元格數組的行和列。 這個循環具有相同的迭代次數,但是它是一個循環而不是兩個循環,因此代碼更加精簡了:
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
我得到的答案幾乎與沃爾夫完全相同,但他擊敗了我。
無論如何,這是一個我認為稍微好一點的班輪:
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)在arrayfun
指定'UniformOutput'
( 'un'
) arrayfun
返回單元格數組,因此results
變量也是單元格數組,不需要初始化(與使用循環相反)。
2)索引的維度確定輸出results
的維度,因此它們可以匹配您喜歡的維度。
3)單行可以直接用作函數的輸入參數。
壞處
我想到的一種解決方案是將2D與3D矩陣的乘法外包給一個函數。 但是,我很想知道這是否是解決此問題的最有效方法?
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.