예제 #1
0
 def fit(self, X, Y, Kin=None, return_cputime=False):
     # Memorize training input data
     self.X = X
     # Compute mean func from output data
     self.Ymean = disc_fd.mean_func(*Y)
     # Center discrete output data if relevant and put it in discrete general form
     if self.center_output:
         Ycentered = disc_fd.center_discrete(*Y, self.Ymean)
         Ycentered = disc_fd.to_discrete_general(*Ycentered)
     else:
         Ycentered = disc_fd.to_discrete_general(*Y)
     # Extract functions from centered output data using linear interpolation
     smoother_out = smoothing.LinearInterpSmoother()
     smoother_out.fit(*Ycentered)
     Yfunc = smoother_out.get_functions()
     # Evaluate those functions on the discretization grid
     Yeval = np.array([f(self.approx_locs) for f in Yfunc])
     # Compute input kernel matrix
     if Kin is None:
         Kin = self.kernel_in(X, X)
     # Compute representer coefficients
     n = len(X)
     m = self.Kout.shape[0]
     start = time.process_time()
     self.alpha = sb04qd(n, m, Kin / (self.regu * n), self.Kout, Yeval / (self.regu * n))
     end = time.process_time()
     if return_cputime:
         return end - start
예제 #2
0
 def fit(self, X, Y, K=None):
     self.X = X
     if K is not None:
         self.K = K
     else:
         self.K = self.kernel(X, X)
     n = len(X)
     m = len(self.B)
     self.alpha = sb04qd(n, m, self.K / (self.regu * n), self.B, Y / (self.regu * n))
예제 #3
0
def solve_sylvester(A,B,C,D,Ainv = None,method='linear'):
    # Solves equation : A X + B X [C,...,C] + D = 0
    # where X is a multilinear function whose dimension is determined by D
    # inverse of A can be optionally specified as an argument

    n_d = D.ndim - 1
    n_v = C.shape[1]

    n_c = D.size//n_v**n_d

#    import dolo.config
#    opts = dolo.config.use_engine
#    if opts['sylvester']:
#        DD = D.flatten().reshape( n_c, n_v**n_d)
#        [err,XX] = dolo.config.engine.engine.feval(2,'gensylv',n_d,A,B,C,-DD)
#        X = XX.reshape( (n_c,)+(n_v,)*(n_d))

    DD = D.reshape( n_c, n_v**n_d )

    if n_d == 1:
        CC = C
    else:
        CC = np.kron(C,C)
    for i in range(n_d-2):
        CC = np.kron(CC,C)

    if method=='linear':
        I = np.eye(CC.shape[0])
        XX = solve_sylvester_vectorized((A,I),(B,CC),DD)

    else:
        # we use slycot by default
        import slycot

        if Ainv != None:
            Q = sdot(Ainv,B)
            S = sdot(Ainv,DD)
        else:
            Q = np.linalg.solve(A,B)
            S = np.linalg.solve(A,DD)

        n = n_c
        m = n_v**n_d

        XX = slycot.sb04qd(n,m,Q,CC,-S)

    X = XX.reshape( (n_c,)+(n_v,)*(n_d) )

    return X
예제 #4
0
def solve_sylvester(A, B, C, D, Ainv=None, method="linear"):
    # Solves equation : A X + B X [C,...,C] + D = 0
    # where X is a multilinear function whose dimension is determined by D
    # inverse of A can be optionally specified as an argument

    n_d = D.ndim - 1
    n_v = C.shape[1]

    n_c = D.size // n_v**n_d

    #    import dolo.config
    #    opts = dolo.config.use_engine
    #    if opts['sylvester']:
    #        DD = D.flatten().reshape( n_c, n_v**n_d)
    #        [err,XX] = dolo.config.engine.engine.feval(2,'gensylv',n_d,A,B,C,-DD)
    #        X = XX.reshape( (n_c,)+(n_v,)*(n_d))

    DD = D.reshape(n_c, n_v**n_d)

    if n_d == 1:
        CC = C
    else:
        CC = np.kron(C, C)
    for i in range(n_d - 2):
        CC = np.kron(CC, C)

    if method == "linear":
        I = np.eye(CC.shape[0])
        XX = solve_sylvester_vectorized((A, I), (B, CC), DD)

    else:
        # we use slycot by default
        import slycot

        if Ainv != None:
            Q = sdot(Ainv, B)
            S = sdot(Ainv, DD)
        else:
            Q = np.linalg.solve(A, B)
            S = np.linalg.solve(A, DD)

        n = n_c
        m = n_v**n_d

        XX = slycot.sb04qd(n, m, Q, CC, -S)

    X = XX.reshape((n_c, ) + (n_v, ) * (n_d))

    return X
