def _solve_P_Q(U, V, structure=None): """ A helper function for expm_2009. Parameters ---------- U : ndarray Pade numerator. V : ndarray Pade denominator. structure : str, optional A string describing the structure of both matrices `U` and `V`. Only `upper_triangular` is currently supported. Notes ----- The `structure` argument is inspired by similar args for theano and cvxopt functions. """ P = U + V Q = -U + V if isspmatrix(U): return spsolve(Q, P) elif structure is None: return solve(Q, P) elif structure == UPPER_TRIANGULAR: return solve_triangular(Q, P) else: raise ValueError('unsupported matrix structure: ' + str(structure))
def _solve_P_Q(U, V): """ A helper function for expm_2009. """ P = U + V Q = -U + V if isspmatrix(U): R = spsolve(Q, P) else: R = solve(Q, P) return R
def generate(src, dst): """ Function to generate the distortion parameters between the source and the destination. The name of the variables are the same as in the original article. """ n = src.shape[0] # Variables as defined by Bookstein K = U(cdist(src, src, metric="euclidean")) P = np.hstack((np.ones((n, 1)), src)) L = np.vstack((np.hstack((K, P)), np.hstack((P.T, np.zeros((3, 3)))))) V = np.hstack((dst.T, np.zeros((2, 3)))) # Matrix system solving Wa = solve(L, V.T) W = Wa[:-3, :] a = Wa[-3:, :] WK = np.dot(W.T, K) WKW = np.dot(WK, W) be = max(0.5 * np.trace(WKW), 0) # Implementation of other variables not present in the original publication surfaceratio = (a[1, 0] * a[2, 1]) - (a[2, 0] * a[1, 1]) scale = np.sqrt(np.abs(surfaceratio)) mirror = surfaceratio < 0 shearing = angle_between(Wa[-2:, 0], Wa[-2:, 1], True) # Prepare the return dictionary src = src.tolist() dst = dst.tolist() W = W.tolist() a = a.tolist() return { 'src': src, 'dst': dst, 'linear': a, 'scale': scale, 'mirror': mirror, 'shearing': shearing, 'weights': W, 'be': be }
def expm(A): """ Compute the matrix exponential using Pade approximation. .. versionadded:: 0.12.0 Parameters ---------- A : (M,M) array or sparse matrix 2D Array or Matrix (sparse or dense) to be exponentiated Returns ------- expA : (M,M) ndarray Matrix exponential of `A` References ---------- N. J. Higham, "The Scaling and Squaring Method for the Matrix Exponential Revisited", SIAM. J. Matrix Anal. & Appl. 26, 1179 (2005). """ n_squarings = 0 Aissparse = isspmatrix(A) if Aissparse: A_L1 = max(abs(A).sum(axis=0).flat) ident = speye(A.shape[0], A.shape[1], dtype=A.dtype, format=A.format) else: A = asarray(A) A_L1 = norm(A, 1) ident = eye(A.shape[0], A.shape[1], dtype=A.dtype) if A.dtype == 'float64' or A.dtype == 'complex128': if A_L1 < 1.495585217958292e-002: U, V = _pade3(A, ident) elif A_L1 < 2.539398330063230e-001: U, V = _pade5(A, ident) elif A_L1 < 9.504178996162932e-001: U, V = _pade7(A, ident) elif A_L1 < 2.097847961257068e+000: U, V = _pade9(A, ident) else: maxnorm = 5.371920351148152 n_squarings = max(0, int(ceil(log2(A_L1 / maxnorm)))) A = A / 2**n_squarings U, V = _pade13(A, ident) elif A.dtype == 'float32' or A.dtype == 'complex64': if A_L1 < 4.258730016922831e-001: U, V = _pade3(A, ident) elif A_L1 < 1.880152677804762e+000: U, V = _pade5(A, ident) else: maxnorm = 3.925724783138660 n_squarings = max(0, int(ceil(log2(A_L1 / maxnorm)))) A = A / 2**n_squarings U, V = _pade7(A, ident) else: raise ValueError("invalid type: " + str(A.dtype)) P = U + V # p_m(A) : numerator Q = -U + V # q_m(A) : denominator if Aissparse: from scipy.sparse.linalg import spsolve R = spsolve(Q, P) else: R = solve(Q, P) # squaring step to undo scaling for i in range(n_squarings): R = R.dot(R) return R
def expm(A): """Compute the matrix exponential using Pade approximation. .. versionadded:: 0.12.0 Parameters ---------- A : array or sparse matrix, shape(M,M) 2D Array or Matrix (sparse or dense) to be exponentiated Returns ------- expA : array, shape(M,M) Matrix exponential of A References ---------- N. J. Higham, "The Scaling and Squaring Method for the Matrix Exponential Revisited", SIAM. J. Matrix Anal. & Appl. 26, 1179 (2005). """ n_squarings = 0 Aissparse = isspmatrix(A) if Aissparse: A_L1 = max(abs(A).sum(axis=0).flat) ident = speye(A.shape[0], A.shape[1], dtype=A.dtype, format=A.format) else: A = asarray(A) A_L1 = norm(A,1) ident = eye(A.shape[0], A.shape[1], dtype=A.dtype) if A.dtype == 'float64' or A.dtype == 'complex128': if A_L1 < 1.495585217958292e-002: U,V = _pade3(A, ident) elif A_L1 < 2.539398330063230e-001: U,V = _pade5(A, ident) elif A_L1 < 9.504178996162932e-001: U,V = _pade7(A, ident) elif A_L1 < 2.097847961257068e+000: U,V = _pade9(A, ident) else: maxnorm = 5.371920351148152 n_squarings = max(0, int(ceil(log2(A_L1 / maxnorm)))) A = A / 2**n_squarings U,V = _pade13(A, ident) elif A.dtype == 'float32' or A.dtype == 'complex64': if A_L1 < 4.258730016922831e-001: U,V = _pade3(A, ident) elif A_L1 < 1.880152677804762e+000: U,V = _pade5(A, ident) else: maxnorm = 3.925724783138660 n_squarings = max(0, int(ceil(log2(A_L1 / maxnorm)))) A = A / 2**n_squarings U,V = _pade7(A, ident) else: raise ValueError("invalid type: "+str(A.dtype)) P = U + V # p_m(A) : numerator Q = -U + V # q_m(A) : denominator if Aissparse: from scipy.sparse.linalg import spsolve R = spsolve(Q, P) else: R = solve(Q,P) # squaring step to undo scaling for i in range(n_squarings): R = R.dot(R) return R