Home > Mobile >  Raise matrix to power N as in maths
Raise matrix to power N as in maths

Time:07-03

In numpy if we want to raise a matrix A to power N (but raise it as defined in mathematics, in linear algebra in particular), then it seems we need to use this function

numpy.linalg.matrix_power

Isn't there a simpler way? Some Python symbol/operator?

E.g. I was expecting A**N to do this but it doesn't.
Seems that A**N is raising each element to power N, and not the whole matrix to power N (in the usual math sense). So A**N is some strange element-wise raising to power N.

By matrix I mean of course a two-dimensional ndarray.

CodePudding user response:

In [4]: x=np.arange(4).reshape(2,2)

For this square array:

In [6]: np.linalg.matrix_power(x,3)
Out[6]: 
array([[ 6, 11],
       [22, 39]])

In [7]: x@x@x
Out[7]: 
array([[ 6, 11],
       [22, 39]])

matrix_power is written in python so you can easily read it. It essentially does a sequence of dot products, with some refinements to reduce the steps.

For np.matrix subclass, ** does the same thing:

In [8]: mx=np.matrix(x)
In [9]: mx**3
Out[9]: 
matrix([[ 6, 11],
        [22, 39]])

** is translated by the interpreter to a __pow__ call. For this class that just amounts to a matrix_power call:

In [10]: mx.__pow__??
Signature: mx.__pow__(other)
Docstring: Return pow(self, value, mod).
Source:   
    def __pow__(self, other):
        return matrix_power(self, other)
File:      c:\users\paul\anaconda3\lib\site-packages\numpy\matrixlib\defmatrix.py
Type:      method

But for ndarray this method is a compiled one:

In [3]: x.__pow__??
Signature:      x.__pow__(value, mod=None, /)
Call signature: x.__pow__(*args, **kwargs)
Type:           method-wrapper
String form:    <method-wrapper '__pow__' of numpy.ndarray object at 0x0000022A8B2B5ED0>
Docstring:      Return pow(self, value, mod).

numpy does not alter python syntax. It has not added any operators. The @ operator was added to python several years ago, largely as a convenience for packages like numpy. But it had to added to the interpreter's syntax first.

Note that matrix_power works for a

a : (..., M, M) array_like
     Matrix to be "powered".

That means it has to have at least 2 dimensions, and the trailing two must be equal size. So even that extends the normal linear algebra definition (which is limited to 2d).

numpy isn't just a linear algebra package. It's meant to be a general purpose array tool. Linear algebra is just a subset of math that can be performed with multidimensional collections of numbers (and other objects).

CodePudding user response:

numpy.linalg.matrix_power is the best way as far as I know. You could use dot or * in a loop, but that would just be more code, and probably less efficient.

  • Related