def logdet(matrix, name=None): """Computes log of the determinant of a hermitian positive definite matrix. ```python # Compute the determinant of a matrix while reducing the chance of over- or underflow: A = ... # shape 10 x 10 det = tf.exp(tf.linalg.logdet(A)) # scalar ``` Args: matrix: A `Tensor`. Must be `float16`, `float32`, `float64`, `complex64`, or `complex128` with shape `[..., M, M]`. name: A name to give this `Op`. Defaults to `logdet`. Returns: The natural log of the determinant of `matrix`. @compatibility(numpy) Equivalent to numpy.linalg.slogdet, although no sign is returned since only hermitian positive definite matrices are supported. @end_compatibility """ # This uses the property that the log det(A) = 2*sum(log(real(diag(C)))) # where C is the cholesky decomposition of A. with ops.name_scope(name, 'logdet', [matrix]): chol = gen_linalg_ops.cholesky(matrix) return 2.0 * math_ops.reduce_sum( math_ops.log(math_ops.real(array_ops.matrix_diag_part(chol))), axis=[-1])
def logdet(matrix, name=None): """Computes log of the determinant of a hermitian positive definite matrix. ```python # Compute the determinant of a matrix while reducing the chance of over- or underflow: A = ... # shape 10 x 10 det = tf.exp(tf.logdet(A)) # scalar ``` Args: matrix: A `Tensor`. Must be `float16`, `float32`, `float64`, `complex64`, or `complex128` with shape `[..., M, M]`. name: A name to give this `Op`. Defaults to `logdet`. Returns: The natural log of the determinant of `matrix`. @compatibility(numpy) Equivalent to numpy.linalg.slogdet, although no sign is returned since only hermitian positive definite matrices are supported. @end_compatibility """ # This uses the property that the log det(A) = 2*sum(log(real(diag(C)))) # where C is the cholesky decomposition of A. with ops.name_scope(name, 'logdet', [matrix]): chol = gen_linalg_ops.cholesky(matrix) return 2.0 * math_ops.reduce_sum( math_ops.log(math_ops.real(array_ops.matrix_diag_part(chol))), reduction_indices=[-1])
def _RegularizedGramianCholesky(matrix, l2_regularizer, first_kind): r"""Computes Cholesky factorization of regularized gramian matrix. Below we will use the following notation for each pair of matrix and right-hand sides in the batch: `matrix`=\\(A \in \Re^{m \times n}\\), `output`=\\(C \in \Re^{\min(m, n) \times \min(m,n)}\\), `l2_regularizer`=\\(\lambda\\). If `first_kind` is True, returns the Cholesky factorization \\(L\\) such that \\(L L^H = A^H A + \lambda I\\). If `first_kind` is False, returns the Cholesky factorization \\(L\\) such that \\(L L^H = A A^H + \lambda I\\). Args: matrix: `Tensor` of shape `[..., M, N]`. l2_regularizer: 0-D `double` `Tensor`. Ignored if `fast=False`. first_kind: bool. Controls what gramian matrix to factor. Returns: output: `Tensor` of shape `[..., min(M,N), min(M,N)]` whose inner-most 2 dimensions contain the Cholesky factors \\(L\\) described above. """ gramian = math_ops.matmul(matrix, matrix, adjoint_a=first_kind, adjoint_b=not first_kind) if isinstance(l2_regularizer, ops.Tensor) or l2_regularizer != 0: matrix_shape = array_ops.shape(matrix) batch_shape = matrix_shape[:-2] if first_kind: small_dim = matrix_shape[-1] else: small_dim = matrix_shape[-2] identity = eye(small_dim, batch_shape=batch_shape, dtype=matrix.dtype) small_dim_static = matrix.shape[-1 if first_kind else -2] identity.set_shape(matrix.shape[:-2].concatenate( [small_dim_static, small_dim_static])) gramian += l2_regularizer * identity return gen_linalg_ops.cholesky(gramian)
def _RegularizedGramianCholesky(matrix, l2_regularizer, first_kind): r"""Computes Cholesky factorization of regularized gramian matrix. Below we will use the following notation for each pair of matrix and right-hand sides in the batch: `matrix`=\\(A \in \Re^{m \times n}\\), `output`=\\(C \in \Re^{\min(m, n) \times \min(m,n)}\\), `l2_regularizer`=\\(\lambda\\). If `first_kind` is True, returns the Cholesky factorization \\(L\\) such that \\(L L^H = A^H A + \lambda I\\). If `first_kind` is False, returns the Cholesky factorization \\(L\\) such that \\(L L^H = A A^H + \lambda I\\). Args: matrix: `Tensor` of shape `[..., M, N]`. l2_regularizer: 0-D `double` `Tensor`. Ignored if `fast=False`. first_kind: bool. Controls what gramian matrix to factor. Returns: output: `Tensor` of shape `[..., min(M,N), min(M,N)]` whose inner-most 2 dimensions contain the Cholesky factors \\(L\\) described above. """ gramian = math_ops.matmul( matrix, matrix, adjoint_a=first_kind, adjoint_b=not first_kind) if isinstance(l2_regularizer, ops.Tensor) or l2_regularizer != 0: matrix_shape = array_ops.shape(matrix) batch_shape = matrix_shape[:-2] if first_kind: small_dim = matrix_shape[-1] else: small_dim = matrix_shape[-2] identity = eye(small_dim, batch_shape=batch_shape, dtype=matrix.dtype) small_dim_static = matrix.shape[-1 if first_kind else -2] identity.set_shape( matrix.shape[:-2].concatenate([small_dim_static, small_dim_static])) gramian += l2_regularizer * identity return gen_linalg_ops.cholesky(gramian)