Sto eseguendo il porting di un algoritmo che funziona in Matlab per numpy e ho osservato uno strano comportamento. Il segmento rilevante di codice èMatlab/Ottava/Numpia differenza numerica
P = eye(4)*1e20;
A = [1 -0.015 -0.025 -0.035; 0.015 1 0.035 -0.025; 0.025 -0.035 1 0.015; 0.035 0.025 -0.015 1];
V1 = A*(P*A')
V2 = (A*P)*A'
Questo codice, quando corro con Matlab, fornisce le seguenti matrici:
V1 = 1.0021e+20 0 -8.0000e+00 0
0 1.0021e+20 0 0
-8.0000e+00 0 1.0021e+20 0
0 0 0 1.0021e+20
V2 = 1.0021e+20 0 -8.0000e+00 0
0 1.0021e+20 0 0
-8.0000e+00 0 1.0021e+20 0
0 0 0 1.0021e+20
noti che V1 e V2 sono gli stessi, come previsto.
Quando lo stesso codice viene eseguito in Octave, fornisce:
V1 = 1.0021e+20 4.6172e+01 -1.3800e+02 1.8250e+02
-4.6172e+01 1.0021e+20 -1.8258e+02 -1.3800e+02
1.3801e+02 1.8239e+02 1.0021e+20 -4.6125e+01
-1.8250e+02 1.3800e+02 4.6125e+01 1.0021e+20
V2 = 1.0021e+20 -4.6172e+01 1.3801e+02 -1.8250e+02
4.6172e+01 1.0021e+20 1.8239e+02 1.3800e+02
-1.3800e+02 -1.8258e+02 1.0021e+20 4.6125e+01
1.8250e+02 -1.3800e+02 -4.6125e+01 1.0021e+20
Nel numpy, il segmento diventa
from numpy import array, dot, eye
A = numpy.array([[1, -0.015, -0.025, -0.035],[0.015, 1, 0.035, -0.025],[0.025, -0.035, 1, 0.015],[0.035, 0.025, -0.015, 1]])
P = numpy.eye(4)*1e20
print numpy.dot(A,numpy.dot(P,A.transpose()))
print numpy.dot(numpy.dot(A,P),A.transpose())
che emette
[[ 1.00207500e+20 4.61718750e+01 -1.37996094e+02 1.82500000e+02]
[ -4.61718750e+01 1.00207500e+20 -1.82582031e+02 -1.38000000e+02]
[ 1.38011719e+02 1.82386719e+02 1.00207500e+20 -4.61250000e+01]
[ -1.82500000e+02 1.38000000e+02 4.61250000e+01 1.00207500e+20]]
[[ 1.00207500e+20 -4.61718750e+01 1.38011719e+02 -1.82500000e+02]
[ 4.61718750e+01 1.00207500e+20 1.82386719e+02 1.38000000e+02]
[ -1.37996094e+02 -1.82582031e+02 1.00207500e+20 4.61250000e+01]
[ 1.82500000e+02 -1.38000000e+02 -4.61250000e+01 1.00207500e+20]]
Quindi, sia Octave e numpy fornisce la stessa risposta, ma è molto diversa da quella di Matlab. Il primo punto è V1! = V2, che non sembra giusto. L'altro punto è che, sebbene gli elementi non diagonali siano molti ordini di grandezza più piccoli di quelli diagonali, questo sembra causare alcuni problemi nel mio algoritmo.
Qualcuno conosce il modo insensato e Octave si comporta in questo modo?
Questo non è giusto. Esiste un tipo di dati float128, tuttavia la sua precisione potrebbe non essere sempre ben definita. – seberg
@Sebastian, non ho trovato alcun riferimento a un tipo float128 - solo complex128 (perché quelli sono due float64 visti come un numero con la parte reale e immaginaria). http://docs.scipy.org/doc/numpy/user/basics.types.html – Lucero
Sì ... questo perché float128 è disponibile solo a seconda del computer su cui è in esecuzione. Ma sul solito PC lo è. – seberg