I was looking for a way to circshift using index values.
I know I can shift all values using the circshift command see below
a=[1:9]
b=circshift(a,[0,1])
But how do I shift every 3rd value over 1?
example:
Note: variable a can be any length
a=[1,2,30,4,5,60,7,8,90] %note variable `a` could be any length
I'm trying to get b to be
b=[1,30,2,4,60,5,7,90,8] % so the values in the index 3,6 and 9 are shifted over 1.
You're not going to be able to do this with the standard usage of circshift. There are a couple of other ways that you could approach this. Here are just a few.
mod to create index valuesYou could use mod to subtract 1 from the index values at locations 3:3:end and add 1 to the index values at locations 2:3:end.
b = a((1:numel(a)) + mod(1:numel(a), 3) - 1);
Explanation
Calling mod 3 on 1:numel(a) yields the following sequence
mod(1:numel(a), 3)
% 1 2 0 1 2 0 1 2 0
If we subtract 1 from this sequence we get the "shift" for a given index
mod(1:numel(a), 3) - 1
% 0 1 -1 0 1 -1 0 1 -1
Then we can add this shift to the original index
(1:numel(a)) + mod(1:numel(a), 3) - 1
% 1 3 2 4 6 5 7 9 8
And then assign the values in a to these positions in b.
b = a((1:numel(a)) + mod(1:numel(a), 3) - 1);
% 1 30 2 4 60 5 7 90 8
reshape.Another option is to reshape your data into a 3 x N array and flip the 2nd and 3rd rows, then reshape back to the original size. This option will only work if numel(a) is divisible by 3.
tmp = reshape(a, 3, []);
% Grab the 2nd and 3rd rows in reverse order to flip them
b = reshape(tmp([1 3 2],:), size(a));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With