<commit_before>from __future__ import absolute_import, division, unicode_literals

from math import fsum

from numpy import dot, isfinite, log, sqrt

from numpy_sugar import epsilon
from numpy_sugar.linalg import cho_solve, ddot, dotd

from .ep import EP
from .posterior_linear_kernel import PosteriorLinearKernel


def ldot(A, B):
    return ddot(A, B, left=True)


def dotr(A, B):
    return ddot(A, B, left=False)


class EPLinearKernel(EP):
    def __init__(self, nsites, rtol=epsilon.small * 1000, atol=epsilon.small):
        super(EPLinearKernel, self).__init__(
            nsites, PosteriorLinearKernel, rtol=rtol, atol=atol)

    def lml(self):
        if self._cache['lml'] is not None:
            return self._cache['lml']

        self._update()

        L = self._posterior.L()
        LQT = self._posterior.LQT()
        cov = self._posterior.cov
        Q = cov['QS'][0][0]
        S = cov['QS'][1]
        ttau = self._site.tau
        teta = self._site.eta
        ctau = self._cav['tau']
        ceta = self._cav['eta']
        m = self._posterior.mean

        TS = ttau + ctau

        s = cov['scale']
        d = cov['delta']
        A = self._posterior._A

        lml = [
            -log(L.diagonal()).sum(),
            -0.5 * sum(log(s * S)),
            +0.5 * sum(log(A)),
            # lml += 0.5 * sum(log(ttau)),
            +0.5 * dot(teta * A, dot(Q, dot(LQT, teta * A))) * (1 - d),
            -0.5 * dot(teta, teta / TS),
            +dot(m, A * teta) - 0.5 * dot(m, A * ttau * m),
            -0.5 * dot(m * A * ttau,
                       dot(Q, dot(LQT, 2 * A * teta - A * ttau * m))) *
            (1 - d),
            +sum(self._moments['log_zeroth']),
            +0.5 * sum(log(TS)),
            # lml -= 0.5 * sum(log(ttau)),
            -0.5 * sum(log(ctau)),
            +0.5 * dot(ceta / TS, ttau * ceta / ctau - 2 * teta),
            0.5 * s * d * sum(teta * A * teta)
        ]
        lml = fsum(lml)

        if not isfinite(lml):
            raise ValueError("LML should not be %f." % lml)

        self._cache['lml'] = lml

        return lml

    def lml_derivatives(self, dm):
        if self._cache['grad'] is not None:
            return self._cache['grad']

        self._update()

        L = self._posterior.L()
        # LQT = self._posterior.LQT()
        ttau = self._site.tau
        teta = self._site.eta
        A = self._posterior._A

        cov = self._posterior.cov
        Q = cov['QS'][0][0]
        S = cov['QS'][1]
        s = cov['scale']
        d = cov['delta']
        tQ = sqrt(1 - d) * Q
        tQS = dotr(tQ, S)
        QS = dotr(Q, S)

        e_m = teta - ttau * self._posterior.mean
        Ae_m = A * e_m
        TA = ttau * A
        tQTAe_m = dot(tQ.T, Ae_m)
        dKAd_m = dot(tQS, tQTAe_m) + d * Ae_m
        w = TA * dot(tQ, cho_solve(L, tQTAe_m))
        QTAe_m = dot(Q.T, Ae_m)
        dKAs_m = -s * dot(QS, QTAe_m) + s * Ae_m
        TAtQ = ldot(TA, tQ)
        LQT = self._posterior.LQT()
        TAQ = ldot(TA, Q)
        r = dotd(TAQ, dot(dot(LQT, TAQ), QS.T)).sum()

        dlml_mean = dot(e_m, ldot(A, dm)) - dot(
            Ae_m, dot(tQ, cho_solve(L, dot(tQ.T, ldot(TA, dm)))))

        dlml_scale = 0.5 * dot(Ae_m, dKAd_m)
        dlml_scale -= sum(w * dKAd_m)
        dlml_scale += 0.5 * dot(w, dot(tQS, dot(tQ.T, w)) + d * w)
        dlml_scale -= 0.5 * dotd(TAtQ, tQS.T).sum()
        dlml_scale -= 0.5 * sum(TA) * d
        dlml_scale += 0.5 * r * (1 - d)**2
        dlml_scale += 0.5 * d * dotd(TAQ, dotr(LQT, TA)).sum() * (1 - d)<commit_msg>cho_solve less<commit_after>from __future__ import absolute_import, division, unicode_literals

