许多矩阵指数的矢量化计算

时间:2020-02-02 23:52:49

标签: python scipy

我有许多2×2矩阵,AA.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)

有办法避免这种循环吗?

2 个答案:

答案 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