定点和任意精度计算的相关性
在某些情况下,使用定点算术可能是合适的。通常对于科学计算(至少在大多数人认为的意义上)它是不合适的,因为需要表达遇到的大动态范围。您以特征值问题为例,但在科学中,人们经常对矩阵的最小特征值感兴趣(例如,计算量子系统的基态)。如果使用定点,小特征值的精度通常会相对于大特征值大幅下降。如果您的矩阵包含以大比率变化的条目,则小特征值可能在工作精度中完全无法表达。这是数字表示的问题;无论您如何进行中间计算,这些参数都成立。您可能会制定一个缩放比例以应用于计算结果,但现在您刚刚发明了浮点数。构造元素表现良好但特征值表现极差的矩阵很容易(如威尔金森矩阵,甚至是具有完全整数项的矩阵)。这些例子并不像看起来那样病态,科学前沿的许多问题都涉及性能非常差的矩阵,因此在这种情况下使用定点是一个坏主意(TM)。
您可能会争辩说您知道结果的大小并且不想在指数上浪费位,所以让我们谈谈中间体。使用定点通常会加剧灾难性取消和舍入的影响,除非您真的非常努力地以更高的精度工作。性能损失将是巨大的,我猜想使用具有相同尾数位宽度的浮点表示会更快、更准确。
定点可以发光的一个领域是几何计算的某些领域。特别是如果您需要精确的算术运算或事先知道所有数字的动态范围,定点可让您利用表示中的所有位。例如,假设您想计算两条线的交点,并且两条线的端点以某种方式归一化以位于单位正方形中。在这种情况下,与使用等效的浮点数(这将浪费指数上的位)相比,可以用更多位的精度表示交点。现在,几乎可以肯定的是,此计算中所需的中间数需要以更高的精度计算,或者至少需要非常小心地计算(就像将两个数字的乘积除以另一个数字一样,您需要非常小心)。在这方面,从表示的角度而不是从计算的角度来看,定点更有优势,而且我什至可以说,当您可以在算法输出的动态范围上建立明确的上限和下限时,这通常是正确的. 这种情况很少发生。
我曾经认为浮点表示是粗略的或不准确的(为什么要在指数上浪费位?!)。但随着时间的推移,我开始意识到它确实是实数的最佳表示之一。自然界中的事物以对数刻度显示,因此真实数据最终会跨越大范围的指数。此外,要获得尽可能高的相对精度,还需要使用对数刻度,使指数的跟踪更加自然。“自然”表示的唯一其他竞争者是对称级别索引。然而,加法和减法在这种表示中要慢得多,而且它缺乏 IEEE 754 的硬件支持。浮点标准投入了大量的思想,由数值线性代数的支柱。我认为他知道数字的“正确”表示是什么。
作为一个为什么很少使用精确算术/定点算术的例子,考虑一下:
在有限元方法中,就像在科学计算中使用的几乎所有其他方法一样,我们得到的线性或非线性系统只是对现实世界的近似。例如,在 FEM 中,要求解的线性系统只是原始偏微分方程的近似值(其本身可能只是现实世界的近似值)。那么,为什么要付出巨大的努力来解决只是一个近似值的问题呢?
我们今天使用的大多数算法本质上都是迭代的:牛顿法、共轭梯度等。只要我们对问题解决方案的迭代近似的准确性感到满意,我们就会终止这些迭代。换句话说,我们在得到精确解之前就终止了。和以前一样,当我们知道我们只是在计算近似值时,为什么要对迭代方案使用精确算术呢?
如果您查看此库以进行正确的舍入:CRlibm,您将在文档中看到通常必须证明算法是准确的(通过合理的证明)。为什么?函数结果的稳定性和收敛速度没有“一刀切”的答案。简而言之,没有免费的午餐——你必须努力证明你的推理是正确的。这是由于被建模的函数的行为,而不是底层硬件(无论您使用整数还是浮点单位,虽然是的,但两者都有“陷阱”,如上溢/下溢、非正规数等)即使结果您正在寻找收敛到整数,用于查找结果的算法不一定非常稳定。
Eigen 是一个 C++ 库,它具有用于求解矩阵的多种算法,每种算法具有不同的属性。 此页面包含一个表格,讨论了用于求解矩阵的各种算法的速度与准确性权衡。我怀疑 Eigen 库可以做你想做的事。:-)
有关高精度算术在数学中的用处的一些很好的例子,请查看Jonathan Borwein 和 David Bailey所著的《 Mathematics by Experiment 》一书。还有这个续集,我没看过。