Matlab中的左循环移位,用于不同数量位置的矩阵的每一行

Posted

技术标签:

【中文标题】Matlab中的左循环移位,用于不同数量位置的矩阵的每一行【英文标题】:Left circular shift in Matlab for each row of a matrix of a different number of positions 【发布时间】:2017-07-07 10:11:36 【问题描述】:

我在 Matlab 中有一个矩阵 A,维度为 mxn,由零和一组成,还有一个矩阵 J,维度为 mx1,报告来自 1,...,n 的一些整数。

我想构造一个维度为mxn 的矩阵B,这样对于

(1)B(1,:)=A(1,:)

(2) 对于i=2,...,mB(i,:) 是通过将A(i,:) 向左循环移动等于(J(1)-1)+ (J(2)-1)+...+ (J(i-1)-1) 的位置数得到的

这段代码做我想做的事

m=4;
n=5;
A=[1 0 1 1 0; ...
   0 1 0 0 1; ...
   1 1 0 0 0; ...
   0 0 0 0 1;
J=[2;1;5;8];
B=zeros(m,n);
B(1,:)=A(1,:);

foridx=cumsum(J); %mx1
shift=foridx-(1:1:m).'; %mx1
v=shift(1:m-1); %(m-1)x1

for i=2:m
    B(i,:)=(circshift((A(i,:)).', -v(i-1),1)).';
end

我想避免最后的循环。我喜欢 Divakar 的答案here,但它适用于右循环。

Arelevant=A(2:end,:);  
idx0 = mod(bsxfun(@plus,n-v(:),1:n)-1,n);
out = Arelevant(bsxfun(@plus,(idx0*(m-1)),(1:(m-1))'));
B(2:end,:)=out;    

你能帮我做一个类似的左循环移位吗?

【问题讨论】:

如果你使用 bsxfun 你并没有真正避免最后的循环,bsxfun 只是隐藏循环。 好的,我明白了,谢谢。那么,你觉得性能和我的版本一模一样吗? 要测量性能,请测试 for 循环和 bsxfunright 换档情况,无论如何,您的代码都更清晰...否则,您也许只需要更改索引,从 1:n-1:-1:-n 以转移另一个方向。 【参考方案1】:

这里有一个小技巧可以在没有循环的情况下执行此操作。

我使用 fft 来移动每一行。

m=4;
n=5;
A=[1 0 1 1 0; ...
   0 1 0 0 1; ...
   1 1 0 0 0; ...
   0 0 0 0 1;]
J=[2;1;5;8];

foridx=cumsum(J); %mx1
shift=foridx-(1:1:m).'; %mx1
v=[0;shift(1:m-1)]; %(m-1)x1
L=real(round(ifft(fft(A,[],2) .* exp(2i*pi/n*v*(0:m)) ,[],2))) %left shift
R=real(round(ifft(fft(A,[],2) .* exp(-2i*pi/n*v*(0:m)) ,[],2))) %right shift

【讨论】:

这很聪明......我想知道这对于更大尺寸的数组会有什么性能。 老实说,我不认为它会比循环更快。即使 fft 的第一个 f 表示“快” =)

以上是关于Matlab中的左循环移位,用于不同数量位置的矩阵的每一行的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB:在矩阵中插入不同数量的 NaN

matlab的左除和右除

利用matlab对矩阵的特定位置赋值?

matlab中如何给一个矩阵中的某几个特定位置赋值

矩阵循环移位

MATLAB一维数组循环移位