• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 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"""Common utilities for registering LinearOperator methods."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20
21
22# Note: only use this method in the commuting case.
23def combined_commuting_self_adjoint_hint(operator_a, operator_b):
24  """Get combined hint for self-adjoint-ness."""
25
26  # The property is preserved under composition when the operators commute.
27  if operator_a.is_self_adjoint and operator_b.is_self_adjoint:
28    return True
29
30  # The property is not preserved when an operator with the property is composed
31  # with an operator without the property.
32
33  # pylint:disable=g-bool-id-comparison
34  if ((operator_a.is_self_adjoint is True and
35       operator_b.is_self_adjoint is False) or
36      (operator_a.is_self_adjoint is False and
37       operator_b.is_self_adjoint is True)):
38    return False
39  # pylint:enable=g-bool-id-comparison
40
41  # The property is not known when operators are not known to have the property
42  # or both operators don't have the property (the property for the complement
43  # class is not closed under composition).
44  return None
45
46
47def is_square(operator_a, operator_b):
48  """Return a hint to whether the composition is square."""
49  if operator_a.is_square and operator_b.is_square:
50    return True
51  if operator_a.is_square is False and operator_b.is_square is False:  # pylint:disable=g-bool-id-comparison
52    # Let A have shape [B, M, N], B have shape [B, N, L].
53    m = operator_a.range_dimension
54    l = operator_b.domain_dimension
55    if m is not None and l is not None:
56      return m == l
57
58  if (operator_a.is_square != operator_b.is_square) and (
59      operator_a.is_square is not None and operator_b.is_square is not None):
60    return False
61
62  return None
63
64
65# Note: Positive definiteness is only guaranteed to be preserved
66# when the operators commute and are symmetric. Only use this method in
67# commuting cases.
68def combined_commuting_positive_definite_hint(operator_a, operator_b):
69  """Get combined PD hint for compositions."""
70  # pylint:disable=g-bool-id-comparison
71  if (operator_a.is_positive_definite is True and
72      operator_a.is_self_adjoint is True and
73      operator_b.is_positive_definite is True and
74      operator_b.is_self_adjoint is True):
75    return True
76  # pylint:enable=g-bool-id-comparison
77
78  return None
79
80
81def combined_non_singular_hint(operator_a, operator_b):
82  """Get combined hint for when ."""
83  # If either operator is not-invertible the composition isn't.
84
85  # pylint:disable=g-bool-id-comparison
86  if (operator_a.is_non_singular is False or
87      operator_b.is_non_singular is False):
88    return False
89  # pylint:enable=g-bool-id-comparison
90
91  return operator_a.is_non_singular and operator_b.is_non_singular
92