I am having trouble using simpify when changing the parameters in a loop. Before adding the loop it worked just fine so I am a bit confused about what is going wrong. The idea is to calculate the fixed points for the above equations when having a varying parameter. I determined the parameters by using a random algorithm beforehand.
data used
index c1 c2 c3 c4 c5
2 0.182984 2.016811 0.655393 1.581344 1000.0
3 0.481093 3.696431 0.174021 2.604066 1000.0
4 2.651888 0.665661 2.010521 1.004902 1000.0
5 4.356905 3.805205 0.169469 0.188154 1000.0
6 0.618898 1.205760 0.394822 0.624573 1000.0
7 1.628458 0.908339 0.117855 0.801636 1000.0
8 1.084346 0.251490 5.008077 4.606338 1000.0
9 0.314420 4.553279 0.279103 1.136288 1000.0
10 0.309323 3.447195 0.769426 1.058890 1000.0
11 1.353905 5.034620 3.025668 0.136687 1000.0
12 0.294230 0.590507 0.203964 0.105073 1000.0
13 0.433693 1.040195 0.197015 0.214636 1000.0
14 5.597691 2.734779 0.298786 6.869852 1000.0
15 0.106748 0.329506 1.642285 2.259433 1000.0
16 7.065243 0.138986 6.280275 0.265305 1000.0
17 0.676381 0.263757 6.540224 2.890927 1000.0
18 0.646750 2.573060 0.157341 1.779078 1000.0
19 2.829030 0.208247 0.102454 0.117786 1000.0
20 3.973703 0.134666 1.099034 4.255214 1000.0
df1 = df[df.columns[1]]
df2 = df[df.columns[2]]
df3 = df[df.columns[3]]
df4 = df[df.columns[4]]
EQ=[]
for i in df[:5]:
a = df["c1"]
b = df["c2"]
c = df["c3"]
d = df["c4"]
Q = 1
a1 = 0
b1 = 0
c1 = 0
d1 = 0
u,v = sm.symbols('u,v', negative=False)
# equations
U = a * u -a1* v**2 - b*v b1*v Q
V = c * u -c1*u*v- d*v d1 Q
# use sympy's way of setting equations to zero
Uqual = sm.Eq(U, 0)
Vqual = sm.Eq(V, 0)
# compute fixed points
equilibria = sm.solve( (Uqual, Vqual), u,v)
print('The fixed point(s) of this system are: %s' %equilibria)
equilibria.append(equilibria)
SympifyError Traceback (most recent call last)
<ipython-input-81-7104e05ced6a> in <module>
16 V = c * u -c1*u*v- d*v d1 Q
17 # use sympy's way of setting equations to zero
---> 18 Uqual = sm.Eq(U, 0)
19 Vqual = sm.Eq(V, 0)
20
~\anaconda3\lib\site-packages\sympy\core\relational.py in __new__(cls, lhs, rhs, **options)
501 rhs = 0
502 evaluate = options.pop('evaluate', global_parameters.evaluate)
--> 503 lhs = _sympify(lhs)
504 rhs = _sympify(rhs)
505 if evaluate:
~\anaconda3\lib\site-packages\sympy\core\sympify.py in _sympify(a)
510
511 """
--> 512 return sympify(a, strict=True)
513
514
~\anaconda3\lib\site-packages\sympy\core\sympify.py in sympify(a, locals, convert_xor, strict, rational, evaluate)
431
432 if strict:
--> 433 raise SympifyError(a)
434
435 if iterable(a):
SympifyError: SympifyError: index
1 0.32539361355594*u - 0.153951771353544*v 1
2 0.111286178007145*u - 0.211620881593914*v 1
3 0.410704332996077*u - 0.338148622964363*v 1
4 1.39126513227539*u - 0.715390758416011*v 1
5 0.289981428632838*u - 3.76334113661812*v 1
...
96 0.450838908230239*u - 7.00849756407416*v 1
97 4.59646738213032*u - 1.45107766000711*v 1
98 6.28779804684458*u - 0.395831415205476*v 1
99 0.196464087698782*u - 0.205057919337616*v 1
100 1.69031014508742*u - 0.140571509904066*v 1
Length: 100, dtype: object
CodePudding user response:
In an isympy
session:
Make a sample dataframe:
In [11]: import pandas as pd
In [12]: df = pd.DataFrame(np.arange(12).reshape(3,4))
In [13]: df
Out[13]:
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
Set up a non-iterative case:
In [15]: u,v = symbols('u,v', negative=False)
In [16]: a,a1,b,b1 = 1,2,3,4
In [17]: U = a * u -a1* v**2 - b*v b1*v
In [18]: U
Out[18]:
2
u - 2⋅v v
Versus on with dataframe values:
In [19]: a,b = df[0],df[1]
In [20]: a,b
Out[20]:
(0 0
1 4
2 8
Name: 0, dtype: int64,
0 1
1 5
2 9
Name: 1, dtype: int64)
In [21]: U = a * u -a1* v**2 - b*v b1*v
In [22]: U
Out[22]:
0 -2*v**2 3*v
1 4*u - 2*v**2 - v
2 8*u - 2*v**2 - 5*v
dtype: object
This U
is a pandas Series
, with object elements (which are sympy expressions). But U
itself is not sympy.
Eq applied to the simple expression:
In [23]: Eq(Out[18],0)
Out[23]:
2
u - 2⋅v v = 0
Your error - Eq applied to the Series:
In [24]: Eq(Out[22],0)
---------------------------------------------------------------------------
SympifyError Traceback (most recent call last)
Input In [24], in <cell line: 1>()
----> 1 Eq(Out[22],0)
File /usr/local/lib/python3.8/dist-packages/sympy/core/relational.py:626, in Equality.__new__(cls, lhs, rhs, **options)
624 rhs = 0
625 evaluate = options.pop('evaluate', global_parameters.evaluate)
--> 626 lhs = _sympify(lhs)
627 rhs = _sympify(rhs)
628 if evaluate:
File /usr/local/lib/python3.8/dist-packages/sympy/core/sympify.py:528, in _sympify(a)
502 def _sympify(a):
503 """
504 Short version of :func:`~.sympify` for internal usage for ``__add__`` and
505 ``__eq__`` methods where it is ok to allow some things (like Python
(...)
526
527 """
--> 528 return sympify(a, strict=True)
File /usr/local/lib/python3.8/dist-packages/sympy/core/sympify.py:449, in sympify(a, locals, convert_xor, strict, rational, evaluate)
446 continue
448 if strict:
--> 449 raise SympifyError(a)
451 if iterable(a):
452 try:
SympifyError: SympifyError: 0 -2*v**2 3*v
1 4*u - 2*v**2 - v
2 8*u - 2*v**2 - 5*v
dtype: object
Eq()
does not have a 'iterate over Series' (or even over list) capability.
We can iterate (list comprehension) and apply the Eq
to each terms of the Series:
In [25]: [Eq(U[i],0) for i in range(3)]
Out[25]:
⎡ 2 2 2 ⎤
⎣- 2⋅v 3⋅v = 0, 4⋅u - 2⋅v - v = 0, 8⋅u - 2⋅v - 5⋅v = 0⎦
As a general rule, sympy
and pandas/numpy
does not work well.
CodePudding user response:
It's hard to understand what you are trying to achieve with the code you posted above. So, the following represents my guess:
# NOTE: the following variables are of type
# pandas.core.series.Series. They are iterables
# (think of them as arrays)
a = df["c1"]
b = df["c2"]
c = df["c3"]
d = df["c4"]
# constants
Q = 1
a1 = 0
b1 = 0
c1 = 0
d1 = 0
# symbols
u, v = symbols('u, v', negative=False)
# equations
# NOTE: because a, b, c, d are iterables, then U, V
# will be iterables too. Each element will be a SymPy
# expression because you used the symbols u and v.
U = a * u - a1 * v**2 - b * v b1 * v Q
V = c * u - c1 * u * v - d * v d1 Q
EQ = []
# loop over the equations and solve them
for u_eq, v_eq in zip(U, V):
# here we are asking to solve u_eq=0 and v_eq=0
equilibria = solve((u_eq, v_eq), (u, v))
EQ.append(equilibria)
print('The fixed point(s) of this system are: %s' % equilibria)