Re: [labeled-array] larry support for numpy.dot and similar operators

23 views
Skip to first unread message

Thomas Coffee

unread,
Jan 14, 2012, 4:02:25 PM1/14/12
to labele...@googlegroups.com
The example you give involves square matrices that have the same labels on the same axes. However, in general, contraction operators like numpy.dot and numpy.tensordot operate on non-square matrices, and in the case of larrys, should be expected to match labels on the corresponding pairs of axes that are contracted.

So I would expect the following to work:

>>> l1 = la.larry([[1,2,3],[4,5,6]],[['i1','i2'],['j1','j2','j3']])

>>> l2 = la.larry([[7,8],[9,10],[11,12]],[['j1','j2','j3'],['k1','k2']])

>>> np.dot(l1.x, l2.x)
array([[ 58,  64],
       [139, 154]])

>>> la.binaryop(np.dot, l1, l2)
label_0
label_1
x
array([], shape=(0, 0), dtype=int64)


The expected result in this case would be:

>>> la.larry([[58,64],[139,154]],[['i1','i2'],['k1','k2']])
label_0
    i1
    i2
label_1
    k1
    k2
x
array([[ 58,  64],
       [139, 154]])


In general, I would expect label matching and joining along corresponding contraction axes between the two larrys, but for this to work in the current framework with arbitrary binary operators, the user must be able to specify which axes correspond as such. This is the motivation for the specification I suggested below, which (without being familiar with the details of the current implementation) I would expect would provide the necessary information to make it work.

Has anyone already thought about this sort of functionality?

- Thomas


    Thomas Coffee <thomas...@gmail.com> Jan 12 02:48PM -0800  

    From the documentation at
     
    http://berkeleyanalytics.com/la/ref_flarry.html#binary-functions
     
    it does not seem immediately obvious that
     
    la.binaryop(numpy.dot, ...)
     
    will not work, and indeed, upon my first look at the documentation, I
    assumed that it would. Some prospective users could be saved
    disappointment by making this clear.
     
     
    In the longer term, I can imagine many useful scenarios for supporting
    tensor contraction operators like numpy.dot, for instance, in my own
    application using larrys to facilitate the process of assembling large
    linear programming problems. I'm imagining a specification like the
    following:
     
    la.binaryop(func, la1, la2, ..., axes=None, ...)
     
    where
     
    axes=None
     
    yields the current behavior, but
     
    axes=[(axis_1_0, axis_2_0), (axis_1_1, axis_2_1), ...]
     
    specifies that axis_1_K in la1 should be aligned with axis_2_K in la2
    for purposes of applying func.
     
    Then, for example, one could write
     
    la.binaryop(numpy.dot, la1, la2, ..., axes=[(-1, -2)], ...)
     
    When such an axes specification is given, the list form of the join
    option would be interpreted to apply the method join[K] to the axis
    alignment axes[K].
     
    Is anyone aware of a reason why something like this could not be
    implemented? If not, I may attempt a prototype when time permits.

     

Keith Goodman <kwgo...@gmail.com> Jan 12 03:05PM -0800  


> will not work, and indeed, upon my first look at the documentation, I
> assumed that it would. Some prospective users could be saved
> disappointment by making this clear.
 
binaryop aligns the data in the two larrys according to the join
method you specify. And then it applies the binary function that you
supply.
 
Can you give a simple example of what is not working?
 
Here's an example of use.
 
Make two larrys:
 
I[15] lar1 = la.rand(2,2)
I[16] lar2 = la.rand(2,2)
 
Here's what numpy gives:
 
I[17] np.dot(lar1.x, lar2.x)
O[17]
array([[ 0.6679216 , 0.423808 ],
[ 0.75695756, 0.67014283]])
 
la gives the same answer:
 
I[18] la.binaryop(np.dot, lar1, lar2)
O[18]
label_0
0
1
label_1
0
1
x
array([[ 0.6679216 , 0.423808 ],
[ 0.75695756, 0.67014283]])

Keith Goodman

unread,
Jan 16, 2012, 3:10:02 PM1/16/12
to labele...@googlegroups.com

Yes, I see now.

I think a good addition to la would be la.dot() and/or a dot method:

lar1.dot(lar2, join='inner', fill=np.nan)

where fill is used when the join method ('outer', 'left', 'right')
creates new data.

I created an issue for it here: https://github.com/kwgoodman/la/issues/37

Reply all
Reply to author
Forward
0 new messages