Programmatically contracting multiple tensors

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Programmatically contracting multiple tensors

Michael Lamparski
Greetings,

I have something in my code where I can receive an array M of unknown dimensionality and a list of "labels" for each axis.  E.g. perhaps I might get an array of shape (2, 47, 3, 47, 3) with labels ['spin', 'atom', 'coord', 'atom', 'coord'].

For every axis that is labeled "coord", I want to multiply in some rotation matrix R.  So, for the above example, this could be done with the following handwritten line:

return np.einsum('Cc,Ee,abcde->abCdE', R, R, M)

But since I want to do this programmatically, I find myself in the awkward situation of having to construct this string (and e.g. having to arbitrarily limit the number of axes to 26 or something like that).  Is there a more idiomatic way to do this that would let me supply integer labels for summation indices?  Or should I just bite the bullet and start generating strings?

---
Michael

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: Programmatically contracting multiple tensors

Eric Wieser
Einsum has a secret integer argument format that appears in the Examples section of the `np.einsum` docs, but appears not to be mentioned at all in the parameter listing.

Eric

On Sat, 13 Mar 2021 at 00:25, Michael Lamparski <[hidden email]> wrote:
Greetings,

I have something in my code where I can receive an array M of unknown dimensionality and a list of "labels" for each axis.  E.g. perhaps I might get an array of shape (2, 47, 3, 47, 3) with labels ['spin', 'atom', 'coord', 'atom', 'coord'].

For every axis that is labeled "coord", I want to multiply in some rotation matrix R.  So, for the above example, this could be done with the following handwritten line:

return np.einsum('Cc,Ee,abcde->abCdE', R, R, M)

But since I want to do this programmatically, I find myself in the awkward situation of having to construct this string (and e.g. having to arbitrarily limit the number of axes to 26 or something like that).  Is there a more idiomatic way to do this that would let me supply integer labels for summation indices?  Or should I just bite the bullet and start generating strings?

---
Michael
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion

_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: Programmatically contracting multiple tensors

Andras Deak
On Sat, Mar 13, 2021 at 1:32 AM Eric Wieser <[hidden email]> wrote:
>
> Einsum has a secret integer argument format that appears in the Examples section of the `np.einsum` docs, but appears not to be mentioned at all in the parameter listing.

It's mentioned (albeit somewhat cryptically) sooner in the Notes:

"einsum also provides an alternative way to provide the subscripts and
operands as einsum(op0, sublist0, op1, sublist1, ..., [sublistout]).
If the output shape is not provided in this format einsum will be
calculated in implicit mode, otherwise it will be performed
explicitly. The examples below have corresponding einsum calls with
the two parameter methods.

New in version 1.10.0."

Not that this helps much, because I definitely wouldn't understand
this API without the examples.
But I'm not sure _where_ this could be highlighted among the
parameters; after all this is all covered by the *operands parameter.

András



> Eric
>
> On Sat, 13 Mar 2021 at 00:25, Michael Lamparski <[hidden email]> wrote:
>>
>> Greetings,
>>
>> I have something in my code where I can receive an array M of unknown dimensionality and a list of "labels" for each axis.  E.g. perhaps I might get an array of shape (2, 47, 3, 47, 3) with labels ['spin', 'atom', 'coord', 'atom', 'coord'].
>>
>> For every axis that is labeled "coord", I want to multiply in some rotation matrix R.  So, for the above example, this could be done with the following handwritten line:
>>
>> return np.einsum('Cc,Ee,abcde->abCdE', R, R, M)
>>
>> But since I want to do this programmatically, I find myself in the awkward situation of having to construct this string (and e.g. having to arbitrarily limit the number of axes to 26 or something like that).  Is there a more idiomatic way to do this that would let me supply integer labels for summation indices?  Or should I just bite the bullet and start generating strings?
>>
>> ---
>> Michael
>> _______________________________________________
>> NumPy-Discussion mailing list
>> [hidden email]
>> https://mail.python.org/mailman/listinfo/numpy-discussion
>
> _______________________________________________
> NumPy-Discussion mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion
Reply | Threaded
Open this post in threaded view
|

Re: Programmatically contracting multiple tensors

Michael Lamparski
Hi, I must thank y'all for the exceptionally fast responses (and apologize for my own tragically slow response!)

On Sat, Mar 13, 2021 at 1:32 AM Eric Wieser <[hidden email]> wrote:
> Einsum has a secret integer argument format that appears in the Examples section of the
> `np.einsum` docs, but appears not to be mentioned at all in the parameter listing.
  
Ah, yes, this is precisely the sort of API I was hoping for!  I found it pretty easy to use, but here's a snippet that solves my original problem for those wondering:


On Fri, Mar 12, 2021 at 8:09 PM Andras Deak <[hidden email]> wrote:  
> But I'm not sure _where_ this could be highlighted among the
> parameters; after all this is all covered by the *operands parameter.

The parameter list is definitely one of the places I checked most closely, and having something there would have helped.  I'd say that, technically, this also overlaps with the subscripts argument, which now holds the first array, and I feel like that may be the best place to put something.  For instance, a short paragraph could be added to the end of 'subscripts':

"einsum also has an alternative interface that uses integer labels for axes, in which case the subscripts argument is not present.  This is documented below." (with a link)

(the idea I'm trying to capture here is to avoid creating any specific (or potentially wrong) picture of how the arguments look in the alternate signature, more or less forcing the reader to follow a link to where it is more easily described somewhere outside the constraints of parameter-based documentation)

---
Michael


_______________________________________________
NumPy-Discussion mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/numpy-discussion