Quelle est la manière la plus moderne de mettre en œuvre des fonctions spéciales double précision? J'ai besoin de l'intégrale suivante: pour et , qui peut être écrit en termes de fonction gamma incomplète inférieure. Voici mon implémentation Fortran et C: m=0,1,2,. . . t>0
https://gist.github.com/3764427
qui utilise l'expansion en série, résume les termes jusqu'à la précision donnée, puis utilise les relations de récursivité pour obtenir efficacement des valeurs pour inférieur . Je l'ai bien testé et j'obtiens une précision de 1e-15 pour toutes les valeurs de paramètres dont j'ai besoin, voir les commentaires de la version Fortran pour plus de détails.
Existe-t-il un meilleur moyen de le mettre en œuvre? Voici une implémentation de la fonction gamma dans gfortran:
https://github.com/mirrors/gcc/blob/master/libgfortran/intrinsics/c99_functions.c#L1781
il utilise l'approximation de fonction rationnelle au lieu de résumer une série infinie que je fais. Je pense que c'est une meilleure approche, car il faut obtenir une précision uniforme. Existe-t-il une manière canonique d'aborder ces choses, ou faut-il trouver un algorithme spécial pour chaque fonction spéciale?
Mise à jour 1 :
Sur la base des commentaires, voici l'implémentation utilisant SLATEC:
https://gist.github.com/3767621
il reproduit les valeurs de ma propre fonction, à peu près au niveau de précision 1e-15. Cependant, j'ai remarqué un problème: pour t = 1e-6 et m = 50, le terme est égal à 1e-303 et pour un "m" supérieur, il commence simplement à donner des réponses incorrectes. Ma fonction n'a pas ce problème, car j'utilise une série de relations expansion / récurrence directement pour . Voici un exemple de valeur correcte: Fm
(1e-6)=4.97511945200351715E-003
,
mais je ne peux pas obtenir cela en utilisant SLATEC parce que le dénominateur explose. Comme vous pouvez le voir, la valeur réelle de est belle et petite.
Mise à jour 2 :
Pour éviter le problème ci-dessus, on peut utiliser la fonction dgamit
(la fonction Gamma incomplète de Tricomi), donc F(m, t) = dgamit(m+0.5_dp, t) * gamma(m+0.5_dp) / 2
, il n'y a plus de problème avec , mais malheureusement le souffle pour . Cela pourrait cependant être assez élevé pour mes besoins.m ≈ 172 mgamma(m+0.5_dp)
la source
Réponses:
L'intégrale en question est également connue sous le nom de fonction Boys, d'après le chimiste britannique Samuel Francis Boys qui a introduit son utilisation au début des années 1950. Il y a quelques années, j'avais besoin de calculer cette fonction en double précision, le plus rapidement possible mais avec précision. J'ai réussi à obtenir une erreur relative de l'ordre de dans le domaine d'entrée entier.dix- 15
Il est généralement avantageux d'utiliser différentes approximations pour les petits et les grands arguments, où la commutation optimale entre "grand" et "petit" est mieux déterminée expérimentalement, et est en général fonction de . Pour mon code, j'ai défini les "petits" arguments comme ceux satisfaisant la condition a ≤ m + 1 1m .a ≤ m + 1 12
Pour les gros arguments, je calcule
Cet ordre d'opérations évite un débordement prématuré. Comme nous n'avons besoin que de la fonction gamma incomplète inférieure des ordres demi-entiers ici plutôt que d'une fonction gamma incomplète inférieure entièrement générale, il est avantageux du point de vue des performances de calculer
en utilisant des valeurs tabulées de et calculΓ(m+1Γ ( m + 12) selon
cette réponse, tout en évitant soigneusement le problème de l'annulation soustractive par l'utilisation d'une opération multipliée-ajoutée fusionnée. Une optimisation supplémentaire potentielle consiste à observer que poura,γ(m+1suffisamment grand)Γ ( m + 12, a ) une à l'intérieur d'une précision en virgule flottante donnée.γ( m + 12, a ) = Γ ( m + 12)
Pour les petits arguments, j'ai commencé par une expansion en série pour la fonction gamma incomplète inférieure de
A. Erdelyi, W. Magnus, F. Oberhettinger et FG Tricomi, "Fonctions transcendantales supérieures, Vol. 2". New York, NY: McGraw-Hill 1953
et l'a modifié pour calculer la fonction de garçons comme suit (tronquer la série lorsque le terme est suffisamment petit pour une précision donnée):Fm( A )
ERF
erf
erff
la source
Vous pouvez jeter un œil aux méthodes numériques pour les fonctions spéciales d'Amparo Gil, Javier Segura et Nico M. Temme.
la source
Je voudrais jeter un œil au livre d'Abramowicz & Stegun, ou à la nouvelle révision que le NIST a publiée il y a quelques années et qui est disponible en ligne, je crois. Ils discutent également des moyens de mettre en œuvre les choses de manière stable.
la source
Il ne semble pas être à la pointe de la technologie, mais SLATEC chez Netlib propose «1400 routines mathématiques et statistiques à usage général». Le Gamma incomplet est disponible sous les fonctions spéciales ici .
L'implémentation de telles fonctions prend du temps et est sujette aux erreurs, donc je ne le ferais pas moi-même sauf en cas d'absolue nécessité. SLATEC existe depuis un certain temps maintenant et est largement utilisé, au moins en fonction du nombre de téléchargements , donc je m'attends à ce que l'implémentation soit mature.
la source