下面我解决了描述弹簧质量缓冲器系统的二阶ODE:u''+ c u'+ k u = 0。我对odeint求解器没有任何问题.odeint函数在指定时间内正确求解位置U(t)。
#modeling spring mass system
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy import integrate
#Make the following substitution to make system first order
#Y[1]=y′(t) and Y[0]=y(t),
#system: Y[0]'=Y[1] and Y[1]'=-c*Y[1]-k*Y[0]
#=======================================================
def eq(par,initial_cond,start_t,end_t,incr):
#-time-grid-----------------------------------
t = np.linspace(start_t, end_t,incr)
#differential-eq-system----------------------
def funct(y,t):
ut=y[0]
ut_dt=y[1]
c,k=par
# the model equations u'=Y[1], u''=-k*Y[0]-c*Y[1] from u''+c*u'+k*u=0
f0 =ut_dt
f1 =-k*ut-c*ut_dt
return [f0, f1]
#integrate------------------------------------
ds = integrate.odeint(funct,initial_cond,t)
return (ds[:,0],ds[:,1],t)
#=======================================================
#parameters
c=2. #spring coefficient
k=10. #dampening coefficient
#collect parameters in tuple
coefs=(c,k)
# initial conditions
u0=6.
ud0=0.
y0=[u0,ud0]
start,stop,incr=0,20,100
#Solve and plot solution
F0,F1,T=eq(coefs,y0,start,stop,incr)
plt.figure()
plt.plot(T,F0,'-b',T,F1,'-r')
plt.legend(('u0', 'u1'),'upper center')
plt.title('Mass-Spring System')
但是,如果给定模拟测量,我想使用scipy.optimize.fmin()来找到该系统的最佳拟合参数(c,k)。所以我使用上面的解决方案,其中c = 2,k = 10,并添加随机噪声。
rand_i=randn(incr)
#noiselevel
nl=.05
noisy_data=F0+nl*rand_i
plt.plot(noisy_data,label="noisy_data:c=2,k=10")
plt.legend()
接下来,我为fmin()设置了一个评分函数以最小化。我猜测参数,c = 1,k = 1。
from scipy.optimize import fmin
#1.Get 'Real' Data
#====================================================
nd=noisy_data#solution with parameters: c=2,k=10
#====================================================
#2.Set up Info for Model System
#===================================================
# guess parameters
c=1 #spring coefficient
k=1 #dampening coefficient
#collect parameters in tuple
coefs=(c,k)
# initial conditions
u0=6.
ud0=0.
y0=[u0,ud0]
# model steps
#---------------------------------------------------
start_time=0
end_time=20
intervals=100
mt=np.linspace(start_time,end_time,intervals)
#3.Score Fit of System
#=========================================================
def score(parms):
#a.Get Solution to system
F0,F1,T=eq(coefs,y0,start_time,end_time,intervals)
#b.Pick of Model Points to Compare
um=F0
#c.Score Difference between model(ode output) and data points (noisy data)
ss=lambda data,model:((data-model)**2).sum()
return ss(nd,um)
#========================================================
#4.Optimize Fit
#=======================================================
fit_score=score(coefs)
answ=fmin(score,(coefs))
问题是fmin找不到正确的参数。它发现即使得分函数很高,猜测参数也是最好的。下面我打印fmin解答,并显示即使在调用fmin()之后它与初始猜测相同。
print(answ==[c,k])
有谁知道为什么fmin()找不到正确的参数,c = 2,k = 10?
答案 0 :(得分:0)
您的代码中存在一个微不足道的错误:您使用输入参数score
定义parms
,但随后将所述变量称为coefs
。修正:
def score(coefs): #changed
#a.Get Solution to system
F0,F1,T=eq(coefs,y0,start_time,end_time,intervals)
#b.Pick of Model Points to Compare
um=F0
#c.Score Difference between model(ode output) and data points (noisy data)
ss=lambda data,model:((data-model)**2).sum()
return ss(nd,um)
在:
In [369]: answ
Out[369]: array([ 1., 1.])
后:
In [373]: answ
Out[373]: array([ 2.0425695 , 9.96937966])
但是,请注意answ==(c,k)
总是 False
,即使是完美契合:您正在使用浮点数。任何有意义的比较应该看起来像max(abs(answ-[2,10])/abs(answ))<tol
或类似的东西。 (我知道您的原始问题用于表明值没有更改,但仍然。)