def sample_transition_full_rank(model, state, hyperparams, pseudo_dof=None, pseudo_sd=None): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance with full rank model """ Q = model.transition_covariance() # Sampke a pseudo-observation to constrain the size of move if pseudo_dof is not None: extra_nu = pseudo_dof extra_Psi = smp.sample_wishart(pseudo_dof, Q) else: extra_nu = 0 extra_Psi = 0 # Calculate sufficient statistics suffStats = smp.evaluate_transition_sufficient_statistics(state) # Sample a new projected transition matrix and transition covariance nu0 = model.ds + extra_nu Psi0 = model.ds*hyperparams['rPsi0'] + extra_Psi nu,Psi,M,V = smp.hyperparam_update_basic_mniw_transition( suffStats, nu0, Psi0, hyperparams['M0'], hyperparams['V0']) Q = la.inv(smp.sample_wishart(nu, la.inv(Psi))) F = smp.sample_matrix_normal(M, Q, V) model.parameters['F'] = F model.parameters['Q']= Q return model
def sample_transition_within_subspace(model, state, hyperparams): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance within the constrained subspace """ # Calculate sufficient statistics suffStats = smp.evaluate_transition_sufficient_statistics(state) # Convert to Givens factorisation form U, D = model.convert_to_givens_form() # Sample a new projected transition matrix and transition covariance rank = model.parameters['rank'][0] nu0 = rank Psi0 = rank * hyperparams['rPsi0'] nu, Psi, M, V = smp.hyperparam_update_degenerate_mniw_transition( suffStats, U, nu0, Psi0, hyperparams['M0'], hyperparams['V0']) D = la.inv(smp.sample_wishart(nu, la.inv(Psi))) FU = smp.sample_matrix_normal(M, D, V) # Project out Fold = model.parameters['F'] F = smp.project_degenerate_transition_matrix(Fold, FU, U) model.parameters['F'] = F # Convert back to eigen-decomposition form model.update_from_givens_form(U, D) return model
def sample_transition_within_subspace(model, state, hyperparams): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance within the constrained subspace """ # Calculate sufficient statistics suffStats = smp.evaluate_transition_sufficient_statistics(state) # Convert to Givens factorisation form U,D = model.convert_to_givens_form() # Sample a new projected transition matrix and transition covariance rank = model.parameters['rank'][0] nu0 = rank Psi0 = rank*hyperparams['rPsi0'] nu,Psi,M,V = smp.hyperparam_update_degenerate_mniw_transition( suffStats, U, nu0, Psi0, hyperparams['M0'], hyperparams['V0']) D = la.inv(smp.sample_wishart(nu, la.inv(Psi))) FU = smp.sample_matrix_normal(M, D, V) # Project out Fold = model.parameters['F'] F = smp.project_degenerate_transition_matrix(Fold, FU, U) model.parameters['F'] = F # Convert back to eigen-decomposition form model.update_from_givens_form(U, D) return model
def sample_transition_full_rank(model, state, hyperparams, pseudo_dof=None, pseudo_sd=None): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance with full rank model """ Q = model.transition_covariance() # Sampke a pseudo-observation to constrain the size of move if pseudo_dof is not None: extra_nu = pseudo_dof extra_Psi = smp.sample_wishart(pseudo_dof, Q) else: extra_nu = 0 extra_Psi = 0 # Calculate sufficient statistics suffStats = smp.evaluate_transition_sufficient_statistics(state) # Sample a new projected transition matrix and transition covariance nu0 = model.ds + extra_nu Psi0 = model.ds * hyperparams['rPsi0'] + extra_Psi nu, Psi, M, V = smp.hyperparam_update_basic_mniw_transition( suffStats, nu0, Psi0, hyperparams['M0'], hyperparams['V0']) Q = la.inv(smp.sample_wishart(nu, la.inv(Psi))) F = smp.sample_matrix_normal(M, Q, V) model.parameters['F'] = F model.parameters['Q'] = Q return model
def sample_transition(self): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance """ # Calculate sufficient statistics using current state trajectory suffStats = smp.evaluate_transition_sufficient_statistics(self.state) # Update hyperparameters nu,Psi,M,V = smp.hyperparam_update_basic_mniw_transition( suffStats, self.hyperparams['nu0'], self.hyperparams['Psi0'], self.hyperparams['M0'], self.hyperparams['V0']) # Sample new parameters Q = la.inv(smp.sample_wishart(nu, la.inv(Psi))) F = smp.sample_matrix_normal(M, Q, V) # Update the model self.model.parameters['F'] = F self.model.parameters['Q'] = Q # self.flt and self.lhood are no longer up-to-date self.filter_current = False
def sample_transition_within_subspace(model, state, hyperparams, pseudo_dof=None, pseudo_sd=None): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance within the constrained subspace """ # Calculate sufficient statistics suffStats = smp.evaluate_transition_sufficient_statistics(state) # Convert to Givens factorisation form U,D = model.convert_to_givens_form() # Sampke a pseudo-observation to constrain the size of move if pseudo_dof is not None: extra_nu = pseudo_dof extra_Psi = smp.sample_wishart(pseudo_dof, D) else: extra_nu = 0 extra_Psi = 0 # Sample a new projected transition matrix and transition covariance rank = model.parameters['rank'][0] nu0 = rank + extra_nu Psi0 = rank*hyperparams['rPsi0'] + np.dot(U, np.dot(extra_Psi, U.T)) nu,Psi,M,V = smp.hyperparam_update_degenerate_mniw_transition( suffStats, U, nu0, Psi0, hyperparams['M0'], hyperparams['V0']) D = la.inv(smp.sample_wishart(nu, la.inv(Psi))) FU = smp.sample_matrix_normal(M, D, V) # Project out Fold = model.parameters['F'] F = smp.project_degenerate_transition_matrix(Fold, FU, U) model.parameters['F'] = F # Convert back to eigen-decomposition form model.update_from_givens_form(U, D) return model
def sample_transition_within_subspace(model, state, hyperparams, pseudo_dof=None, pseudo_sd=None): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance within the constrained subspace """ # Calculate sufficient statistics suffStats = smp.evaluate_transition_sufficient_statistics(state) # Convert to Givens factorisation form U, D = model.convert_to_givens_form() # Sampke a pseudo-observation to constrain the size of move if pseudo_dof is not None: extra_nu = pseudo_dof extra_Psi = smp.sample_wishart(pseudo_dof, D) else: extra_nu = 0 extra_Psi = 0 # Sample a new projected transition matrix and transition covariance rank = model.parameters['rank'][0] nu0 = rank + extra_nu Psi0 = rank * hyperparams['rPsi0'] + np.dot(U, np.dot(extra_Psi, U.T)) nu, Psi, M, V = smp.hyperparam_update_degenerate_mniw_transition( suffStats, U, nu0, Psi0, hyperparams['M0'], hyperparams['V0']) D = la.inv(smp.sample_wishart(nu, la.inv(Psi))) FU = smp.sample_matrix_normal(M, D, V) # Project out Fold = model.parameters['F'] F = smp.project_degenerate_transition_matrix(Fold, FU, U) model.parameters['F'] = F # Convert back to eigen-decomposition form model.update_from_givens_form(U, D) return model
def sample_transition(self): """ MCMC iteration (Gibbs sampling) for transition matrix and covariance """ # Calculate sufficient statistics using current state trajectory suffStats = smp.evaluate_transition_sufficient_statistics(self.state) # Update hyperparameters nu, Psi, M, V = smp.hyperparam_update_basic_mniw_transition( suffStats, self.hyperparams['nu0'], self.hyperparams['Psi0'], self.hyperparams['M0'], self.hyperparams['V0']) # Sample new parameters Q = la.inv(smp.sample_wishart(nu, la.inv(Psi))) F = smp.sample_matrix_normal(M, Q, V) # Update the model self.model.parameters['F'] = F self.model.parameters['Q'] = Q # self.flt and self.lhood are no longer up-to-date self.filter_current = False
def sample_transition_matrix(self): """ MCMC iteration (Metropolis-Hastings) for transition matrix """ # Make sure there's a dictionary to store stats for this move type moveType = 'perturb' if moveType not in self.chain_accept: self.chain_accept[moveType] = [] if moveType not in self.chain_algoparams: self.chain_algoparams[moveType] = [] # Need to make sure the likelihood value is current if not self.filter_current: self.flt, _, self.lhood = self.model.kalman_filter(self.observ) self.filter_current = True # Copy model ppsl_model = self.model.copy() if self.verbose: print("Metropolis-Hastings move for transition matrix.") # Propose a new transition matrix ds = ppsl_model.ds I = np.identity(ds) sf = smp.sample_matrix_normal(np.zeros((ds, ds)), self.algoparams[moveType] * I, I) ppsl_model.parameters['F'] *= np.exp(sf) # ppsl_model.parameters['F'] = smp.sample_matrix_normal( # self.model.parameters['F'], self.algoparams[moveType]*I, I) self.chain_algoparams[moveType].append(self.algoparams[moveType]) # Random walk, so forward and backward probabilities are same fwd_prob = 0 bwd_prob = 0 # # Propose a new transition matrix # suffStats = smp.evaluate_transition_sufficient_statistics(self.state) # padded_Q = ppsl_model.transition_covariance() + \ # self.algoparams[moveType]*np.identity(ppsl_model.ds) # M,V = smp.hyperparam_update_basic_mn_transition_matrix( # suffStats, # self.hyperparams['M0'], # self.hyperparams['V0'],) # ppsl_F = smp.sample_matrix_normal(M,padded_Q,V) # fwd_prob = smp.matrix_normal_density(ppsl_F,M,padded_Q,V) # ppsl_model.parameters['F'] = ppsl_F # self.chain_algoparams[moveType].append(self.algoparams[moveType]) # # # Sample a new trajectory # ppsl_state = ppsl_model.sample_posterior(self.observ) # ppsl_suffStats = smp.evaluate_transition_sufficient_statistics( # ppsl_state) # # # Reverse move probaility # M,V = smp.hyperparam_update_basic_mn_transition_matrix( # ppsl_suffStats, # self.hyperparams['M0'], # self.hyperparams['V0'],) # bwd_prob = smp.matrix_normal_density(self.model.parameters['F'], # M,padded_Q,V) # Kalman filter ppsl_flt, _, ppsl_lhood = ppsl_model.kalman_filter(self.observ) # Prior terms prior = self.transition_prior(self.model) ppsl_prior = self.transition_prior(ppsl_model) # print(ppsl_lhood-self.lhood) # print(ppsl_prior-prior) # Decide acceptRatio = (ppsl_lhood-self.lhood) \ + (ppsl_prior-prior) \ + (bwd_prob-fwd_prob) if self.verbose: print(" Acceptance ratio: {}".format(acceptRatio)) if np.log(np.random.random()) < acceptRatio: self.model = ppsl_model self.flt = ppsl_flt self.lhood = ppsl_lhood # self.state = ppsl_state self.chain_accept[moveType].append(True) if self.verbose: print(" accepted") else: self.chain_accept[moveType].append(False) if self.verbose: print(" rejected")
def sample_transition_matrix(self): """ MCMC iteration (Metropolis-Hastings) for transition matrix """ # Make sure there's a dictionary to store stats for this move type moveType = 'perturb' if moveType not in self.chain_accept: self.chain_accept[moveType] = [] if moveType not in self.chain_algoparams: self.chain_algoparams[moveType] = [] # Need to make sure the likelihood value is current if not self.filter_current: self.flt,_,self.lhood = self.model.kalman_filter(self.observ) self.filter_current = True # Copy model ppsl_model = self.model.copy() if self.verbose: print("Metropolis-Hastings move for transition matrix.") # Propose a new transition matrix ds = ppsl_model.ds I = np.identity(ds) sf = smp.sample_matrix_normal(np.zeros((ds,ds)), self.algoparams[moveType]*I, I) ppsl_model.parameters['F'] *= np.exp(sf) # ppsl_model.parameters['F'] = smp.sample_matrix_normal( # self.model.parameters['F'], self.algoparams[moveType]*I, I) self.chain_algoparams[moveType].append(self.algoparams[moveType]) # Random walk, so forward and backward probabilities are same fwd_prob = 0 bwd_prob = 0 # # Propose a new transition matrix # suffStats = smp.evaluate_transition_sufficient_statistics(self.state) # padded_Q = ppsl_model.transition_covariance() + \ # self.algoparams[moveType]*np.identity(ppsl_model.ds) # M,V = smp.hyperparam_update_basic_mn_transition_matrix( # suffStats, # self.hyperparams['M0'], # self.hyperparams['V0'],) # ppsl_F = smp.sample_matrix_normal(M,padded_Q,V) # fwd_prob = smp.matrix_normal_density(ppsl_F,M,padded_Q,V) # ppsl_model.parameters['F'] = ppsl_F # self.chain_algoparams[moveType].append(self.algoparams[moveType]) # # # Sample a new trajectory # ppsl_state = ppsl_model.sample_posterior(self.observ) # ppsl_suffStats = smp.evaluate_transition_sufficient_statistics( # ppsl_state) # # # Reverse move probaility # M,V = smp.hyperparam_update_basic_mn_transition_matrix( # ppsl_suffStats, # self.hyperparams['M0'], # self.hyperparams['V0'],) # bwd_prob = smp.matrix_normal_density(self.model.parameters['F'], # M,padded_Q,V) # Kalman filter ppsl_flt,_,ppsl_lhood = ppsl_model.kalman_filter(self.observ) # Prior terms prior = self.transition_prior(self.model) ppsl_prior = self.transition_prior(ppsl_model) # print(ppsl_lhood-self.lhood) # print(ppsl_prior-prior) # Decide acceptRatio = (ppsl_lhood-self.lhood) \ + (ppsl_prior-prior) \ + (bwd_prob-fwd_prob) if self.verbose: print(" Acceptance ratio: {}".format(acceptRatio)) if np.log(np.random.random()) < acceptRatio: self.model = ppsl_model self.flt = ppsl_flt self.lhood = ppsl_lhood # self.state = ppsl_state self.chain_accept[moveType].append(True) if self.verbose: print(" accepted") else: self.chain_accept[moveType].append(False) if self.verbose: print(" rejected")