我正在寻找一种有效的方法来查找区间[a,b]上函数f的所有根。 我遇到的问题是来自scipy.optimize的所有好方法要求f(a)和f(b)有不同的符号,或者我提供初始猜测x0,但在运行代码之前我对我的根一无所知
注意:函数f是平滑的(至少是C1),并且没有病态行为[没有像sin(1 / x)]。然而,它需要构建矩阵A(x)并找到其特征值,因此是耗时的。预计在[a,b]上有0到10个根,其位置完全是任意的。我不能错过任何一个(例如我不能接受100个初始猜测x0,只希望我能抓住所有根源)。
我正在考虑实施这样的事情:
有没有更好的方法来解决这个问题?
如果没有,fmin和brentq是scipy.optimize库中的最佳选择,以尽量减少对函数f的调用次数吗?
答案 0 :(得分:1)
对此的一种“通常”方法是找到函数的近似值,根查找很容易,然后找到近似值的根。
例如,您可以在多个点处对函数值进行采样,使样条拟合点,然后找到样条曲线的根(这是一个简单的问题)。这将至少为根提供初步猜测。
更棘手的部分是确定采样点。如果您知道您的函数是C1,则可以根据函数值在函数显示为非平滑的点处更加密集地进行采样。几年前我需要这样做,所以这里有一种启发式烹饪方法来解决这个问题:https://gist.github.com/pv/acc71bafede0a84b074c7751985ecc6f为我工作,但YMMV。
答案 1 :(得分:0)
取决于您的功能,但可以使用SymPy以符号方式解决。这将给所有的根源。如有必要,它可以象征性地找到特征值。
找到所有极值与找到函数导数的所有根相同,所以它不会比找到所有根更容易(正如WarrenWeckesser所提到的那样)。
以数字方式查找所有根将需要使用有关该函数的知识。举个简单的例子,假设您知道根之间的最小间距。您可以尝试以递归方式对区间进行分区,并在每个区间中找到根。找到最大根数后停止。但是如果间距很小,这可能需要许多功能评估(例如,在最坏的情况下,当根有零时)。您可以施加的约束越多,您就越能减少功能评估。