2015-10-05 15 views
11

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.

+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. –

+0

Vedere http://docs.scipy.org/doc/numpy/release.html#better-numerical-stability-for-sum-in-some-cases –

+1

Anche https://github.com/numpy/numpy/pull/3685, che è dove è stata implementata la modifica in 'sum'. –

risposta

2

Sembra che abbiano recentemente aggiunto uno speciale Pairwise Summation a ndarray.sum per una migliore stabilità numerica.

Da PR 3685, questo influenza:

all add.reduce calls that go over float_add with IS_BINARY_REDUCE true 
so this also improves mean/std/var and anything else that uses sum. 

Vedi here per le modifiche del codice.

+0

Un algoritmo "divide et impera". Sì, avrebbe senso, grazie. –

+0

Ciò significa che in realtà è meglio utilizzare strategie alternative per calcolare le matrici rispetto alle funzioni integrate? Sarebbe ironico, dato che gli scopi intorpiditi sono di facilitare il lavoro scientifico. –

Problemi correlati