При поиске некоторого Numpy материала, я наткнулся на вопрос обсуждали скругления точность numpy.dot():Numpy с плавающей запятой ошибки округления
Numpy: Difference between dot(a,b) and (a*b).sum()
Так как я, случается, есть два (разных) Компьютеры с Haswell-CPU, сидящими на моем столе, которые должны обеспечить FMA и все, я думал, что испытаю пример, данный Ophion в первом ответе, и я получил результат, который несколько удивил меня:
После обновления/установки/фиксирующий лапак/blas/atlas/numpy, на обеих машинах я получаю следующее:
>>> a = np.ones(1000, dtype=np.float128)+1e-14
>>> (a*a).sum()
1000.0000000000199999
>>> np.dot(a,a)
1000.0000000000199948
>>> a = np.ones(1000, dtype=np.float64)+1e-14
>>> (a*a).sum()
1000.0000000000198
>>> np.dot(a,a)
1000.0000000000176
Значит, стандартное умножение + sum() точнее, чем np.dot(). timeit однако подтвердил, что версия .dot() быстрее (но не очень) для float64 и float128.
Может ли кто-нибудь дать объяснение этому?
Редактировать: Я случайно удалил информацию о версиях numpy: те же результаты для 1.9.0 и 1.9.3 с python 3.4.0 и 3.4.1.
Интересно, что я получаю это несоответствие только на NumPy 1.9.2, а не NumPy 1.8.2. Оба используют блаз + лапак (не атлас). С NumPy 1.8.2 результаты идентичны точкам и сумме, предлагая одинаковые события округления, на NumPy 1.9.2 умножение + sum() является более точным. –
См. Http://docs.scipy.org/doc/numpy/release.html#better-numerical-stability-for-sum-in-some-cases –
Также https://github.com/numpy/numpy/pull/3685, в котором было реализовано изменение в 'sum'. –