Home > Software engineering >  SympifyError: SympifyError: index when using a loop
SympifyError: SympifyError: index when using a loop

Time:04-05

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)
  • Related