0

I am trying to solve for non linear equations in python. I have tried using the solver of the Sympy but it doesn't seem to work in a for loop statement. I am tyring to solve for the variable x over a range of inputs [N].

I have attached my code below

import numpy as np
import matplotlib.pyplot as plt
from sympy import *

f_curve_coefficients = [-7.14285714e-02, 1.96333333e+01, 6.85130952e+03]
S = [0.2122, 0, 0]

a2 = f_curve_coefficients[0]
a1 = f_curve_coefficients[1]
a0 = f_curve_coefficients[2]

s2 = S[0]
s1 = S[1]
s0 = S[2]

answer=[]
x = symbols('x')
for N in range(0,2500,5):
    solve([a2*x**2+a1*N*x+a0*N**2-s2*x**2-s1*x-s0-0])
    answer.append(x)
    
print(answer)

There could be more efficient ways of solving this problem than using sympy * any help will be much appreicated.

Note I am still new to python, after transisitioning from Matlab. I could easliy solve this problem in Matlab and could attach the code, but I am battiling with this in Python

Mat
  • 45
  • 7
  • What is it about the `for` loop that is giving you trouble? It looks ok to me. The first iteration, N==0, is the most interesting, as a few of the terms drop out. Does it solve the first iteration? – CryptoFool Sep 28 '20 at 06:33
  • I see what might be your problem. Do you expect there to be three equations that you're passing to solve? I wonder because of the space you have in there. Do you really want a comma in front of that space so that you have three equations instead of just two. I see three unknown, so maybe that's your trouble. – CryptoFool Sep 28 '20 at 06:36
  • Hi Steve thanks for the feedback. When I run the code all I get is x's in the array and not values. There should only be two equations. I used the comma to separate the two equations. I will try running the code by removing the space as well. Let me see what happens. – Mat Sep 28 '20 at 06:40
  • I modified the code - so that it has to solve for one equation. But still not solving. Keeps giving me x's as the answer – Mat Sep 28 '20 at 06:47

2 Answers2

1

Answering to your question "There could be more efficient ways of solving this problem than using sympy * "

you can use fsolve to find the roots of non linear equation: fsolve returns the roots of the (non-linear) equations defined by func(x) = 0 given a starting estimate https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html

below is the code:

from scipy.optimize import fsolve
import numpy as np

def f(variables) :
    (x,y) = variables
    first_eq = 2*x + y - 1
    second_eq = x**2 + y**2 - 1
    return [first_eq, second_eq]

roots = fsolve(f, (-1 , -1)) # fsolve(equations, X_0)
print(roots)

# [ 0.8  -0.6]
print(np.isclose(f(roots), [0.0, 0.0]))  # func(root) should be almost 0.0.

If you prefer sympy you can use nsolve.

>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1])

[0.620344523485226] [1.83838393066159]

The first argument is a list of equations, the second is list of variables and the third is an initial guess.

Also For details, you can checkout similar question asked earlier on stack overflow regarding ways to solve Non-linear equations in python: How to solve a pair of nonlinear equations using Python?

mudassir ahmed
  • 191
  • 1
  • 1
  • 13
  • Thanks for answering the part of using a more efficient solver for the equations. I managed to use your code with the for loop and worked equally well. I do see that the fsolve works much faster. Espeically when dealing with a big range in the for loop as in my case. – Mat Sep 28 '20 at 08:35
0

According to this documentation, the output of solve is the solution. Nothing is assigned to x, that's still just the symbol.

x = symbols('x')
for N in range(0,2500,5):
    result = solve(a2*x**2+a1*N*x+a0*N**2-s2*x**2-s1*x-s0-0)
    answer.append(result)
kutschkem
  • 7,826
  • 3
  • 21
  • 56