Example #1
0
    def fit(self, X, y):
        """Fit OVK ridge regression model.

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape = [n_samples, n_features]
            Training data.

        y : {array-like}, shape = [n_samples] or [n_samples, n_targets]
            Target values. numpy.NaN for missing targets (semi-supervised
            learning).

        Returns
        -------
        self : returns an instance of self.
        """
        X = check_array(X, force_all_finite=True, accept_sparse=False,
                        ensure_2d=True)
        y = check_array(y, force_all_finite=False, accept_sparse=False,
                        ensure_2d=False)
        if y.ndim == 1:
            y = check_array(y, force_all_finite=True, accept_sparse=False,
                            ensure_2d=False)
        self._validate_params()

        self.linop_ = self._get_kernel_map(X, y)
        Gram = self.linop_._Gram(X)
        if self.lbda > 0:
            self.dual_coefs_ = dlyap(-Gram / self.lbda, self.linop_.A,
                                     y / self.lbda)
        else:
            # TODO: Check A is invertible!!
            self.dual_coefs_ = solve(Gram, y)
        return self
Example #2
0
 def fit(self, X, Y, K=None):
     self.X = X
     if K is not None:
         self.K = K
     else:
         self.K = self.k.compute_K(X)
     n = X.shape[0]
     self.alpha = dlyap(-self.K/(self.lamb * n), self.B.T, Y/(self.lamb * n))
    def __init__(self,
                 plant: LinearPlant,
                 controller: LinearController,
                 h=None,
                 P=None,
                 Q=None,
                 kmin=1,
                 kmax=50):
        super().__init__(plant, controller, P, Q)

        assert controller.is_discrete_time, \
            'Controller needs to be discrete-time'

        self.kmin = kmin
        if h is None:
            h = controller.h
        self.h = h
        if kmax is not None:
            self.kmax = kmax
        else:
            self.kmax = 50
        '''If provided P matrix is not a valid continuous-time Lyapunov
        matrix, for PETC it also suffices that it is a valid discrete-time
        Lyapunov matrix. The same goes even if the continuous-time controller
        is unstable. (TBP/TBC)
        '''
        nx = plant.nx
        p = PeriodicLinearController(plant, controller, h=h * kmin, P=P)
        controller.h = h  # Revert back because the statement above changed it
        Phi = p.Phi

        # Get/make Lyapunov info
        P = self.P
        if not is_positive_definite(P):
            if Q is None:
                Q = np.eye(nx)
            else:
                assert (Q == Q.T).all() and is_positive_definite(Q), \
                    'Q must be symmetric positive definite'
            P = ct.dlyap(Phi.T, Q)
            assert (P == P.T).all() and is_positive_definite(P), \
                'Closed-loop system is not stable'
        else:  # P is good in continuous time
            assert (P == P.T).all() and is_positive_definite(P), \
                'Provided P matrix is not symmetric positive definite'
            if Q is None:
                Q = -(Phi.T @ P @ Phi - P)
                assert is_positive_definite(Q), \
                    'Provided P matrix is not a Lyapunov matrix'
            else:
                assert (Phi.T @ P @ Phi - P == -Q).all(), \
                    'Provided P and Q do not satisfy the discrete-time' \
                    ' Lyapunov equation'
        self.P = P
        self.Qd = Q  # Qd for the discrete-time
        self.Phi = Phi
        self.Ad = p.Ad
        self.Bd = p.Bd
Example #4
0
def _se_do(A_wave1, A_wave2, lmda):
    from control import dlyap
    S = lmda * A_wave2
    T_t = A_wave1
    # use uniform distribution if there is no prior knowledge.
    nb_pd = len(A_wave1) * len(A_wave2)
    p_times_uni = 1 / nb_pd
    M0 = np.full((len(A_wave2), len(A_wave1)), p_times_uni)
    X = dlyap(S, T_t, M0)
    X = np.reshape(X, (-1, 1), order='F')
    # use uniform distribution if there is no prior knowledge.
    q_times = np.full((1, nb_pd), p_times_uni)
    return np.dot(q_times, X)
