2017-05-08 277 views
2

我試圖解決這個問題:的Python:無法解決使用odeint與符號函數微分方程

enter image description here

其中U是

enter image description here

這裏:

s=c*e(t)+e_dot(t) 

and

e(t)=theta(t)-thetad(t) 

e_dot(t)=theta_dot(t)-thetad_dot(t) 

其中thetad(希塔需要的話)= SIN(T) - 待跟蹤即信號!我試着第一次使用odeint,它在t = 0.4後給出的誤差是θ(上面的微分方程的解)平穩地下降到了0, 0並留下。然而,當我試圖將mxstep提高到5000000時,我可以得到一些正確的圖,直到t = 4.3s。

我想得到一個純正弦曲線圖。那就是我希望theta(上述微分方程的解)跟蹤時間即sin(t)。但在t = 4.3秒後無法準確地追蹤該點。在這段時間之後,θ(上述微分方程的解)簡單地下降到0並停留在那裏。

這裏是我的代碼 -

from scipy.integrate import odeint 
import numpy as np 
import matplotlib.pyplot as plt 

c=0.5 
eta=0.5 
def f(Y,t): 
    x=Y[0] 
    y=Y[1] 
    e=x-np.sin(t) 
    de=y-np.cos(t) 
    s=c*e+de 
    return [y,-c*(de)-np.sin(t)-eta*np.sign(s)] 

t=np.linspace(0,10,1000) 
y0=[0.5,1.0] 
sol=odeint(f,y0,t,mxstep=5000000) 
#sol=odeint(f,y0,t) 
print(sol) 
angle=sol[:,0] 
omega=sol[:,1] 
error=angle-np.sin(t) 
derror=omega-np.cos(t) 
plt.subplot(4,2,1) 
plt.plot(t,angle) 
plt.plot(t,error,'r--') 
plt.grid() 
plt.subplot(4,2,2) 
plt.plot(t,omega) 
plt.plot(t,derror,'g--') 
plt.grid() 
plt.subplot(4,2,3) 
plt.plot(angle,omega) 
plt.grid() 
plt.subplot(4,2,4) 
plt.plot(error,derror,'b--') 
plt.savefig('signum_graph.eps') 
plt.show() 

回答

1

odeint(你發現實現,可能是所有集成商)採用積分是基於這樣的假設,你的衍生物(f)是連續的(並具有連續衍生物)在每個步驟中。 signum函數顯然打破了這個要求。這會導致誤差估計值非常高,無論步長有多小,反過來導致步長過小以及遇到的問題。

達到這一目的有兩種常用的解決方案:

  1. 選擇你的步長,使得標誌翻轉正好落在了一步。 (這可能會非常乏味)

  2. 用非常陡峭的sigmoid代替signum函數,這對大多數應用程序來說應該是很好的,甚至更現實。在代碼中,你可以使用

    sign = lambda x: np.tanh(100*x) 
    

    ,而不是np.sign。這裏的因子100控制了S形的陡度。選擇它足夠高,以反映你實際需要的行爲。如果選擇過高,這可能會對運行時間產生負面影響,因爲積分器會將步長調整到不必要的小。

在你的情況,設定絕對值小的公差也似乎是工作,但我不會依靠這樣的:

sol = odeint(f,y0,t,mxstep=50000,atol=1e-5) 
+0

的ODE功能應具有中等規模的連續導數最多的順序的方法。什麼「中等大小」取決於步長算法的內部。即使是階梯函數的一階導數,也是一個狄拉克三角洲峯值,較高的一個更差...... – LutzL

+0

非常感謝! Wrzlprmft你救了我很多麻煩!我正在查看integrate.ode中的Vode選項。然而,tanh在這裏幫助了我很多! –

+0

另一個變體是'def sign(s):s * = 1e3;返回s /(1 + np.abs(s));'。同時嘗試移動sigmoid函數以使其不對稱,使其不對稱,或者其他小的偏移量。只有在這種變化下解的相似性,你才能希望在給定的時間間隔內存在某種廣義的解。 – LutzL