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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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")
Exemplo n.º 10
0
    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")