How to read this code...

4 views (last 30 days)
Isa Elias
Isa Elias on 21 May 2015
Commented: Walter Roberson on 11 Jun 2015
Can someone break down how they would read this code?
>> A=[0:2:6];k=2;
>> B=A(mod((1:end)-k-1,end)+1);
The 1:end would evaluate the indices of A, then subtract the value of k and subtract 1, correct? If so, then, through the first index of A you would get 1-2-1 = -3. The next thing I see is "A(-3,end)"... and this is where it starts to not make sense to me. Thanks!
  2 Comments
wu chao
wu chao on 21 May 2015
size(A)=[1 4],so end=4. here my test for clearlly explainaton:
>> (1:4)-k-1 ans =
-2 -1 0 1
>> mod((1:4)-k-1,4) ans =
2 3 0 1
>> mod((1:4)-k-1,4)+1 ans =
3 4 1 2
B=A(mod((1:end)-k-1,end)+1) B =
4 6 0 2
Guillaume
Guillaume on 21 May 2015
This is a shining example of why writing comments in code is very important. Here we have a fairly simply operation (see Walter's answer) coded in a way that is not immediately obvious to the reader.

Sign in to comment.

Answers (2)

Walter Roberson
Walter Roberson on 21 May 2015
You missed the mod() layer before the indexing is done. mod() always returns a non-negative value.
I would read the code as being a circular shift left of A, equivalent to
B = circshift(A,-k);

Isa Elias
Isa Elias on 11 Jun 2015
Edited: Isa Elias on 11 Jun 2015
Oh so end gives you the second output of the size of A, not the end of A itself(which would be 6)? Can someone try give me some insight into why that is? Im trying to see where/why MATLAB would recognize that... More specifically, why does it read end as the columns of A, instead of give me the vector of A(1:end) or maybe a vector going from 1:10, since A(end) = 10? Any insight would be greatly appreciated!
Thank you Walter for redirecting me here.
  1 Comment
Walter Roberson
Walter Roberson on 11 Jun 2015
inside an array reference only, "end" is translated into the size of the dimension it appears in, as if you had written the appropriate size() call. So if B is 3 x 5 then B(2:end,end-3:end-1) is the same as B(2:size(B,1),size(B,2)-3:size(B,2)-1)
In the case where you only specify a single index, such as
A(2:end) - A(1:end-1)
then the "end" is translated as the number of elements in the array which is equivalent to the index of the last element when using linear indexing. So the above would translate as
A(2:numel(A)) - A(1:numel(A)-1)
and so
A(mod((1:end)-k-1,end)+1)
would translate as
A(mod((1:numel(A))-k-1,numel(A))+1)
Notice that it is the index that "end" is translated to, not the content.
In the case where A had (for example) 6 elements, then substituting that in, we get
A(mod((1:6)-k-1,6)+1)
and expanding the ":" that would be
A([mod(1-k-1,6)+1, mod(2-k-1,6)+1, mod(3-k-1,6)+1, mod(4-k-1,6)+1, mod(5-k-1,6)+1, mod(6-k-1,6)+1])
if k were 0 the first of those would be mod(1-0-1,6)+1 which would be mod(0,6)+1 which would be 1, and the second would be mod(2-0-1,6)+1 which would be mod(1,6)+1 which would be 2, and so on to mod(6-0-1,6)+1 = mod(5,6)+1 = 6. We thus see that when k = 0 there is no change to the indices, that it would be the same as A([1:6]).
If k were 1 the first would be mod(1-1-1,6)+1 which would be mod(-1,6)+1 which would be 5+1 which would be 6; the second would be mod(2-1-1,6)+1 which would be mod(0,6)+1 which would be 1, then 2, 3, 4, and the last would be mod(6-1-1,6)+1 which would b mod(4,6)+1 which would be 5. So when k is 1 the list becomes A([6,1:5]).
When k is 2, the list would become A([5,6,1:4]). Generalizing, when k is positive, that many elements are moved from the end of [1:6] to the beginning. Another way of writing this case would be
A([end-k+1:end,1:end-k])
If you work through with negative k, the elements get moved from the beginning of the list to the end of the list.
This is, in other words, a circular shift by k elements "leftward"

Sign in to comment.

Categories

Find more on Interactive Control and Callbacks 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!