MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply TodayTo resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

Asked by Giorgos Papakonstantinou on 15 Jun 2013

As the tittle suggests I am wondering if it is possible to circshift the columns of an array with a different shiftsize in each column without using a for loop.

Example:

a=randi(10,5,4);

I want to do this

a(:,4)=circshift(a(:,4),[-1 0]);

a(:,3)=circshift(a(:,3),[-2 0]);

without a loop. Is it possible?

*No products are associated with this question.*

Answer by Matt J on 15 Jun 2013

Edited by Matt J on 15 Jun 2013

Accepted answer

[m,n]=size(a); S=full(sparse(mod(shiftindex,m)+1,1:n,1,m,n));

a_new=ifft(fft(a).*fft(S),'symmetric')

Show 1 older comment

Giorgos Papakonstantinou on 15 Jun 2013

Can you explain me why a_new matrix has trailing zeros (even in format short) but a matrix does not? I don't get it.

Matt J on 15 Jun 2013

a_new does not consist of exact integers. There are floating point residuals due to the fft/ifft operations used to transform a.

Answer by Andrei Bobrov on 15 Jun 2013

Edited by Andrei Bobrov on 16 Jun 2013

[m,n] = size(a); b = rem(shiftindex-1,m)+1; c = rem(bsxfun(@plus,m + 1 - b - m*(b == 0),(0:m-1)')-1,m)+1; out = a(bsxfun(@plus,c,m*(0:n-1)));

Show 1 older comment

Matt J on 15 Jun 2013

I think maybe this was the idea

[m,n] = size(a);

b=mod(bsxfun(@plus,(0:m-1).',-shiftindex(:).' ),m)+1; b=bsxfun(@plus,b,(0:n-1)*m);

out = a(b)

Giorgos Papakonstantinou on 16 Jun 2013

Indeed Matt thee solution was making shifted copies of the first column. What you proposed last does the shifting correctly. I have question in your second solution.

What is the purpose of the dots in the second line? When you want to square the elements of a matrix you have to put the dot in order this to do it elementwise. But bsxfun is doing the same operation, I think.

Answer by Giorgos Papakonstantinou on 15 Jun 2013

Where is Anrei's answer??? It was here before 2 minutes ago.

Is an answer deleted after accepting a previous one?

I had some question on it that why?

He proposed this:

[m,n] = size(a); out = a(bsxfun(@plus,toeplitz(1:m,[1,m-(0:n-2)]),(0:n-1)*m));

Apart from the fact that its hardcore, my question would be what would be the case if the shiftindex was not linear..

ex.

shiftindex=[2 2 10 5];

## 6 Comments

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/79169#comment_155117

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/79169#comment_155118

oops.. I am sorry

not..5

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/79169#comment_155121

But it still not clear, when it starts and when it ends

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/79169#comment_155122

I want to avoid this loop:

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/79169#comment_155123

Thank you

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/79169#comment_155128

In your example, you modify 'a' in-place. If that's really what you're after, for-loops are going to be pretty competitive. Notice that no iteration of your loop ever allocates any additional memory larger than 1 column a(:,uu). I think there are tools on the FEX that can get rid of even that.