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)
fonte
Respostas:
A integral em questão também é conhecida como função de Boys, após o químico britânico Samuel Francis Boys, que introduziu seu uso no início dos anos 50. Alguns anos atrás, eu precisava calcular essa função em dupla precisão, o mais rápido possível, mas com precisão. Eu consegui alcançar um erro relativo da ordem de10- 15 em todo o domínio de entrada.
É geralmente vantajoso usar aproximações diferentes para argumentos pequenos e grandes, onde a melhor alternância entre "grande" e "pequeno" é melhor determinada experimentalmente e, em geral, é uma função de . Para o meu código, defini argumentos "pequenos" como aqueles que satisfazem a condição a ≤ m + 1 1m .a ≤ m + 1 12
Para grandes argumentos, eu computo
Essa ordem de operações evita o fluxo insuficiente prematuro. Como precisamos apenas da função gama incompleta mais baixa de ordens sem número inteiro aqui, em vez de uma função gama incompleta mais baixa totalmente geral, é vantajoso do ponto de vista do desempenho calcular
usando valores tabulados de e computaçãoΓ(m+1Γ ( m + 12) acordo com
esta resposta, evitando cuidadosamente a questão do cancelamento subtrativo através do uso de uma operação de adição múltipla fundida. Uma possível otimização adicional é observar que paraa,γsuficientemente grande(m+1Γ ( m + 12, Um ) uma dentro de uma determinada precisão de ponto flutuante.γ( m + 12, a ) = Γ ( m + 12)
Para pequenos argumentos, comecei com uma expansão em série para a função gama incompleta mais baixa de
A. Erdelyi, W. Magnus, F. Oberhettinger e FG Tricomi, "Higher Transcendental Functions, Vol. 2". Nova York, NY: McGraw-Hill 1953
e modificou-o para calcular a função de meninos seguinte maneira (truncando a série quando o termo é suficientemente pequeno para uma determinada precisão):Fm( Um )
ERF
erf
erff
fonte
Você pode dar uma olhada em Métodos numéricos para funções especiais de Amparo Gil, Javier Segura e Nico M. Temme.
fonte
Eu daria uma olhada no livro de Abramowicz & Stegun, ou na revisão mais recente que o NIST publicou há alguns anos atrás e acredito que esteja disponível online. Eles também discutem maneiras de implementar as coisas de maneira estável.
fonte
Não parece ser o estado da arte, mas o SLATEC da Netlib oferece "1400 rotinas matemáticas e estatísticas de uso geral". A gama incompleta está disponível sob as funções especiais aqui .
A implementação de tais funções é demorada e propensa a erros, então eu não faria isso a menos que fosse absolutamente necessário. O SLATEC já existe há algum tempo e é amplamente utilizado, pelo menos com base na contagem de downloads , portanto, espero que a implementação esteja madura.
fonte