3

I am trying to use numpys numpy.einsum function on symbolic sympy arrays due to sympys cruel lack of einstein summation convention capabilities. I have tried this so far:

>>> from sympy import *
>>> import numpy as np
>>> a11,a12,a13,a21,a22,a23,a31,a32,a33 = symbols('a11,a12,a13,a21,a22,a23,a31,a32,a33')
>>> np.einsum('ii', a)
Traceback (most recent call last):
  File "<pyshell#469>", line 1, in <module>
    np.einsum('ii', a)
  File "C:\Python35\lib\site-packages\numpy\core\einsumfunc.py", line 948, in einsum
    return c_einsum(*operands, **kwargs)
TypeError: invalid data type for einsum
>>> a = Array([[a11,a12,a13],[a21,a22,a23],[a31,a32,a33]])
>>> np.einsum('ii', a)
Traceback (most recent call last):
  File "<pyshell#472>", line 1, in <module>
    np.einsum('ii', a)
  File "C:\Python35\lib\site-packages\numpy\core\einsumfunc.py", line 948, in einsum
    return c_einsum(*operands, **kwargs)
ValueError: einstein sum subscripts string contains too many subscripts for operand 0

As you can see I have tried passing both a numpy native array and also a sympy array both with no success. Is this sort of mixing (for data types across modules) possible for python classes in general but also for this situation in specific?

user32882
  • 5,094
  • 5
  • 43
  • 82
  • 1
    Basically this is not possible. [Here's](https://stackoverflow.com/questions/44780195/generating-np-einsum-evaluation-graph) a link to a imilar question. depending on what you need you might be able to reuse the ansewers there – Jürg W. Spaak Aug 09 '17 at 12:41
  • 1
    `einsum` uses compiled code to translate the 'ij->...' string into an iteration scheme. That multidimensional iteration is compiled for numeric values (floats, ints etc) - you know how `c` likes to know when it's working with doubles etc. Some numpy code can work with an object dtype, which conceivably could be a pointer to a `sympy` object. But that is not true for `einsum`. – hpaulj Aug 09 '17 at 17:40

1 Answers1

3

NumPy's einsum requires numerical data (after all, "Num" in NumPy is for Numerical). But SymPy can handle symbolic tensor contractions on its own, with the Tensor module.

from sympy import *
A = Matrix(MatrixSymbol("a", 3, 3))
trace = tensorcontraction(A, (0, 1))

Returns a[0, 0] + a[1, 1] + a[2, 2]

  • yes but I'm trying to do more than just tensor contraction. I need to expand large expressions like the elastic wave equation for example which in most formulations are entirely based on einstein summation convention – user32882 Aug 09 '17 at 13:55