我有一个> 1000点的曲线,我希望以x''=(a * x''+ bx'+ cx + d)的形式拟合微分方程,其中a,b, c,d是常数。我将如何使用Python 2.7继续这样做?
答案 0 :(得分:1)
您可以使用优化来找到最佳参数a
,b
,c
,d
,以使测量值和预测值之间的差异最小。这是我开发的在gekko中具有三阶微分方程的示例代码。
from gekko import GEKKO
t_data = [0,0.1,0.2,0.4,0.8,1,1.5,2,2.5,3,3.5,4]
x_data = [2.0,1.6,1.2,0.7,0.3,0.15,0.1,\
0.05,0.03,0.02,0.015,0.01]
m = GEKKO()
m.time = t_data
# states
x = m.CV(value=x_data); x.FSTATUS = 1 # fit to measurement
y,z = m.Array(m.Var,2,value=0)
# adjustable parameters
a,b,c,d = m.Array(m.FV,4)
a.STATUS=1; b.STATUS=1; c.STATUS=1; d.STATUS=1
# differential equation
# Original: x''' = a*x'' + b x' + c x + d
# Transform: y = x'
# z = y'
# z' = a*z + b*y + c*x + d
m.Equations([y==x.dt(),z==y.dt()])
m.Equation(z.dt()==a*z+b*y+c*x+d) # differential equation
m.options.IMODE = 5 # dynamic estimation
m.options.NODES = 3 # collocation nodes
m.solve(disp=False) # display solver output
print(a.value[0],b.value[0],c.value[0],d.value[0])
import matplotlib.pyplot as plt # plot solution
plt.plot(m.time,x.value,'bo',label='Predicted')
plt.plot(m.time,x_data,'rx',label='Measured')
plt.legend(); plt.xlabel('Time'), plt.ylabel('Value'); plt.show()
大多数微分方程求解器要求将高阶导数转换为单独的一阶导数方程。这很容易做到,因为您需要为每个附加订单(二阶和三阶导数)定义新状态为shown here。
答案 1 :(得分:0)
当然,你打算在右边有三阶导数。
将数据分组到相对较小的容器中,可能重叠。对于每个bin,计算数据的三次近似。从中计算出该组中心点的衍生物。使用所有组的衍生物,您现在有一个经典的线性回归问题。
如果样本间隔相等,您可能会尝试通过FFT将问题移到频率空间。合理地截断数据可能是一个问题。在频率空间中,任务简化为多项式线性回归。