Durante la ricerca di un po 'di roba NumPy, mi sono imbattuto in una domanda a discutere la precisione di arrotondamento di numpy.dot():NumPy virgola mobile errori di arrotondamento
Numpy: Difference between dot(a,b) and (a*b).sum()
Dato che mi capita di avere due (diverse) Computer con le CPU Haswell sulla mia scrivania, che dovrebbero fornire FMA e tutto, ho pensato di testare l'esempio dato da Ophion nella prima risposta, e ho ottenuto un risultato che mi ha un po 'sorpreso:
Dopo l'aggiornamento/l'installazione/fissando lapack/blas/atlas/numpy, ottengo il seguente su entrambe le macchine:
>>> 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
Quindi la moltiplicazione standard + sum() è più precisa di np.dot(). timeit comunque ha confermato che la versione .dot() è più veloce (ma non molto) sia per float64 che per float128.
Qualcuno può fornire una spiegazione per questo?
modifica: ho eliminato per errore le informazioni sulle versioni di numpy: stessi risultati per 1.9.0 e 1.9.3 con python 3.4.0 e 3.4.1.
È interessante notare che ottengo questa discrepanza solo su NumPy 1.9.2 e non su NumPy 1.8.2. Entrambi usano il blas + lapack (non l'atlante). Con NumPy 1.8.2, i risultati sono identici a punto e somma, suggerendo identici eventi di arrotondamento, su NumPy 1.9.2, moltiplicazione + somma() è più preciso. –
Vedere http://docs.scipy.org/doc/numpy/release.html#better-numerical-stability-for-sum-in-some-cases –
Anche https://github.com/numpy/numpy/pull/3685, che è dove è stata implementata la modifica in 'sum'. –