ElleryL
ElleryL

Reputation: 527

numpy array operation method

>>> c= array([[[1, 2],
               [3, 4]],

               [[2, 1],
                [4, 3]],

               [[3, 2],
                [1, 4]]])
 >>> x
 array([[0, 1, 2],
       [3, 4, 5]])

return me a matrix such that each column is the product of each matrix in c multiply the each corresponding column of x in regular matrix multiplication. I'm trying to figure out a way to vectorized it or at least not using for loop to solve it.

array([[6,  6, 16]
       12, 16, 22]])

to extends this operation further let's say that I have an array of matrices,say

>>> c
    array([[[1, 2],
    [3, 4]],

   [[2, 1],
    [4, 3]],

   [[3, 2],
    [1, 4]]])  
>>> x
    array([[[1, 2, 3],
    [1, 2, 3]],

   [[1, 0, 2],
    [1, 0, 2]],

   [[2, 3, 1],
    [0, 1, 0]]])


def fun(c,x):
    for i in range(len(x)):
         np.einsum('ijk,ki->ji',c,x[i])
         ##something

So basically, I want to have each matrix in x multiply with all of c. return a structure similar to c without introducing this for loop

The reason I'm doing this because I've encounter a problem to solve a problem ,trying to vectorized

Xc (the operation follows the normal matrix column vector multiplication), c is 3D array; like the c from above-- a column vector that each element is a matrix (in numpy its the form in the above). X is the matrix with each elements is a 1D array. The output of the Xc should be 1D array.

Upvotes: 2

Views: 88

Answers (1)

Divakar
Divakar

Reputation: 221614

You can use np.einsum -

np.einsum('ijk,ki->ji',c,x)

Sample run -

In [155]: c
Out[155]: 
array([[[1, 2],
        [3, 4]],

       [[2, 1],
        [4, 3]],

       [[3, 2],
        [1, 4]]])

In [156]: x
Out[156]: 
array([[0, 1, 2],
       [3, 4, 5]])

In [157]: np.einsum('ijk,ki->ji',c,x)
Out[157]: 
array([[ 6,  6, 16],
       [12, 16, 22]])

For the 3D case of x, simply append the new dimension at the start of the string notation for x and correspondingly at the output string notation too, like so -

np.einsum('ijk,lki->lji',c,x)

Sample run -

In [151]: c
Out[151]: 
array([[[1, 2],
        [3, 4]],

       [[2, 1],
        [4, 3]],

       [[3, 2],
        [1, 4]]])

In [152]: x
Out[152]: 
array([[[1, 2, 3],
        [1, 2, 3]],

       [[1, 0, 2],
        [1, 0, 2]],

       [[2, 3, 1],
        [0, 1, 0]]])

In [153]: np.einsum('ijk,lki->lji',c,x)
Out[153]: 
array([[[ 3,  6, 15],
        [ 7, 14, 15]],

       [[ 3,  0, 10],
        [ 7,  0, 10]],

       [[ 2,  7,  3],
        [ 6, 15,  1]]])

Upvotes: 1

Related Questions