# Path: brainiak/matnormal/utils.py
# def scaled_I(x, size):
#     """Scaled identity matrix
#     :math:`x I_{size}`
# 
#     Parameters
#     ------------
#     x: float or coercable to float
#         Scale to multiply the identity matrix by
#     size: int or otherwise coercable to a size
#         Dimension of the scaled identity matrix to return
#     """
#     return tf.linalg.tensor_diag(tf.ones([size], dtype=tf.float64) * x)


import tensorflow as tf
import logging
from tensorflow import linalg as tlinalg
from .utils import scaled_I
        Tensor to multiply the solve by
    sigma: brainiak.matnormal.CovBase
        Covariance object implementing solve and logdet
    A: tf.Tensor
        Factor multiplying the variable we conditioned on
    Q: brainiak.matnormal.CovBase
        Covariance object of conditioning variable,
        implementing solve and logdet

    """

    # (Q - A^T Sigma^{-1} A)
    lemma_factor = tlinalg.cholesky(
        Q._cov - tf.matmul(A, sigma.solve(A), transpose_a=True)
    )

    logdet = (
        -Q.logdet
        + sigma.logdet
        + 2 *
        tf.reduce_sum(input_tensor=tf.math.log(
            tlinalg.diag_part(lemma_factor)))
    )

    # A^T Sigma^{-1}
    Atrp_Sinv = tf.matmul(A, sigma._prec, transpose_a=True)
    # (Q - A^T Sigma^{-1} A)^{-1} A^T Sigma^{-1}
    prod_term = tlinalg.cholesky_solve(lemma_factor, Atrp_Sinv)

    solve = tf.matmul(

# Path: brainiak/matnormal/utils.py
# def scaled_I(x, size):
#     """Scaled identity matrix
#     :math:`x I_{size}`
# 
#     Parameters
#     ------------
#     x: float or coercable to float
#         Scale to multiply the identity matrix by
#     size: int or otherwise coercable to a size
#         Dimension of the scaled identity matrix to return
#     """
#     return tf.linalg.tensor_diag(tf.ones([size], dtype=tf.float64) * x)


# Path: brainiak/matnormal/matnormal_likelihoods.py
import tensorflow as tf
import logging
from tensorflow import linalg as tlinalg
from .utils import scaled_I

        Tensor to multiply the solve by
    sigma: brainiak.matnormal.CovBase
        Covariance object implementing solve and logdet
    A: tf.Tensor
        Factor multiplying the variable we conditioned on
    Q: brainiak.matnormal.CovBase
        Covariance object of conditioning variable,
        implementing solve and logdet

    """

    # (Q - A^T Sigma^{-1} A)
    lemma_factor = tlinalg.cholesky(
        Q._cov - tf.matmul(A, sigma.solve(A), transpose_a=True)
    )

    logdet = (
        -Q.logdet
        + sigma.logdet
        + 2 *
        tf.reduce_sum(input_tensor=tf.math.log(
            tlinalg.diag_part(lemma_factor)))
    )

    # A^T Sigma^{-1}
    Atrp_Sinv = tf.matmul(A, sigma._prec, transpose_a=True)
    # (Q - A^T Sigma^{-1} A)^{-1} A^T Sigma^{-1}
    prod_term = tlinalg.cholesky_solve(lemma_factor, Atrp_Sinv)

    solve = tf.matmul(

        sigma.solve(scaled_I(1.0, sigma.size) + tf.matmul(A, prod_term)), x