I have a the following code:
p = classp();
for i in range(1,10):
x = numpy.array([[2],[4],[5]])
print p.update(x)
class classp:
def __init__(self):
self.mymodel = array([2*x[1]], [3*x[0]], [x[2]]);
def update(self, x):
return self.mymodel #replace x(0)...x(1) with the given parameter
My question is related the code above, I would like to define a model using sympy if it's possible, afterwards in the update function replace the sympy variables with the x values. Is it possible? How can I do that?
In general, SymPy functions do not work with objects from other libraries, such as NumPy arrays, and functions from numeric libraries like NumPy or mpmath do not work on SymPy expressions.
If you want to deep into the inner workings of SymPy, the check out expression trees. Relationship with NumPy: NumPy and SymPy are both libraries that can deal with mathematics. However, they are fundamentally different! NumPy operates numerically, while SymPy works with symbolic expressions.
The lambdify function translates SymPy expressions into Python functions. If an expression is to be evaluated over a large range of values, the evalf() function is not efficient. lambdify acts like a lambda function, except it converts the SymPy names to the names of the given numerical library, usually NumPy.
As one point of comparison, SymPy is comically slow compared to Sage. This is mostly because SymPy is purely Python; Sage on the other hand uses its own derivative of GiNaC [1], Pynac [2], for its internal symbolic expression representation, and then multiple external libraries for non-trivial operations.
I can propose you two solutions.
Firstly, there is DeferedVector
that was created for use with lambdify
:
In [1]: from sympy.matrices import DeferredVector
In [2]: v = DeferredVector('v')
In [3]: func = lambdify(v, Matrix([v[1], 2*v[2]]))
In [4]: func(np.array([10,20,30]))
Out[4]:
[[20]
[60]]
However lambdify does too much magic for my taste.
Another option is to use the .subs
method:
In [11]: x1, x2, x3 = symbols('x1:4')
In [12]: m = Matrix([x2,2*x1,x3/2])
In [13]: m.subs({x1:10, x2:20, x3:30})
Out[13]:
⎡20⎤
⎢ ⎥
⎢20⎥
⎢ ⎥
⎣15⎦
You can create the dictionary for the substitution like that:
dict(zip(symbols('x1:4'), your_value_array))
.
Do not forget that all the return objects are sympy matrices. To convert them to numpy arrays just use np.array(the_matrix_in_question)
and do not forget to specify the dtype
, otherwise it will default to dtype=object
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With