Ich muss das folgende Integral numerisch auswerten:
wobei , und . Hier ist die modifizierte Bessel-Funktion der zweiten Art. In meinem speziellen Fall habe ich , und .x∈R+λ,κ,ν>0Kλ=0,00313κ=0,00825ν=0,33
Ich benutze MATLAB und habe die eingebauten Funktionen integral
und ausprobiert quadgk
, wodurch ich viele Fehler erleide (siehe unten). Ich habe natürlich auch zahlreiche andere Dinge ausprobiert, wie das Integrieren nach Teilen und das Summieren von Integralen von zu .( k + 1 ) x π
Haben Sie Vorschläge, welche Methode ich als nächstes ausprobieren sollte?
UPDATE (hinzugefügte Fragen)
Ich habe den Artikel @Pedro gelesen, der mit diesem Artikel verlinkt ist, und ich glaube nicht, dass es zu schwer zu verstehen war. Ich habe jedoch ein paar Fragen:
- Wäre es in Ordnung, als Basiselemente in der beschriebenen univariaten Levin-Methode zu verwenden?ψ k
- Könnte ich stattdessen einfach eine Filon-Methode verwenden, da die Frequenz der Oszillationen fest ist?
Beispielcode
>> integral(@(r) sin(x*r).*sqrt(E(r)),0,Inf)
Warning: Reached the limit on the maximum number of intervals in use. Approximate
bound on error is 1.6e+07. The integral may not exist, or it may be difficult to
approximate numerically to the requested accuracy.
> In funfun\private\integralCalc>iterateScalarValued at 372
In funfun\private\integralCalc>vadapt at 133
In funfun\private\integralCalc at 84
In integral at 89
ans =
3.3197e+06
quelle
Antworten:
Ich habe meinen eigenen Integrator geschrieben,
quadcc
der mit Singularitäten wesentlich besser zurechtkommt als die Matlab-Integratoren und eine zuverlässigere Fehlerschätzung liefert.Um es für Ihr Problem zu verwenden, habe ich Folgendes getan:
Die Funktion
f
ist jetzt Ihr Integrand. Beachten Sie, dass ich gerade einen alten Wert zugewiesen habex
.Um in eine unendliche Domäne zu integrieren, setze ich Variablen ein:
dh das Integrieren∞
g
von 0 nach 1 sollte dasselbe sein wie das Integrierenf
von 0 nach . Verschiedene Transformationen können unterschiedliche Qualitätsergebnisse liefern: Mathematisch sollten alle Transformationen das gleiche Ergebnis liefern, aber verschiedene Transformationen können glattere oder leichter integrierbare s erzeugen .g
Ich rufe dann meinen eigenen Integrator an
quadcc
, der mit demNaN
s auf beiden Seiten umgehen kann :Beachten Sie, dass die Fehlerschätzung sehr groß ist, dh
quadcc
nicht viel Vertrauen in die Ergebnisse hat. Bei Betrachtung der Funktion ist dies jedoch nicht verwunderlich, da sie bei Werten schwankt, die drei Größenordnungen über dem tatsächlichen Integral liegen. Die Verwendung einer anderen Intervalltransformation kann wiederum zu besseren Ergebnissen führen.Möglicherweise möchten Sie auch spezifischere Methoden wie diese untersuchen . Es ist ein bisschen komplizierter, aber definitiv die richtige Methode für diese Art von Problem.
quelle
integral
(1e-10, glaube ich) üblich ist, aber 1.7e + 07 ist immer noch sehr, sehr groß. Vielleicht hilft eine andere Transformation, wie Sie bereits erwähnt haben.Wie Pedro betont, sind Levin-Methoden die am besten etablierten Methoden für diese Art von Problemen.
Haben Sie Zugang zu Mathematica? Für dieses Problem erkennt und verwendet Mathematica sie standardmäßig:
Hier ist ein Diagramm über einen Wertebereich von x:
Sie können die jeweilige anzuwendende Levin-Methode auch manuell angeben, was in diesem Fall zu einer leichten Leistungsverbesserung führen kann:
Weitere Informationen zu Levin-Methoden in Mathematica finden Sie in der Dokumentation .
quelle
Wenn Sie keinen Zugang zu Mathematica haben, können Sie in Matlab eine Levin-Methode (oder eine andere spezialisierte Oszillationsmethode) schreiben, wie Pedro vorschlägt.
Verwenden Sie die Chebfun- Bibliothek für Matlab? Ich habe gerade erfahren, dass hier eine grundlegende Levin-Methode implementiert ist . Die Implementierung wurde von Olver (einem der Experten auf dem Gebiet der oszillierenden Quadratur) geschrieben. Es befasst sich nicht mit Singularitäten, adaptiver Unterteilung usw., aber es kann genau das sein, was Sie brauchen, um anzufangen.
quelle
Die von Pedro empfohlene Transformation ist eine großartige Idee. Haben Sie versucht, mit den Parametern in Matlabs "quadgk" -Funktion herumzuspielen? Mit der Pedro-Transformation können Sie beispielsweise Folgendes tun:
quadgk(f, 0.0+eps, 1.0-eps, 'AbsTol', eps, 'MaxIntervalCount', 100000)
Mit dieser Methode erhalte ich eine Lösung von:
-2184689.50220729
und es dauert nur 0,8 Sekunden (mit den oben genannten Werten: x = 10).
Walter Gander und Walter Gautschi haben eine Arbeit über adaptive Quadratur mit Matlab Code, den Sie auch verwenden können (Link hier )
quelle