简体   繁体   中英

Fsolve precision issue (python)

I am experiencing precision issue with fsolve.

import numpy as np
from scipy.optimize import fsolve


ens=np.arange(0,50,1)


def f(x):
     return x*(np.sin(x)/np.cos(x))-1000

s=[]        

roots=fsolve(f,ens)
roots=np.around(roots, decimals=3 , out=None)
a = roots[roots >= 0]
g = np.unique(a)
g=g[:5]
s.append(g)
print(s)
            

result :

[array([10.842, 11.006, 15.165, 21.116, 22.382])]

The result should be: [ 1.569,4.708,7.846 ,10.985,14.123]

My code miss the first three solutions, and the others are not accurate. Do you know how could I improve the precision of my results?

You can use scipy.optimize.newton() with first and second derivative of the function f to get a more accurate result. You can do it by hand, or use derivative-calculator.net or wolframalpha . Pass both the first derivative fprime and the second derivative, fprime2 to newton() . If you do this, Halley's method will be used instead of a simple Newton-Raphson , which is more accurate (see the description below fprime2 in newton() docs).

def f(x):
     return x*(np.sin(x)/np.cos(x))-1000

def fprime(x):
    # first derivative of f
    # do this by hand or use derivative-calculator.net or wolframalpha
    return np.tan(x)+ x*(1/np.cos(x))**2

def fprime2(x):
    # second derivative of f
    # do this by hand or use derivative-calculator.net or wolframalpha
    return 2*1/(np.cos(x)**2)*(x*np.tan(x)+1)

res = newton(f,x0=[1,4,7,10,14],fprime=fprime, fprime2=fprime2)
res = np.around(res, decimals=3)

res will be:

array([ 1.569,  4.708,  7.846, 10.985, 14.123])

The x0 argument in newton() above are the list of so-called initial guesses of where the roots are. As your function have infinitely many roots (see plot below), passing some of these helps to get the roots you actually care about.

This is how f looks like (well, f/1000 to make features visible):

在此处输入图像描述

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