from math import fsum

from numpy import dot, isfinite, log

from numpy_sugar import epsilon
from numpy_sugar.linalg import ddot, dotd

from .ep import EP
from .posterior_linear_kernel import PosteriorLinearKernel


def ldot(A, B):
    return ddot(A, B, left=True)


def dotr(A, B):
    return ddot(A, B, left=False)


class EPLinearKernel(EP):
    def __init__(self, nsites, rtol=epsilon.small * 1000, atol=epsilon.small):
        super(EPLinearKernel, self).__init__(
            nsites, PosteriorLinearKernel, rtol=rtol, atol=atol)

    def lml(self):
        if self._cache['lml'] is not None:
            return self._cache['lml']

        self._update()

        L = self._posterior.L()
        LQT = self._posterior.LQT()
        cov = self._posterior.cov
        Q = cov['QS'][0][0]
        S = cov['QS'][1]
        ttau = self._site.tau
        teta = self._site.eta
        ctau = self._cav['tau']
        ceta = self._cav['eta']
        m = self._posterior.mean

        TS = ttau + ctau

        s = cov['scale']
        d = cov['delta']
        A = self._posterior._A

        lml = [
            -log(L.diagonal()).sum(),
            -0.5 * sum(log(s * S)),
            +0.5 * sum(log(A)),
            # lml += 0.5 * sum(log(ttau)),
            +0.5 * dot(teta * A, dot(Q, dot(LQT, teta * A))) * (1 - d),
            -0.5 * dot(teta, teta / TS),
            +dot(m, A * teta) - 0.5 * dot(m, A * ttau * m),
            -0.5 * dot(m * A * ttau,
                       dot(Q, dot(LQT, 2 * A * teta - A * ttau * m))) *
            (1 - d),
            +sum(self._moments['log_zeroth']),
            +0.5 * sum(log(TS)),
            # lml -= 0.5 * sum(log(ttau)),
            -0.5 * sum(log(ctau)),
            +0.5 * dot(ceta / TS, ttau * ceta / ctau - 2 * teta),
            0.5 * s * d * sum(teta * A * teta)
        ]
        lml = fsum(lml)

        if not isfinite(lml):
            raise ValueError("LML should not be %f." % lml)

        self._cache['lml'] = lml

        return lml

    def lml_derivatives(self, dm):
        if self._cache['grad'] is not None:
            return self._cache['grad']

        self._update()

        LQT = self._posterior.LQT()
        ttau = self._site.tau
        teta = self._site.eta
        A = self._posterior._A

        cov = self._posterior.cov
        Q = cov['QS'][0][0]
        S = cov['QS'][1]
        s = cov['scale']
        d = cov['delta']
        QS = dotr(Q, S)

        e_m = teta - ttau * self._posterior.mean
        Ae_m = A * e_m
        TA = ttau * A
        LtQTAe_m = dot(LQT, Ae_m)
        tQTAe_m = dot(Q.T, Ae_m)
        dKAd_m = dot(QS, tQTAe_m) * (1 - d) + d * Ae_m
        w = TA * dot(Q, LtQTAe_m) * (1 - d)
        QTAe_m = dot(Q.T, Ae_m)
        dKAs_m = -s * dot(QS, QTAe_m) + s * Ae_m
        TAQ = ldot(TA, Q)
        r = dotd(TAQ, dot(dot(LQT, TAQ), QS.T)).sum()

        dlml_mean = dot(e_m, ldot(
            A, dm)) - dot(Ae_m, dot(Q, dot(LQT, ldot(TA, dm)))) * (1 - d)

        dlml_scale = 0.5 * dot(Ae_m, dKAd_m)
        dlml_scale -= sum(w * dKAd_m)
        dlml_scale += 0.5 * dot(w, dot(QS, dot(Q.T, w) * (1 - d)) + d * w)
        dlml_scale -= 0.5 * dotd(TAQ, QS.T).sum() * (1 - d)
        dlml_scale -= 0.5 * sum(TA) * d
        dlml_scale += 0.5 * r * (1 - d) * (1 - d)
        dlml_scale += 0.5 * d * dotd(TAQ, dotr(LQT, TA)).sum() * (1 - d)
{'fraction_non_alphanumeric': 0.15961703343812517, 'fraction_numerical': 0.01600457273506716, 'mean_word_length': 1.6857252494244053, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3079827', 'n_tokens_mistral': 2911, 'n_tokens_neox': 2744, 'n_words': 633}