Ich versuche, eine Integralgleichung mit dem folgenden Code (irrelevante Teile entfernt) zu lösen:in scipy.optimize.fsolve mit Gleichungen Verbesserung der Genauigkeit Integration Einbeziehung
def _pdf(self, a, b, c, t):
pdf = some_pdf(a,b,c,t)
return pdf
def _result(self, a, b, c, flag):
return fsolve(lambda t: flag - 1 + quad(lambda tau: self._pdf(a, b, c, tau), 0, t)[0], x0)[0]
, die eine Wahrscheinlichkeitsdichtefunktion nimmt und findet Ergebnis tau
so dass das Integral von PDF von Tau nach unendlich ist gleich flag
. Beachten Sie, dass x0
eine (Gleitkomma-) Schätzung des Stamms ist, der an anderer Stelle im Skript definiert ist. Beachte auch, dass flag
eine extrem kleine Zahl ist, in der Größenordnung von 1e-9
.
In meiner Anwendung findet fsolve nur etwa 50% der Zeit erfolgreich eine Wurzel. Es gibt oft nur x0
zurück, was meine Ergebnisse signifikant beeinflusst. Es gibt keine geschlossene Form für das Integral von pdf, also bin ich gezwungen, mich numerisch zu integrieren und fühle, dass dies eine gewisse Ungenauigkeit mit sich bringt?
EDIT:
Dies wurde seit löst ein anderes Verfahren als das unten beschrieben ist, aber ich mag quadpy Arbeit bekommen und sehen, ob die Ergebnisse überhaupt verbessern. Der spezifische Code, den ich versuche zu bekommen zu arbeiten wie folgt:
import quadpy
import numpy as np
from scipy.optimize import *
from scipy.special import gammaln, kv, gammaincinv, gamma
from scipy.integrate import quad, simps
l = 226.02453163
mu = 0.00212571582056
nu = 4.86569872444
flag = 2.5e-09
estimate = 3 * mu
def pdf(l, mu, nu, t):
return np.exp(np.log(2) + (l + nu - 1 + 1)/2 * np.log(l * nu/mu) + (l + nu - 1 - 1)/2 * np.log(t) + np.log(
kv(nu - l, 2 * np.sqrt(l * nu/mu * t))) - gammaln(l) - gammaln(nu))
def tail_cdf(l, mu, nu, tau):
i, error = quadpy.line_segment.adaptive_integrate(
lambda t: pdf(l, mu, nu, t), [tau, 10000], 1.0e-10
)
return i
result = fsolve(lambda tau: flag - tail_cdf(l, mu, nu, tau[0]), estimate)
Als ich das laufen erhalte ich eine Behauptung Fehler von assert all(lengths > minimum_interval_length)
. Ich bin mir nicht sicher, wie ich das beheben soll. jede Hilfe würde sehr geschätzt werden!
Wenn ich Ihren Code richtig gelesen habe, wie Sie ihn eingerichtet haben, verschwenden Sie 9 Ziffern der Genauigkeit; Kein Wunder, dass Scipy kämpft. Kannst du das Integral von _t_ nach + unendlich nicht ausführen? –
@PaulPanzer Leider, woher kommen die 9 Ziffern? – oirectine
Wenn ich Sie richtig verstehe, möchten Sie schließlich _flag_, ein Begriff der Ordnung 1e-9. Aber du machst den eigentlichen Root-Befund auf 1 - _flag_ was bedeutet, dass wenn du das mit einer relativen Genauigkeit von zB 1e-12 löst (was ziemlich anspruchsvoll ist und nicht immer möglich ist) und dann von 1 - _S_ nach _S_ zurücktransformiert, dann wird _S_ einen absoluten Fehler in der Reihenfolge 1e-12 haben, so wird der relative Fehler in der Reihenfolge 1e-3 sein. Wenn Sie stattdessen von _tau_ nach + unendlich integrieren könnten, könnten Sie direkt mit _flag_ vergleichen und dieses Problem würde verschwinden. –