How To Convert Class 'sympy.core' To 'number' Or 'float' For Optimization?
Solution 1:
To work in in fsolve
your function
has to run with something like the x0
value.
In the first case:
In [1]: def function(v):
...:
...: b_1 = v[0]
...: b_2 = v[1]
...:
...: return (2*b_1 + 2*b_2/3,2*b_1/3 + 2*b_2/5)
...:
In [3]: function([1,2])
Out[3]: (3.333333333333333, 1.4666666666666668)
In the second case:
In [4]: y= symbols('y')
...: b_1, b_2 = symbols ('b_1,b_2')
...:
...: b = 1
...:
...: f = b_1 + b_2*(y/b)**2
...:
...: K1 = integrate(f**2,(y,0,b))
...:
...:
...: eq1 = diff(K1,b_1)
...: eq2 = diff(K1,b_2)
...:
In [5]: eq1
Out[5]:
2⋅b₂
2⋅b₁ + ────
3
In [6]: eq2
Out[6]:
2⋅b₁ 2⋅b₂
──── + ────
35
In [7]: def function(v):
...:
...: b_1 = v[0]
...: b_2 = v[1]
...:
...: return (eq1,eq2)
...:
In [8]: function([1,2])
Out[8]:
⎛ 2⋅b₂ 2⋅b₁ 2⋅b₂⎞
⎜2⋅b₁ + ────, ──── + ────⎟
⎝ 335 ⎠
This returns a tuple of sympy expressions. fsolve
needs numbers as in the first case. Note that the v
values don't change the returned expressions. The b_1
inside the function is not the same as the b₁
in the eq
.
We can use lambdify
to convert the sympy into numpy functions:
In [15]: f1 = lambdify([b_1, b_2], eq1)
In [17]: f1(1,2)
Out[17]: 3.333333333333333
In [18]: f2 = lambdify([b_1, b_2], eq2)
In [19]: def function(v):
...:
...: b_1 = v[0]
...: b_2 = v[1]
...:
...: return (f1(b_1,b_2), f2(b_1, b_2))
In [20]: function([1,2])
Out[20]: (3.333333333333333, 1.4666666666666668)
This should now work in fsolve
.
Note what lambdify
has produced:
In [22]: print(f1.__doc__)
Created with lambdify. Signature:
func(b_1, b_2)
Expression:
2*b_1 + 2*b_2/3
Source code:
def_lambdifygenerated(b_1, b_2):
return (2*b_1 + (2/3)*b_2)
Your error was produced when trying to do something like:
In [23]: np.array(Out[8], dtype=float)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-23-5f2b1be0015f> in <module>
----> 1 np.array(Out[8], dtype=float)
/usr/local/lib/python3.6/dist-packages/sympy/core/expr.py in __float__(self)
325if result.is_number and result.as_real_imag()[1]:
326 raise TypeError("can't convert complex to float")
--> 327 raise TypeError("can't convert expression to float")
328329 def __complex__(self):
TypeError: can't convert expression to float
(It doesn't look like you gave the full traceback. In any case, fsolve
wants a function that returns an array of floats (or equivalent) when given array input (shaped like x0
).
lambdify
is the best, if not the only, way to convert a sympy expression into a numpy
compatible function.
Post a Comment for "How To Convert Class 'sympy.core' To 'number' Or 'float' For Optimization?"