ShanZhengYang
ShanZhengYang

Reputation: 17631

Numpy np.dot() on multidimensional arrays

This is an easy question, but I'm getting confused by the size involved.

Using NumPy, I have a 3-dimensional array, shape = (10, 100, 100).

(The way I think of it is as an np.ndarray of 10 "matrices", each shaped 100 by 100, i.e.

arr1 = [M1 M2 M3....M10]

where M1.shape = (100,100), M2.shape = (100,100),...

I also have a second array of data called "arrB", which is arrB.shaped (100,). My goal is to do matrix multiplication with these numpy arrays, i.e. (arrB.T)*arr1*(arrB), resulting in a single integer. Using numpy arrays, this operation should be completed with np.dot()

op1 = np.dot(arr1, arrB)
op2 = np.dot((arrB.T), op1)

or

endproduct = np.dot((arrB.T), np.dot(arr1, arrB) )

However, this does not work. I get an error:

ValueError: shapes (100,) and (10,100) not aligned: 100 (dim 0) != 10 (dim 0)

If I do the operation on one "matrix" M# at a time, I can perform this operation, i.e.

element1 = arr1[0]
end = np.dot((arrB.T), np.dot(element1, arrB) )

Without splicing my original array, doing the operations, and appending again, how can I perform these operations on my original array arr1 to result in

result = [(arrB.T)*arr1[0]*(arrB) (arrB.T)*arr1[1]*(arrB) (arrB.T)*arr1[2]*(arrB) ... 
                                                ....(arrB.T)*arr1[9]*(arrB) ]

Upvotes: 0

Views: 1726

Answers (2)

hpaulj
hpaulj

Reputation: 231375

With arrB, shape (100,), .T does nothing. It needs to be (1,100) if you want .T to turn it into a (100,1) array.

In any case, to do the double dot with a (100,100) element you don't need .T. Try:

np.dot(arrB, np.dot(element1, arrB) )

With only 10 'elements', the list comprehension or iterative method isn't bad:

out = np.empty((10,))
for i in range(10):
   out[i] = np.dot(arrB, np.dot(arrA[i], arrB))

or using a comprehension:

np.array([np.dot(arrB,np.dot(elmt,arrB)) for elmt in arrA] )

np.einsum is another option:

np.einsum('i,kij,j->k',arrB, arrA, arrB)

np.tensordot is also designed to work with 3d arrays. It reshapes and transposes its inputs, so they become 2d arrays that np.dot can use.

np.dot(np.tensordot(arrA,arrB,[(2,),(0,)]),arrB) # needs more testing

You'll have to do some timings with realistic arrays to determine which is most efficient (and readable) for you.

Upvotes: 5

Anand S Kumar
Anand S Kumar

Reputation: 90889

You can use list comprehension for this as -

arr3 = np.array([np.dot(arr2.T , np.dot(arr1[i] , arr2)) for i in range(arr1.shape[0])])

Upvotes: 0

Related Questions