def _make_multiplier_matrix(self, conjugate=False):
     # Shape [B1,...Bb, 1, 1]
     multiplier_matrix = array_ops.expand_dims(
         array_ops.expand_dims(self.multiplier, -1), -1)
     if conjugate:
         multiplier_matrix = math_ops.conj(multiplier_matrix)
     return multiplier_matrix
예제 #2
0
def _adjoint_diag(diag_operator):
    diag = diag_operator.diag
    if np.issubdtype(diag.dtype, np.complexfloating):
        diag = math_ops.conj(diag)

    return linear_operator_diag.LinearOperatorDiag(
        diag=diag,
        is_non_singular=diag_operator.is_non_singular,
        is_self_adjoint=diag_operator.is_self_adjoint,
        is_positive_definite=diag_operator.is_positive_definite,
        is_square=True)
예제 #3
0
def _adjoint_scaled_identity(identity_operator):
    multiplier = identity_operator.multiplier
    if np.issubdtype(multiplier.dtype, np.complexfloating):
        multiplier = math_ops.conj(multiplier)

    return linear_operator_identity.LinearOperatorScaledIdentity(
        num_rows=identity_operator._num_rows,  # pylint: disable=protected-access
        multiplier=multiplier,
        is_non_singular=identity_operator.is_non_singular,
        is_self_adjoint=identity_operator.is_self_adjoint,
        is_positive_definite=identity_operator.is_positive_definite,
        is_square=True)
예제 #4
0
def _adjoint_circulant(circulant_operator):
    spectrum = circulant_operator.spectrum
    if np.issubdtype(spectrum.dtype, np.complexfloating):
        spectrum = math_ops.conj(spectrum)

    # Conjugating the spectrum is sufficient to get the adjoint.
    return linear_operator_circulant.LinearOperatorCirculant(
        spectrum=spectrum,
        is_non_singular=circulant_operator.is_non_singular,
        is_self_adjoint=circulant_operator.is_self_adjoint,
        is_positive_definite=circulant_operator.is_positive_definite,
        is_square=True)
예제 #5
0
    def __init__(self,
                 spectrum,
                 block_depth,
                 input_output_dtype=dtypes.complex64,
                 is_non_singular=None,
                 is_self_adjoint=None,
                 is_positive_definite=None,
                 is_square=True,
                 name="LinearOperatorCirculant"):
        r"""Initialize an `_BaseLinearOperatorCirculant`.

    Args:
      spectrum:  Shape `[B1,...,Bb, N]` `Tensor`.  Allowed dtypes: `float16`,
        `float32`, `float64`, `complex64`, `complex128`.  Type can be different
        than `input_output_dtype`
      block_depth:  Python integer, either 1, 2, or 3.  Will be 1 for circulant,
        2 for block circulant, and 3 for nested block circulant.
      input_output_dtype: `dtype` for input/output.
      is_non_singular:  Expect that this operator is non-singular.
      is_self_adjoint:  Expect that this operator is equal to its hermitian
        transpose.  If `spectrum` is real, this will always be true.
      is_positive_definite:  Expect that this operator is positive definite,
        meaning the quadratic form `x^H A x` has positive real part for all
        nonzero `x`.  Note that we do not require the operator to be
        self-adjoint to be positive-definite.  See:
        https://en.wikipedia.org/wiki/Positive-definite_matrix\
            #Extension_for_non_symmetric_matrices
      is_square:  Expect that this operator acts like square [batch] matrices.
      name:  A name to prepend to all ops created by this class.

    Raises:
      ValueError:  If `block_depth` is not an allowed value.
      TypeError:  If `spectrum` is not an allowed type.
    """

        allowed_block_depths = [1, 2, 3]

        self._name = name

        if block_depth not in allowed_block_depths:
            raise ValueError("Expected block_depth to be in %s.  Found: %s." %
                             (allowed_block_depths, block_depth))
        self._block_depth = block_depth

        with ops.name_scope(name, values=[spectrum]):
            self._spectrum = self._check_spectrum_and_return_tensor(spectrum)

            # Check and auto-set hints.
            if not np.issubdtype(self.spectrum.dtype, np.complexfloating):
                if is_self_adjoint is False:
                    raise ValueError(
                        "A real spectrum always corresponds to a self-adjoint operator."
                    )
                is_self_adjoint = True

            if is_square is False:
                raise ValueError(
                    "A [[nested] block] circulant operator is always square.")
            is_square = True

            # If _ops.TensorShape(spectrum.shape) = [s0, s1, s2], and block_depth = 2,
            # block_shape = [s1, s2]
            s_shape = array_ops.shape(self.spectrum)
            self._block_shape_tensor = s_shape[-self.block_depth:]

            # Add common variants of spectrum to the graph.
            self._spectrum_complex = _to_complex(self.spectrum)
            self._abs_spectrum = math_ops.abs(self.spectrum)
            self._conj_spectrum = math_ops.conj(self._spectrum_complex)

            super(_BaseLinearOperatorCirculant,
                  self).__init__(dtype=dtypes.as_dtype(input_output_dtype),
                                 graph_parents=[self.spectrum],
                                 is_non_singular=is_non_singular,
                                 is_self_adjoint=is_self_adjoint,
                                 is_positive_definite=is_positive_definite,
                                 is_square=is_square,
                                 name=name)
 def _solve(self, rhs, adjoint=False, adjoint_arg=False):
     diag_term = math_ops.conj(self._diag) if adjoint else self._diag
     rhs = linalg.adjoint(rhs) if adjoint_arg else rhs
     inv_diag_mat = array_ops.expand_dims(1. / diag_term, -1)
     return rhs * inv_diag_mat
 def _matvec(self, x, adjoint=False):
     diag_term = math_ops.conj(self._diag) if adjoint else self._diag
     return diag_term * x
 def _matmul(self, x, adjoint=False, adjoint_arg=False):
     diag_term = math_ops.conj(self._diag) if adjoint else self._diag
     x = linalg.adjoint(x) if adjoint_arg else x
     diag_mat = array_ops.expand_dims(diag_term, -1)
     return diag_mat * x
예제 #9
0
 def _trace(self):
     if self.is_self_adjoint:
         return self.operator.trace()
     return math_ops.conj(self.operator.trace())
예제 #10
0
 def _determinant(self):
     if self.is_self_adjoint:
         return self.operator.determinant()
     return math_ops.conj(self.operator.determinant())
예제 #11
0
 def _diag_part(self):
     normalized_axis = self.reflection_axis / linalg.norm(
         self.reflection_axis, axis=-1, keepdims=True)
     return 1. - 2 * normalized_axis * math_ops.conj(normalized_axis)