[Matrix-SIG] Yet another newbie question

Konrad Hinsen hinsen@ibs.ibs.fr
Thu, 23 Apr 1998 19:25:52 +0200


> ... a while later... I think I understand it slightly better now.
> where() that is. Still, what I've just coded up feels clumsy:
> 
> from Numeric import *
> # some coordinates
> a = array([[ 163.,  -28.],
>        [ 152.,  -28.],
>        [ 117.,  -23.],
>        [  88.,    0.],
>        [  34.,   43.],
>        [  16.,  123.],
>        [  16.,  180.],
>        [  16.,  201.],
>        [  18.,  217.],
>        [  21.,  227.]],'f')
> # the rectangle I'd like to match
> lefttop = [30, 40]
> rightbottom = [40, 50]
> 
> condition = logical_and(greater(a, lefttop), less(a, rightbottom))
> w = where(condition, 1, 0)
> print w
>
> Now w is an array containing [0, 0] pairs for mismatches, and [1, 1] for
> matches. But I still have to iterate to get to the indices...
> Is there something more convenient/efficient?

First of all you must reduce your condition to a 1D array. In your
case, both the x and the y comparison must be true for the point
to be in the box, so use:

  condition = logical_and(greater(a, lefttop), less(a, rightbottom))
  condition = logical_and.reduce(condition, -1)

To get the indices, use repeat() with an arange() list as the first
argument:

  indices = repeat(arange(len(condition)), condition)

That's it, no explicit loops!

Konrad.
-- 
-------------------------------------------------------------------------------
Konrad Hinsen                          | E-Mail: hinsen@ibs.ibs.fr
Laboratoire de Dynamique Moleculaire   | Tel.: +33-4.76.88.99.28
Institut de Biologie Structurale       | Fax:  +33-4.76.88.54.94
41, av. des Martyrs                    | Deutsch/Esperanto/English/
38027 Grenoble Cedex 1, France         | Nederlands/Francais
-------------------------------------------------------------------------------