Qual é a maneira mais avançada de implementar funções especiais de precisão dupla? Preciso da seguinte integral: para e , que pode ser escrita em termos da função gama incompleta inferior. Aqui está minha implementação de Fortran e C: m=0,1,2,. . . t>0
https://gist.github.com/3764427
que usa expansão em série, resume os termos até a precisão especificada e, em seguida, usa relações de recursão para obter com eficiência valores para inferiores . Testei bem e obtenho precisão 1e-15 para todos os valores de parâmetros necessários, consulte os comentários da versão Fortran para obter detalhes.
Existe uma maneira melhor de implementá-lo? Aqui está uma implementação da função gama no gfortran:
https://github.com/mirrors/gcc/blob/master/libgfortran/intrinsics/c99_functions.c#L1781
está usando aproximação de função racional em vez de resumir algumas séries infinitas que estou fazendo. Eu acho que é uma abordagem melhor, porque é preciso obter precisão uniforme. Existe alguma maneira canônica de abordar essas coisas, ou é preciso descobrir um algoritmo especial para cada função especial?
Atualização 1 :
Com base nos comentários, aqui está a implementação usando o SLATEC:
https://gist.github.com/3767621
reproduz valores de minha própria função, aproximadamente no nível de precisão 1e-15. No entanto, notei um problema que, para t = 1e-6 em = 50, o termo fica igual a 1e-303 e, para "m" superior, ele simplesmente começa a dar respostas incorretas. Minha função não tem esse problema, porque eu uso uma série de relações de expansão / recorrência diretamente para . Aqui está um exemplo de um valor correto: Fm
(1e-6)=4.97511945200351715E-003
,
mas não consigo fazer isso usando SLATEC porque o denominador explode. Como você pode ver, o valor real de é bom e pequeno.
Atualização 2 :
Para evitar o problema acima, pode-se usar a função dgamit
( função Gamma incompleta do Tricomi) e F(m, t) = dgamit(m+0.5_dp, t) * gamma(m+0.5_dp) / 2
, portanto, não há mais problema com , mas, infelizmente, a explosão ocorre por . Este, porém, pode ser alta o suficiente para os meus propósitos.m ≈ 172 mgamma(m+0.5_dp)