Nollaig MacKenzie wrote:
>  I had two M by N arrays, and I wanted a sort of product 
>  with shape M by N by M.
>       (1 3;2) |: A */ B
>       1|: A *"1/ B
>       A ] . * |: B

Intriguing observations!

I had never really considered the relationships among " |: / . before, and
bringing them together like this leads to some interesting territory to
explore.

The first thing the assembly brings to mind is an illuminating post Raul
once made, which described the relationship between |:, inner, and outer
products [1].  In that post, Raul convincingly argues that x |: y
constitutes an outer product on the dimensions of y when x is open, and an
inner product when x is boxed.  This jibes well with your observations
above.

The second thing they brings to mind is a comment Roger once made (I'd call
it an offhand comment, but Roger doesn't make offhand comments). In [2],
Roger said:

>  The reason why I asked is that the dyad u/ was defined
>  and set in concrete before we really understood rank,
>  and now that we do, and knowing that u/ is simply u"(lv,_),
>  we would probably use u/ for something else
>  (/ is prime real estate, being a single character word).

Which, restated, means / (in the sense x u/ y) is a another way of saying "
. 

Because I learned J before I learned APL, I learned to use " (which is
ubiquitous in the J world) before I learned to use / (which is more
prevalent in the APL world). As a consequence, I never really got into the
habit of using /, which compounded Roger's comment above, has made me
particularly sensitive to using a combination of both (because it begins to
feel redundant) [3].

Similarly, the inner product u . v can be recast in terms of " .  For
example, see Roger's anecdote about the last thing he got brag about to Ken
[4]:

>  The dictionary definition of f .g  (the rank 1 _ thing)
>  is the basis of the improvement to +/ .* from 2004.
>  This speed-up has special meaning for me, because it's 
>  the last improvement I was able to tell Ken about and 
>  because of the way it happened ("Hey Ken, if I implement 
>  inner product the way the dictionary has specified it for
>  the last 10 years, I get a factor of x speed-up.")

So this is what was swirling around in my head as I read your identities
f"1/ and ] . f . The former feels redundant, and the second, with its no-op
placeholder, cries out for reduction.  If I saw these in my own code, my
instinct would be to recast them in terms of a pure " operation.

So, for fun, let's try those exercises!  Implementing models of / and .
using their Dictionary definitions [5,6]:

           Table =: 'u   "((  1{u b. 0),_) ' (1 :)
           Inner =: 'u@(v"((1+1{v b. 0),_))' (2 :)
   
Here, the origins of your identities start to become clear (what happens to
Inner if u =. ] ? What happens to Table if u is really v"(1+lv) ?). In fact,
you can see the beginnings of the rationale for creating J.

But, to make sure we're on the right track, let's test these models
alongside your other identities:
           
           'A B'=.0 ?@$~ 2,'m n'=.3 4
           $A
        3 4
           $B
        3 4
           
           m,n,m
        3 4 3
           
           $(1 3;2) |: A */ B
        3 4 3
           $1|: A *"1/ B
        3 4 3
           $A ] . * |: B
        3 4 3
           
           $(1 3;2) |: A * Table B
        3 4 3
           $1|: A *"1 Table B
        3 4 3
           $A ] Inner  * |: B
        3 4 3
      
It looks like the models are faithful.  So, what can they tell us about this
m,n,m tabulation?

           *"1 Table
        *"1"1 _
           ]  Inner *
        ]@(*"1 _)
           
Here we see the underlying symmetry which accounts for the identities you
observed. Both verbs are applied at "1 _ . We must still account for the
transposes, but discarding the obvious no-op ]@ in the second phrase
(satisfying that urge for reduction!) tells us that *"1 _ is the core
operation.  Thus:

           $A *"1 _ |: B
        3 4 3

I think this is the natural way to express the idea in J.  Read in English,
it says what we want is to "take the entire matrix on the right and multiply
it by each row of the matrix on the left". 

Of course, since multiplication is a scalar operation (it only makes sense
to multiple atomic numbers), in order to multiply an entire matrix by a
single row, the number of values in that row must correspond to the number
of rows in the matrix (one value per row). And since the number of values in
a single row of a matrix is simply the number of columns of that matrix, the
number of rows of one matrix must correspond to the number of columns of the
other.  This accounts for the transpose.

But more than this particular tabulation, I think the big takeaway is your
identity ] .u <==> u"(1+lu)/ <==> u"( (1+lu) , _) .  It is quite pretty,
and, I think, will prove useful (especially in code gold competitions!).

-Dan

PS:  For the sake of the tabulation, it might be cleaner, as you said, to
define one of the matrices with shape n,m ab initio (rather than applying |:
explicitly). Though I'd only recommend doing so if that's a natural
representation for that matrix (that is, where the rows represent
independent items, and the columns -- the values of each row -- represent
independent observations of those items).

[1] Raul describes |: in terms of inner and outer products:
    http://www.jsoftware.com/pipermail/programming/2012-December/030387.html

[2] Roger discusses the redundancy of the dyad u/ with " :
    http://www.jsoftware.com/pipermail/programming/2011-December/025887.html

[3] So / is a "slippery slope" for me:
    http://www.jsoftware.com/pipermail/programming/2010-February/018644.html

[4] Roger's 10x improvement to +/ .* by implementing it the way it's
defined:
    http://www.jsoftware.com/pipermail/programming/2011-December/025887.html
and http://www.jsoftware.com/papers/innerproduct/ip.htm

[5] Dictionary definition of x */ y is x u"(lu,_) y where where lu is the
left rank of u:
    http://www.jsoftware.com/help/dictionary/d420.htm

[6] Dictionary definition of u . v is u@(v"(1+lv,_)) :
    http://www.jsoftware.com/help/dictionary/d300.htm


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

Reply via email to