2016-04-07 2 views
2

I Python und scipy.integrate.odeint zu verwenden, versuchen folgendes dynamisches System zu simulieren:Scipy Odein bricht mit diskontinuierlicher Dynamikfunktion, z.B. xdot = -sgn (x)

enter image description here

Aber diese Integration bricht in Python was zu den folgenden und ähnlichen Bildern (in der Regel auch numerisch schlimmer als diese):

enter image description here

folgend in iPython/Jupyter notebook generierten mit:

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

f = lambda x,t: -np.sign(x) 
x0 = 3 
ts = np.linspace(0,10,1000) 
xs = odeint(f,x0,ts) 
plt.plot(ts,xs) 
plt.show() 

Irgendwelche Ratschläge, wie man ein solches System mit diskontinuierlicher Dynamik besser simuliert?

Edit # 1:

Beispiel Ergebnis, wenn lief mit kleinem Zeitschritt, ts = np.linspace(0,10,1000000), als Antwort auf @ Hun Antwort. Dies ist auch ein falsches Ergebnis gemäß meinen Erwartungen.

enter image description here

+0

Nur hinzufügen, dass ich verschiedene Bilder bei der Ausführung des Codes wiederholen ... –

+0

Auch ausgeführt Python-Version: 2.7.11 –

+0

Ich benutze Python 3.5.1, numpy 1.10.4, scipy 0.17.0. Es hat einfach gut funktioniert, als ich Ihren Code genau wie gezeigt lief. – Hun

Antwort

0

lief ich den Code genau wie gezeigt und das ist, was ich bekam.

enter image description here

+0

Kannst du es bitte mehrmals wiederholen und melden, wenn du immer dieses Bild bekommst? –

+0

(Dies ist, wie ich es erwarte aussehen) –

+0

ts = np.linspace (0,10,1000) # machen Sie diese Zeit Schritt kleiner. Zum Beispiel, machen Sie es 1e4. – Hun

0

Ich lief es auch genau wie gezeigt und bekam:

enter image description here

+0

Dies ist eine andere Art von Ergebnis, die ich irgendwann bekomme ... –

+0

Haben Sie weitere Informationen für dieses dynamische System, heißt es alles, was ich vielleicht nachschlagen kann? –

0

Ein Ansatz, der besser ist, eine benutzerdefinierte sgn() Funktion durch die Implementierung, die Epsilon-Toleranz hat um Null arbeiten kann, statt Erwarte präzise Gleichheit mit Null.

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

sgn = lambda x,eps: (x<-eps)*(-1) + (x>=-eps and x<eps)*0 + (x>=eps)*1 
f = lambda x,t: -sgn(x,1e-7) 
x0 = 3 
ts = np.linspace(0,10,1000) 
xs = odeint(f,x0,ts) 
plt.plot(ts,xs) 
plt.show() 

Beachten Sie, dass ein eps Parameter von 1e-7 gut für mich gearbeitet, aber kleiner als das schien zum Absturz bringen. Es scheint von numpy.finfo und demonstriert here, dass die Maschine Epsilon von numpy.float32 um 1e-7 ist, während float um 1e-16 ist.