我有许多2×2矩阵,A
,A.shape == (2, 2, 7324)
,我必须计算所有这些矩阵的指数。不幸的是,scipy.linalg.expm
一次只能接受一个矩阵,这样我就不得不遍历计算,
import numpy
import scipy.linalg
numpy.random.seed(0)
A = numpy.random.rand(2, 2, 7324)
out = numpy.array([scipy.linalg.expm(A[:, :, k]) for k in range(A.shape[-1])])
out = numpy.moveaxis(out, 0, -1)
有办法避免这种循环吗?
答案 0 :(得分:0)
浏览一下代码,https://github.com/scipy/scipy/blob/v1.4.1/scipy/sparse/linalg/matfuncs.py#L550-L595 看来它实际上只假设一个矩阵。因此,如果要避免python循环,则需要提取相关部分,然后对它们进行cythonize或numpy-vectorize。仅适合于稠密的基质才能使其变得更容易。
答案 1 :(得分:0)
这是 pade 近似的代码。这仅适用于 1 个数组,您必须对其进行 numpy 矢量化/ cythonise。或者直接使用 numba 中的 @njit
def matrixexponen(n,a):
q = 6
a2 = a.copy ( )
a_norm = np.linalg.norm ( a2, np.inf )
ee = ( int ) ( np.log2 ( a_norm ) ) + 1
s = max ( 0, ee + 1 )
a2 = a2 / ( 2.0 ** s )
x = a2.copy ( )
c = 0.5
e = np.eye ( n, dtype = np.complex64 ) + c * a2
d = np.eye ( n, dtype = np.complex64 ) - c * a2
p = True
for k in range ( 2, q + 1 ):
c = c * float ( q - k + 1 ) / float ( k * ( 2 * q - k + 1 ) )
x = np.dot ( a2, x )
e = e + c * x
if ( p ):
d = d + c * x
else:
d = d - c * x
p = not p
# E -> inverse(D) * E
e = np.linalg.solve ( d, e )
# E -> E^(2*S)
for k in range ( 0, s ):
e = np.dot ( e, e )
return e