Using find on matrices

classic Classic list List threaded Threaded
2 messages Options
harishankar ramachandran harishankar ramachandran
Reply | Threaded
Open this post in threaded view
|

Using find on matrices

Hi all,

If I have a matrix "A", and I apply a condition on it, I can extract the
indices for which the condition is true, and I can then use that vector to
change those values. For eg:

indx=find(A>4);
A(indx)=5;

There is also a double index version of find, where I can get the (i,j)
coordinates of the points. However, I do not seem to be able to use the
following code:

[ii,jj]=find(A>4);
A(ii,jj)=5;

This instead assigns 5 to a submatrix of A defined by rows ii and columns jj.

What is the proper way to vectorially assign values to elements of a matrix A,
if I have the element locations in the form [ii,jj]? Without a for loop, that
is.

Another question: Suppose I have a set of disjoint conditions with which I
wish to partition a matrix. How do I extract the corresponding elements with
a single command? This seems like a very useful capability, but I don't find
anyway to do this without using a for loop. Eg:

A=int(rand(5,5)*12);
v=0:2:12;
l=list()
for k=1:length(v)-1
  l(k)=find(A>=v(k) & A<v(k+1));
end

This yields:
A  =

    2.    7.     6.    2.     3.
    9.    10.    7.    2.     11.
    0.    8.     8.    2.     2.
    3.    10.    2.    10.    3.
    7.    0.     6.    7.     4.

 l  =
    l(1) = 3.    10.
    l(2) = 1.    4.    14.    16.    17.    18.    21.    23.    24.
    l(3) = 25.
    l(4) = 5.    6.    11.    12.    15.    20.
    l(5) = 2.    8.    13.
    l(6) = 7.    9.    19.    22.

But can I do it faster, without for loops? I would like to have a command that
does:

A=int(rand(5,5)*12);
v=0:2:12;
l=findmany(A>=v(1:$-1) & A<v(2:$));

or something like that. Is there some such thing?

Thanks in advance

hari ramachandran
--
Dr. Hari Ramachandran, EE Dept, IIT-Madras

Eric Dubois Eric Dubois
Reply | Threaded
Open this post in threaded view
|

Re: Using find on matrices

What does the winner of this logical contest win? ;-)
 
Anyway, I have an exact and an approximate solution (if the only problem is to avoid loops!):
 
- first problem:
--> A((jj-1)*size(A,1)+ii) = 5
 
- second problem:
--> B= matrix(A,-1,1)
--> C=matrix(B,-1,1) .*. ones(1,size(v,2)) - ones(size(C,1),1) .*. v
--> D=C(:,2:$) <0 & C(:,1:$-1) >=0
--> [f1,f2]=find(D)
 
which provides the result you want (although presented slightly diffrently, but I do not know if it makes a difference for your uses).
 
Eric.

 
2008/4/7, harishankar ramachandran <[hidden email]>:
Hi all,

If I have a matrix "A", and I apply a condition on it, I can extract the
indices for which the condition is true, and I can then use that vector to
change those values. For eg:

indx=find(A>4);
A(indx)=5;

There is also a double index version of find, where I can get the (i,j)
coordinates of the points. However, I do not seem to be able to use the
following code:

[ii,jj]=find(A>4);
A(ii,jj)=5;

This instead assigns 5 to a submatrix of A defined by rows ii and columns jj.

What is the proper way to vectorially assign values to elements of a matrix A,
if I have the element locations in the form [ii,jj]? Without a for loop, that
is.

Another question: Suppose I have a set of disjoint conditions with which I
wish to partition a matrix. How do I extract the corresponding elements with
a single command? This seems like a very useful capability, but I don't find
anyway to do this without using a for loop. Eg:

A=int(rand(5,5)*12);
v=0:2:12;
l=list()
for k=1:length(v)-1
l(k)=find(A>=v(k) & A<v(k+1));
end

This yields:
A  =

   2.    7.     6.    2.     3.
   9.    10.    7.    2.     11.
   0.    8.     8.    2.     2.
   3.    10.    2.    10.    3.
   7.    0.     6.    7.     4.

l  =
   l(1) = 3.    10.
   l(2) = 1.    4.    14.    16.    17.    18.    21.    23.    24.
   l(3) = 25.
   l(4) = 5.    6.    11.    12.    15.    20.
   l(5) = 2.    8.    13.
   l(6) = 7.    9.    19.    22.

But can I do it faster, without for loops? I would like to have a command that
does:

A=int(rand(5,5)*12);
v=0:2:12;
l=findmany(A>=v(1:$-1) & A<v(2:$));

or something like that. Is there some such thing?

Thanks in advance

hari ramachandran
--
Dr. Hari Ramachandran, EE Dept, IIT-Madras