Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB:将二维矩阵与单元阵列内的三维矩阵相乘_Matlab_Multidimensional Array_Cell Array_Multiplication - Fatal编程技术网

MATLAB:将二维矩阵与单元阵列内的三维矩阵相乘

MATLAB:将二维矩阵与单元阵列内的三维矩阵相乘,matlab,multidimensional-array,cell-array,multiplication,Matlab,Multidimensional Array,Cell Array,Multiplication,我有一个恒定的2D双矩阵mat1。我还有一个2D单元数组mat2,其中每个单元都包含一个2D或3D双矩阵。这些双矩阵的行数和列数与mat1相同。我需要对mat2中每个双矩阵的每个切片进行点乘(.*)mat1。结果需要是另一个单元格数组results,其大小与mat2相同,其中包含的双矩阵在大小上必须等于mat2的双矩阵 以下是我的代码,用于生成mat1和mat2,以便于说明。我在乘法运算应该发生的地方苦苦挣扎 rowCells = 5; colCells = 3; rowTimeSeries =

我有一个恒定的2D双矩阵
mat1
。我还有一个2D单元数组
mat2
,其中每个单元都包含一个2D或3D双矩阵。这些双矩阵的行数和列数与
mat1
相同。我需要对
mat2
中每个双矩阵的每个切片进行点乘(.*)
mat1
。结果需要是另一个单元格数组
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

我提出的一个解决方案是将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

我提出的一个解决方案是将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
您可以使用来消除对自定义函数的需求,它的工作方式与此类似!更新代码:

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
您可以使用来消除对自定义函数的需求,它的工作方式与此类似!更新代码:

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);
这用于执行循环索引和乘法


一些优势

1) 在中指定
'UniformOutput'
'un'
)将返回一个单元格数组,因此
results
变量也是一个单元格数组,不需要初始化(与使用循环相反)

2) 索引的维度决定了输出的
结果的维度,因此它们可以匹配您喜欢的内容

3) 单行可以直接用作函数的输入参数

劣势


1) 而不是像Wolfie在评论中指出的那样,对循环使用

我得到了与Wolfie几乎完全相同的答案,但他抢先给了我答案

不管怎么说,这里有一句话我觉得稍微好一点:

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);
这用于执行循环索引和乘法


一些优势

1) 在中指定
'UniformOutput'
'un'
)将返回一个单元格数组,因此
results
变量也是一个单元格数组,不需要初始化(与使用循环相反)

2) 索引的维度决定了输出的
结果的维度,因此它们可以匹配您喜欢的内容

3) 单行可以直接用作函数的输入参数

劣势


1) 而不是像Wolfie在评论中指出的那样为循环使用

回答得好/code Jacob,我没有想到使用
arrayfun
!也许值得注意的是,这也是一个缺点。我刚刚做了一些测试,使用
arrayfun
似乎比循环各种大小的输入要慢。看看这个问题,最重要的答案是关于
arrayfun
的开销和速度问题:@JacobD您的代码也运行得很好,但是,我更喜欢Wolfie的解决方案。对我来说,主要的优点是代码更容易阅读和理解。但这是我个人的看法。@Wolfie说得好,我忘了在
arrayfun
中添加一些关于速度/开销的内容。对于小尺寸而言,这可能不是一个问题,但扩大规模是的,肯定会浪费一些时间。我可以想象在这种情况下使用
arrayfun
for
循环之间的速度差异很大程度上取决于“内部”和“外部”矩阵大小的比率(
Cells
vs
TimeSeries
),
for
循环通常提供更易于阅读/理解的代码。但是,通常在Matlab中,
for
循环会减慢计算速度,因此可以首选矩阵操作。这个解决方案可能更针对这一点,即使它因为
arrayfun
而变慢,它至少显示了一个没有
for
循环的解决方案。回答好/code Jacob,我没有想到使用
arrayfun
!也许值得注意的是,这也是一个缺点。我刚刚做了一些测试,使用
arrayfun
似乎比循环各种大小的输入要慢。看看这个问题,最重要的答案是关于
arrayfun
的开销和速度问题:@JacobD您的代码也运行得很好,但是,我更喜欢Wolfie的解决方案。对我来说,主要的优点是代码更容易阅读和理解。但这是我个人的看法。@Wolfie说得好,我忘了在
arrayfun
中添加一些关于速度/开销的内容。小号的就可以了