2017-10-11 13 views
-2

Pour une fonction comme f (x) = sqrt (1 + x) - sqrt (1-x), nous obtenons des résultats non désirés pour une certaine plage de valeurs x. Cependant, nous pouvons réécrire l'équation par morceaux pour utiliser l'équation originale dans certains cas et la nouvelle équation dans d'autres.Instabilité arithmétique des virgules flottantes

Comment puis-je déterminer la plage de valeurs x et trouver une autre expression pour des questions comme celles-ci? (De la recherche en ligne, j'ai trouvé que vous ne voulez pas que les fonctions "s'annulent" pour certaines valeurs, mais est-ce tout ce que nous cherchons? Par exemple, dans f (x) = e^x - 1, TOUJOURS juste chercher autour de f (x) = 0?)

+1

Cette question est beaucoup trop large comme écrit. Pourriez-vous être plus précis? –

+0

Pouvez-vous fournir une plage de valeurs de x où f (x) = sqrt (1 + x) - sqrt (1-x) donne de mauvais résultats lorsqu'il est évalué à l'aide de l'arithmétique en virgule flottante? Fournissez une expression alternative pour f (x) pour ces valeurs de x afin que "l'erreur d'annulation" ne se produise pas. – Brainpower2049

+1

@ Brainpower2049: les petits 'x' sont problématiques. Par exemple, 'f (1e-16)' donne '1.1102230246251565e-16', tandis que' f (1e-17) 'donne' 0.0'. Une expression qui est mathématiquement mais non numériquement équivalente est '2 * x/(sqrt (1 + x) + sqrt (1-x))'. Cela donne de bons résultats numériquement sur l'ensemble du domaine '[-1.0, 1.0]'. –

Répondre

3

Malheureusement, il n'y a pas de puces d'or ici: la manière habituelle est beaucoup d'expérimentation et d'analyse d'erreur fastidieuse. Quelques outils utiles:

  • des bibliothèques arithmétiques de précision arbitraires, telles que MPFR, pour calculer des expressions en utilisant une précision plus élevée et comparer le résultat avec une précision normale. J'aime utiliser Julia pour cela, car il fournit un type BigFloat qui prend en charge les opérateurs et fonctions mathématiques génériques.
  • arithmétique d'intervalle: fournit des limites garanties sur l'erreur (de sorte que les calculs instables vont exploser). Le seul paquet avec lequel j'ai une expérience personnelle est ValidatedNumerics.jl (voir le examples).
  • herbie utilise certaines astuces pour réécrire automatiquement les expressions numériques pour être plus stable. Je n'ai aucune expérience personnelle avec, mais ça a l'air cool. (Par coïncidence, l'exemple qu'ils ont sur leur page d'accueil est assez proche du vôtre)
+0

Je pense que herbie doit être beaucoup plus sophistiqué (ou moins buggé) avant que ce soit utile. Entrer l'expression de l'OP m'a donné '1/8 x^3/+ (7/128 x^5 + x)', sans aucune indication du domaine dans lequel cette expression pourrait être utile. –

+0

C'est étrange: je viens de l'essayer la petite application web, et elle a donné la réponse que vous avez suggérée dans la question à la question: '(x + x)/(sqrt (1 + x) + sqrt (1-x))'. –

+0

Hmm, ça c'est bizarre. Je reçois toujours le même résultat que précédemment (l'expansion de la série Taylor autour de 0). Il semble cependant qu'il y ait une entrée aléatoire dans les algorithmes; peut-être que cela l'explique. –