1

I've a series of coordinates (i,j) and I want to loop through each one.

For example

A = ones(3,3);
i = [1 2 3];
j = [3 2 1];

I tried with this but it doesn't work:

for (i = i && j = j)
   A(i,j) = 0;
end

I also tried this but it doens't work as expected:

for i = i
    for j = j
        A(i,j) = 0;
    end
end

Desired result:

A =
1 1 0
1 0 1
0 1 1

Although A is a matrix in this example, I am working with table data.

krisdestruction
  • 1,950
  • 1
  • 10
  • 20
mat
  • 2,412
  • 5
  • 31
  • 69

2 Answers2

3

The correct syntax to do what you want is:

A = ones(3,3);
i = [1 2 3];
j = [3 2 1];

for ii = 1:length( i )
    A( i(ii) , j(ii) ) = 0;
end

Essentially you loop through each element and index i and j accordingly using ii. ii loops through 1..3 indexing each element.

This will give the a final result below.

>> A
A =
     1     1     0
     1     0     1
     0     1     1

While this works and fixes your issue, I would recommend rayryeng's alternate solution with conversions if you don't have more complex operations involved.

Community
  • 1
  • 1
krisdestruction
  • 1,950
  • 1
  • 10
  • 20
2

Though this doesn't answer your question about for loops, I would avoid using loops all together and create column-major linear indices to access into your matrix. Use sub2ind to help facilitate that. sub2ind takes in the size of the matrix in question, the row locations and column locations. The output will be an array of values that specify the column-major locations to access in your matrix.

Therefore:

A = ones(3); i = [1 2 3]; j = [3 2 1]; %// Your code
%// New code
ind = sub2ind(size(A), i, j);
A(ind) = 0;

Given that you have a table, you can perhaps convert the table into an array, apply sub2ind on this array then convert the result back to a table when you're done. table2array and array2table are useful tools here. Given that your table is stored in A, you can try:

Atemp = table2array(A);
ind = sub2ind(size(Atemp), i, j);
Atemp(ind) = 0;
A = array2table(Atemp);
rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • 1
    Agree with the `sub2ind` and I recommend this solution, unless you have some more complex operation involved. +1 – krisdestruction Apr 23 '15 at 20:45
  • 1
    I like this solution. However, in my script A is a table, so I cannot use linear indices. – mat Apr 23 '15 at 20:48
  • Gotta start learning `sub2ind`. I've seen it multiple times but have never gotten used to using it >. – krisdestruction Apr 23 '15 at 20:48
  • 1
    @krisdestruction - Thanks :) I +1ed you too as you fundamentally found what was wrong with the original method. – rayryeng Apr 23 '15 at 20:49
  • @krisdestruction - It's actually very easy. If you read the post on that bilinear interpolation stuff without `interp2`, I give a brief tutorial on what it's about. http://stackoverflow.com/questions/26142288/resize-an-image-with-bilinear-interpolation-without-imresize/26143655#26143655 – rayryeng Apr 23 '15 at 20:49
  • 1
    @mat - I thought it was a matrix. If I knew it was a table, I would have not suggested this answer. You need to tell me the whole story! – rayryeng Apr 23 '15 at 20:50
  • @rayryeng Is there a way to use `sub2ind` even with a table? I assume with a few conversions, it would work. Thanks for the link, I'll look at it when I have spare time! – krisdestruction Apr 23 '15 at 20:51
  • 1
    @krisdestruction - Yes... though it's very hackish. You can convert the table to an array, perform `sub2ind`, then convert back to a table... so `table2array`, then `sub2ind` then `array2table`. – rayryeng Apr 23 '15 at 20:56
  • 1
    @krisdestruction - I've added in how to accommodate for tables to make it complete. BTW, you're welcome for the link :) You can ignore the fluff about the interpolation bit. Just read the part where I talk about `sub2ind`. – rayryeng Apr 23 '15 at 21:04