MATLAB 中的逐元素矩阵复制
Element-wise Matrix Replication in MATLAB
我有一个 3 维矩阵。我想将大小为 8x2x9 的矩阵复制到向量给出的第三维中的指定次数,例如 [3, 2, 1, 1, 5, 4, 2, 2, 1]
,以便生成的矩阵大小为 8x2x21。是否有任何内置的 MATLAB 函数(我是 运行 版本 2014a)来执行类似于更新的 repelem
函数的矩阵?
我需要的一个简单示例:
% Input:
A(:,:,1) = [1 2; 1 2];
A(:,:,2) = [2 3; 2 3];
% Function call:
A = callingfunction(A, 1, 1, [1 2]);
% Output:
A(:,:,1) = [1 2; 1 2];
A(:,:,2) = [2 3; 2 3];
A(:,:,3) = [2 3; 2 3];
对于 R2015a 和更新版本...
根据 repelem
的文档(首次在版本 R2015a 中引入),它也可以对矩阵进行运算。我相信下面的代码应该可以完成你想要的(我无法测试它,因为我有一个旧版本):
newMat = repelem(mat, 1, 1, [3 2 1 1 5 4 2 2 1]);
对于 R2015a 之前的版本...
您可以使用 this question to replicate an index into the third dimension, then simply index your matrix with that. For example (adapting Divakar's solution 中的一种方法):
vals = 1:size(mat, 3);
clens = cumsum([3 2 1 1 5 4 2 2 1]);
index = zeros(1, clens(end));
index([1 clens(1:end-1)+1]) = diff([0 vals]);
newMat = mat(:, :, cumsum(index));
然后您可以将其概括为一个函数以在多个维度上进行操作,例如 repelem
:
function A = my_repelem(A, varargin)
index = cell(1, nargin-1);
for iDim = 1:nargin-1
lens = varargin{iDim};
if isscalar(lens)
if (lens == 1)
index{iDim} = ':';
continue
else
lens = repmat(lens, 1, size(A, iDim));
end
end
vals = 1:size(A, iDim);
clens = cumsum(lens);
index{iDim} = zeros(1, clens(end));
index{iDim}([1 clens(1:end-1)+1]) = diff([0 vals]);
index{iDim} = cumsum(index{iDim});
end
A = A(index{:});
end
对于您的示例数据,您可以像这样使用它:
>> A(:,:,1) = [1 2; 1 2];
>> A(:,:,2) = [2 3; 2 3];
>> A = my_repelem(A, 1, 1, [1 2])
A(:,:,1) =
1 2
1 2
A(:,:,2) =
2 3
2 3
A(:,:,3) =
2 3
2 3
我有一个 3 维矩阵。我想将大小为 8x2x9 的矩阵复制到向量给出的第三维中的指定次数,例如 [3, 2, 1, 1, 5, 4, 2, 2, 1]
,以便生成的矩阵大小为 8x2x21。是否有任何内置的 MATLAB 函数(我是 运行 版本 2014a)来执行类似于更新的 repelem
函数的矩阵?
我需要的一个简单示例:
% Input:
A(:,:,1) = [1 2; 1 2];
A(:,:,2) = [2 3; 2 3];
% Function call:
A = callingfunction(A, 1, 1, [1 2]);
% Output:
A(:,:,1) = [1 2; 1 2];
A(:,:,2) = [2 3; 2 3];
A(:,:,3) = [2 3; 2 3];
对于 R2015a 和更新版本...
根据 repelem
的文档(首次在版本 R2015a 中引入),它也可以对矩阵进行运算。我相信下面的代码应该可以完成你想要的(我无法测试它,因为我有一个旧版本):
newMat = repelem(mat, 1, 1, [3 2 1 1 5 4 2 2 1]);
对于 R2015a 之前的版本...
您可以使用 this question to replicate an index into the third dimension, then simply index your matrix with that. For example (adapting Divakar's solution 中的一种方法):
vals = 1:size(mat, 3);
clens = cumsum([3 2 1 1 5 4 2 2 1]);
index = zeros(1, clens(end));
index([1 clens(1:end-1)+1]) = diff([0 vals]);
newMat = mat(:, :, cumsum(index));
然后您可以将其概括为一个函数以在多个维度上进行操作,例如 repelem
:
function A = my_repelem(A, varargin)
index = cell(1, nargin-1);
for iDim = 1:nargin-1
lens = varargin{iDim};
if isscalar(lens)
if (lens == 1)
index{iDim} = ':';
continue
else
lens = repmat(lens, 1, size(A, iDim));
end
end
vals = 1:size(A, iDim);
clens = cumsum(lens);
index{iDim} = zeros(1, clens(end));
index{iDim}([1 clens(1:end-1)+1]) = diff([0 vals]);
index{iDim} = cumsum(index{iDim});
end
A = A(index{:});
end
对于您的示例数据,您可以像这样使用它:
>> A(:,:,1) = [1 2; 1 2];
>> A(:,:,2) = [2 3; 2 3];
>> A = my_repelem(A, 1, 1, [1 2])
A(:,:,1) =
1 2
1 2
A(:,:,2) =
2 3
2 3
A(:,:,3) =
2 3
2 3