示例#1
0
def _expm_pade3(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (120., 60., 12., 1.)
    A2 = dot(A, A)
    U = dot(A, b[3]*A2 + b[1]*ident)
    V = b[2]*A2 + b[0]*ident
    return U,V
示例#2
0
def _expm_pade3(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (120., 60., 12., 1.)
    A2 = dot(A, A)
    U = dot(A, b[3]*A2 + b[1]*ident)
    V = b[2]*A2 + b[0]*ident
    return U,V
示例#3
0
def _expm_pade5(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (30240., 15120., 3360., 420., 30., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    U = dot(A, b[5]*A4 + b[3]*A2 + b[1]*ident)
    V = b[4]*A4 + b[2]*A2 + b[0]*ident
    return U,V
示例#4
0
def _expm_pade5(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (30240., 15120., 3360., 420., 30., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    U = dot(A, b[5]*A4 + b[3]*A2 + b[1]*ident)
    V = b[4]*A4 + b[2]*A2 + b[0]*ident
    return U,V
示例#5
0
def _expm_pade7(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (17297280., 8648640., 1995840., 277200., 25200., 1512., 56., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    A6 = dot(A2, A4)
    U = dot(A, b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*ident)
    V = b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*ident
    return U, V
示例#6
0
def _expm_pade7(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (17297280., 8648640., 1995840., 277200., 25200., 1512., 56., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    A6 = dot(A2, A4)
    U = dot(A, b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*ident)
    V = b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*ident
    return U, V
示例#7
0
def _expm_pade9(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (17643225600., 8821612800., 2075673600., 302702400., 30270240.,
            2162160., 110880., 3960., 90., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    A6 = dot(A2, A4)
    A8 = dot(A2, A6)
    U = dot(A, b[9]*A8 + b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*ident)
    V = b[8]*A8 + b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*ident
    return U,V
示例#8
0
def _expm_pade9(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (17643225600., 8821612800., 2075673600., 302702400., 30270240.,
            2162160., 110880., 3960., 90., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    A6 = dot(A2, A4)
    A8 = dot(A2, A6)
    U = dot(A, b[9]*A8 + b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*ident)
    V = b[8]*A8 + b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*ident
    return U,V
示例#9
0
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
示例#10
0
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
示例#11
0
def _expm_pade13(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (
            64764752532480000., 32382376266240000., 7771770303897600.,
            1187353796428800., 129060195264000., 10559470521600.,
            670442572800., 33522128640., 1323241920.,
            40840800., 960960., 16380., 182., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    A6 = dot(A2, A4)
    U = dot(A,
            dot(A6, b[13]*A6 + b[11]*A4 + b[9]*A2) + (
                b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*ident))
    V = dot(A6, b[12]*A6 + b[10]*A4 + b[8]*A2) + (
            b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*ident)
    return U, V
示例#12
0
def _expm_pade13(A, ident):
    """ Helper function for Pade approximation of expm.
    """
    b = (
            64764752532480000., 32382376266240000., 7771770303897600.,
            1187353796428800., 129060195264000., 10559470521600.,
            670442572800., 33522128640., 1323241920.,
            40840800., 960960., 16380., 182., 1.)
    A2 = dot(A, A)
    A4 = dot(A2, A2)
    A6 = dot(A2, A4)
    U = dot(A,
            dot(A6, b[13]*A6 + b[11]*A4 + b[9]*A2) + (
                b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*ident))
    V = dot(A6, b[12]*A6 + b[10]*A4 + b[8]*A2) + (
            b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*ident)
    return U, V
示例#13
0
def f(A,x):
    for n in range(3):
        y = dot(x.T,dot(A,x))
        A = A - dot(x,x.T) * y
        
    return trace(A)
示例#14
0
def svd(A, epsilon=1e-8):
    """
    computes the singular value decomposition A = U S V.T
    of matrices A with full rank (i.e. nonzero singular values)
    by reformulation to eigh.

    (U, S, VT) = UTPM.svd(A, epsilon= 1e-8)

    Parameters
    ----------

    A: array_like
        input array (numpy.ndarray, algopy.UTPM or algopy.Function instance)

    epsilon:   float
        threshold to evaluate the rank of A

    Implementation
    --------------

    The singular value decomposition is directly related to the symmetric
    eigenvalue decomposition.

    See A. Bjoerk, Numerical Methods for Least Squares Problems, SIAM, 1996
    for the relation between SVD and symm. eigenvalue decomposition

    and S. F. Walter, Structured Higher-Order Algorithmic Differentiation
    in the Forward and Reverse Mode with Application in Optimum Experimental
    Design, PhD thesis, 2011
    for the Taylor polynomial arithmetic.

    """

    M,N = A.shape

    if N > M:
        raise NotImplementedError("A.shape = (M,N) and N > M is not supported (yet)")

    # real symmetric eigenvalue decomposition

    B = zeros((M+N, M+N),dtype=A)
    B[:M,M:] = A
    B[M:,:M] = A.T
    l,Q = eigh(B, epsilon=epsilon)


    # compute the rank
    r = 0
    for i in range(N):
        if abs(l[i]) > epsilon:
            r = i+1

    if r < N:
        raise NotImplementedError('rank deficient matrices are not supported')

    # permutation matrix

    tmp  = [M+N-1 - i for i in range(r)] + [i for i in range(r)]
    tmp += [M+N-1-r-i for i in range(N-r)] + [N-1+i for i in range(N-r)]
    tmp += [N+i for i in range(M-N)]
    P = numpy.eye(M+N)
    P = P[tmp]


    # bring Q into the required format

    Q = dot(Q, P.T)


    # find U S V.T

    U = zeros((M,M), dtype=Q)
    V = zeros((N,N), dtype=Q)

    U[:,:r] = 2.**0.5*Q[:M,:r]
    U[:,r:] = Q[:M, 2*r: r+M]
    V[:,:r] = 2.**0.5*Q[M:,:r]
    V[:,r:] = Q[M:,r+M:]
    s = -l[:N]

    return U, s, V
示例#15
0
def f(A,x):
    for n in range(3):
        y = dot(x.T,dot(A,x))
        A = A - dot(x,x.T) * y
        
    return trace(A)