예제 #1
0
    def kl(self, other: "NaturalNormal"):
        """Compute the Kullback-Leibler divergence with respect to another normal
        parametrised by its natural parameters.

        Args:
            other (:class:`.NaturalNormal`): Other.

        Returns:
            scalar: KL divergence with respect to `other`.
        """
        ratio = B.solve(B.chol(self.prec), B.chol(other.prec))
        diff = self.mean - other.mean
        return 0.5 * (B.sum(ratio**2) - B.logdet(B.mm(
            ratio, ratio, tr_a=True)) + B.sum(B.mm(other.prec, diff) * diff) -
                      B.cast(self.dtype, self.dim))
예제 #2
0
def test_dense_lr(lr1):
    lr_dense = B.mm(B.dense(lr1.left),
                    B.dense(lr1.middle),
                    B.dense(lr1.right),
                    tr_c=True)
    approx(B.dense(lr1), lr_dense)
    _check_cache(lr1)
예제 #3
0
def test_dense_wb(wb1):
    lr_dense = B.mm(B.dense(wb1.lr.left),
                    B.dense(wb1.lr.middle),
                    B.dense(wb1.lr.right),
                    tr_c=True)
    approx(B.dense(wb1), B.diag(wb1.diag.diag) + lr_dense)
    _check_cache(wb1)
예제 #4
0
def root(a: B.Numeric):  # pragma: no cover
    """Compute the positive square root of a positive-definite matrix.

    Args:
        a (matrix): Matrix to compute square root of.

    Returns:
        matrix: Positive square root of `a`.
    """
    _assert_square_root(a)
    u, s, _ = B.svd(a)
    return B.mm(u, B.diag(B.sqrt(s)), u, tr_c=True)
예제 #5
0
    def logpdf(self, x):
        """Compute the log-pdf of some data.

        Args:
            x (column vector): Data to compute log-pdf of.

        Returns:
            scalar: Log-pdf of `x`.
        """
        diff = B.subtract(x, self.mean)
        return -0.5 * (-B.logdet(self.prec) + B.cast(self.dtype, self.dim) *
                       B.cast(self.dtype, B.log_2_pi) +
                       B.sum(B.mm(self.prec, diff) * diff))
예제 #6
0
파일: schur.py 프로젝트: wesselb/matrix
def schur(a: Woodbury):
    """Compute the Schur complement associated to a matrix. A Schur complement will need
    to make sense for the type of `a`.

    Args:
        a (matrix): Matrix to compute Schur complement of.

    Returns:
        matrix: Schur complement.
    """
    if a.schur is None:
        second = B.mm(a.lr.right, B.inv(a.diag), a.lr.left, tr_a=True)
        a.schur = B.add(B.inv(a.lr.middle), second)
    return a.schur
예제 #7
0
def closest_psd(a, inv=False):
    """Map a matrix to the closest PSD matrix.

    Args:
        a (tensor): Matrix.
        inv (bool, optional): Also invert `a`.

    Returns:
        tensor: PSD matrix closest to `a` or the inverse of `a`.
    """
    a = B.dense(a)
    a = (a + B.transpose(a)) / 2
    u, s, v = B.svd(a)
    signs = B.matmul(u, v, tr_a=True)
    s = B.maximum(B.diag(signs) * s, 0)
    if inv:
        s = B.where(s == 0, 0, 1 / s)
    return B.mm(u * B.expand_dims(s, axis=-2), v, tr_b=True)
예제 #8
0
def iqf(a, b, c):
    """Compute `transpose(b) inv(a) c` where `a` is assumed to be positive
    definite.

    Args:
        a (matrix): Matrix `a`.
        b (matrix): Matrix `b`.
        c (matrix, optional): Matrix `c`. Defaults to `b`.

    Returns:
        matrix: Resulting quadratic form.
    """
    chol = B.cholesky(a)
    chol_b = B.solve(chol, b)
    if c is b:
        chol_c = chol_b
    else:
        chol_c = B.solve(chol, c)
    return B.mm(chol_b, chol_c, tr_a=True)
예제 #9
0
파일: dense.py 프로젝트: wesselb/matrix
def dense(a: LowRank):
    if a.dense is None:
        a.dense = B.dense(B.mm(a.left, a.middle, a.right, tr_c=True))
    return a.dense
예제 #10
0
def iqf(a: Woodbury, b, c):
    return B.mm(b, B.pd_inv(a), c, tr_a=True)
예제 #11
0
def rand_normal(n=3):
    cov = B.randn(n, n)
    cov = B.mm(cov, cov, tr_b=True)
    return Normal(B.randn(n, 1), cov)