I need to circularly shift individual columns of a matrix.
This is easy if you want to shift all the columns by the same amount, however, in my case I need to shift them all by a different amount.
Currently I’m using a loop and if possible I’d like to remove the loop and use a faster, vector based, approach.
My current code
A = randi(2, 4, 2);
B = A;
for i = 1:size( A,2 );
d = randi( size( A,1 ));
B(:,i) = circshift( A(:,i), [d, 0] );
end
Is is possible to remove the loop from this code?
Update I tested all three methods and compared them to the loop described in this question. I timed how long it would take to execute a column by column circular shift on a 1000×1000 matrix 100 times. I repeated this test several times.
Results:
- My loop took more than 12 seconds
- Pursuit’s suggestion less than a seconds
- Zroth’s orginal answer took just over 2 seconds
- Ansari’s suggest was slower than the original loop
Edit
Pursuit is right: Using a for-loop and appropriate indexing seems to be the way to go here. Here’s one way of doing it:
Original answer
I’ve looked for something similar before, but I never came across a good solution. A modification of one of the algorithms used here gives a slight performance boost in my tests:
Ugly? Definitely. Like I said, it seems to be slightly faster (2–3 times faster for me); but both algorithms are clocking in at under a second for
m = 3000andn = 1000(on a rather old computer, too).It might be worth noting that, for me, both algorithms seem to outperform the algorithm provided by Ansari, though his answer is certainly more straightforward. (Ansari’s algorithm’s output does not agree with the other two algorithms for me; but that could just be a discrepancy in how the shifts are being applied.) In general,
arrayfunseems pretty slow when I’ve tried to use it. Cell arrays also seem slow to me. But my testing might be biased somehow.