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)