How to improve the speed

341 views
Skip to first unread message

Jim Zhang

unread,
May 23, 2022, 10:23:38 AM5/23/22
to sympy
Hello,

I am new to Sympy. At times, I wish to get an analytical expression in terms of certain variables. In the following case, one is a Numpy array (T) and the other is a Sympy matrix (X). I know it is not a good idea to directly multiply them, so I  convert T to a Sympy matrix first. However, it would take forever to get the result because of this large-sized matrix. Are there any more computationally efficient ways? 

Thanks in advance,

Jim


import numpy as np
import sympy as sp

T =  np.random.rand(100, 6000)
x = sp.symbols('x:'+str(6000))
X = sp.Matrix(x)
W = sp.Matrix(T)
V = W * X

Junjie Shi

unread,
May 24, 2022, 6:38:44 AM5/24/22
to sympy
Hi,
Try symengine (https://github.com/symengine), which is much faster than sympy but less functionalities (only basic functions of sympy). It also has python wrappers (https://github.com/symengine/symengine.py).

Best

Oscar

unread,
May 24, 2022, 8:53:16 AM5/24/22
to sympy
Jonathan already mentioned SymEngine which can be used here and is likely to be faster for this particular operation. However I want to question your approach here: is this operation genuinely representative of what you are actually doing in your code?

I suspect that there is a much better way of doing what you want to do here just using NumPy. If we make this smaller and show what these objects are then maybe you can see what I mean:

   ...: import numpy as np
   ...: import sympy as sp
   ...:
   ...: T =  np.random.rand(3, 3)
   ...: x = sp.symbols('x:3')
   ...: X = sp.Matrix(x)
   ...: W = sp.Matrix(T)
   ...: V = W * X

In [2]: T
Out[2]:
array([[0.02171629, 0.07314606, 0.20216258],
       [0.5911101 , 0.02585039, 0.57907704],
       [0.21691524, 0.21911551, 0.84199378]])

In [3]: V
Out[3]:
⎡0.0217162949338237⋅x₀ + 0.0731460590358582⋅x₁ + 0.202162579518612⋅x₂⎤
⎢                                                                    ⎥
⎢ 0.59111010291895⋅x₀ + 0.0258503861066768⋅x₁ + 0.579077042048328⋅x₂ ⎥
⎢                                                                    ⎥
⎣ 0.216915237539653⋅x₀ + 0.21911551409902⋅x₁ + 0.841993775366244⋅x₂  ⎦


The matrix V here is really just an inefficient way of representing the original array T. Whatever operation you want to do with V can probably be done much more efficiently with T. For example if you want to differentiate with respect to x0 then that's really just extracting the first column of T e.g.:

In [4]: V.diff(X[0])
Out[4]:
⎡0.0217162949338237⎤
⎢                  ⎥
⎢ 0.59111010291895 ⎥
⎢                  ⎥
⎣0.216915237539653 ⎦

In [5]: T[:,0]
Out[5]: array([0.02171629, 0.5911101 , 0.21691524])


Whatever it is you are trying to do with V can almost certainly be done better in some other way e.g. by using SymPy to derive a formula and then using NumPy to evaluate that formula.

--
Oscar
Reply all
Reply to author
Forward
0 new messages