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
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
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)
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)))
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