Exemplo n.º 1
0
    def lml_derivative_over_cov(self, dQS):
        from numpy_sugar.linalg import cho_solve, ddot, dotd

        self._update()

        L = self._posterior.L()
        Q = self._posterior.cov["QS"][0][0]
        ttau = self._site.tau
        teta = self._site.eta

        diff = teta - ttau * self._posterior.mean

        v0 = dot(dQS[0][0], dQS[1] * dot(dQS[0][0].T, diff))
        v1 = ttau * dot(Q, cho_solve(L, dot(Q.T, diff)))
        dlml = 0.5 * dot(diff, v0)
        dlml -= dot(v0, v1)
        dlml += 0.5 * dot(v1, dot(dQS[0][0], dQS[1] * dot(dQS[0][0].T, v1)))
        dqs = ddot(dQS[1], dQS[0][0].T, left=True)
        diag = dotd(dQS[0][0], dqs)
        dlml -= 0.5 * sum(ttau * diag)

        tmp = cho_solve(L, dot(ddot(Q.T, ttau, left=False), dQS[0][0]))
        dlml += 0.5 * sum(ttau * dotd(Q, dot(tmp, dqs)))

        return dlml
Exemplo n.º 2
0
    def _joint_update(self):
        A = self._A()
        C = self._C()
        m = self.m()
        Q = self._Q
        v = self.v
        delta = self.delta
        teta = self._sitelik_eta
        jtau = self._joint_tau
        jeta = self._joint_eta
        Kteta = self._Kdot(teta)

        BiQt = self._BiQt()
        uBiQtAK0, uBiQtAK1 = self._uBiQtAK()

        jtau[:] = -dotd(Q, uBiQtAK0)
        jtau *= 1 - delta
        jtau -= delta * dotd(Q, uBiQtAK1)
        jtau *= v
        jtau += self._diagK()

        jtau[:] = 1 / jtau

        dot(Q, dot(BiQt, -A * Kteta), out=jeta)
        jeta += Kteta
        jeta += m
        jeta -= self._QBiQtAm()
        jeta *= jtau
        jtau /= C
Exemplo n.º 3
0
    def update(self):
        from numpy_sugar.linalg import ddot, dotd

        self._flush_cache()

        s = self._cov["scale"]
        d = self._cov["delta"]
        Q = self._cov["QS"][0][0]

        A = self.A
        LQt = self.LQt()

        T = self._site.tau
        E = self._site.eta

        AQ = self.AQ()
        QS = self.QS()

        LQtA = ddot(LQt, A)
        D = self.QSQtATQLQtA()

        self.tau[:] = s * (1 - d) * dotd(QS, AQ.T)
        self.tau -= s * (1 - d) * D * (1 - d)
        self.tau += s * d * A
        self.tau -= s * d * dotd(self.ATQ(), LQtA) * (1 - d)
        self.tau **= -1

        v = s * (1 - d) * dot(Q, dot(QS.T, E)) + s * d * E + self._mean

        self.eta[:] = A * v
        self.eta -= dot(AQ, dot(LQtA, T * v)) * (1 - d)
        self.eta *= self.tau
