# Path: distributions/dbg/random.py
# def score_student_t(x, nu, mu, sigma):
#     """
#     multivariate score_student_t
# 
#     \cite{murphy2007conjugate}, Eq. 313
#     """
#     p = len(mu)
#     z = x - mu
#     S = inner(inner(z, inv(sigma)), z)
#     score = (
#         gammaln(0.5 * (nu + p))
#         - gammaln(0.5 * nu)
#         - 0.5 * (
#             p * log(nu * pi)
#             + log(det(sigma))
#             + (nu + p) * log(1 + S / nu)
#         )
#     )
#     return score
# 
# def sample_normal_inverse_wishart(mu0, lambda0, psi0, nu0):
#     D, = mu0.shape
#     assert psi0.shape == (D, D)
#     assert lambda0 > 0.0
#     assert nu0 > D - 1
#     cov = sample_inverse_wishart(nu0, psi0)
#     mu = np.random.multivariate_normal(mean=mu0, cov=(1. / lambda0) * cov)
#     return mu, cov


import numpy as np
import math
from scipy.special import multigammaln
from distributions.dbg.random import (
    score_student_t,
    sample_normal_inverse_wishart,
)
from distributions.mixins import SharedMixin, GroupIoMixin, SharedIoMixin
        assert self.sum_xxT.shape == (D, D)

    def dump(self):
        return {
            'count': self.count,
            'sum_x': self.sum_x.copy(),
            'sum_xxT': self.sum_xxT.copy(),
        }

    def protobuf_load(self, message):
        self.count = message.count
        self.sum_x = np.array(message.sum_x, dtype=np.float)
        self.sum_xxT = np.array(message.sum_xxT, dtype=np.float)
        D = self.sum_x.shape[0]
        self.sum_xxT = self.sum_xxT.reshape((D, D))

    def protobuf_dump(self, message):
        message.Clear()
        message.count = self.count
        for x in self.sum_x:
            message.sum_x.append(x)
        for x in self.sum_xxT:
            for y in x:
                message.sum_xxT.append(y)


class Sampler(object):
    def init(self, shared, group=None):
        if group is not None:
            shared = shared.plus_group(group)

# Path: distributions/dbg/random.py
# def score_student_t(x, nu, mu, sigma):
#     """
#     multivariate score_student_t
# 
#     \cite{murphy2007conjugate}, Eq. 313
#     """
#     p = len(mu)
#     z = x - mu
#     S = inner(inner(z, inv(sigma)), z)
#     score = (
#         gammaln(0.5 * (nu + p))
#         - gammaln(0.5 * nu)
#         - 0.5 * (
#             p * log(nu * pi)
#             + log(det(sigma))
#             + (nu + p) * log(1 + S / nu)
#         )
#     )
#     return score
# 
# def sample_normal_inverse_wishart(mu0, lambda0, psi0, nu0):
#     D, = mu0.shape
#     assert psi0.shape == (D, D)
#     assert lambda0 > 0.0
#     assert nu0 > D - 1
#     cov = sample_inverse_wishart(nu0, psi0)
#     mu = np.random.multivariate_normal(mean=mu0, cov=(1. / lambda0) * cov)
#     return mu, cov


# Path: distributions/dbg/models/niw.py
import numpy as np
import math
from scipy.special import multigammaln
from distributions.dbg.random import (
    score_student_t,
    sample_normal_inverse_wishart,
)
from distributions.mixins import SharedMixin, GroupIoMixin, SharedIoMixin

        assert self.sum_xxT.shape == (D, D)

    def dump(self):
        return {
            'count': self.count,
            'sum_x': self.sum_x.copy(),
            'sum_xxT': self.sum_xxT.copy(),
        }

    def protobuf_load(self, message):
        self.count = message.count
        self.sum_x = np.array(message.sum_x, dtype=np.float)
        self.sum_xxT = np.array(message.sum_xxT, dtype=np.float)
        D = self.sum_x.shape[0]
        self.sum_xxT = self.sum_xxT.reshape((D, D))

    def protobuf_dump(self, message):
        message.Clear()
        message.count = self.count
        for x in self.sum_x:
            message.sum_x.append(x)
        for x in self.sum_xxT:
            for y in x:
                message.sum_xxT.append(y)


class Sampler(object):
    def init(self, shared, group=None):
        if group is not None:
            shared = shared.plus_group(group)

        self.mu, self.sigma = sample_normal_inverse_wishart(