ekj
ekj

Reputation: 81

Sympy - solve does not fully solve equation system (despite easily solvable equation system)

i'm wondering why i am only getting a partial solve This is my system:

import sympy as smp
K4,K3,K2,K1 = smp.symbols(['K4','K3','K2','K1']) #unknown coefficients
dt = smp.symbols('dt',real=True,nonzero=True) #unknown variable
v_max, a_max, v_zu = smp.symbols(['v_max','a_max','v_zu'],real=True) #known coefficients

eqSys= [
        7*K1*dt**6 + 6*K2*dt**5 + 5*K3*dt**4 + 4*K4*dt**3 - 0.5*v_max + v_zu,
        42*K1*dt**5 + 30*K2*dt**4 + 20*K3*dt**3 + 12*K4*dt**2 - a_max,
        210*K1*dt**4 + 120*K2*dt**3 + 60*K3*dt**2 + 24*K4*dt,
        840*K1*dt**3 + 360*K2*dt**2 + 120*K3*dt + 24*K4,
        2520*K1*dt**2 + 720*K2*dt + 120*K3
]

unknown= [K4,K3,K2,K1,dt]

retval = smp.solve(eqSys, unknown, rational=True, check=False,manual=True)
print('retval=',retval) 
#--> retval= [(0, K3, nan, nan, 0), (K4, 0, zoo*K4, zoo*K4, 0), (5*a_max/(6*dt**2), -a_max/dt**3, a_max/(2*dt**4), -2*a_max/(21*dt**5), dt)]

The 3rd solution is correct, but why doesn't it solve for dt? It can be easily calculated by hand based of the provided solution, so i dont understand what i am/it is doing wrong here.

equation system expanded manually by the solved K's and eq1 solved for dt proves this:

eq1= 7*(-2*a_max/(21*dt**5))*dt**6 + 6*(a_max/(2*dt**4))*dt**5 + 5*(-a_max/dt**3)*dt**4 + 4*(5*a_max/(6*dt**2))*dt**3 - 0.5*v_max + v_zu
eq2= 42*(-2*a_max/(21*dt**5))*dt**5 + 30*(a_max/(2*dt**4))*dt**4 + 20*(-a_max/dt**3)*dt**3 + 12*(5*a_max/(6*dt**2))*dt**2 - a_max
eq3= 210*(-2*a_max/(21*dt**5))*dt**4 + 120*(a_max/(2*dt**4))*dt**3 + 60*(-a_max/dt**3)*dt**2 + 24*(5*a_max/(6*dt**2))*dt
eq4= 840*(-2*a_max/(21*dt**5))*dt**3 + 360*(a_max/(2*dt**4))*dt**2 + 120*(-a_max/dt**3)*dt + 24*(5*a_max/(6*dt**2))
eq5= 2520*(-2*a_max/(21*dt**5))*dt**2 + 720*(a_max/(2*dt**4))*dt + 120*(-a_max/dt**3)

eq1 = smp.nsimplify(smp.simplify(eq1))
eq2 = smp.nsimplify(smp.simplify(eq2))
eq3 = smp.nsimplify(smp.simplify(eq3))
eq4 = smp.nsimplify(smp.simplify(eq4))
eq5 = smp.nsimplify(smp.simplify(eq5))
print('eq1->',eq1)   #  eq1-> 2*a_max*dt/3 - v_max/2 + v_zu
print('eq2->',eq2)   #  eq2-> 0
print('eq3->',eq3)   #  eq3-> 0
print('eq4->',eq4)   #  eq4-> 0
print('eq5->',eq5)   #  eq5-> 0

print('dt = ',smp.solve(eq1,dt)) #dt =  [3*(v_max - 2*v_zu)/(4*a_max)]

If i change manual=False to manual=True, the solution is provided fully in this case. But it seems that manual=False takes extremely long to calculate sometimes, depending on the equation system (with similar character as shown here - polynomial derivatives + known coefficients). That's why i would like to stick with manual=True if possible.

Upvotes: 1

Views: 197

Answers (1)

Oscar Benjamin
Oscar Benjamin

Reputation: 14530

The problem is check=False. With sympy 1.8:

In [4]: solve(eqSys, unknown, manual=True)
Out[4]: 
⎡⎛                     3                         4                          5                          6                         ⎞⎤
⎢⎜0.37037037037037⋅aₘₐₓ   -0.296296296296296⋅aₘₐₓ    0.0987654320987654⋅aₘₐₓ   -0.0125416421712718⋅aₘₐₓ    0.75⋅(vₘₐₓ - 2.0⋅v_zu)⎟⎥
⎢⎜──────────────────────, ─────────────────────────, ────────────────────────, ──────────────────────────, ──────────────────────⎟⎥
⎢⎜                   2                         3                         4                          5               aₘₐₓ         ⎟⎥
⎣⎝  (0.5⋅vₘₐₓ - v_zu)         (0.5⋅vₘₐₓ - v_zu)         (0.5⋅vₘₐₓ - v_zu)          (0.5⋅vₘₐₓ - v_zu)                             ⎠⎦

In [5]: solve(eqSys, unknown, manual=True, check=False)
Out[5]: 
⎡                                                          ⎛0.833333333333333⋅aₘₐₓ  -aₘₐₓ   0.5⋅aₘₐₓ  -0.0952380952380952⋅aₘₐₓ     ⎞⎤
⎢(0.0, K₃, nan, nan, 0.0), (K₄, 0.0, zoo⋅K₄, zoo⋅K₄, 0.0), ⎜──────────────────────, ──────, ────────, ─────────────────────────, dt⎟⎥
⎢                                                          ⎜           2               3        4                  5               ⎟⎥
⎣                                                          ⎝         dt              dt       dt                 dt                ⎠⎦

Note that a bug affecting this case was recently fixed and the fix will be in sympy 1.9 (but is already there in master):

https://github.com/sympy/sympy/pull/21883

You might want to try running with the latest master as it already gives different output. After checking with latest master I suggest opening a GitHub issue if there are still problems.

Upvotes: 2

Related Questions