Example #1
0
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))
Example #2
0
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))
Example #3
0
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
Example #4
0
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
Example #5
0
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
    }
Example #6
0
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
Example #7
0
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