예제 #5
0
def dlyap(A,Q,C=None,E=None):
    """ dlyap(A,Q) solves the discrete-time Lyapunov equation

        A X A^T - X + Q = 0

    where A and Q are square matrices of the same dimension. Further
    Q must be symmetric.

    dlyap(A,Q,C) solves the Sylvester equation

        A X Q^T - X + C = 0

    where A and Q are square matrices.

    dlyap(A,Q,None,E) solves the generalized discrete-time Lyapunov
    equation

        A X A^T - E X E^T + Q = 0

    where Q is a symmetric matrix and A, Q and E are square matrices
    of the same dimension. """

    # Make sure we have access to the right slycot routines
    try:
        from slycot import sb03md
    except ImportError:
        raise ControlSlycot("can't find slycot module 'sb03md'")

    try:
        from slycot import sb04qd
    except ImportError:
        raise ControlSlycot("can't find slycot module 'sb04qd'")

    try:
        from slycot import sg03ad
    except ImportError:
        raise ControlSlycot("can't find slycot module 'sg03ad'")

    # Reshape 1-d arrays
    if len(shape(A)) == 1:
        A = A.reshape(1,A.size)

    if len(shape(Q)) == 1:
        Q = Q.reshape(1,Q.size)

    if C != None and len(shape(C)) == 1:
        C = C.reshape(1,C.size)

    if E != None and len(shape(E)) == 1:
        E = E.reshape(1,E.size)

    # Determine main dimensions
    if size(A) == 1:
        n = 1
    else:
        n = size(A,0)

    if size(Q) == 1:
        m = 1
    else:
        m = size(Q,0)

    # Solve standard Lyapunov equation
    if C==None and E==None:
        # Check input data for consistency
        if shape(A) != shape(Q):
            raise ControlArgument("A and Q must be matrices of identical \
                                 sizes.")

        if size(A) > 1 and shape(A)[0] != shape(A)[1]:
            raise ControlArgument("A must be a quadratic matrix.")

        if size(Q) > 1 and shape(Q)[0] != shape(Q)[1]:
            raise ControlArgument("Q must be a quadratic matrix.")

        if not (asarray(Q) == asarray(Q).T).all():
            raise ControlArgument("Q must be a symmetric matrix.")

        # Solve the Lyapunov equation by calling the Slycot function sb03md
        try:
            X,scale,sep,ferr,w = sb03md(n,-Q,A,eye(n,n),'D',trana='T')
        except ValueError(ve):
            if ve.info < 0:
                e = ValueError(ve.message)
                e.info = ve.info
            else:
                e = ValueError("The QR algorithm failed to compute all the \
                    eigenvalues (see LAPACK Library routine DGEES).")
                e.info = ve.info
            raise e

    # Solve the Sylvester equation
    elif C != None and E==None:
        # Check input data for consistency
        if size(A) > 1 and shape(A)[0] != shape(A)[1]:
            raise ControlArgument("A must be a quadratic matrix")

        if size(Q) > 1 and shape(Q)[0] != shape(Q)[1]:
            raise ControlArgument("Q must be a quadratic matrix")

        if (size(C) > 1 and shape(C)[0] != n) or \
            (size(C) > 1 and shape(C)[1] != m) or \
            (size(C) == 1 and size(A) != 1) or (size(C) == 1 and size(Q) != 1):
            raise ControlArgument("C matrix has incompatible dimensions")

        # Solve the Sylvester equation by calling Slycot function sb04qd
        try:
            X = sb04qd(n,m,-A,asarray(Q).T,C)
        except ValueError(ve):
            if ve.info < 0:
                e = ValueError(ve.message)
                e.info = ve.info
            elif ve.info > m:
                e = ValueError("A singular matrix was encountered whilst \
                    solving for the %i-th column of matrix X." % ve.info-m)
                e.info = ve.info
            else:
                e = ValueError("The QR algorithm failed to compute all the \
                    eigenvalues (see LAPACK Library routine DGEES)")
                e.info = ve.info
            raise e

    # Solve the generalized Lyapunov equation
    elif C == None and E != None:
        # Check input data for consistency
        if (size(Q) > 1 and shape(Q)[0] != shape(Q)[1]) or \
            (size(Q) > 1 and shape(Q)[0] != n) or \
            (size(Q) == 1 and n > 1):
            raise ControlArgument("Q must be a square matrix with the same \
                dimension as A.")

        if (size(E) > 1 and shape(E)[0] != shape(E)[1]) or \
            (size(E) > 1 and shape(E)[0] != n) or \
            (size(E) == 1 and n > 1):
            raise ControlArgument("E must be a square matrix with the same \
                dimension as A.")

        if not (asarray(Q) == asarray(Q).T).all():
            raise ControlArgument("Q must be a symmetric matrix.")

        # Solve the generalized Lyapunov equation by calling Slycot 
        # function sg03ad
        try:
            A,E,Q,Z,X,scale,sep,ferr,alphar,alphai,beta = \
                sg03ad('D','B','N','T','L',n,A,E,eye(n,n),eye(n,n),-Q)
        except ValueError(ve):
            if ve.info < 0 or ve.info > 4:
                e = ValueError(ve.message)
                e.info = ve.info
            elif ve.info == 1:
                e = ValueError("The matrix contained in the upper \
                                Hessenberg part of the array A is not in \
                                upper quasitriangular form")
                e.info = ve.info
            elif ve.info == 2:
                e = ValueError("The pencil A - lambda * E cannot be \
                                reduced to generalized Schur form: LAPACK \
                                routine DGEGS has failed to converge")
                e.info = ve.info
            elif ve.info == 3:
                e = ValueError("The pencil A - lambda * E has a \
                                pair of reciprocal eigenvalues. That is, \
                                lambda_i = 1/lambda_j for some i and j, \
                                where  lambda_i and lambda_j are eigenvalues \
                                of A - lambda * E. Hence, the equation is \
                                singular;  perturbed values were \
                                used to solve the equation (but the \
                                matrices A and E are unchanged)")
                e.info = ve.info
            raise e
    # Invalid set of input parameters    
    else:
        raise ControlArgument("Invalid set of input parameters")

    return X