2016-05-27 4 views
-1

Für eines meiner Projekte muss ich wiederholt einen Ausdruck mit der allgemeinen hypergeometrischen Funktion auswerten. Während SciPy die allgemeine HypGeo-Funktion nicht unterstützt, tut dies MPMath. Die Verwendung von mp.hyper(..) ist jedoch sehr zeitaufwendig. Stattdessen entschied ich mich, ihre schnelle Präzisions-Bibliotheksfunktion fp.hyper(..) zu verwenden. Leider scheint das Verhalten völlig anders zu sein. Mein Beispiel unten:Mpmath hypergeometrische Funktion zeigt unterschiedliches Verhalten für hohe und niedrige Präzision

from mpmath import mp, fp 
from math import sin, cos, pi 

H = 0.2 
k = 2 

A = 4 * sqrt(H)/(1 + 2 * H) 
B = 4 * pi/(3 + 2 * H) 
C = H/2 + 3/4 


f_high = lambda t: (B * k * t * sin(pi * k) * 
        mp.hyper([1], [C+1/2, C+1], -(k*pi*t)**2) + 
        cos(pi * k) * mp.hyper([1], [C, C + 1/2], 
        -(k*pi*t)**2)) * A * t**(H + 1/2) 


f_low = lambda t: (B * k * t * sin(pi * k) * 
        fp.hyper([1], [C+1/2, C+1], -(k*pi*t)**2) + 
        cos(pi * k) * fp.hyper([1], [C, C + 1/2], 
        -(k*pi*t)**2)) * A * t**(H + 1/2) 

Obtained using fp.plot(f_high,[0,5

Obtained through fp.plot(f_low,[0,5

Die erste Kurve zeigt fp.plot(f_high,[0,1]), die zweite fp.plot(f_low,[0,1]). Falls jemand sich fragt: Die Funktionen sehen hässlich aus, aber eine ist eine Kopie der anderen, nur mp ersetzt durch fp, also gibt es keine Chance, dass sie sich auf andere Weise unterscheiden.

Ich habe es auch in Mathematica geplottet und das Bild ist eher wie das obere (hohe Präzision).

Sieht aus wie es ist ein Fehler bei der Implementierung der fp.hyper Funktion, richtig?

Antwort

1

Die documentation für fp sagt (Hervorhebung hinzugefügt):

Aufgrund Zwischenrundung und Löschungsfehler, mit fp arithmetischen Berechnungsergebnisse sein können viel weniger genau als die mit mp berechnet eine äquivalenten Genauigkeit unter Verwendung von (mp. prec = 53), da letztere oft eine erhöhte interne Präzision verwendet. Die Genauigkeit ist sehr problemabhängig: Für einige Funktionen gibt fp fast immer 14-15 richtige Ziffern; für andere können die Ergebnisse nur auf zwei bis drei Ziffern genau sein oder sogar komplett falsch. Die empfohlene Verwendung für fp besteht daher darin, umfangreiche Berechnungen zu beschleunigen, bei denen die Genauigkeit im Voraus für eine Teilmenge der Eingabesatzgruppe verifiziert werden kann oder bei der die Ergebnisse später verifiziert werden können.

Wenn fp waren nur ein Drop-in-Ersatz für mp mit schnellen Berechnung und ohne Nachteil, gäbe es keinen Grund für mp zu existieren. In diesem Fall scheint es, dass fp nicht für Ihre Aufgabe geeignet ist, so dass Sie mp verwenden müssen.

+0

Natürlich ist klar, dass es einen Kompromiss zwischen Präzision und Rechenzeit gibt, aber die fp.implementation zeigt ein völlig anderes Verhalten? – sbm

+1

Ich weiß nicht, was ich Ihnen sagen soll, außer was die Dokumentation schon sagt. Beachten Sie, wo es heißt "oder sogar völlig falsch". Vermutlich gibt es zu einem entscheidenden Zeitpunkt in Ihrer Berechnung einen Genauigkeitsverlust, der zu "völlig falschen" Ergebnissen führt. – BrenBarn

+1

@sbm: Es gibt einen Kompromiss. Sie haben im Wesentlichen * alle * Ihrer Präzision gehandelt. Sie wurden gewarnt, dass dies passieren könnte. – user2357112

Verwandte Themen