Python: Finding multiple roots of nonlinear equation

匿名 (未验证) 提交于 2019-12-03 01:31:01

问题:

Assume the following function:

f(x) = x * cos(x-4)

With x = [-2.5, 2.5] this function crosses 0 at f(0) = 0 and f(-0.71238898) = 0.

This was determined with the following code:

import math from scipy.optimize import fsolve def func(x):     return x*math.cos(x-4) x0 = fsolve(func, 0.0) # returns [0.] x0 = fsolve(func, -0.75) # returns [-0.71238898] 

What is the proper way to use fzero (or any other Python root finder) to find both roots in one call? Is there a different scipy function that does this?

fzero reference

回答1:

Define your function so that it can take either a scalar or a numpy array as an argument:

>>> import numpy as np >>> f = lambda x : x * np.cos(x-4) 

Then pass a vector of arguments to fsolve.

>>> x = np.array([0.0, -0.75]) >>> fsolve(f,x) array([ 0.        , -0.71238898]) 


回答2:

I once wrote a module for this task. It's based on chapter 4.3 from the book Numerical Methods in Engineering with Python by Jaan Kiusalaas:

import math  def rootsearch(f,a,b,dx):     x1 = a; f1 = f(a)     x2 = a + dx; f2 = f(x2)     while f1*f2 > 0.0:         if x1 >= b:             return None,None         x1 = x2; f1 = f2         x2 = x1 + dx; f2 = f(x2)     return x1,x2  def bisect(f,x1,x2,switch=0,epsilon=1.0e-9):     f1 = f(x1)     if f1 == 0.0:         return x1     f2 = f(x2)     if f2 == 0.0:         return x2     if f1*f2 > 0.0:         print('Root is not bracketed')         return None     n = int(math.ceil(math.log(abs(x2 - x1)/epsilon)/math.log(2.0)))     for i in range(n):         x3 = 0.5*(x1 + x2); f3 = f(x3)         if (switch == 1) and (abs(f3) >abs(f1)) and (abs(f3) > abs(f2)):             return None         if f3 == 0.0:             return x3         if f2*f3 

roots finds all roots of f in the interval [a, b].



回答3:

In general (i.e. unless your function belongs to some specific class) you can't find all the global solutions - these methods usually do local optimization from given starting points.

However, you can switch math.cos() with numpy.cos() and that will vectorize your function so it can solve for many values at once, e.g. fsolve(func, np.arange(-10,10,0.5)).



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!