2016-12-12 2 views
1

Ich benutze Odein in Scipy, um eine Funktion zu integrieren. Die Funktion ist eigentlich ein Vektor (es ist der zurückgegebene Wert aus der L_total-Funktion unten). Das Problem, das ich habe, ist, dass für einige Einträge dieses Vektors die Integration sehr einfach ist, was bedeutet, dass es nicht viele interne Teilschritte benötigt, für einige andere Werte sollte die Integration jedoch detaillierter sein. Ich nehme an, dass Odein eine Anzahl von Unterschritten benötigt und das ist diejenige, die auf jeden Eintrag des Vektors angewendet wird. Wenn diese Annahme richtig ist, gibt es eine Möglichkeit, eine maximale Anzahl von internen Teilschritten in scipy in Abhängigkeit vom Eintrag im Funktionsvektor effizient zuzuweisen? Ich weiß, dass ich mit einer IF-Anweisung vielleicht die Anzahl der erlaubten maximalen Anzahl von Schritten ändern kann, aber dann befürchte ich, dass es mehr Rechenzeit benötigt, und das ist es, was ich reduzieren möchte. Mein Code sieht wie folgt aus:scipy.odeint verstehende interne Zeitschritte

def L_total(self, r, d, u): 
    tem = self.T(u) 
    condlist = [numpy.log10(tem) <= 2, numpy.log10(tem) >= 2] 
    choicelist = [self.L1(r, d, tem), self.L2(r, tem)] 
    return numpy.select(condlist, choicelist) #This is the returned value for the scipy integration, i.e. the vector I want to integrate 

def integrate_function(self, i_0, time_final, r, d): 
    def f(i, t): 
     return - self.L_total(r, d, i) 
    time = numpy.linspace(0., time_final, 2) 
    result = odeint(f, i_0, time) 
    return result[-1] 

Die letzte Funktion ist für eine Weile gut, bis die Werte der Variablen tem zu erhöhen, dann habe ich eine Meldung erhalten, ‚Excess Arbeit an diesem Aufruf getan‘ und der Vorschlag ist, die Anzahl der Zeitschritte zu erhöhen erlaubt:

lsoda-- at current t (=r1), mxstep (=i1) steps ^@^@ 
    taken on this call before reaching tout  ^@^@ 
    in above message, i1 =  500 
    in above message, r1 = 0.3319309749049D+03 

Überschuss Arbeit an diesem Aufruf gemacht (vielleicht falsch Dfun Typ)

die Nummer des Arguments mxstep Erhöhung klingt wie die Lösung, außer für die fac t so lange wie log (tem) < 2 die Integration ist einfach und die Anzahl der internen Zeitschritte kann klein sein, ich möchte keine Zeit mit dieser einfachen Integration zu verschwenden, ist die Idee, nur die mxstep Wert für bestimmte Werte zu erhöhen des Vektors. Eine Art und Weise, es zu tun ist:

def integrate_function(self, i_0, time_final, r, d, tem): 
    def f(i, t): 
     return - self.L_total(r, d, i) 
    time = numpy.linspace(0., time_final, 2) 
    if numpy.log10(tem)<=2: 
     result = odeint(f, i_0, time, mxstep=10) 
    else: 
     result = odeint(f, i_0, time, mxstep=1000) 
    return result[-1] 

jedoch die Länge der Vektorfunktion ist sehr groß, so dass es eine Menge Rechenzeit verbrauchen, da ich in einer anderen Schleife diese Schleife zu tun habe. Was ich brauche, ist Effizienz, weil mein Code schon viel Zeit braucht.

+0

Das Erhöhen von 'maxstep' bedeutet nicht, dass' odeint' mehr Schritte in den einfachen Fällen verwendet. Es ist kein Parameter, der die Schrittgrößen bestimmt. Es bestimmt nur, wie lange 'Odeint' bestehen soll, bevor es aufgibt. – FTP

+0

Aber meine Frage ist, pro Integration, wird die Anzahl der subtimessteps je nach Wert des Vektors ändern oder wird es die gleiche Anzahl von subtimesps für alle Einträge des Vektors sein? – user3412058

+0

Subtimesteps sind die gleichen, weil normalerweise, wenn man ein System von ODE löst, man nicht mit den Komponenten getrennt arbeiten kann: alle müssen zum selben Zeitpunkt bekannt sein, um die Ableitung zu dieser Zeit zu finden. Wenn Ihr System _uncoupled_ ist (Gleichungen haben nichts miteinander zu tun), kann das Lösen einzelner Gleichungen in der Schleife tatsächlich schneller sein; Ich würde beide Optionen zeitlich und vergleichen. – FTP

Antwort

1

Subtimesteps, die automatisch von odeint ausgewählt werden, sind für alle Gleichungen im System identisch. Dies liegt daran, dass normalerweise beim Lösen eines Systems von ODEs nicht mit den Komponenten separat gearbeitet werden kann: Alle müssen zum selben Zeitpunkt bekannt sein, um die Ableitung zu dieser Zeit zu finden.

Für ein entkoppeltes System, in dem Gleichungen nichts miteinander zu tun haben, führt das Obige zu einer möglicherweise unnötigen Einschränkung der Zeitschritte. In diesem Fall kann das Lösen einzelner Gleichungen in einer Schleife tatsächlich schneller sein als das Arbeiten mit ihnen als System.