在 MATLAB 中将一个小矩阵移动到一个更大的矩阵中
Moving a small matrix inside of a bigger matrix in MATLAB
假设 A 是一个 5x5 的零矩阵:
>> A = zeros(5)
A =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
而 B 是一个小矩阵 (2x2):
>> B = ones(2)
B =
1 1
1 1
现在,我正在寻找代表 C1, C2, C3, ..., C16
矩阵的 16 种不同情况
它们是:
C1 =
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
C2 =
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
C3 =
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
... 最后 C16
等于 :
C16 =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
如你所见,它就像是较小的矩阵 (B) 在较大的矩阵 (A) 内部移动。
非常感谢,
您可以在 shift the values about the Matrix 的适当行和列上使用 circshift(...)
来实现您想要的效果。您提到的示例是页面的 'Move Matrix Elements' 部分中显示的带有 4x4 矩阵的示例。
举个例子
A = [1 1 0 0; 1 1 0 0; 0 0 0 0; 0 0 0 0]
A =
1 1 0 0
1 1 0 0
0 0 0 0
0 0 0 0
Y = circshift(A,[1 1])
Y =
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
在 Mathworks 网站上,有一个内置函数似乎可以完全满足您的需求。在 5x5 矩阵上显示 16 种组合的确切代码可以保持小矩阵在大矩阵中移动的错觉
已编辑:所以它现在有一个 5x5x16 矩阵,输出称为 C
A=zeros(5,5);
A(1:2,1:2)=1
c=1;C=zeros(5,5,16);
for i=0:3
for j=0:3
C(:,:,c)=circshift(A,[i j])
c=c+1;
end
end
产生输出(注意输出未编辑)
A =
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 1 1
0 0 0 1 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
我认为这样做的好方法
A = zeros(5);
B = ones(2);
C = cell(size(A,1)-size(B,1) + 1, size(A,2)-size(B,2) + 1);
for i = 1:size(A,1)-size(B,1) + 1
for j = 1:size(A,2)-size(B,2) + 1
C{i, j} = A;
C{i, j}(i:i+size(B,1) - 1, j:j+size(B,2) - 1) = B;
% Additional code here
end
end
C = C(:);
% Additional code here
一种矢量化方法 bsxfun
-
%// Get sizes and form size parameters for creating output
[mA,nA] = size(A);
[mB,nB] = size(B);
mC = mA - mB + 1;
nC = nA - nB + 1;
%// Get linear indices
stage1 = bsxfun(@plus,[1:mB]',[0:nB-1]*mA); %//'
stage2 = bsxfun(@plus,[1:mC]',[0:nC-1]*mA)-1; %//'
idx = bsxfun(@plus,stage1(:),stage2(:).' + [0:mC*nC-1]*mA*nA); %//'
%// Replicate A to setup output; index into it with idx & replace B
C = repmat(A,1,1,mC*nC);
C(idx) = repmat(B(:),1,mC*nC)
样本运行-
A =
1 1 8 4
9 8 8 2
7 9 5 1
7 9 2 9
B =
3 5
3 6
3 1
C(:,:,1) =
3 5 8 4
3 6 8 2
3 1 5 1
7 9 2 9
C(:,:,2) =
1 1 8 4
3 5 8 2
3 6 5 1
3 1 2 9
C(:,:,3) =
1 3 5 4
9 3 6 2
7 3 1 1
7 9 2 9
....
C(:,:,6) =
1 1 8 4
9 8 3 5
7 9 3 6
7 9 3 1
假设 A 是一个 5x5 的零矩阵:
>> A = zeros(5)
A =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
而 B 是一个小矩阵 (2x2):
>> B = ones(2)
B =
1 1
1 1
现在,我正在寻找代表 C1, C2, C3, ..., C16
它们是:
C1 =
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
C2 =
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
C3 =
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
... 最后 C16
等于 :
C16 =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
如你所见,它就像是较小的矩阵 (B) 在较大的矩阵 (A) 内部移动。
非常感谢,
您可以在 shift the values about the Matrix 的适当行和列上使用 circshift(...)
来实现您想要的效果。您提到的示例是页面的 'Move Matrix Elements' 部分中显示的带有 4x4 矩阵的示例。
举个例子
A = [1 1 0 0; 1 1 0 0; 0 0 0 0; 0 0 0 0]
A =
1 1 0 0
1 1 0 0
0 0 0 0
0 0 0 0
Y = circshift(A,[1 1])
Y =
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
在 Mathworks 网站上,有一个内置函数似乎可以完全满足您的需求。在 5x5 矩阵上显示 16 种组合的确切代码可以保持小矩阵在大矩阵中移动的错觉
已编辑:所以它现在有一个 5x5x16 矩阵,输出称为 C
A=zeros(5,5);
A(1:2,1:2)=1
c=1;C=zeros(5,5,16);
for i=0:3
for j=0:3
C(:,:,c)=circshift(A,[i j])
c=c+1;
end
end
产生输出(注意输出未编辑)
A =
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 1 1
0 0 0 1 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
0 0 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
0 0 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
1 1 0 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
ans =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
我认为这样做的好方法
A = zeros(5);
B = ones(2);
C = cell(size(A,1)-size(B,1) + 1, size(A,2)-size(B,2) + 1);
for i = 1:size(A,1)-size(B,1) + 1
for j = 1:size(A,2)-size(B,2) + 1
C{i, j} = A;
C{i, j}(i:i+size(B,1) - 1, j:j+size(B,2) - 1) = B;
% Additional code here
end
end
C = C(:);
% Additional code here
一种矢量化方法 bsxfun
-
%// Get sizes and form size parameters for creating output
[mA,nA] = size(A);
[mB,nB] = size(B);
mC = mA - mB + 1;
nC = nA - nB + 1;
%// Get linear indices
stage1 = bsxfun(@plus,[1:mB]',[0:nB-1]*mA); %//'
stage2 = bsxfun(@plus,[1:mC]',[0:nC-1]*mA)-1; %//'
idx = bsxfun(@plus,stage1(:),stage2(:).' + [0:mC*nC-1]*mA*nA); %//'
%// Replicate A to setup output; index into it with idx & replace B
C = repmat(A,1,1,mC*nC);
C(idx) = repmat(B(:),1,mC*nC)
样本运行-
A =
1 1 8 4
9 8 8 2
7 9 5 1
7 9 2 9
B =
3 5
3 6
3 1
C(:,:,1) =
3 5 8 4
3 6 8 2
3 1 5 1
7 9 2 9
C(:,:,2) =
1 1 8 4
3 5 8 2
3 6 5 1
3 1 2 9
C(:,:,3) =
1 3 5 4
9 3 6 2
7 3 1 1
7 9 2 9
....
C(:,:,6) =
1 1 8 4
9 8 3 5
7 9 3 6
7 9 3 1