2016-04-24 9 views
0

Ist es möglich, einen einzigen Schritt mit einem scipy ODE-Integrator zu machen? Ich bin mir des Arguments step zu scipy.integrate.ode.integrate bewusst, aber ich kann nicht herausfinden, das t Argument so festzulegen, dass es garantiert ist, genau einen vollen Schritt zu nehmen. Die offensichtliche Wahl ist t=inf, aber das gibt einen ODE Ausfall ::Unter einem einzigen ODE-Schritt

from scipy.integrate import ode 
obj = ode(lambda t, y: -y) 
obj.set_initial_value(1) 
y_new = obj.integrate(inf, step=True) 

-

DVODE-- At T (=R1) and step size H (=R2), the  
     corrector convergence failed repeatedly  
     or with abs(H) = HMIN 
     In above, R1 = 0.0000000000000D+00 R2 =    Infinity 
C:\Anaconda3\lib\site-packages\scipy\integrate\_ode.py:869: UserWarning: 
vode: Repeated convergence failures. (Perhaps bad Jacobian supplied or 
wrong choice of MF or tolerances.) 
    'Unexpected istate=%s' % istate)) 

Wenn ich t=0, dann wird die ODE überhaupt nicht vorantreiben. Ich kann eine endliche positive Zahl wählen, aber ist das garantiert, einen vollen Schritt zu machen und über t zu gehen, wenn t kleiner als der volle Schritt ist? Ich schreibe eine allgemeine Bibliothek und weiß nicht, was eine typische Schrittgröße sein wird.

Antwort

0

Ich habe einige Tests durchgeführt und verifiziert, dass die Einstellung step=True und t gleich einer positiven endlichen Zahl genau einen Schritt dauert. Es wird über t gehen, wenn t kleiner als der nächste Schritt ist.

from scipy.integrate import ode 
obj = ode(lambda t, y: -y) 
obj.set_initial_value(1) 
while obj.t < 1: 
    y_new = obj.integrate(1, step=True) 
print(obj.t) # prints 1.037070648009345 

Eine Sache zu beachten ist, dass die adaptive Schrittgröße schätzt die anfängliche Schrittgröße basierend auf einem bestimmten Bruchteil t. Die Wahl eines kleineren t verursacht einen kleineren ersten Schritt. Dies ist der Grund, warum inf fehlschlägt und warum es keinen Wert t gibt, der dazu führt, dass der Integrator im ersten Schritt über t springt.

0

Numerische Integratoren sind nicht wirklich in festen Schritten entworfen, so dass es schwierig, wenn überhaupt möglich ist, Ihr Ziel auf diese Weise zu erreichen. Sie können einen Weg finden, indem Sie mit den Parametern der maximalen und minimalen Schrittgröße fudgen. Wenn Sie jedoch überprüfen möchten, was der Integrator tut, oder eine Protokollierungsfunktion an den Integratorprozess anhängen, können Sie Folgendes tun: Verwenden Sie set_solout() method.

Die Funktion (callable Objekt), die Sie als Argument an set_solout() übergeben, wird bei jedem Integrationsschritt aufgerufen.

+0

Ich bin nicht auf der Suche nach einem festen Schritt. Aber auch Variable-Schritt-Solver haben noch Schritte (die Funktion, die an 'set_selout' übergeben wird, wird jeweils nach jedem aufgerufen). Ich werde versuchen, '-1' von der Selout-Funktion zurückzugeben, um zu tun, was ich will. – drhagen

+0

Ja, das war der Punkt meiner Antwort: 'set_selout' ist das, was du wahrscheinlich wolltest, aber deine Frage war, einen einzigen Schritt mit dem Integrator zu machen. – Cyb3rFly3r

+0

"Numerische Integratoren sind nicht wirklich in festen Schritten entworfen" - es hängt von der Methode ab. Beispielsweise verwenden die expliziten [Runge-Kutta] (https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods) eine feste Schrittgröße. – dkv