Exemplo n.º 4
0
    def lml_derivatives(self, dm):
        from numpy_sugar.linalg import dotd

        if self._cache["grad"] is not None:
            return self._cache["grad"]

        self._update()

        LQt = self._posterior.LQt()
        ATQ = self._posterior.ATQ()
        ttau = self._site.tau
        teta = self._site.eta
        A = self._posterior.A

        cov = self._posterior.cov
        Q = cov["QS"][0][0]
        s = cov["scale"]
        d = cov["delta"]
        QS = self._posterior.QS()

        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

        r = (self._posterior.QSQtATQLQtA() * ttau).sum()

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

        r1 = (TA * dotd(Q, LQt) * TA).sum()

        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(ATQ, 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 * r1 * (1 - d)

        dlml_delta = 0.5 * dot(Ae_m, dKAs_m)
        dlml_delta -= sum(w * dKAs_m)
        dlml_delta += 0.5 * dot(w, -s * dot(QS, dot(Q.T, w)) + s * w)
        dlml_delta += 0.5 * s * dotd(ATQ, QS.T).sum()
        dlml_delta -= 0.5 * sum(TA) * s
        dlml_delta -= 0.5 * s * r * (1 - d)
        dlml_delta += 0.5 * s * r1 * (1 - d)

        g = dict(mean=dlml_mean, scale=dlml_scale, delta=dlml_delta)

        self._cache["grad"] = g

        return g
Exemplo n.º 5
0
    def update(self):
        from numpy_sugar.linalg import ddot, dotd

        self._flush_cache()

        Q = self._cov["QS"][0][0]

        K = dot(self.QS(), Q.T)

        BiQt = self.LQt()
        TK = ddot(self._site.tau, K, left=True)
        BiQtTK = dot(BiQt, TK)

        self.tau[:] = K.diagonal()
        self.tau -= dotd(Q, BiQtTK)
        self.tau[:] = 1 / self.tau

        if not all(self.tau >= 0.0):
            raise RuntimeError("'tau' has to be non-negative.")

        self.eta[:] = dot(K, self._site.eta)
        self.eta[:] += self._mean
        self.eta[:] -= dot(Q, dot(BiQtTK, self._site.eta))
        self.eta[:] -= dot(Q, dot(BiQt, self._site.tau * self._mean))

        self.eta *= self.tau
Exemplo n.º 6
0
def _bstar_1effect(beta, alpha, yTBy, yTBX, yTBM, XTBX, XTBM, MTBM):
    """
    Same as :func:`_bstar_set` but for single-effect.
    """
    from numpy_sugar import epsilon
    from numpy_sugar.linalg import dotd
    from numpy import sum

    r = full(MTBM[0].shape[0], yTBy)
    r -= 2 * add.reduce([dot(i, beta) for i in yTBX])
    r -= 2 * add.reduce([i * alpha for i in yTBM])
    r += add.reduce([dotd(beta.T, dot(i, beta)) for i in XTBX])
    r += add.reduce([dotd(beta.T, i * alpha) for i in XTBM])
    r += add.reduce([sum(alpha * i * beta, axis=0) for i in XTBM])
    r += add.reduce([alpha * i.ravel() * alpha for i in MTBM])
    return clip(r, epsilon.tiny, inf)
Exemplo n.º 7
0
def test_dotd():
    random = RandomState(958)
    A = random.randn(10, 2)
    B = random.randn(2, 10)

    r = A.dot(B).diagonal()
    assert_allclose(r, dotd(A, B))
    r1 = empty(len(r))
    assert_allclose(dotd(A, B, out=r1), r)

    a = random.randn(2)
    b = random.randn(2)
    c = array(0.0)

    assert_allclose(dotd(a, b), -1.05959423672)
    dotd(a, b, out=c)
    assert_allclose(c, -1.05959423672)
Exemplo n.º 8
0
    def _init_svd(self):
        from numpy_sugar.linalg import dotd
        from scipy.linalg import svd

        if self._Lx is not None:
            return
        G = self._G
        U, S, _ = svd(G, check_finite=False)
        S *= S
        self._Sxe = S
        self._Sx = concatenate((S, [0.0] * (U.shape[0] - S.shape[0])))
        self._Lx = U.T
        self._LxG = self._Lx @ G
        self._diag_LxGGLx = dotd(self._LxG, self._LxG.T)
        self._Lxe = U[:, : S.shape[0]].T
        self._LxGe = self._Lxe @ G
        self._diag_LxGGLxe = dotd(self._LxGe, self._LxGe.T)
Exemplo n.º 9
0
    def logdet_gradient(self):
        """
        Implements ∂log|K| = Tr[K⁻¹∂K].

        It can be shown that::

            ∂log|K| = diag(D)ᵀdiag(L(∂K)Lᵀ) = diag(D)ᵀ(diag(Lₕ∂C₀Lₕᵀ)⊗diag(LₓGGᵀLₓᵀ)),

        when the derivative is over the parameters of C₀. Similarly,

            ∂log|K| = diag(D)ᵀdiag(L(∂K)Lᵀ) = diag(D)ᵀ(diag(Lₕ∂C₁Lₕᵀ)⊗diag(I)),

        over the parameters of C₁.

        Returns
        -------
        C0 : ndarray
            Derivative of C₀ over its parameters.
        C1 : ndarray
            Derivative of C₁ over its parameters.
        """
        from numpy_sugar.linalg import dotd

        self._init_svd()

        dC0 = self._C0.gradient()["Lu"]
        grad_C0 = zeros_like(self._C0.Lu)
        for i in range(self._C0.Lu.shape[0]):
            t = kron(dotd(self.Lh, dC0[..., i] @ self.Lh.T), self._diag_LxGGLxe)
            grad_C0[i] = (self._De * t).sum()

        dC1 = self._C1.gradient()["Lu"]
        grad_C1 = zeros_like(self._C1.Lu)
        p = self._Sxe.shape[0]
        np = self._G.shape[0] - p
        for i in range(self._C1.Lu.shape[0]):
            t = (dotd(self.Lh, dC1[..., i] @ self.Lh.T) * np).sum()
            t1 = kron(dotd(self.Lh, dC1[..., i] @ self.Lh.T), eye(p))
            t += (self._De * t1).sum()
            grad_C1[i] = t

        return {"C0.Lu": grad_C0, "C1.Lu": grad_C1}
Exemplo n.º 10
0
    def QSQtATQLQtA(self):
        from numpy_sugar.linalg import ddot, dotd

        if self._QSQtATQLQtA_cache is not None:
            return self._QSQtATQLQtA_cache

        LQt = self.LQt()
        A = self.A
        Q = self._cov["QS"][0][0]
        LQtA = ddot(LQt, A)
        AQ = self.AQ()
        QS = self.QS()
        T = self._site.tau
        self._QSQtATQLQtA_cache = dotd(QS, dot(dot(ddot(AQ.T, T), Q), LQtA))
        return self._QSQtATQLQtA_cache