def expm_higham_2005(A): """ Compute the matrix exponential using the method of Higham 2005. N. J. Higham, "The Scaling and Squaring Method for the Matrix Exponential Revisited", SIAM. J. Matrix Anal. & Appl. 26, 1179 (2005). """ n_squarings = 0 # FIXME: is there an algopy norm implementation? A_L1 = numpy.linalg.norm(A, 1) ident = numpy.eye(A.shape[0]) if A_L1 < 1.495585217958292e-002: U,V = _expm_pade3(A, ident) elif A_L1 < 2.539398330063230e-001: U,V = _expm_pade5(A, ident) elif A_L1 < 9.504178996162932e-001: U,V = _expm_pade7(A, ident) elif A_L1 < 2.097847961257068e+000: U,V = _expm_pade9(A, ident) else: maxnorm = 5.371920351148152 # FIXME: this should probably use algopy log, # and algopy max and ceil if they exist. n_squarings = max(0, int(math.ceil(math.log(A_L1 / maxnorm, 2)))) A /= 2**n_squarings U, V = _expm_pade13(A, ident) R = solve(-U + V, U + V) for i in range(n_squarings): R = dot(R, R) return R
def expm_pade(A, q): """ Compute the matrix exponential using a fixed-order Pade approximation. """ q_to_pade = { 3 : _expm_pade3, 5 : _expm_pade5, 7 : _expm_pade7, 9 : _expm_pade9, 13 : _expm_pade13, } pade = q_to_pade[q] ident = numpy.eye(A.shape[0]) U, V = pade(A, ident) return solve(-U + V, U + V)