Python - Matrix outer product

后端 未结 4 1404
时光取名叫无心
时光取名叫无心 2020-12-14 10:54

Given two matrices

A: m * r
B: n * r

I want to generate another matrix C: m * n, with each entry C_ij being a mat

相关标签:
4条回答
  • 2020-12-14 11:29

    Use numpy;

    In [1]: import numpy as np
    
    In [2]: A = np.array([[1, 2], [3, 4]])
    
    In [3]: B = np.array([[3, 1], [1, 2]])
    
    In [4]: C = np.outer(A, B)
    
    In [5]: C
    Out[5]: 
    array([[ 3,  1,  1,  2],
           [ 6,  2,  2,  4],
           [ 9,  3,  3,  6],
           [12,  4,  4,  8]])
    

    Once you have the desired result, you can use numpy.reshape() to mold it in almost any shape you want;

    In [6]: C.reshape([4,2,2])
    Out[6]: 
    array([[[ 3,  1],
            [ 1,  2]],
    
           [[ 6,  2],
            [ 2,  4]],
    
           [[ 9,  3],
            [ 3,  6]],
    
           [[12,  4],
            [ 4,  8]]])
    
    0 讨论(0)
  • 2020-12-14 11:42
    temp = numpy.multiply.outer(A, B)
    C = numpy.swapaxes(temp, 1, 2)
    

    NumPy ufuncs, such as multiply, have an outer method that almost does what you want. The following:

    temp = numpy.multiply.outer(A, B)
    

    produces a result such that temp[a, b, c, d] == A[a, b] * B[c, d]. You want C[a, b, c, d] == A[a, c] * B[b, d]. The swapaxes call rearranges temp to put it in the order you want.

    0 讨论(0)
  • 2020-12-14 11:46

    The Einstein notation expresses this problem nicely

    In [85]: np.einsum('ac,bd->abcd',A,B)
    Out[85]: 
    array([[[[ 3,  1],
             [ 6,  2]],
    
            [[ 1,  2],
             [ 2,  4]]],
    
    
           [[[ 9,  3],
             [12,  4]],
    
            [[ 3,  6],
             [ 4,  8]]]])
    
    0 讨论(0)
  • 2020-12-14 11:50

    Simple Solution with Numpy Array Broadcasting

    Since, you want C_ij = A_i * B_j, this can be achieved simply by numpy broadcasting on element-wise-product of column-vector-A and row-vector-B, as shown below:

    # import numpy as np
    # A = [[1, 2], [3, 4]]
    # B = [[3, 1], [1, 2]]
    A, B = np.array(A), np.array(B)
    C = A.reshape(-1,1) * B.reshape(1,-1)
    # same as: 
    # C = np.einsum('i,j->ij', A.flatten(), B.flatten())
    print(C)
    

    Output:

    array([[ 3,  1,  1,  2],
           [ 6,  2,  2,  4],
           [ 9,  3,  3,  6],
           [12,  4,  4,  8]])
    

    You could then get your desired four sub-matrices by using numpy.dsplit() or numpy.array_split() as follows:

    np.dsplit(C.reshape(2, 2, 4), 2)
    # same as:
    # np.array_split(C.reshape(2,2,4), 2, axis=2)
    

    Output:

    [array([[[ 3,  1],
             [ 6,  2]],
    
            [[ 9,  3],
             [12,  4]]]), 
    array([[[1, 2],
             [2, 4]],
    
            [[3, 6],
             [4, 8]]])]
    

    0 讨论(0)
提交回复
热议问题