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

New to MATLAB?

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

Asked by Giorgos Papakonstantinou on 15 Jun 2013
Accepted Answer by Matt J

Matt J (view profile)

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

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

Matt J (view profile)

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.

Products

No products are associated with this question.

3 Answers

Answer by Matt J

Matt J (view profile)

on 15 Jun 2013
Edited by Matt J

Matt J (view profile)

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

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

Matt J (view profile)

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

Matt J (view profile)

Answer by Andrei Bobrov

Andrei Bobrov (view profile)

on 15 Jun 2013
Edited by Andrei Bobrov

Andrei Bobrov (view profile)

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

Matt J (view profile)

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)

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

Matt J (view profile)

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

Andrei Bobrov (view profile)

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

Contact us