Jaki jest najnowocześniejszy sposób wdrażania funkcji specjalnych podwójnej precyzji? Potrzebuję następującej całki:
https://gist.github.com/3764427
który korzysta z interpretacji szeregowej, sumuje warunki do danej dokładności, a następnie używa relacji rekurencyjnych w celu skutecznego uzyskania wartości dla niższego . Testowałem to dobrze i uzyskuję dokładność 1e-15 dla wszystkich wartości parametrów, których potrzebuję, zobacz komentarze do wersji Fortran, aby uzyskać szczegółowe informacje.
Czy istnieje lepszy sposób na jego wdrożenie? Oto implementacja funkcji gamma w gfortran:
https://github.com/mirrors/gcc/blob/master/libgfortran/intrinsics/c99_functions.c#L1781
wykorzystuje przybliżenie funkcji racjonalnej zamiast sumowania niektórych nieskończonych szeregów, które robię. Myślę, że to lepsze podejście, ponieważ należy uzyskać jednolitą dokładność. Czy istnieje jakiś kanoniczny sposób podejścia do tych rzeczy, czy też trzeba opracować specjalny algorytm dla każdej funkcji specjalnej?
Aktualizacja 1 :
W oparciu o komentarze, oto implementacja wykorzystująca SLATEC:
https://gist.github.com/3767621
odtwarza wartości z mojej własnej funkcji, mniej więcej na poziomie dokładności 1e-15. Zauważyłem jednak problem, że dla t = 1e-6 im = 50, wyrażenie równa się 1e-303, a dla większego „m” zaczyna po prostu dawać nieprawidłowe odpowiedzi. Moja funkcja nie ma tego problemu, ponieważ używam relacji rozszerzania / powtarzania serii bezpośrednio dlaFm. Oto przykład poprawnej wartości:
,(1e-6)=4.97511945200351715E-003
ale nie mogę tego uzyskać za pomocą SLATEC, ponieważ mianownik się wysadza. Jak widać, rzeczywista wartość jest ładna i mała.
Aktualizacja 2 :
Aby uniknąć powyższego problemu, można użyć funkcji dgamit
(niekompletna funkcja gamma Tricomi) F(m, t) = dgamit(m+0.5_dp, t) * gamma(m+0.5_dp) / 2
, więc nie ma już problemu z , ale niestety wysadza się dla m ≈ 172 . Może to jednak być wystarczająco wysoka m dla moich celów.gamma(m+0.5_dp)
źródło
Odpowiedzi:
Całka, o której mowa, znana jest również jako funkcja Boys, od brytyjskiego chemika Samuela Francisa Boysa, który wprowadził jej stosowanie na początku lat 50. XX wieku. Kilka lat temu musiałem obliczyć tę funkcję z podwójną precyzją, tak szybko, jak to możliwe, ale dokładnie. Udało mi się osiągnąć względny błąd rzędu w całej domenie wejściowej.10- 15
Zasadniczo korzystne jest stosowanie różnych przybliżeń dla małych i dużych argumentów, przy czym optymalne przełączanie między „dużym” i „małym” najlepiej określa się eksperymentalnie i ogólnie jest funkcją . W moim kodzie zdefiniowałem „małe” argumenty jako spełniające warunek a ≤ m + 1 1m .a ≤ m + 1 12)
W przypadku dużych argumentów obliczam
Ta kolejność operacji pozwala uniknąć przedwczesnego niedomiaru. Ponieważ potrzebujemy tutaj tylko niższej niepełnej funkcji gamma rzędów o wartościach całkowitych, a nie w pełni ogólnej niższej niepełnej funkcji gamma, z punktu widzenia wydajności korzystne jest obliczenie
przy użyciu tabelarycznych wartości i obliczeniaΓ(m+1Γ ( m + 12)) zgodnie z
tą odpowiedzią, przy jednoczesnym ostrożnym unikaniu problemu subtraktywnego anulowania poprzez zastosowanie połączonej operacji wielokrotnego dodawania. Potencjalną dalszą optymalizacją jest zaobserwowanie, że dla wystarczająco dużegoa,γ(m+1Γ ( m + 12), a ) za w ramach określonej precyzji zmiennoprzecinkowej.γ( m + 12), a ) =Γ ( m + 12))
W przypadku małych argumentów zacząłem od rozszerzenia serii dla niższej niepełnej funkcji gamma od
A. Erdelyi, W. Magnus, F. Oberhettinger i FG Tricomi, „Higher Transcendental Functions, Vol. 2”. Nowy Jork, NY: McGraw-Hill 1953
i zmodyfikowałem go, aby obliczyć funkcję Boys w następujący sposób (obcięcie serię gdy termin jest dostatecznie mała dla danej dokładności)Fm(a)
ERF
erf
erff
źródło
Możesz rzucić okiem na metody numeryczne dla funkcji specjalnych autorstwa Amparo Gil, Javiera Segury i Nico M. Temme.
źródło
Rzuciłbym okiem na książkę Abramowicza i Steguna lub na nowszą wersję, którą NIST opublikował kilka lat temu i wydaje mi się, że jest dostępna online. Dyskutują także o sposobach wdrażania rzeczy w stabilny sposób.
źródło
Nie wydaje się to być najnowocześniejszym, ale SLATEC w Netlib oferuje „1400 ogólnych procedur matematycznych i statystycznych”. Niekompletna wartość gamma jest dostępna tutaj w ramach funkcji specjalnych .
Wdrożenie takich funkcji jest czasochłonne i podatne na błędy, więc nie zrobiłbym tego sam, chyba że absolutnie konieczne. SLATEC istnieje już od dłuższego czasu i jest szeroko stosowany, przynajmniej w oparciu o liczbę pobrań , więc oczekiwałbym, że implementacja będzie dojrzała.
źródło