Discover MakerZone

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

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Circshift the columns of an array with different shiftsize withou using for loop

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?

6 Comments

Giorgos Papakonstantinou on 15 Jun 2013

I want to avoid this loop:

 a=randi(10,5,4)
  shiftindex=[0 1 2 3];
for uu=1:length(shiftindex);
    a(:,uu)=circshift(a(:,uu),[shiftindex(uu) 0]);
end
Matt J on 15 Jun 2013

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.

Giorgos Papakonstantinou

Products

No products are associated with this question.

3 Answers

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')

4 Comments

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.

Matt J
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)));

4 Comments

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.

Matt J on 17 Jun 2013

What is the purpose of the dots in the second line?

Not sure which "dots" you mean. I think you know what the dots in (0:m-1) does. The colon operator produces a vector 0,1,2,..m-1.

Andrei Bobrov
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];

0 Comments

Giorgos Papakonstantinou

Contact us