何时使用python函数expm1而不是exp-1 [英] when to use python function expm1 rather than exp-1

查看:158
本文介绍了何时使用python函数expm1而不是exp-1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

expm1该函数避免了为小x直接评估exp(x)-1所涉及的精度损失."

the expm1 "function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x."

关于小东西有经验法则吗? 1e-1、1e-10、1e-100? (问题Q:是否有性能问题或其他原因不总是使用expm1?)

is there a rule of thumb as to what is small? 1e-1, 1e-10, 1e-100 ? (side Q: is there a performance or other reason not to always use expm1?)

np.info(np.expm1)
Examples
--------
The true value of ``exp(1e-10) - 1`` is ``1.00000000005e-10`` to
about 32 significant digits. This example shows the superiority of
expm1 in this case.

>>> np.expm1(1e-10)
1.00000000005e-10
>>> np.exp(1e-10) - 1
1.000000082740371e-10

推荐答案

简短答案

如果6个有效的十进制数字足以满足您的需要,则exp(x)-1可以,直到x为1e-10.通常,当x大约为10**(-N)时,您将失去N个精度的十进制数字.我们从双精度的约16位数字开始.

Short answer

If 6 significant decimal digits are enough for you, exp(x)-1 is okay up to x being 1e-10. In general, you are going to lose N decimal digits of accuracy when x is about 10**(-N). We start with about 16 digits in double precision.

为什么不总是使用expm1?因为expm1(x) + 1绝对没有对exp(x)的好处,所以无论x多么小.仅当您的计算实际需要诸如exp(x) - 1之类的东西时,才使用expm1是有意义的.人们必须考虑更广泛的计算环境.

Why not always use expm1? Because expm1(x) + 1 has absolutely no benefit over exp(x), no matter how small x is. It only makes sense to use expm1 when your computation actually requires something like exp(x) - 1. One has to consider the wider context of the computation.

这实际上与x的大小无关,而是与exp(x)在计算中的使用方式有关. expm1的目的应该在重要性损失的更广泛的上下文中理解.对于某些参数范围,某些公式可能会失去重要性;人们必须分析公式,看看它是否以及何时发生.并且,如果在某个范围内可能会失去重要意义,请将公式重新处理为代数等效但数值稳定的值.维基百科在二次方程的例子中对此进行了很好的解释.

It's not really about how small x is, but about how exp(x) is used in your computation. The purpose of expm1 should be understood in wider context of Loss of significance. Some formulas are subject to loss of significance for certain ranges of parameters; one has to analyze the formula to see if and when it happens. And if there is a potential loss of significance in some range, rework the formula into something algebraically equivalent but numerically stable. Wikipedia explains this well on the example of quadratic equation.

如果您的目标是计算exp(x)3*exp(x) + 4等,则应使用exp.无论x有多小,在这里都不会失去意义,也没有将expm1放在这样的公式中的好处.用expm1(x) + 1代替exp(x)是完全没有意义的.

If your goal is to compute exp(x), or 3*exp(x) + 4 or such, you should use exp. There is no loss of significance here, and no benefit of putting expm1 in such a formula, regardless of how small x is. Writing expm1(x) + 1 instead of exp(x) is entirely pointless.

如果您的公式是exp(x) - 1exp(x) - cos(x),则对于小x而言,可能会失去重要性.这并不总是一个重写的理由;如果仅打算在x为1或更大时使用此公式,则没有问题.如果您完全可以将绝对错误设置为机器epsilon级别(大约1e-16),并且不太在意 relative 错误,则没有问题.

If your formula is exp(x) - 1 or exp(x) - cos(x), then there is potential loss of significance for small x. This is not always a reason to rewrite; if you only plan to use this formula when x is 1 or more, there is no issue. If you are okay with absolute error being at machine epsilon level (1e-16 or so), and don't care much about relative error, there is no issue.

当发生重大损失时,最终的信息使用者将决定可接受多少损失.通常,获得6个有效数字足以满足实际需要,因此,可以接受双精度精度损失10个十进制数字.在这种情况下,当x小于1e-10时,公式exp(x) - 1会导致不可接受的精度损失.的确,exp(x) - 1的值接近于x,但exp(x)看起来像1.00000000 ...,其中点后的10位为0.因此x本身仅剩下6位数字.

When the loss of significance occurs, it's up to the ultimate user of information to decide how much loss is acceptable. Often, getting 6 significant digits is quite enough for practical purposes, so losing 10 decimal digits out of double precision accuracy may be acceptable then. In this context, the formula exp(x) - 1 incurs unacceptable loss of precision when x is smaller than 1e-10. Indeed, the value of exp(x) - 1 is close to x but exp(x) looks like 1.00000000... with 10 digits after dot being 0; so only 6 digits remain from x itself.

以数字上更安全的形式重写函数需要一些人的努力,以计算出所需的代数或三角身份.此类重写的示例:

Rewriting functions in a numerically safer form requires some human effort, to work out whatever algebraic or trigonometric identities are needed. Examples of such rewriting:

f = lambda x: np.exp(x) - np.cos(x)
g = lambda x: np.sqrt(x**2 + 1) - 1  

上述数字的较安全形式:

Numerically safer form of the above:

f_safe = lambda x: np.expm1(x) + 2*np.sin(x/2)**2 
g_safe = lambda x: x / (np.sqrt(x**2 + 1) + 1)

np.exp(x) - np.cos(x)重写为np.expmp(x) - np.cos(x) + 1根本没有好处.人们必须仔细考虑整个计算过程,以消除几乎相等的数字.

Rewriting np.exp(x) - np.cos(x) as np.expmp(x) - np.cos(x) + 1 would have no benefit at all; one has to think through the entire computation to eliminate the subtraction of nearly-equal numbers.

这篇关于何时使用python函数expm1而不是exp-1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