vectorized computation of many matrix exponentials

Question:

I have many 2-by-2 matrices, A, A.shape == (2, 2, 7324), and I have to compute the matrix exponential of all of those. Unfortunately, scipy.linalg.expm only accepts one matrix at a time such that I’d have to loop over the computations,

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)

Is there a way to avoid this loop?

Edit: The corresponding scipy bug: #12838

Asked By: Nico Schlömer

||

Answers:

From glancing over the code, https://github.com/scipy/scipy/blob/v1.4.1/scipy/sparse/linalg/matfuncs.py#L550-L595
it seems that it really only assumes a single matrix. Therefore, if you want to avoid a python loop, you’ll need to extract the relevant parts and either cythonize or numpy-vectorize them yourselves. Only catering to dense matrices can make it easier.

Answered By: ev-br

here’s the code for the pade approximation. This is just for 1 array, you’ll have to numpy vectorise/ cythonise it. or just use @njit from numba

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
Answered By: R K Rupesh

As of SciPy release 1.9.0 (released in July 28, 22), you can pass scipy.linalg.expm an array where the last two dimensions are square—that is, an array with shape (..., n, n)—and it will compute the matrix exponential
in a vectorized fashion.

The documentation is here.

Answered By: Jonathan Jeffrey
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.