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

2

7

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.

Jodijodie answered 26/3, 2016 at 7:40 Comment(0)
H
4

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... :)

Howrah answered 26/3, 2016 at 14:33 Comment(0)
T
1

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.

Timeserver answered 30/3, 2016 at 21:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.