Circshift an ND array by values in an (N-1)D array w/out for loop

I have an ND array A that I would like to circshift (in its Nth dimension) by the corresponding values in an (N-1)D array b, ideally without a for loop (and/or fft/ifft). For example:
A(:,:,1) =
1 3 5
2 4 6
A(:,:,2) =
7 9 11
8 10 12
A(:,:,3) =
13 15 17
14 16 18
A(:,:,4) =
19 21 23
20 22 24
b =
1 -1 -3
-1 -1 0
with the result:
A_shift_b(:,:,1) =
19 9 23
8 10 6
A_shift_b(:,:,2) =
1 15 5
14 16 12
A_shift_b(:,:,3) =
7 21 11
20 22 18
A_shift_b(:,:,4) =
13 3 17
2 4 24
I've been trying to use arrayfun to get to a solution, but so far have been unsuccessful. Any help would be appreciated. Thanks!

 Accepted Answer

A = reshape(1:24,[2 3 4]);
b = [1 -1 -3
-1 -1 0];
[m,n,k]= size(A);
A1 = reshape(A,[],k);
mn = m*n;
try
out = reshape(A1((1:mn)'+mn*rem((1:k) - b(:) + k-1,k)),[m,n,k]);% R2016b and later
catch
out = reshape(A1(bsxfun(@plus,(1:mn)',...
mn*rem(bsxfun(@minus,1:k,b(:)) + k-1,k))),[m,n,k]); %R2016a and earlier
end

2 Comments

Could you explain the the role played by (1:k) in this code? It seems to me that it would require length(1:k) = length(b(:)), except that condition doesn't hold in the example given and the code still works. In addition, why doesn't (1:k) - b(:) throw an error, since one is a row vector and the other a column vector? I have started getting a "matrix dimensions must agree" error from this code and am not sure why I didn't earlier on.
(and, fyi, the bsxfun catch does properly evaluate, but I'm also running on R2016b, so I'm curious about why the "try" code hits an error)

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!