用scipy拟合贝塞尔函数(第二类)的数据

时间:2014-02-28 13:58:28

标签: python scipy curve-fitting

我的数据看起来像第二种Bessel函数(可以说应该用其中一种函数来描述)。

我一直在尝试使用scipy优化工具箱按照文档示例执行此操作但到目前为止没有成功:我收到以下错误消息

ValueError: array must not contain infs or NaNs

我会说0的分歧是导致问题的原因。

顺便说一句,我试图拟合两个参数,贝塞尔函数的索引和变量中的比例因子,a和b在K a (bx)中。尝试适应离散空间(在自然整数中取值)是一个问题。

我的代码目前看起来像这样:

from scipy.special import yn #importing the Bessel functions
from scipy.optimize import curve_fit

def func(var, a, b):
    return yn(b*var,a)
popt, pcov = curve_fit(func, x, y) # x and y are my data points

1 个答案:

答案 0 :(得分:2)

首先,您以错误的顺序传递yn个参数,它应该是yn(a,b*var)而不是yn(b*var,a)。可能是导致函数yn爆炸到inf的错误。

作为第二点,正如您所怀疑的那样,scipy会在您致电a时将yn截断为浮点数,并提升RuntimeWarning。您最好只针对缩放变量b进行优化,然后调整整数阶a的不同值。您可以手动或循环执行此操作。

我将讨论一些以示例开头的融合问题,在sin(x)/2上使用yn(1,x)[1,2*pi]拟合。

from scipy.special import yn
from scipy.optimize import curve_fit
from numpy import sin,linspace,pi

a=1#choose the order a here!
func = lambda var,b : yn(a,b*var)

x=linspace(1,2*pi,100)
y=sin(x)/2.#we fit this as an example
[b], pcov = curve_fit(func, x, y) # x and y are my data points
print b

enter image description here

如果您现在将域名更改为x=linspace(0,2*pi,100)[1:],则curve_fit将无法收敛。这是因为在域的接近零的部分中,优化算法将尝试向轴挤压yn。这导致b的值很大,这反过来导致函数的强烈振荡行为(尝试plot(x,yn(a,10*x)))直到离散化限制(尝试plot(x,yn(a,10*x))),事情变得更糟

道德观点是,如果你的数据对于低x接近于零,你应该从零开始拟合,以获得适当的收敛。

作为旁注,通常Ka(x)指的是第二类的MODIFIED Bessel函数,而yn是第二类的Bessel函数,通常称为Ia(x)