Um problema muito comum na cadeia de Markov Monte Carlo envolve probabilidades de computação que são soma de grandes termos exponenciais,
onde os componentes de lata podem variar de muito pequeno a muito grande. Minha abordagem foi fatorar o maior termo exponencial para que:K : = max i ( a i )
e um ' ≡ e um 1 + um e um 2 + . . .
Essa abordagem é razoável se todos os elementos de forem grandes, mas não é uma boa ideia se não forem. Obviamente, os elementos menores não estão contribuindo para a soma de ponto flutuante, mas não tenho certeza de como lidar com eles de maneira confiável. No código R, minha abordagem se parece com:
if ( max(abs(a)) > max(a) )
K <- min(a)
else
K <- max(a)
ans <- log(sum(exp(a-K))) + K
Parece um problema bastante comum que deve haver uma solução padrão, mas não tenho certeza do que seja. Obrigado por todas as sugestões.
fonte
Respostas:
Existe uma solução direta com apenas duas passagens pelos dados:
Primeiro calcule
que informa que, se houver termos, então Σ i e um i ≤ N e K .n
Como você presumivelmente não tem nem tão grande quanto , não deve se preocupar em transbordar no cálculo de em dupla precisão .10 20 τ : = Σ i e um i - K ≤ nn 1020
Portanto, calcule e sua solução será .e K ττ eKτ
fonte
Para manter a precisão enquanto você adiciona duplas, você precisa usar o Kahan Summation , este é o software equivalente a ter um registro de transporte.
Isso é bom para a maioria dos valores, mas se você está recebendo estouro, em seguida, você está batendo os limites da IEEE 754 de precisão dupla que seria cerca . Neste ponto, você precisa de uma nova representação. Você pode detectar um estouro no momento da adição e também detectar expoentes grandes para avaliar . Nesse ponto, você pode modificar a interpretação de um duplo deslocando o expoente e acompanhando esse deslocamento.e709.783
doubleMax - sumSoFar < valueToAdd
exponent > 709.783
fonte
Sua abordagem é sólida.
fonte
Existe um pacote R que fornece uma implementação rápida e eficiente do "truque log-soma-exp"
http://www.inside-r.org/packages/cran/matrixStats/docs/logSumExp
A função logSumExp aceita um vetor numérico lX e gera log (soma (exp (lX))), evitando problemas de estouro e estouro usando o método que você descreveu.
fonte