Search code examples
pythonnumpymatrixdiagonal

python negative sum of rows on matrix diagonal efficiently


I need to sum the rows of a matrix, negate them, and put them on the diagonal of either the original matrix or a matrix where the off-diagonal terms are zero. What works is

 Mat2 = numpy.diag(numpy.negative(numpy.squeeze(numpy.asarray(numpy.sum(Mat1,axis=1))))

Is there a cleaner/faster way to do this? I'm trying to optimize some code.


Solution

  • I think np.diag(-Mat1.A.sum(1)) would produce the same results:

    >>> Mat1 = np.matrix(np.random.rand(3,3))
    >>> Mat1
    matrix([[ 0.35702661,  0.0191392 ,  0.34793743],
            [ 0.9052968 ,  0.16182118,  0.2239716 ],
            [ 0.57865916,  0.77934846,  0.60984091]])
    >>> Mat2 = np.diag(np.negative(np.squeeze(np.asarray(np.sum(Mat1,axis=1)))))
    >>> Mat2
    array([[-0.72410324,  0.        ,  0.        ],
           [ 0.        , -1.29108958,  0.        ],
           [ 0.        ,  0.        , -1.96784852]])
    >>> np.diag(-Mat1.A.sum(1))
    array([[-0.72410324,  0.        ,  0.        ],
           [ 0.        , -1.29108958,  0.        ],
           [ 0.        ,  0.        , -1.96784852]])
    

    Note that matrices are a bit of a headache in numpy -- arrays are generally much more convenient -- and the only syntactic advantage they had, namely easier multiplication, doesn't really count any more now that we have @ for matrix multiplication in modern Python.

    If Mat1 were an array instead of a matrix, you wouldn't need the .A there.