简体   繁体   English

F解决精度问题(python)

[英]Fsolve precision issue (python)

I am experiencing precision issue with fsolve.我遇到了 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]结果应该是:[ 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.您可以使用scipy.optimize.newton()与 function f的一阶和二阶导数来获得更准确的结果。 You can do it by hand, or use derivative-calculator.net or wolframalpha .您可以手动完成,或使用导数计算器.net 或wolframalpha Pass both the first derivative fprime and the second derivative, fprime2 to newton() .将一阶导数fprime和二阶导数fprime2newton() 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).如果您这样做,将使用Halley 方法而不是更准确的简单Newton-Raphson方法(请参阅newton()文档中fprime2下面的描述)。

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: res将是:

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.上面newton()中的x0参数是所谓的根在哪里的初始猜测列表。 As your function have infinitely many roots (see plot below), passing some of these helps to get the roots you actually care about.由于您的 function 有无限多的根(请参阅下面的 plot),因此传递其中一些有助于获得您真正关心的根。

This is how f looks like (well, f/1000 to make features visible):这就是f的样子(嗯, f/1000使特征可见):

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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