一些数学库函数有存在的必要吗?
2018-03-13 15:12
239 查看
本文将给出一些在 C 数学库中乍一看似乎不必要存在的函数示例。
好了。
等等。。。如果 x 非常小呢?例如,如果 x 是 10−1610−16,那么在典型系统上会出现
幸运的是,这是一个很好解决的问题。对于小的 x 值,
为什么这很重要?即使代码对于非零的答案直接返回零,其绝对误差也很小。这不是还可以吗?是的,它可能是可行的。这取决于你下一步做什么——如果将结果添加到大量数据中,那么答案中的相对误差无关紧要;但是如果将结果乘以大数,大的相对误差也会变成大的绝对误差。
对于适当的 x 来说这能很好的工作。但是,对于非常小的 x 值,
本文翻译自:Math library functions that seem unnecessary
函数 log1p(x) = log(1 + x)
函数log1p计算
log(1 + x)。这有多难实现呢?
log(1 + x);
好了。
等等。。。如果 x 非常小呢?例如,如果 x 是 10−1610−16,那么在典型系统上会出现
1 + x = 1,因为机器精度缺乏足够的有效位来区分
1 + x和 1(参见这里了解更多)。这意味着代码
log(1 + x)会先计算
1 + x,得到 1,然后计算
log(1),返回 0。但是 log(1+10−16)≈10−16log(1+10−16)≈10−16 。这意味着绝对误差约 10−1610−16 ,而 相对误差为 100%。对于那些比 10−1610−16 大但总体还是相当小的数来说,代码
log(1 + x)可能并不完全不正确,但是相对误差还是大的不可接受。
幸运的是,这是一个很好解决的问题。对于小的 x 值,
log(x + 1)约等于 x。所以对于非常小的参数,只需要返回 x。对于大的参数,直接计算
log(1 + x)。具体细节参见这里。
为什么这很重要?即使代码对于非零的答案直接返回零,其绝对误差也很小。这不是还可以吗?是的,它可能是可行的。这取决于你下一步做什么——如果将结果添加到大量数据中,那么答案中的相对误差无关紧要;但是如果将结果乘以大数,大的相对误差也会变成大的绝对误差。
函数 expm1(x) = exp(x) - 1
另一个似乎不必要的函数是expm1。这个函数计算 ex−1ex−1。为什么不写成这样?
exp(x) - 1.0;
对于适当的 x 来说这能很好的工作。但是,对于非常小的 x 值,
exp(x)接近于 1,这可能会导致太接近 1 以至于在机器精度上实际就是 1。在这种情况下,代码
exp(x) - 1将返回 0 并产生 100% 的相对误差。和上面的一样,对于稍微大一点的 x 值,朴素代码不会完全错误,但可能不如所需的精确。解决方案是直接计算
exp(x) - 1,而不是先计算
exp(x)。
exp(x)的泰勒级数是 1+x+x22...1+x+x22...,所以对于非常小的 x,
exp(x) - 1返回 x。对于稍大的 x,可以返回 x+x2/2x+x2/2。(具体细节参见这里)
函数 erf(x) 与 erfc(x)
C 数学库包含一对函数erf与
erfc。结尾的 c 代表互补(complement),因为
erfc(x) = 1 - erf(x)。 函数
erf(x)被称为误差函数,实现并不容易。但是为什么还有一个单独的
erfc函数?一旦你有
erf的代码实现它不是很容易吗?对于某些 x 的值来说,这是真的。但是,如果 x 很大,则
erf(x)接近 1,当结果很小且为正时,代码
1 - erf(x)可能会返回 0。和上面的例子一样,朴素的实现会导致某些值精度的完全丧失,其他一些值精度也会部分丢失。
函数 Γ(x)Γ(x) 与 logΓ(x)logΓ(x)
标准 C 数学库有两个与 gamma 函数相关的函数:返回 Γ(x)Γ(x) 的tgamma和返回 logΓ(x)logΓ(x) 的
lgamma。为什么有两个?为什么后者不能使用前者的对数?gamma 函数的增长非常快。对于一般大小的参数,其值超过计算机数值的容量。 有时你可能需要这些天文数字大小的值作为中间结果。你需要一个适当大小的数作为两个非常大的值的比值(这里有一个例子)。在这种情况下,只需要将
lgamma值相减,而不是用
tgamma的值相比。(为什么函数叫做 tgamma 而不是 gamma?请参阅这篇文章的最后一段与第一条评论)
总结
标准 C 数学库汲取了许多经验。对于一些参数来说有些函数是不必要的,但是,对于另一些参数来说它们是不可或缺的。本文翻译自:Math library functions that seem unnecessary
相关文章推荐
- php的一些小笔记--数学函数
- QT 中一些数学计算函数
- Shell实现的一些数学运算自定义函数分享
- Shell实现的一些数学运算自定义函数分享
- QT 中一些数学计算函数
- Ccocos2d-x中的一些常用数学函数
- Python 基础语法——数字和表达式(包含数学上的一些函数)
- 字符串的一些函数(数学c语言课程设计)
- 函数设计中存在的一些问题
- Java中一些基本的数学类操作函数及注意事项
- 一些数学函数的使用方法(持续更新)
- D3D开发中你必须知道的一些函数和数学知识
- H.264中的一些数学函数
- [再寄小读者之数学篇](2014-05-30 存在无穷多个函数, 其复合为恒等函数)
- DirectX 9的一些数学计算函数:平面
- Delphi中一些数学函数
- [学习记录]iOS的一些数学函数
- 在采集程序中,定时器函数和WindowProc函数存在的一些问题
- 一些数学函数
- cocos2dx 3.0 的一些数学函数