用积分函数拟合数据

时间:2015-05-19 17:11:45

标签: python scipy integral data-fitting

当使用curve_fit中的scipy.optimize来拟合python中的某些数据时,首先定义拟合函数(例如二阶多项式),如下所示:

  1. window.$
  2. 然后继续进行拟合def f(x, a, b): return a*x**2+b*x
  3. 但现在的问题是,如果函数包含一个整数(或一个离散的和),如何在第1点定义函数,例如:

    enter image description here

    仍然给出了x和f(x)的实验数据,因此,一旦我可以在python中定义f(x),第2点将是类似的。顺便说一下,我忘了说这里假设g(t)具有众所周知的形式,并且包含拟合参数,即在多项式例子中给出的像a和b这样的参数。任何帮助深表感谢。问题实际上应该是通用的,而帖子中使用的函数只是随机的例子。

2 个答案:

答案 0 :(得分:7)

这是一个拟合用积分定义的曲线的例子。该曲线是sin(t*w)/t+pt之间从0到Pi的积分。我们的x数据点对应w,我们正在调整p参数以使数据适合。

import math, numpy, scipy.optimize, scipy.integrate

def integrand(t, args):
    w, p = args
    return math.sin(t * w)/t + p

def curve(w, p):
    res = scipy.integrate.quad(integrand, 0.0, math.pi, [w, p])
    return res[0]

vcurve = numpy.vectorize(curve, excluded=set([1]))

truexdata = numpy.asarray([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
trueydata = vcurve(truexdata, 1.0)

xdata = truexdata + 0.1 * numpy.random.randn(8)
ydata = trueydata + 0.1 * numpy.random.randn(8)

popt, pcov = scipy.optimize.curve_fit(vcurve,
                                      xdata, ydata,
                                      p0=[2.0])
print popt

这会打印出非常接近1.0的内容,这是我们在创建p时用作trueydata的内容。

请注意,我们在曲线函数上使用numpy.vectorize来生成与scipy.optimize.curve_fit兼容的矢量化版本。

答案 1 :(得分:3)

有时候你很幸运,你能够分析地评估积分。在以下示例中,h(t)=exp(-(t-x)**2/2)和二次多项式g(t)的乘积从0到无穷大积分。 Sympy用于评估积分并生成可用于curve_fit()的函数:

import sympy as sy
sy.init_printing()  # LaTeX-like pretty printing of IPython


t, x = sy.symbols("t, x", real=True)

h = sy.exp(-(t-x)**2/2)

a0, a1, a2 = sy.symbols('a:3', real=True)  # unknown coefficients
g = a0 + a1*t + a2*t**2

gh = (g*h).simplify()  # the intgrand
G = sy.integrate(gh, (t, 0, sy.oo)).simplify()  # integrate from 0 to infinty

# Generate numeric function to be usable by curve_fit()
G_opt = sy.lambdify((x, t, a0, a1, a2), G)

print(G_opt(1, 2, 3, 4, 5))  # example usage

请注意,一般来说,问题通常是不适合的,因为积分不必在解的一个足够大的邻域中收敛(由curve_fit()假设)。