Example #5
0
 def sylv_eq_kernel(self, A1, A2):
     """ 
     Sylvester equation Methods (lyapunov)
     O(n^3)
     for graph with no labels only : else implement "COMPUTATION OF THE CANONICAL DECOMPOSITION BYMEANS OF A SIMULTANEOUS GENERALIZED SCHURDECOMPOSITION∗"
     with https://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.linalg.qz.html
     """
     #https://python-control.readthedocs.io/en/0.8.0/generated/control.dlyap.html
     #resoudre AXQt - X + C
     n1 = A1.shape[0]
     n2 = A2.shape[0]
     #in case the matrix is empty i add a diagonal, works great
     A1 = (A1 + A1.T) / 2 + np.eye(n1) * 1e1
     A2 = (A2 + A2.T) / 2 + np.eye(n2) * 1e1
     n = A1.shape[0] * A2.shape[0]
     px = np.ones((n, 1)) / n
     qx = np.ones((n, 1)) / n
     M = dlyap(A=self.lbd * A1,
               Q=A2,
               C=px.reshape((A1.shape[0], A2.shape[0])))
     return -1 * np.asscalar(qx.T @ M.reshape((-1, 1)))
Example #6
0
def FitLTSParamsSSID(seq, xDim, varagin=None):

    algo = 'SVD'
    hS = xDim
    minFanoFactor = 1.01
    minEig = 0.0001
    params = dict
    saveHankel = 0
    doNonlinTransf = 0
    useB = 0

    yall = seq['y']
    yDim, allT = yall.shape
    minMoment = 5 / allT
    '''
    extraOptsIn     = assignopts(who, varargin)
    '''

    print('Fitting data with LDS-SSID')
    print('---------------------------')
    print('using HankelSize = %i\n', hS)
    print('useB = %i \n', useB)
    print('doNonlinTransform = %i \n', doNonlinTransf)

    if useB: algo = 'n4SID'

    SIGfp, SIGff, SIGpp, _ = generateCovariancesFP.generateCovariancesFP(
        seq, hS)

    mu = np.mean(yall, axis=1)
    muBig = np.tile(mu, 2 * hS)
    gammaBig = muBig

    SIGBig = np.r_[np.c_[np.copy(SIGff), np.copy(SIGfp)],
                   np.c_[np.copy(SIGfp.T), np.copy(SIGpp)]]

    SIGyy = SIGBig[:yDim, :yDim]
    SIGfp = SIGBig[:yDim * hS, yDim * hS:]
    SIGff = SIGBig[:yDim * hS, :yDim * hS]
    SIGpp = SIGBig[yDim * hS:, yDim * hS:]

    SIGBig = np.r_[np.c_[SIGff, SIGfp], np.c_[SIGfp.T, SIGpp]]
    params = {'d': gammaBig[:yDim]}

    if algo == 'SVD':

        print('PPLDSID: Using SVD with hS %d \n', hS)

        A, C, Q, R, Q0 = ssidSVD.ssidSVD(SIGfp, SIGyy, xDim)
        params.update({
            'A': A,
            'C': C,
            'Q': Q,
            'R': R,
            'Q0': Q0,
        })

    else:
        print('Not implemented')

    if isinstance(params['Q'], complex):
        params['Q'] = np.real(params['Q'])

    params['Q'] = (params['Q'] + params['Q'].T) / 2

    if np.min(np.linalg.eig(params['Q'])[0]) < 0:

        a, b = np.linalg.eig(params['Q'])
        params['Q'] = a * np.max(b, 10**-10) * a.T

    if 'Q0' not in params:
        params['Q0'] = np.real(control.dlyap(params['A'], params['Q']))

    params.update({'x0': np.zeros(xDim)})
    params['R'] = np.diag(np.diag(params['R']))

    if saveHankel:
        params.SIGBig = SIGBig

    print('Done!')
    return params, SIGBig