Beispiel #1
0
def calcELBO_LinearTerms(SS=None,
                         StartStateCount=None,
                         TransStateCount=None,
                         rho=None,
                         omega=None,
                         Ebeta=None,
                         startTheta=None,
                         transTheta=None,
                         startAlpha=0,
                         alpha=0,
                         kappa=None,
                         gamma=None,
                         afterGlobalStep=0,
                         todict=0,
                         **kwargs):
    """ Calculate ELBO objective terms that are linear in suff stats.

    Returns
    -------
    L : scalar float
        L is sum of any term in ELBO that is const/linear wrt suff stats.
    """
    Ltop = L_top(rho=rho,
                 omega=omega,
                 alpha=alpha,
                 gamma=gamma,
                 kappa=kappa,
                 startAlpha=startAlpha)
    LdiffcDir = -c_Dir(transTheta) - c_Dir(startTheta)
    if afterGlobalStep:
        if todict:
            return dict(Lalloc=Ltop + LdiffcDir, Lslack=0)
        return Ltop + LdiffcDir

    K = rho.size
    if Ebeta is None:
        Ebeta = rho2beta(rho, returnSize='K+1')

    if SS is not None:
        StartStateCount = SS.StartStateCount
        TransStateCount = SS.TransStateCount
    # Augment suff stats to be sure have 0 in final column,
    # which represents inactive states.
    if StartStateCount.size == K:
        StartStateCount = np.hstack([StartStateCount, 0])
    if TransStateCount.shape[-1] == K:
        TransStateCount = np.hstack([TransStateCount, np.zeros((K, 1))])

    LstartSlack = np.inner(StartStateCount + startAlpha * Ebeta - startTheta,
                           digamma(startTheta) - digamma(startTheta.sum()))

    alphaEbetaPlusKappa = alpha * np.tile(Ebeta, (K, 1))
    alphaEbetaPlusKappa[:, :K] += kappa * np.eye(K)
    digammaSum = digamma(np.sum(transTheta, axis=1))
    LtransSlack = np.sum((TransStateCount + alphaEbetaPlusKappa - transTheta) *
                         (digamma(transTheta) - digammaSum[:, np.newaxis]))

    if todict:
        return dict(Lalloc=Ltop + LdiffcDir, Lslack=LstartSlack + LtransSlack)
    return Ltop + LdiffcDir + LstartSlack + LtransSlack
    def L_alloc_no_slack(self):
        ''' Compute allocation term of objective function, without slack term

        Returns
        -------
        L : scalar float
        '''
        prior_cDir = L_top(nDoc=self.theta.shape[0],
            alpha=self.alpha, gamma=self.gamma,
            rho=self.rho, omega=self.omega)
        post_cDir = c_Dir(self.theta, self.thetaRem)
        return prior_cDir - post_cDir