Sto cercando di implementare la seguente funzione in virgola mobile a precisione doppia con errore relativo basso :
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:
L'annullamento da avviene, ma è mitigato da . Peggio ancora è quando e sono vicini. Ecco un diagramma di errore relativo:
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 - 11
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 p
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 m
Sembra che abbia bisogno di un nuovo approccio. Cosa potrebbe essere?