Home | History | Annotate | Download | only in linalg
      1 # Copyright 2017 The TensorFlow Authors. All Rights Reserved.
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 # ==============================================================================
     15 """Operations for linear algebra."""
     16 
     17 from __future__ import absolute_import
     18 from __future__ import division
     19 from __future__ import print_function
     20 
     21 from tensorflow.python.framework import ops
     22 from tensorflow.python.ops import array_ops
     23 from tensorflow.python.ops import gen_linalg_ops
     24 from tensorflow.python.ops import linalg_ops
     25 from tensorflow.python.ops import math_ops
     26 from tensorflow.python.ops import special_math_ops
     27 from tensorflow.python.util.tf_export import tf_export
     28 
     29 # Linear algebra ops.
     30 band_part = array_ops.matrix_band_part
     31 cholesky = linalg_ops.cholesky
     32 cholesky_solve = linalg_ops.cholesky_solve
     33 det = linalg_ops.matrix_determinant
     34 # pylint: disable=protected-access
     35 slogdet = gen_linalg_ops._log_matrix_determinant
     36 # pylint: disable=protected-access
     37 diag = array_ops.matrix_diag
     38 diag_part = array_ops.matrix_diag_part
     39 eigh = linalg_ops.self_adjoint_eig
     40 eigvalsh = linalg_ops.self_adjoint_eigvals
     41 einsum = special_math_ops.einsum
     42 expm = gen_linalg_ops._matrix_exponential
     43 eye = linalg_ops.eye
     44 inv = linalg_ops.matrix_inverse
     45 logm = gen_linalg_ops._matrix_logarithm
     46 lstsq = linalg_ops.matrix_solve_ls
     47 norm = linalg_ops.norm
     48 qr = linalg_ops.qr
     49 set_diag = array_ops.matrix_set_diag
     50 solve = linalg_ops.matrix_solve
     51 svd = linalg_ops.svd
     52 tensordot = math_ops.tensordot
     53 trace = math_ops.trace
     54 transpose = array_ops.matrix_transpose
     55 triangular_solve = linalg_ops.matrix_triangular_solve
     56 
     57 
     58 @tf_export('linalg.logdet')
     59 def logdet(matrix, name=None):
     60   """Computes log of the determinant of a hermitian positive definite matrix.
     61 
     62   ```python
     63   # Compute the determinant of a matrix while reducing the chance of over- or
     64   underflow:
     65   A = ... # shape 10 x 10
     66   det = tf.exp(tf.logdet(A))  # scalar
     67   ```
     68 
     69   Args:
     70     matrix:  A `Tensor`. Must be `float16`, `float32`, `float64`, `complex64`,
     71       or `complex128` with shape `[..., M, M]`.
     72     name:  A name to give this `Op`.  Defaults to `logdet`.
     73 
     74   Returns:
     75     The natural log of the determinant of `matrix`.
     76 
     77   @compatibility(numpy)
     78   Equivalent to numpy.linalg.slogdet, although no sign is returned since only
     79   hermitian positive definite matrices are supported.
     80   @end_compatibility
     81   """
     82   # This uses the property that the log det(A) = 2*sum(log(real(diag(C))))
     83   # where C is the cholesky decomposition of A.
     84   with ops.name_scope(name, 'logdet', [matrix]):
     85     chol = gen_linalg_ops.cholesky(matrix)
     86     return 2.0 * math_ops.reduce_sum(
     87         math_ops.log(math_ops.real(array_ops.matrix_diag_part(chol))),
     88         reduction_indices=[-1])
     89 
     90 
     91 @tf_export('linalg.adjoint')
     92 def adjoint(matrix, name=None):
     93   """Transposes the last two dimensions of and conjugates tensor `matrix`.
     94 
     95   For example:
     96 
     97   ```python
     98   x = tf.constant([[1 + 1j, 2 + 2j, 3 + 3j],
     99                    [4 + 4j, 5 + 5j, 6 + 6j]])
    100   tf.linalg.adjoint(x)  # [[1 - 1j, 4 - 4j],
    101                         #  [2 - 2j, 5 - 5j],
    102                         #  [3 - 3j, 6 - 6j]]
    103 
    104   Args:
    105     matrix:  A `Tensor`. Must be `float16`, `float32`, `float64`, `complex64`,
    106       or `complex128` with shape `[..., M, M]`.
    107     name:  A name to give this `Op` (optional).
    108 
    109   Returns:
    110     The adjoint (a.k.a. Hermitian transpose a.k.a. conjugate transpose) of
    111     matrix.
    112   """
    113   with ops.name_scope(name, 'adjoint', [matrix]):
    114     matrix = ops.convert_to_tensor(matrix, name='matrix')
    115     return array_ops.matrix_transpose(matrix, conjugate=True)
    116