Calculer

13

La fonction a une singularité proche de . Cette singularité peut être levée, cependant: pour , on devrait avoir , car Et donc Cependant, la forme n'est pas seulement non définie en , il est également numériquement instable au voisinage de ce point; afin d'évaluer pour de très petits numériquement, on pourrait utiliser une expansion de Taylor, c'est-à-dire une troncature de la série de puissance susmentionnée.x = 0 x = 1 f ( x ) = 1 e x = k = 0 x kf:x(ex1)/xx=0x=1f(x)=1(ex-1)/x=k=1x k - 1

ex=k=0xkk!
(ex1)/x=k=1xk1k!
(ex1)/xx=0f(x)x

Q : La fonction f a- t -elle un nom? En d'autres termes, est-ce un problème courant?

Q : Quelqu'un connaît-il une bibliothèque C / C ++ qui gère bien cette situation, c'est-à-dire utilise l'expansion de Taylor d'un degré approprié près de 0 et l'autre représentation loin de zéro?

anonyme
la source

Réponses:

19

On pourrait peut-être commencer par la fonction qui fait partie de la norme C99, et calcule avec précision près de .expm1ex1x=0

n00b
la source
17

Il s'agit d'une instance d'erreur d'annulation. La bibliothèque standard C (à partir de C99) comprend une fonction appelée expm1qui évite ce problème. Si vous utilisez expm1(x) / xau lieu de (exp(x) - 1.0) / x, vous ne rencontrerez pas ce problème (voir le graphique ci-dessous). <code> fabs (expm1 (x) / x - (exp (x) - 1.0) / x) </code>

Les détails et la solution de ce problème particulier sont discutés en détail dans la section 1.14.1 de la précision et de la stabilité des algorithmes numériques . La même solution est également expliquée à la page 19 de l'article de W. Kahan intitulé How Futile are Mindless Assessments of Roundoff in Floating-Point Computation? . L'implémentation réelle de expm1dans la bibliothèque GNU C est différente de l'approche décrite dans les références ci-dessus et est entièrement documentée dans le code source .

Juan M. Bello-Rivas
la source
1
Merci, c'est exactement ce dont j'avais besoin! Malheureusement, je ne peux accepter qu'une seule réponse ...
anonyme
Bien sûr! Pas de problème :-)
Juan M. Bello-Rivas
3

Pour répondre à votre première question, non, la fonction n'a pas de nom (du moins pas un nom largement connu).

Comme d'autres l'ont mentionné, la meilleure façon de calculer la fonction est de traiter plusieurs cas particuliers. C'est ainsi que n'importe quelle bibliothèque calculerait la fonction.

  1. Cas 0: x = 0, retourne 1.
  2. |x|<δ1+x/2δdouble2e-85e-4
  3. Sinon: retour expm1(x)/x.

Vous pouvez être plus sophistiqué et spécial avec plus de choses avec la série Taylor tronquée, mais cela n'en vaut probablement pas la peine. En fait, il n'est pas tout à fait clair que le cas 1 doit être traité séparément, car comme l'a souligné k20, l'annulation est sûre. Cependant, le gérer séparément me permettrait de me sentir plus en confiance.

Victor Liu
la source
2

Je me souviens que cette question avait été posée plus tôt sur ce site, et étonnamment la réponse est que vous n'avez besoin que d'une égalité exacte dans un cas spécial à zéro. Les erreurs s'annulent près de zéro. Je n'ai pas le lien.

Ouais, cette réponse était complètement fausse. Je ne sais pas pourquoi il a été autant voté, probablement parce qu'il a été énoncé avec tant d'autorité. J'ai trouvé le lien que j'avais en tête. C'était sur le stackexchange mathématique ici , pas sur le stackexchange scicomp. La expm1formule d'annulation d'erreur sans erreur est donnée dans la réponse de JM et utilise une u = exp(x)transformation.

k20
la source
+ Droite. Si = infini d x , (xdx(edx1)/dx(1+dx1)/dx1
1
dx1+dx=1
0

Pour répondre à la première question et proposer une méthode (probablement numériquement inefficace) pour la seconde, notez qu'il s'agit de l'inverse de la fonction génératrice des nombres de Bernoulli .

Nikolaj-K
la source
C'est une connexion intéressante, merci de l'avoir souligné. Malheureusement, je crois que la triple somme rendra cela prohibitif. De plus, il n'est pas immédiatement clair où tronquer chaque somme pour obtenir la précision souhaitée.
anonyme
@anonymous: De quelle somme triple pensez-vous? Vous n'avez pas besoin des polynômes de Bernoulli, seulement des nombres de Bernoulli, et vous pouvez les énumérer à l'avance. Mais oui, ce n'est toujours pas mieux que la série Taylor.
Nikolaj-K
Vous pouvez les calculer à l'avance s'il est clair que vous n'avez besoin que d'un nombre fini fixe pour n'importe quelle entrée.
anonyme
@anonymous: Eh bien oui, tout comme vous listeriez les coefficients de Taylor à l'avance.
Nikolaj-K