Robert O'Boyle wrote:
>  What I would like is mat's row average for  the non-zero entries in 
> the mask.

I just realized we can get pretty close with this, using J's sparse arrays.
 When you apply a function to a sparse array, it cannot see the values
that "aren't there", which is exactly what you're asking for here.

For example, we can make your  mat  sparse like this:

           $. mask * mat
        0 1 ?  1
        0 2 ?  2
        0 3 ?  3
        1 0 ?  5
        1 1 ?  6
        1 2 ?  7
        1 3 ?  8
        1 4 ?  9
        3 0 ? 15
        3 1 ? 16
        3 2 ? 17
        3 3 ? 18
           
Notice that only the "mask" entries actually exist.  In general, we'd have
to use something like

           sparsify =: (0&{::)`([: (,:~ $ {. 0&#) 1&{::) }@:(,&:<) 
        
to make any array sparse, given a correspondingly-shaped mask array.

Then, with judicious applications of the sparse functions, we can apply an
verb function to this array, and it won't "see" any of the values that are
missing:

           igm =: (5&$.@:) (@:$.) (@:sparsify)   NB.  IGnore Missing

           mask  (+/ % #)"1 igm  mat
        1.2 7 13.2

Of course, this isn't perfect.  By design, primitives applied on sparse
arrays are supposed to give identical results as when applied to the
corresponding dense arrays (but more efficiently).   They aren't SUPPOSED
to act like the values "aren't there", they're supposed to act exactly the
same, but faster and leaner.

In particular for the current use,  #  always gives the right answer, even
when some of the elements "aren't there"; hence the denominator of our
average is too large.  We could compensate:

           mask (+/ % +/@:~:&0)"1 igm  mat  
        2 7 16.5

But once we have to start thinking this way, we've lost the value of the
approach.  

-Dan

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to