0

I am trying to solve for a single (non linear) equation using fsolve in a for loop, however it doesn't seem to work in my code.

From previous assistance from How to solve nonlinear equations using a for loop in python? I managed to get this right for solving for two or more equations, but could not get it to work for a single non linear equation.

*Note that N is the stepped range values we substitute in for using the for loop

from scipy.optimize import fsolve
import numpy as np

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]


def f(variable):
    x = variable
    first_eq =a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)
    return [first_eq]

for N in range(1,6,1):
    
    roots = fsolve(f,20) # fsolve(equations, X_0)
    print(roots)

In Matlab we have a function called fzero which could solve this - not sure if Python has a similar function?

The solution doesn't have to be fsolve - just working on recommendations from users from python forums...

In advance thank you for all the assistance. Really don't know what I would do without stackoverflow!

Mat
  • 45
  • 7
  • remove you function `def f(variable): ...` and use `f = lambda x : a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)` instead. Running your code I get an exception, this change will solve it. You are alredy using `fsolve` from `scipy.optimize`, so yes there is a similar function. Which is your question ,can you clarify? – Carlo Zanocco Sep 28 '20 at 10:06
  • Carlo Zanocco - thanks for answering my question. By removing the def f(variable) part with the f = lambda solved it for me. I will read up on the f = lambda x: ... not familar with this notation. – Mat Sep 28 '20 at 10:12

1 Answers1

0

You can change you code as follow:

from scipy.optimize import fsolve
import numpy as np

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]

f = lambda x : a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)

for N in range(1,6,1):
    roots = fsolve(f, 20)
    print(roots)

Remove the function:

def f(variable):
    x = variable
    first_eq =a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)
    return [first_eq]

And convert it to:

f = lambda x : a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)

If you want to keep you original code, just correct it:

def f(variable):
    x = variable
    first_eq =a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)
    return first_eq

Your return [first_eq] return a list and generate the exception Result from function call is not a proper array of floats.

You can also simplify the code as follow:

def f(x):
    return a2*x**2+a1*N*x +a0*N**2-(s2*x**2+s1*x+s0)

Take a look to the lambdas reference

fsolve() returns the roots of f(x) look here

Carlo Zanocco
  • 1,967
  • 4
  • 18
  • 31