Using matrix multiplication @ operator in sympy expression

Viewed 101

If I make a Sympy expression with symbols a,b,c as follows

import sympy as sm
import numpy as np
a,b,c = sm.symbols("a,b,c")
expr = 4*a + b*a + b*c + a*b*c

f = sm.lambdify((a,b,c), expr)
a_1 = np.random.rand(10,10)
b_1 = np.random.rand(10,10)
c_1 = np.random.rand(10,10)
f(a_1, b_1, c_1)

The problem here for me, is that lambdify uses * in numpy which is just the element-by-element multiplication, but I need the matmul or @ operator in the above function. Above code is just an example, and in some of my use cases the expression becomes complicated to use. I tried to look for methods to achieve this in Sympy, but lambdify does not work with this operator. I was wondering whether a symbol existed which acts like a matrix for multiplication operators in Sympy, where the matrix size specification is not necessary, but I could not find any. It is also important for me that I can use the same function for matrices of different size choice of a, b and c. Any suggestion would be very helpful. Thanks!

1 Answers

The normal usage of arrays with lambdify is to evaluate a scalar expression over many values of the symbols in the expression. If you want to use arrays as matrices and have matrix multiplication then your symbols need to be MatrixSymbol:

In [235]: A = MatrixSymbol('A', 2, 2)

In [236]: B = MatrixSymbol('B', 2, 2)

In [237]: f = lambdify((A, B), A*B)

In [238]: import inspect

In [239]: inspect.getsource(f)
Out[239]: 'def _lambdifygenerated(A, B):\n    return (A).dot(B)\n'

In [240]: print(inspect.getsource(f))
def _lambdifygenerated(A, B):
    return (A).dot(B)

In [241]: a = np.array([[1, 2], [3, 4]])

In [242]: f(a, a)
Out[242]: 
array([[ 7, 10],
       [15, 22]])
Related