Как поднять массив numpy к власти? (что соответствует неоднократным матричным умножениям, а не элементарным)
Я хочу поднять двумерный numpy array
, называть его A
, степенью некоторого числа n
, но до сих пор мне не удалось найти функцию или оператор для этого.
Мне известно, что я мог бы применить его к типу matrix
и использовать тот факт, что тогда (похоже на поведение в Matlab) A**n
делает то, что я хочу (для array
то же выражение означает элементное возведение в степень). Кастинг до matrix
и обратно кажется довольно уродливым обходным решением.
Конечно, должен быть хороший способ выполнить этот расчет, сохранив формат array
?
Ответы
Ответ 1
Я считаю, что вы хотите numpy.linalg.matrix_power
В качестве быстрого примера:
import numpy as np
x = np.arange(9).reshape(3,3)
y = np.matrix(x)
a = y**3
b = np.linalg.matrix_power(x, 3)
print a
print b
assert np.all(a==b)
Это дает:
In [19]: a
Out[19]:
matrix([[ 180, 234, 288],
[ 558, 720, 882],
[ 936, 1206, 1476]])
In [20]: b
Out[20]:
array([[ 180, 234, 288],
[ 558, 720, 882],
[ 936, 1206, 1476]])
Ответ 2
Функция opencv cvPow, кажется, примерно в 3-4 раза быстрее на моем компьютере, когда поднимается до рационального числа.
Вот примерная функция (вам нужно установить модуль pyopencv):
import pyopencv as pycv
import numpy
def pycv_power(arr, exponent):
"""Raise the elements of a floating point matrix to a power.
It is 3-4 times faster than numpy built-in power function/operator."""
if arr.dtype not in [numpy.float32, numpy.float64]:
arr = arr.astype('f')
res = numpy.empty_like(arr)
if arr.flags['C_CONTIGUOUS'] == False:
arr = numpy.ascontiguousarray(arr)
pycv.pow(pycv.asMat(arr), float(exponent), pycv.asMat(res))
return res