在 numpy 中总结 ndarray 同时最小化浮点不准确性的最有效方法是什么?
What's the most efficient way to sum up an ndarray in numpy while minimizing floating point inaccuracy?
我有一个大矩阵,其值在数量级上变化很大。为了尽可能准确地计算总和,我的方法是将 ndarray 重塑为一维数组,对其进行排序,然后将其相加,从最小的条目开始。有没有更好/更有效的方法来做到这一点?
我认为,对于浮点精度问题,最知名的算法是 Kahan summation。出于实用目的,Kahan 求和的误差界限与被加数的数量无关,而朴素求和的误差界限随被加数的数量线性增长。
NumPy 不使用 Kahan 求和,并且在不牺牲性能的情况下没有简单的方法来实现它。但它使用了次优的东西,pairwise summation,在一些合理的假设下,误差会增加,比如被加数的对数的平方根。
因此很可能 Numpy 本身已经能够为您的问题提供足够好的精度。为了验证这一点,我实际上会 运行 通过 Kahan 求和的一些示例案例(上面维基百科中的伪代码 link 可以简单地转换为 Python),并将其作为黄金,最好的结果,并将其与以下内容进行比较:
- 按原样在您的矩阵上调用
np.sum
。
- 整形为一维后在矩阵上调用
np.sum
,如果矩阵在内存中不连续,这可能会得到更好的结果。
- 正在对一维数组的排序版本调用
np.sum
。
在大多数情况下,最后三个选项的行为应该相似,但唯一的方法是实际测试它。
我有一个大矩阵,其值在数量级上变化很大。为了尽可能准确地计算总和,我的方法是将 ndarray 重塑为一维数组,对其进行排序,然后将其相加,从最小的条目开始。有没有更好/更有效的方法来做到这一点?
我认为,对于浮点精度问题,最知名的算法是 Kahan summation。出于实用目的,Kahan 求和的误差界限与被加数的数量无关,而朴素求和的误差界限随被加数的数量线性增长。
NumPy 不使用 Kahan 求和,并且在不牺牲性能的情况下没有简单的方法来实现它。但它使用了次优的东西,pairwise summation,在一些合理的假设下,误差会增加,比如被加数的对数的平方根。
因此很可能 Numpy 本身已经能够为您的问题提供足够好的精度。为了验证这一点,我实际上会 运行 通过 Kahan 求和的一些示例案例(上面维基百科中的伪代码 link 可以简单地转换为 Python),并将其作为黄金,最好的结果,并将其与以下内容进行比较:
- 按原样在您的矩阵上调用
np.sum
。 - 整形为一维后在矩阵上调用
np.sum
,如果矩阵在内存中不连续,这可能会得到更好的结果。 - 正在对一维数组的排序版本调用
np.sum
。
在大多数情况下,最后三个选项的行为应该相似,但唯一的方法是实际测试它。