2016-03-25 10 views
0

Für E=0.46732451 und t=1.07589765 Ich versuche, für die obere Grenze des Integrals zu lösen t = \ int_ {0}^{z} 1/sqrt (2 * (0.46732451-z ** 2)), Zeichnete ich diese Funktion und es sieht so aus z vs t.Python: fsolve in der Nähe asymptotischer Bereich

Um t=1 es Art von Asymptoten.

Ich habe den folgenden Code

import numpy as np 
from scipy import integrate 
from scipy.optimize import fsolve 

def fg(z_up,t,E): 
     def h(z,E): 
      return 1/(np.sqrt(2*(E-z**2))) 

     b, err = integrate.quad(h, 0, z_up,args=(E)) 
     return b-t 



x0 = 0.1 
print fsolve(fg, x0, args=(1.07589765, 0.46732451))[0] 

Aber dieser Code nur die Vermutung Wert ausgibt, egal, was ich gesagt, so dass ich vermute, es hat etwas mit der Tatsache, dass die Kurve Asymptoten dort zu tun. Ich sollte beachten, dass dieser Code für andere Werte von t funktioniert, die von der asymptotischen Region entfernt sind.

Kann mir jemand helfen, dies zu lösen?

Dank

EDIT Nach dem Spielen um für eine Weile, löste ich das Problem, aber es ist so eine Art Patchwork, es funktioniert nur für ähnliche Probleme in der Regel nicht (oder doch?)

Ich habe folgende Änderungen vorgenommen: Der Maximalwert, den z erreichen kann, ist sqrt(0.46732451), also setze ich x0=0.5*np.sqrt(0.46732451) und setze factor irgendwo zwischen 0.1 bis 1, und die richtige Antwort herauskommt. Ich habe keine Erklärung dafür, vielleicht kann jemand, der ein Experte in dieser Angelegenheit ist, helfen?

+0

fsolve wird gelegentlich Werte relativ weit weg von Ihrem Ausgangspunkt versuchen. Dies kann dazu führen, dass das Argument für sqrt negativ wird. Sie sollten zuerst nach dem Argument suchen und einen speziellen Wert zurückgeben, der angibt, "versuchen Sie es nicht", wenn das Argument kleiner als 0 ist (ein einigermaßen großer Wert kann funktionieren). – Evert

+0

Überprüfen Sie, ob das Argument tatsächlich '2 * (E - z ** 2) 'ist und nicht zum Beispiel' 2 * (E - z) ** 2 '. – Evert

+0

Nein, das Argument ist 2 * (E - z ** 2) – HuShu

Antwort

1

sollten Sie bisect stattdessen verwenden, da es nan ohne Probleme behandelt:

print bisect(fg, 0.4, 0.7, args=(1.07589765, 0.46732451)) 

hier 0,4 und 0,7 sind als Beispiel genommen, aber Sie können dies für fast jede divergierende Integral verallgemeinern durch 0 mit und lassen Sie uns sagen 1e12 als die Grenzen.

Ich bin mir aber nicht sicher, ob ich verstehe, was Sie wirklich wollen ... wenn Sie die Grenze finden wollen, bei der das Integral divergiert, vgl. Ihr

Ich versuche, für die obere Grenze der integralen

dann ist es einfach für z_up -> \sqrt{E} \approx 0,683611374 ... So finden den (ungefähren) Zahlenwert der integral Sie müssen nur zu lösen z_up von diesem Wert bis quad endet mit einem nan ...

+0

Ich sehe nicht, warum mein Ansatz nicht der richtige Ansatz ist. Ihr Ansatz ist eine andere Möglichkeit, das Problem zu lösen. Außerdem ist es meiner nicht überlegen, da Sie die Grenzen '0.4' und' 0.7' einbeziehen müssen, um sie zu bestimmen, müssen Sie wissen, dass 'zmax' bei' 0.683611374' ist. Ich möchte die Obergrenze des Integrals finden, wenn der Wert des Integrals '1.07589765' ist, der an einem Punkt auftritt, der sehr nahe an dem Punkt liegt, an dem das Integral divergiert, aber nicht an diesem Punkt. – HuShu

+0

Es ist nur so, dass "fsolve" nicht gut mit "nan" umgehen kann, während "bisect" dies tut. Und um den numerischen Wert des Integrals zu finden, sollten Sie 'z_up' von' \ sqrt {E} 'wirklich reduzieren, wie in meiner Antwort angegeben: das vermeidet die Verwendung eines Wertes für' t', wenn es tatsächlich die Variable ist. Ich suche nach – Silmathoron

+0

Nicht wirklich, mein Problem ist, ich habe eine Liste von 't' (der Wert des Integrals) und' E' und ich möchte das entsprechende 'z' finden, die die Obergrenze des Integrals ist. Richtig, aber durch Erwähnen eines besseren "x0" und des "Faktors = 0.1-1" können Sie vermeiden, tatsächlich 'NaN' zu treffen. – HuShu

Verwandte Themen