2013-07-17 18 views
5

Ho alcuni dubbi sul prodotto numpy.dot.Numpy, dot products su array multidimensionali

definisco una 6x6 matrice come:

C=np.zeros((6,6)) 
C[0,0], C[1,1], C[2,2] = 129.5, 129.5, 129.5 
C[3,3], C[4,4], C[5,5] = 25, 25, 25 
C[0,1], C[0,2] = 82, 82 
C[1,0], C[1,2] = 82, 82 
C[2,0], C[2,1] = 82, 82 

Poi rifusione in un tensore 4 rango utilizzando una matrice multidimensionale

def long2short(m, n): 
    """ 
    Given two indices m and n of the stiffness tensor the function 
    return i the index of the Voigt matrix 
    i = long2short(m,n) 
    """ 
    if m == n: 
     i = m 
    elif (m == 1 and n == 2) or (m == 2 and n == 1): 
     i = 3 
    elif (m == 0 and n == 2) or (m == 2 and n == 0): 
     i = 4 
    elif (m == 0 and n == 1) or (m == 1 and n == 0): 
     i = 5  
    return i 

c=np.zeros((3,3,3,3)) 
for m in range(3): 
    for n in range(3): 
     for o in range(3): 
      for p in range(3): 
       i = long2short(m, n) 
       j = long2short(o, p) 
       c[m, n, o, p] = C[i, j] 

E poi desidero modificare il riferimento di coordinate sistema del tensore utilizzando la matrice di rotazione che definisco come:

Q=np.array([[sqrt(2.0/3), 0, 1.0/sqrt(3)], [-1.0/sqrt(6), 1.0/sqrt(2), 1.0/sqrt(3)], [-1.0/sqrt(6), -1.0/sqrt(2), 1.0/sqrt(3)]])   
Qt = Q.transpose() 

Il matri x è ortogonale (ma decorate la precisione numerica non è perfetto):

In [157]: np.dot(Q, Qt) 
Out[157]: 
array([[ 1.00000000e+00, 4.28259858e-17, 4.28259858e-17], 
     [ 4.28259858e-17, 1.00000000e+00, 2.24240114e-16], 
     [ 4.28259858e-17, 2.24240114e-16, 1.00000000e+00]]) 

Ma perché allora se mi esibisco:

In [158]: a=np.dot(Q,Qt) 
In [159]: c_mat=np.dot(a, c) 
In [160]: a1 = np.dot(Qt, c) 
In [161]: c_mat1=np.dot(Q, a1) 

ottengo il valore atteso per c_mat (= c), ma non per c_mat1? C'è qualche sottigliezza nell'usare dot su array multidimensionali?

+0

Quale risultato ottieni per c_mat1? in alcuni di questi casi dovresti usare tensordot? – usethedeathstar

+3

Dai un'occhiata a 'numpy.tensordot()' –

risposta

10

Il problema è che np.dot(a,b) per gli array multidimensionali rende il prodotto scalare dell'ultima dimensione del a con il secondo-a-ultima dimensione di b:

np.dot(a,b) == np.tensordot(a, b, axes=([-1],[2])) 

Come si vede, non funziona come un moltiplicazione matrice per matrici multidimensionali. L'utilizzo di np.tensordot() consente di controllare in quale axes da ciascun ingresso si desidera eseguire il prodotto punto. Ad esempio, per ottenere lo stesso risultato in c_mat1 si può fare:

c_mat1 = np.tensordot(Q, a1, axes=([-1],[0])) 

che sta costringendo una matrice comportamento moltiplicazione-like.

+0

Grazie per i suggerimenti! Funziona bene ora! –

Problemi correlati