355durch113
355durch113

Reputation: 201

MATLAB equivalent to Python's negative indexing

Problem: Depending on the boolean value of smth, the array a has to be iterated either forwards or backwards. Because of recursion, the first (or last) element has to be treated beforehand.

In Python I can influence the direction an array is iterated through by tweaking the index a bit (*):

a=range(2,11,2)

sign=1
os=0

if smth:                
    sign=-1
    os=1

print(a[sign*os])          #*
for k in range(5):
    print(a[sign*(k+os)])  #*

Now, as there are no negative indices in MATLAB, I couldn't find a way around doubling the instructions (simplyfied to "print" above) and adapting the indices:

a=2:2:10

if smth
    a(1)
    for i=2:5
        a(i)
    end   
else
    a(end)
    for i=4:-1:1
        a(i)
    end
end

Is there a way around this, eventually similar to the Python code above? The actual instructions will be much longer, including combinations of multi-dimensional indexing.

Also, in this case, flipping the array after the evaluation of smth is not possible.

Upvotes: 2

Views: 867

Answers (4)

355durch113
355durch113

Reputation: 201

I found another (questionable) possibility:

a=2:2:10;
s=smth;
a(5^s)
for k=(5^s-s)*2^~s:(-1)^s:5^~s
    a(k)
end

Upvotes: 0

Dev-iL
Dev-iL

Reputation: 24169

I think what you're looking for is the keyword end. When appearing in indexing expressions, it refers to the last position within an array. You should also remember that in MATLAB it is possible to specify a pre-made vector for loop indices, so it doesn't have to be created "on the fly" using the colon (:) operator. Below is an example of how to use this for your needs:

ind_vec = 1:5;

if smth
  ind_vec = ind_vec(2:end);
else
  ind_vec = ind_vec(end-1:-1:1);
end

for ii = ind_vec
  ... %// do something
end

Alternatively you can use a makeshift ternary operator1 in conjunction with flip to get the right indices:

function out = iftr(cond,in1,in2)

if cond
    out = in1;
else
    out = in2;
end

Then you could get the desired result using:

ind_vec = 1:5;
ind_vec = iftr(smth,ind_vec,flip(ind_vec));
ind_vec = ind_vec(2:end);

1 - Also available as a function handle.

Upvotes: 6

Julien
Julien

Reputation: 15071

what about (you may replace 5 by the actual length of a):

if smth
    it = 1:5
else
    it = 5:-1:1
end

for i=it
    a(i)
end

Upvotes: 1

David
David

Reputation: 8459

It's not very nice, but this might do the trick,

for i=smth*(1:5)+~smth*(5:-1:1)
    a(i)
end

Upvotes: 1

Related Questions