Cancellazione catastrofica nel logum


18

Sto cercando di implementare la seguente funzione in virgola mobile a precisione doppia con errore relativo basso :

logsum(x,y)=log(exp(x)+exp(y))

Questo è ampiamente utilizzato nelle applicazioni statistiche per aggiungere probabilità o densità di probabilità rappresentate nello spazio del registro. Ovviamente, o potrebbero facilmente overflow o underflow, il che sarebbe male perché lo spazio di log viene utilizzato per evitare il underflow in primo luogo. Questa è la soluzione tipica:exp(x)exp(y)

logsum(x,y)=x+log1p(exp(yx))

L'annullamento da avviene, ma è mitigato da . Peggio ancora è quando e sono vicini. Ecco un diagramma di errore relativo:yxexpxlog1p(exp(yx))

inserisci qui la descrizione dell'immagine

La trama è tagliata a per enfatizzare la forma della curva , attorno alla quale si verifica la cancellazione. Ho visto un errore fino a e sospetto che peggiori molto. (FWIW, la funzione "verità di base" è implementata usando i float di precisione arbitraria di MPFR con precisione a 128 bit.) l o g s u m ( x , y ) = 0 10 - 111014logsum(x,y)=01011

Ho provato altre riformulazioni, tutte con lo stesso risultato. Con come espressione esterna, lo stesso errore si verifica prendendo un registro di qualcosa vicino a 1. Con come espressione esterna, la cancellazione avviene nell'espressione interna.l o g 1 ploglog1p

Ora, l' errore assoluto è molto piccolo, quindi ha un errore relativo molto piccolo (all'interno di un epsilon). Si potrebbe obiettare che, poiché un utente di è veramente interessato alle probabilità (non alle probabilità di registro), questo terribile errore relativo non è un problema. È probabile che di solito non lo sia, ma sto scrivendo una funzione di libreria e vorrei che i suoi client potessero contare sull'errore relativo non molto peggio dell'errore di arrotondamento.l o g s u mexp(logsum(x,y))logsum

Sembra che abbia bisogno di un nuovo approccio. Cosa potrebbe essere?


Non capisco il tuo ultimo paragrafo. "All'interno di un epsilon" non significa niente per me. Intendi un'unità nell'ultimo posto ? Per quanto riguarda gli utenti interessati alle probabilità, un piccolo errore di probabilità del registro comporterà un grande errore di probabilità, quindi non è così.
Aron Ahmadia,

Per curiosità, hai provato a prendere il "meglio di" dei tuoi due metodi e a tracciarne l'errore? Quindi tutto ciò di cui hai bisogno è la giusta logica per rilevare in quale caso ti trovi (si spera di essere meno costoso o comunque parte del costo richiesto dell'algoritmo), quindi passare al metodo appropriato.
Aron Ahmadia,

@AronAhmadia: "All'interno di un epsilon" significa un errore relativo inferiore a un epsilon a virgola mobile a doppia precisione, che è circa 2,22e-16. Per i galleggianti normali (cioè non subnormali), corrisponde a circa un ulp. Inoltre, se è l'errore assoluto di , l'errore relativo di è , che è quasi la funzione di identità vicino a zero. IOW, un piccolo errore assoluto per implica un piccolo errore relativo per . axexp(x)exp(a)1xexp(x)
Neil Toronto,

Addendum: quando l'errore assoluto è vicino allo zero. Quando , ad esempio, hai ragione: il relativo esplode. aa>1
Neil Toronto,

Risposte:


12

La formula dovrebbe essere numericamente stabile. Si generalizza numericamente calcolo stabile di

logsum(x,y)=max(x,y)+log1p(exp(abs(xy))
logiexi=ξ+logiexiξ,   ξ=maxixi

Nel caso in cui il log sia molto vicino allo zero e desideri un'elevata precisione relativa, puoi probabilmente usare usando un accurato (vale a dire, più che doppia precisione) implementazione di che è quasi lineare per la piccola .l e x p ( z ) : = log ( 1 + e - | z | ) z

logsum(x,y)=max(x,y)+lexp(xy)
lexp(z):=log(1+e|z|)
z

In termini di errore assoluto, lo è. In termini di errore relativo, è terribile quando l'output è vicino allo zero.
Neil Toronto,

@NeilToronto: Si prega di dare un esempio con due ingressi espliciti ed , in modo che possa giocare con esso. yxy
Arnold Neumaier,

Per x = -0.775 e y = -0.6175, ottengo un errore 62271 ulps e un errore relativo di 1.007e-11.
Neil Toronto,

1
Calcola punti di dati altamente precisi nell'intervallo di interesse - almeno due intervalli diversi sono necessari a causa del comportamento asintotico. Si può usare l'espressione di definizione per z non vicino a zero. Per l'eccezionale gamma, adotta una funzione razionale di grado sufficientemente elevato per ottenere l'accuratezza desiderata. Per stabilità numerica, utilizzare polinomi di bernstein o polinomi di Tchebychev in numeratore e denominatore, adattati all'intervallo di interesse. Alla fine, espandi in una frazione continua e scopri quanto si può troncare i coefficienti senza compromettere la precisione.
Arnold Neumaier,

1
Questo dà Per fare in modo che faccia lo stesso ma applicato alla funzione lexp (z) -l (z). ml=l(z)m
Arnold Neumaier,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.