Existem maneiras aprimoradas de calcular ?

11

A maioria das bibliotecas de matemática possui várias versões de funções de logaritmo. Na maioria das vezes, assumimos que eles são perfeitos, mas na verdade muitos deles oferecem apenas um certo número de dígitos de precisão.

Para algumas funções, existem variantes numericamente mais estáveis. Por exemplo, Fortran, R, Java e C possuem Math.log1p, para computação log(1.0+x)(que oferece maior precisão para pequenos valores de x) e a contrapartida expm1. Aqui, os problemas numéricos surgem de uma perda de precisão - se xé realmente pequeno, 1.0 + xperde dígitos para preservar o 1 no início.

Eu já vi essas funções para aumentar a precisão em várias situações. Isso parece ser bastante comum sempre que você estiver implementando funções de distribuição (Gamma, Beta, Poisson etc.) com alta precisão numérica. Por exemplo, a função Gamma parece ser usada na maioria das vezes logGamma. Em geral, ir ao "espaço de registro" pode melhorar muito a precisão e, portanto, R parece ter um sinalizador de "espaço de registro" na maioria das funções.

Outro exemplo, em R, existe log1mexppara log(1 - exp(p)): http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf

Venho brincando com medidas teóricas da entropia e da informação. Um termo muito comum existe

p * -log(p)

onde normalmente, alguém deseja que a base do logaritmo seja 2, não e; mas com a mesma frequência esse é apenas um fator linear, e você também pode usar o logaritmo natural (portanto, isso não é da maior importância para mim). De qualquer forma, você sabe se existe uma maneira mais rápida / direta / precisa de calcular esse termo? Estou tendo tudo em todo o lugar, para que realmente possa valer a pena para torná-lo um pouco mais preciso e rápido (poupem-me as coisas comuns de "otimização prematura", obrigado).

Não vejo nenhuma razão óbvia que cause perda de precisão. Então, eu estou mais interessado se houver algum truque legal para acelerar esse cálculo. Isso talvez até me poupe tratando a p=0caixa do canto (o que é sensato 0, embora log(0)não exista) ou me dê a base 2 de graça (embora uma única multiplicação com uma constante obviamente não seja muito cara). Obrigado.

Possui QUIT - Anony-Mousse
fonte
1
Se você estiver preocupado com over / underflow, observe que porque (precisão dupla)será no máximo , portanto nunca poderá ser muito grande. (0 quando ) deve estar perfeitamente bem. Como observação, as fórmulas rápidas podem ser diferentes das fórmulas precisas; portanto, às vezes você não pode obter as duas. | log p | 700 p log p p = 0m10308pM10308|logp|700plogpp=0
Kirill
O R vem com uma log2função que, dependendo do seu sistema operacional, pode ser um invólucro simples log/log(2)ou usar o fato de o C99 ter adicionado uma log2função.
anônimo

Respostas:

11

[ 0 , 1 ] 0plogp não sofrerá perda de precisão em nenhum lugar e também não sofrerá excesso de expoente próximo de . Assim, a maneira rápida e precisa é[0,1]0

p ? p * -log(p) : 0
Geoffrey Irving
fonte