Annulation catastrophique dans LogSum

18

J'essaie d'implémenter la fonction suivante en virgule flottante double précision avec une faible erreur relative :

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

Ceci est largement utilisé dans les applications statistiques pour ajouter des probabilités ou des densités de probabilité qui sont représentées dans l'espace logarithmique. Bien sûr, ou pourrait facilement déborder ou déborder, ce qui serait mauvais car l'espace de journal est utilisé pour éviter tout débordement en premier lieu. C'est la solution typique:exp(x)exp(y)

logsum(X,y)=X+log1p(exp(y-X))

L'annulation de se produit, mais est atténuée par . Le pire est de loin lorsque et sont proches. Voici un graphique d'erreur relative:exp x l o g 1 p ( exp ( y - x ) )y-XexpXlog1p(exp(y-X))

entrez la description de l'image ici

Le tracé est coupé à pour souligner la forme de la courbe , autour de laquelle l'annulation se produit. J'ai vu des erreurs jusqu'à et je soupçonne que cela empire. (FWIW, la fonction "vérité au sol" est implémentée à l'aide de flotteurs de précision arbitraire MPFR avec une précision de 128 bits.) l o g s u m ( x , y ) = 0 10 - 11dix-14logsum(X,y)=0dix-11

J'ai essayé d'autres reformulations, toutes avec le même résultat. Avec comme expression externe, la même erreur se produit en prenant un journal de quelque chose près de 1. Avec comme expression externe, l'annulation se produit dans l'expression interne.l o g 1 pJournallog1p

Maintenant, l' erreur absolue est très petite, donc a une très petite erreur relative (dans un epsilon). On pourrait soutenir que, parce qu'un utilisateur de est vraiment intéressé par les probabilités (pas les probabilités de journalisation), cette terrible erreur relative n'est pas un problème. Il est probable que ce ne soit généralement pas le cas, mais j'écris une fonction de bibliothèque, et j'aimerais que ses clients puissent compter sur une erreur relative pas bien pire qu'une erreur d'arrondi.l o g s u mexp(logsum(X,y))logsum

Il semble que j'ai besoin d'une nouvelle approche. Qu'est-ce que ça pourrait être?

Neil Toronto
la source
Je ne comprends pas votre dernier paragraphe. "dans un epsilon" ne veut rien dire pour moi. Voulez-vous dire une unité à la dernière place ? En ce qui concerne les utilisateurs intéressés par les probabilités, une petite erreur de probabilité de journal se traduira par une grande erreur de probabilité, ce n'est donc pas le cas.
Aron Ahmadia
Par curiosité, avez-vous essayé de tirer le meilleur parti de vos deux méthodes et de tracer l'erreur de cela? Ensuite, tout ce dont vous avez besoin est la bonne logique pour détecter le cas dans lequel vous vous trouvez (en espérant être moins coûteux ou faire partie du coût requis de l'algorithme de toute façon), puis passer à la méthode appropriée.
Aron Ahmadia
@AronAhmadia: "Dans un epsilon" signifie une erreur relative inférieure à un epsilon à virgule flottante double précision, qui est d'environ 2,22e-16. Pour les flotteurs normaux (c'est-à-dire non sous-normaux), cela correspond à environ un ulp. De plus, si est l'erreur absolue de , alors l'erreur relative de est , qui est presque la fonction d'identité proche de zéro. IOW, une petite erreur absolue pour implique une petite erreur relative pour . x exp ( x ) exp ( a ) - 1 x exp ( x )uneXexp(X)exp(une)-1Xexp(X)
Neil Toronto
Addendum: Lorsque l'erreur absolue est proche de zéro. Quand , par exemple, vous avez raison: le parent explose. a > 1uneune>1
Neil Toronto

Réponses:

12

La formule doit être numériquement stable. Elle se généralise en numérique calcul stable de log i e x i = ξ + log i e x

logsum(X,y)=max(X,y)+log1p(exp(-abdos(X-y))
JournaljeeXje=ξ+JournaljeeXje-ξ,   ξ=maxjeXje

Dans le cas où la somme des journaux est très proche de zéro et que vous souhaitez une précision relative élevée, vous pouvez probablement utiliser utilisant une précision (c'est-à-dire plus que la double précision) implémentation de qui est presque linéaire pour les petits .l e x p ( z ) : = log ( 1 + e - | z | ) z

logsum(X,y)=max(X,y)+leXp(X-y)
leXp(z): =Journal(1+e-|z|)
z
Arnold Neumaier
la source
En termes d'erreur absolue, c'est le cas. En termes d'erreur relative, c'est affreux lorsque la sortie est proche de zéro.
Neil Toronto
@NeilToronto: Veuillez donner un exemple avec deux entrées explicites et , afin que je puisse jouer avec. yXy
Arnold Neumaier
Pour x = -0,775 et y = -0,6175, j'obtiens une erreur de 62271 ulps et une erreur relative de 1,007e-11.
Neil Toronto
1
Calculez des points de données très précis dans la plage d'intérêt - au moins deux plages différentes sont nécessaires en raison du comportement asymptotique. On peut utiliser l'expression de définition pour z non proche de zéro. Pour la plage exceptionnelle, ajustez une fonction rationnelle suffisamment élevée pour obtenir la précision souhaitée. Pour la stabilité numérique, utilisez des polynômes de Bernstein ou des polynômes de Tchebychev au numérateur et au dénominateur, adaptés à l'intervalle d'intérêt. À la fin, développez en une fraction continue et découvrez combien on peut tronquer les coefficients sans imapirer la précision.
Arnold Neumaier
1
Cela donne Pour que fasse de même mais applique à la fonction lexp (z) -l (z). ml=l(z)m
Arnold Neumaier