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.