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

2 views (last 30 days)
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

Andrei Bobrov
Andrei Bobrov on 19 Jun 2017
Edited: Andrei Bobrov on 19 Jun 2017
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
Ty Easley
Ty Easley on 21 Jun 2017
Edited: Ty Easley on 21 Jun 2017
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.
Ty Easley
Ty Easley on 21 Jun 2017
(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)

Community Treasure Hunt

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

Start Hunting!