circshift columns of array by different shift size

15 views (last 30 days)
I'm trying to do the following with arrayfun and circshift
s_dfp = magic(4);
s_hh1p = circshift(s_dfp(:,1),[1 -1]);
s_hh2p = circshift(s_dfp(:,2),[1 -2]);
s_hh3p = circshift(s_dfp(:,3),[1 -3]);
s_hh4p = circshift(s_dfp(:,4),[1 -4]);
HH = [s_hh1p s_hh2p s_hh3p s_hh4p];
s_dfp =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
HH =
4 14 15 1
16 2 3 13
5 11 10 8
9 7 6 12
Each column is shifted by its column number. I would like to do this for arbitrary size.
Thanks in advance.
  1 Comment
Image Analyst
Image Analyst on 10 Apr 2015
This first column is shifted down 1 because the first element, 16, is now in row 2 instead of row 1. However if you were to circularly shift column 2 down, the top element, 2, would be in row 3 instead of row 1. But you have it in row 2. And in the third column, then 3 shifted down 3 rows would be in row 4, not row 2. Finally if you were to circularly shift column 4 down 4, the 13 would land in the same spot (row 1). So, other than the first column being shifted down 1, I can't see what you're doing. In fact, columns 1, 2, 3, and 4 are all shifted down by 1 row, NOT by their column number.

Sign in to comment.

Accepted Answer

Jon
Jon on 10 Apr 2015
I think this does what you want.
HH=cell2mat(arrayfun(@(k) circshift(d(:,k),k),1:size(d,2),'uni',0))
HH =
4 7 10 13
16 14 6 8
5 2 15 12
9 11 3 1)
You may need to change the sign of the second k in the circshift command to get the elements to move in the direction you want.

More Answers (2)

Image Analyst
Image Analyst on 10 Apr 2015
I don't see that what you did matches what you said. But anyway, try this and see if it does what you want:
s_dfp = magic(4)
outputMatrix = s_dfp; % Initialize.
[rows, columns] = size(s_dfp);
for col = 1 : columns
% Extract just this column only.
thisColumn = s_dfp(:, col);
% Shift it down "col" rows.
shiftedColumn = circshift(thisColumn, -col)
% Put it back in
outputMatrix(:, col) = shiftedColumn;
end
% Print to command window
outputMatrix
  5 Comments
Image Analyst
Image Analyst on 12 Oct 2020
You'd need to keep track of how much you shifted each column and shift it in the opposite direction. Or just keep your original image (don't delete it!).

Sign in to comment.


Star Strider
Star Strider on 10 Apr 2015
One possibility is to vectorise it and use an anonymous function:
csm = @(Mtx,Col) circshift(Mtx(:,Col),[1 1-Col]); % Arbitrary Matrix
callcsm = @(Mtx) csm(Mtx, 1:size(Mtx,2));
s_dfp = magic(4);
HH = callcsm(s_dfp);
The ‘csm’ (circularly shift matrix) function does the shifting, and the ‘callcsm’ function requires only the matrix name to produce the vectorised result.

Categories

Find more on MATLAB in Help Center and File Exchange

Tags

No tags entered yet.

Community Treasure Hunt

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

Start Hunting!