寻找给定范围内的函数的根

2024-04-24 00:28:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组函数f_t有几个根(实际上有两个根)。我想找到“第一个”根,使用fsolve进行此操作在大多数情况下都可以正常工作。问题是,当t趋于无穷大时,两个根会聚。(我的函数的一个简单示例是f_t(x) = x^2 - 1/t)。所以t越大,犯的错误就越多。是否有一个预定义的函数,类似于fsolve,我可以告诉它应该只在给定的范围内查找(例如,始终在[0, inf中查找根)。

这个问题本质上与https://mathematica.stackexchange.com/questions/91784/how-to-find-numerically-all-roots-of-a-function-in-a-given-range?noredirect=1&lq=1相同,但是Mathematica有答案,我希望用Python来回答。

注:我现在如何编写自己的算法,但由于这些算法往往比内置算法慢,所以我希望能找到一个与之相同的内置算法。尤其是我读过这篇文章Find root of a function in a given interval


Tags: of函数inhttps算法示例错误情况
3条回答

通常,您可以使用^{}

import numpy as np
from scipy.optimize import root

def func(x, t):
    return x ** 2 - 1. / t

t = 5000

res = root(func, 0.5, args=(t, )).x[0]
print res

这将打印出正的,在本例中是0.0141421356237

如果要指定范围并确定此间隔内的所有根,可以使用^{}

from chebpy import chebfun

x = chebfun('x', [-100000, 100000])
t = 5000
f = x ** 2 - 1. / t

rts = f.roots()
print rts

这将同时打印正根和负根,在本例中

[-0.01413648  0.01413648]

如果你只想看到正的范围,你可以改变

x = chebfun('x', [-100000, 100000])

x = chebfun('x', [0, 100000])

不过,我不知道如何使用无穷大,但我认为,你可以把一个很高的数字用于实际用途。

一般认为,对于光滑、性能良好的函数,Brent method是保证给出根的最快方法。与列出的其他两个方法一样,您必须提供一个间隔[a,b],在该间隔内函数是连续的并更改符号。

Scipy实现被记录在案。您提到的函数的示例用例如下所示:

from __future__ import division
import scipy

def func(x,t):
    return(x**2 - 1/t)

t0 = 1
min = 0
max = 100000 # set max to some sufficiently large value

root = scipy.optimize.brentq(func, min, max, args = (t0)) # args just supplies any extra
                                                       # argument for the function that isn't the varied parameter

您可以使用^{},它接受定义开始间隔的两个参数ab。但也有一些限制:

  • 间隔必须是有限的。无法在[0,inf]中搜索。
  • 函数必须在根处翻转符号(f(a)f(b)必须有相反的符号),因此,例如,您找不到f(x) = abs(x)的根(如果从数学意义上说,它甚至是“根”)。而且,它对a<;-1和b>;1的f(x) = x**2 - 1和间隔[a,b]也不起作用。
  • 该方法不是基于梯度的。如果函数的计算非常困难或昂贵,但在其他函数上可能较慢,则这是一个优势。

另一种方法是使用^{}来最小化abs(f(x))。这个函数可以取包含无穷大的bounds。但最小化可能会以函数的非根局部最小值结束。

相关问题 更多 >