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