Example #1
0
 def symbolic_logq_not_scaled(self):
     z0 = self.symbolic_initial
     diag = at.diagonal(self.L, 0, self.L.ndim - 2, self.L.ndim - 1)
     logdet = at.log(diag)
     quaddist = -0.5 * z0**2 - at.log((2 * np.pi)**0.5)
     logq = quaddist - logdet
     return logq.sum(range(1, logq.ndim))
Example #2
0
    def L_op(self, inputs, outputs, gradients):
        # Modified from aesara/tensor/slinalg.py
        # No handling for on_error = 'nan'
        dz = gradients[0]
        chol_x = outputs[0]

        # this is for nan mode
        #
        # ok = ~tensor.any(tensor.isnan(chol_x))
        # chol_x = tensor.switch(ok, chol_x, 1)
        # dz = tensor.switch(ok, dz, 1)

        # deal with upper triangular by converting to lower triangular
        if not self.lower:
            chol_x = chol_x.T
            dz = dz.T

        def tril_and_halve_diagonal(mtx):
            """Extracts lower triangle of square matrix and halves diagonal."""
            return tensor.tril(mtx) - tensor.diag(tensor.diagonal(mtx) / 2.0)

        def conjugate_solve_triangular(outer, inner):
            """Computes L^{-T} P L^{-1} for lower-triangular L."""
            return gpu_solve_upper_triangular(
                outer.T, gpu_solve_upper_triangular(outer.T, inner.T).T
            )

        s = conjugate_solve_triangular(
            chol_x, tril_and_halve_diagonal(chol_x.T.dot(dz))
        )

        if self.lower:
            grad = tensor.tril(s + s.T) - tensor.diag(tensor.diagonal(s))
        else:
            grad = tensor.triu(s + s.T) - tensor.diag(tensor.diagonal(s))

        return [grad]
Example #3
0
 def tril_and_halve_diagonal(mtx):
     """Extracts lower triangle of square matrix and halves diagonal."""
     return tensor.tril(mtx) - tensor.diag(tensor.diagonal(mtx) / 2.0)