如何用scipy.optimize.newton求解scipy.special.airy函数的前4个根?
使用scipy.optimize.newton求解airy函数Ai的前4个根
核心问题解决思路
scipy.special.airy(x)返回的是四个函数在点x的取值数组,而scipy.optimize.newton需要的是输入单变量x、返回Ai(x)值的函数。直接调用airy[0]会报错,因为airy是函数对象,不是可索引的数组,必须先包装出单独的Ai函数(及其导数)。
具体实现步骤
- 包装Ai函数与导数函数:从
airy的返回值中提取Ai函数(第一个返回值)和它的导数Aip(第二个返回值),封装成newton可接受的单变量函数。 - 确定初始猜测值:Ai函数的前几个根有已知的近似值,以此作为初始点能保证
newton收敛。 - 调用newton求解:传入包装后的函数、初始猜测,可选传入导数函数提升收敛效率。
完整代码示例
import scipy.optimize as opt import scipy.special as sp # 封装Ai函数:输入x,返回Ai(x) def ai(x): return sp.airy(x)[0] # 封装Ai的导数函数:输入x,返回Ai'(x) def ai_prime(x): return sp.airy(x)[1] # Ai前4个根的初始猜测值 initial_guesses = [-2.3, -4.1, -5.5, -6.8] # 批量求解根 roots = [opt.newton(ai, guess, fprime=ai_prime) for guess in initial_guesses] print("Ai函数的前4个根:") for idx, root in enumerate(roots, 1): print(f"第{idx}个根:{root:.4f}")
简化写法(使用lambda)
如果不想单独定义函数,也可以用lambda表达式直接传入:
roots = [ opt.newton( lambda x: sp.airy(x)[0], guess, fprime=lambda x: sp.airy(x)[1] ) for guess in initial_guesses ]
关键说明
- 传入
fprime参数(解析导数)比让newton自动计算数值微分更准确、收敛更快,而airy恰好直接返回了导数,一定要利用这个特性。 - 初始猜测值不能随意选,比如选正数的话,Ai函数在正数区间单调递减趋近于0,不会有根,必须选负数区间的近似值。
内容的提问来源于stack exchange,提问作者Rex Planalp
相关产品推荐
相关产品推荐

