简体   繁体   中英

How do I solve a non-linear equation in Sympy?

How do I solve a non-linear equation in SymPy which is of the form

y = P*x + Q + sqrt(S*x + T)

where I know y(0) , y'(0) , y(c) , y'(c) . I want to find P , Q , S and T . and represent y as a function of x .

I am getting very confused with the documentation. Please help.

NOTE: My sympy hanged on your original equation of y = P*x + Q + sqrt(S*x + T) . I will be using y = P*x + Q + x*x*(S*x + T) just to be able to demonstrate how the sympy solver works (when it works).

Strategy:

  • Express y as a function of the other variables (x, P, Q, S, T)
  • Differentiate y
  • Set up 4 equations using the known constants ( 0, c, y(0), y(c), y'(0), y'(c) )
  • Use sympy solve
  • Print each possible solution (if there are any)

Code:

# Set up variables and equations
x, y, P, Q, S, T,  = sympy.symbols('x y P Q S T')
c, y_0, y_c, dy_0, dy_c = sympy.symbols('c y_0 y_c dy_0 dy_c')
eq_y = P * x + Q + x * x * (S * x + T)
eq_dy = eq_y.diff(x)

# Set up simultaneous equations that sympy will solve
equations = [
    (y_0 - eq_y).subs(x, 0),
    (dy_0 - eq_dy).subs(x, 0),
    (y_c - eq_y).subs(x, c),
    (dy_c - eq_dy).subs(x, c)
]

# Solve it for P, Q, S and T
solution_set = sympy.solve(equations, P, Q, S, T, set = True) 

# Extract names, individual solutions and print everything
names = solution_set[0]
solutions = list(solution_set[1])
for k in range(len(solutions)):
    print('Solution #%d' % (k+1))
    for k2, name in enumerate(names):
        print('\t%s: %s' % (name, solutions[k][k2]) )

Output:

Solution #1
    P: dy_0
    Q: y_0
    S: (c*(dy_0 + dy_c) + 2*y_0 - 2*y_c)/c**3
    T: (-c*(2*dy_0 + dy_c) - 3*y_0 + 3*y_c)/c**2

You can now use one of these solutions and do another .subs(...) to get y as a function purely consisting of your constants and x .

As for your original equation... I wonder if someone should file a bug report for sympy so they can improve upon it... :)

Right now solver have some issue in solving system of equation having more sqrt . So in below code first removing the sqrt and then solving system of equation.Currently solver is not fast for these types of equations ,it is taking around 10 sec to execute.

P, Q, S, T,  = symbols('P Q S T')
c, y_0, y_c, dy_0, dy_c = symbols('c y_0 y_c dy_0 dy_c')
eq_y = (P*x + Q - y(x))**2 + S*x + T
eq_dy = eq_y.diff(x)
equations = [
  (eq_y).subs([(x, 0), (y(0), y_0), (y(x).diff(x).subs(x, 0), dy_0)]),
  (eq_dy).subs([(x, 0), (y(0), y_0), (y(x).diff(x).subs(x, 0), dy_0)]),
  (eq_y).subs([(x, c), (y(c), y_c), (y(x).diff(x).subs(x, c), dy_c)]),
  (eq_dy).subs([(x, c), (y(c), y_c), (y(x).diff(x).subs(x, c), dy_c)])
 ]
solve(equations, P, Q, S, T)

Answer :

  [(-(y_0 - y_c)/c, y_0, 0, 0), ((2*c*dy_0*dy_c + dy_0*y_0 - dy_0*y_c + dy_c*y_0 - dy_c*y_c)/(c*dy_0 + c*dy_c + 2*y_0 - 2*y_c), -(2*c**3*dy_0*dy_c**2 - c**2*dy_0**2*y_0 + 2*c**2*dy_0*dy_c*y_0 - 4*c**2*dy_0*dy_c*y_c + c**2*dy_c**2*y_0 - 2*c**2*dy_c**2*y_c - 2*c*dy_0*y_0**2 + 2*c*dy_0*y_c**2 - 4*c*dy_c*y_0*y_c + 4*c*dy_c*y_c**2 - 2*y_0**3 + 2*y_0**2*y_c + 2*y_0*y_c**2 - 2*y_c**3)/(c*dy_0 + c*dy_c + 2*y_0 - 2*y_c)**2, -4*(dy_0 - dy_c)*(c*dy_0 + y_0 - y_c)**2*(c*dy_c + y_0 - y_c)**2/(c*dy_0 + c*dy_c + 2*y_0 - 2*y_c)**3, -4*(c*dy_0 + y_0 - y_c)**2*(c*dy_c + y_0 - y_c)**4/(c*dy_0 + c*dy_c + 2*y_0 - 2*y_c)**4)]

please cross check the answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM