예제 #1
0
def _solve_linear_operator(linop_a, linop_b):
  """Generic solve of two `LinearOperator`s."""
  is_square = registrations_util.is_square(linop_a, linop_b)
  is_non_singular = None
  is_self_adjoint = None
  is_positive_definite = None

  if is_square:
    is_non_singular = registrations_util.combined_non_singular_hint(
        linop_a, linop_b)
  elif is_square is False:  # pylint:disable=g-bool-id-comparison
    is_non_singular = False
    is_self_adjoint = False
    is_positive_definite = False

  return linear_operator_composition.LinearOperatorComposition(
      operators=[
          linear_operator_inversion.LinearOperatorInversion(linop_a),
          linop_b
      ],
      is_non_singular=is_non_singular,
      is_self_adjoint=is_self_adjoint,
      is_positive_definite=is_positive_definite,
      is_square=is_square,
  )
def _solve_linear_operator_circulant_circulant(linop_a, linop_b):
    return linear_operator_circulant.LinearOperatorCirculant(
        spectrum=linop_b.spectrum / linop_a.spectrum,
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_a, linop_b),
        is_self_adjoint=registrations_util.
        combined_commuting_self_adjoint_hint(linop_a, linop_b),
        is_positive_definite=(
            registrations_util.combined_commuting_positive_definite_hint(
                linop_a, linop_b)),
        is_square=True)
def _solve_linear_operator_diag_tril(linop_diag, linop_triangular):
    return linear_operator_lower_triangular.LinearOperatorLowerTriangular(
        tril=linop_triangular.to_dense() / linop_diag.diag[..., None],
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_diag, linop_triangular),
        # This is safe to do since the Triangular matrix is only self-adjoint
        # when it is a diagonal matrix, and hence commutes.
        is_self_adjoint=registrations_util.
        combined_commuting_self_adjoint_hint(linop_diag, linop_triangular),
        is_positive_definite=None,
        is_square=True)
def _solve_linear_operator_diag(linop_a, linop_b):
    return linear_operator_diag.LinearOperatorDiag(
        diag=linop_b.diag / linop_a.diag,
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_a, linop_b),
        is_self_adjoint=registrations_util.
        combined_commuting_self_adjoint_hint(linop_a, linop_b),
        is_positive_definite=(
            registrations_util.combined_commuting_positive_definite_hint(
                linop_a, linop_b)),
        is_square=True)
예제 #5
0
def _solve_linear_operator_diag(linop_a, linop_b):
  return linear_operator_diag.LinearOperatorDiag(
      diag=linop_b.diag / linop_a.diag,
      is_non_singular=registrations_util.combined_non_singular_hint(
          linop_a, linop_b),
      is_self_adjoint=registrations_util.combined_commuting_self_adjoint_hint(
          linop_a, linop_b),
      is_positive_definite=(
          registrations_util.combined_commuting_positive_definite_hint(
              linop_a, linop_b)),
      is_square=True)
예제 #6
0
def _solve_linear_operator_circulant_circulant(linop_a, linop_b):
  return linear_operator_circulant.LinearOperatorCirculant(
      spectrum=linop_b.spectrum / linop_a.spectrum,
      is_non_singular=registrations_util.combined_non_singular_hint(
          linop_a, linop_b),
      is_self_adjoint=registrations_util.combined_commuting_self_adjoint_hint(
          linop_a, linop_b),
      is_positive_definite=(
          registrations_util.combined_commuting_positive_definite_hint(
              linop_a, linop_b)),
      is_square=True)
예제 #7
0
def _solve_linear_operator_diag_tril(linop_diag, linop_triangular):
  return linear_operator_lower_triangular.LinearOperatorLowerTriangular(
      tril=linop_triangular.to_dense() / linop_diag.diag[..., None],
      is_non_singular=registrations_util.combined_non_singular_hint(
          linop_diag, linop_triangular),
      # This is safe to do since the Triangular matrix is only self-adjoint
      # when it is a diagonal matrix, and hence commutes.
      is_self_adjoint=registrations_util.combined_commuting_self_adjoint_hint(
          linop_diag, linop_triangular),
      is_positive_definite=None,
      is_square=True)
예제 #8
0
def _solve_linear_operator_diag_scaled_identity_left(
    linop_scaled_identity, linop_diag):
  return linear_operator_diag.LinearOperatorDiag(
      diag=linop_diag.diag / linop_scaled_identity.multiplier,
      is_non_singular=registrations_util.combined_non_singular_hint(
          linop_diag, linop_scaled_identity),
      is_self_adjoint=registrations_util.combined_commuting_self_adjoint_hint(
          linop_diag, linop_scaled_identity),
      is_positive_definite=(
          registrations_util.combined_commuting_positive_definite_hint(
              linop_diag, linop_scaled_identity)),
      is_square=True)
예제 #9
0
def _matmul_linear_operator_diag_scaled_identity_left(
    linop_scaled_identity, linop_diag):
  return linear_operator_diag.LinearOperatorDiag(
      diag=linop_diag.diag * linop_scaled_identity.multiplier,
      is_non_singular=registrations_util.combined_non_singular_hint(
          linop_diag, linop_scaled_identity),
      is_self_adjoint=registrations_util.combined_commuting_self_adjoint_hint(
          linop_diag, linop_scaled_identity),
      is_positive_definite=(
          registrations_util.combined_commuting_positive_definite_hint(
              linop_diag, linop_scaled_identity)),
      is_square=True)
def _solve_linear_operator_scaled_identity(linop_a, linop_b):
    """Solve of two ScaledIdentity `LinearOperators`."""
    return linear_operator_identity.LinearOperatorScaledIdentity(
        num_rows=linop_a.domain_dimension_tensor(),
        multiplier=linop_b.multiplier / linop_a.multiplier,
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_a, linop_b),
        is_self_adjoint=registrations_util.
        combined_commuting_self_adjoint_hint(linop_a, linop_b),
        is_positive_definite=(
            registrations_util.combined_commuting_positive_definite_hint(
                linop_a, linop_b)),
        is_square=True)
예제 #11
0
def _matmul_linear_operator_circulant_circulant(linop_a, linop_b):
    if not isinstance(linop_a, linop_b.__class__):
        return _matmul_linear_operator(linop_a, linop_b)

    return linop_a.__class__(
        spectrum=linop_a.spectrum * linop_b.spectrum,
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_a, linop_b),
        is_self_adjoint=registrations_util.
        combined_commuting_self_adjoint_hint(linop_a, linop_b),
        is_positive_definite=(
            registrations_util.combined_commuting_positive_definite_hint(
                linop_a, linop_b)),
        is_square=True)
def _solve_linear_operator_block_diag_block_diag(linop_a, linop_b):
    return linear_operator_block_diag.LinearOperatorBlockDiag(
        operators=[
            o1.solve(o2)
            for o1, o2 in zip(linop_a.operators, linop_b.operators)
        ],
        is_non_singular=registrations_util.combined_non_singular_hint(
            linop_a, linop_b),
        # In general, a solve of self-adjoint positive-definite block diagonal
        # matrices is not self-=adjoint.
        is_self_adjoint=None,
        # In general, a solve of positive-definite block diagonal matrices is
        # not positive-definite.
        is_positive_definite=None,
        is_square=True)
예제 #13
0
def _matmul_linear_operator(linop_a, linop_b):
    """Generic matmul of two `LinearOperator`s."""
    is_square = registrations_util.is_square(linop_a, linop_b)
    is_non_singular = None
    is_self_adjoint = None
    is_positive_definite = None

    if is_square:
        is_non_singular = registrations_util.combined_non_singular_hint(
            linop_a, linop_b)
    elif is_square is False:  # pylint:disable=g-bool-id-comparison
        is_non_singular = False
        is_self_adjoint = False
        is_positive_definite = False

    return linear_operator_composition.LinearOperatorComposition(
        operators=[linop_a, linop_b],
        is_non_singular=is_non_singular,
        is_self_adjoint=is_self_adjoint,
        is_positive_definite=is_positive_definite,
        is_square=is_square,
    )