这就是我所做的。我保留了xobs
and yobs
:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
xobs=np.linspace(0,10,100)
yl=np.random.rand(50); yr=np.random.rand(50)+100
yobs=np.concatenate((yl,yr),axis=0)
现在,必须生成 Heaviside 函数。为了让您对该函数有一个概述,请考虑 Heaviside 函数的半极大约定:
在 Python 中,这相当于:def f(x): return 0.5 * (np.sign(x) + 1)
示例图如下:
xval = sorted(np.concatenate([np.linspace(-5,5,100),[0]])) # includes x = 0
yval = f(xval)
plt.plot(xval,yval,'ko-')
plt.ylim(-0.1,1.1)
plt.xlabel('x',size=18)
plt.ylabel('H(x)',size=20)
现在,正在策划xobs
and yobs
gives:
plt.plot(xobs,yobs,'ko-')
plt.ylim(-10,110)
plt.xlabel('xobs',size=18)
plt.ylabel('yobs',size=20)
请注意,比较这两个图,第二个图移动了 5 个单位,最大值从 1.0 增加到 100。我推断第二个图的函数可以表示如下:
或者在Python中:(0.5 * (np.sign(x-5) + 1) * 100 = 50 * (np.sign(x-5) + 1)
合并这些图可以得出(其中Fit
代表上面的拟合函数)
剧情证实了我的猜测是正确的。现在,假设您不知道这个正确的拟合函数是如何产生的,则创建一个广义拟合函数:def f(x,a,b,c): return a * (np.sign(x-b) + c)
,理论上,a = 50
, b = 5
, and c = 1
.
继续估算:
popt,pcov=curve_fit(f,xobs,yobs,bounds=([49,4.75,0],[50,5,2]))
.
Now, bounds = ([lower bound of each parameter (a,b,c)],[upper bound of each parameter])
。从技术上讲,这意味着 49 abc < 2.
Here are MY results for popt
and pcov
:
![Results](https://i.stack.imgur.com/SBRty.png)
pcov
表示 popt 的估计协方差。对角线提供参数估计的方差[Source] https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.curve_fit.html.
结果表明参数估计pcov
接近理论值。
基本上,广义赫维赛德函数可以表示为:a * (np.sign(x-b) + c)
以下是将生成参数估计值和相应协方差的代码:
import numpy as np
from scipy.optimize import curve_fit
xobs = np.linspace(0,10,100)
yl = np.random.rand(50); yr=np.random.rand(50)+100
yobs = np.concatenate((yl,yr),axis=0)
def f(x,a,b,c): return a * (np.sign(x-b) + c) # Heaviside fitting function
popt, pcov = curve_fit(f,xobs,yobs,bounds=([49,4.75,0],[50,5,2]))
print 'popt = %s' % popt
print 'pcov = \n %s' % pcov
最后,请注意,估计popt
and pcov
vary.
python /questions/tagged/pythonscipy /questions/tagged/scipy