Estou tentando implementar a seguinte função no ponto flutuante de precisão dupla com baixo erro relativo :
Isso é usado extensivamente em aplicativos estatísticos para adicionar probabilidades ou densidades de probabilidade representadas no espaço de log. Obviamente, ou poderiam facilmente estourar ou estourar, o que seria ruim porque o espaço de log é usado para evitar o estouramento em primeiro lugar. Esta é a solução típica:
O cancelamento de acontece, mas é mitigado pela . Pior ainda, de longe, é quando e encontram-se perto. Aqui está um gráfico de erro relativo:
A trama é cortada em para enfatizar a forma da curva de l o g s u m ( x , y ) = 0 , sobre a qual o cancelamento ocorrer. Eu vi erro até 10 - 11 e suspeito que ele fica muito pior. (FWIW, a função "verdade da terra" é implementada usando flutuadores de precisão arbitrária do MPFR com precisão de 128 bits.)
Eu tentei outras reformulações, todas com o mesmo resultado. Com como a expressão exterior, o mesmo ocorre por erro tendo um registo de algo perto 1. Com l o g um p como a expressão exterior, cancelamento acontece na expressão interior.
Agora, o absoluto de erro é muito pequena, de modo tem muito pequeno erro relativo (dentro de um epsilon). Alguém poderia argumentar que, porque um usuário de l o g s u m está realmente interessado em probabilidades (não probabilidades de log), este erro relativo terrível não é um problema. É provável que geralmente não seja, mas estou escrevendo uma função de biblioteca e gostaria que seus clientes pudessem contar com um erro relativo não muito pior do que um erro de arredondamento.
Parece que preciso de uma nova abordagem. O que poderia ser?
fonte
Respostas:
Caso a soma do log esteja muito próxima de zero e você queira alta precisão relativa, provavelmente você pode usar usando um método preciso (isto é, mais do que precisão dupla) implementação de que é quase linear para pequeno .l e x p ( z ) : = log ( 1 + e - | z | ) z
fonte