Exemple #1
0
  def _trace(self):
    # The diagonal of the [[nested] block] circulant operator is the mean of
    # the spectrum.
    # Proof:  For the [0,...,0] element, this follows from the IDFT formula.
    # Then the result follows since all diagonal elements are the same.

    # Therefore, the trace is the sum of the spectrum.

    # Get shape of diag along with the axis over which to reduce the spectrum.
    # We will reduce the spectrum over all block indices.
    if tensor_shape.TensorShape(self.spectrum.shape).is_fully_defined():
      spec_rank = tensor_shape.TensorShape(self.spectrum.shape).ndims
      axis = np.arange(spec_rank - self.block_depth, spec_rank, dtype=np.int32)
    else:
      spec_rank = array_ops.rank(self.spectrum)
      axis = math_ops.range(spec_rank - self.block_depth, spec_rank)

    # Real diag part "re_d".
    # Suppose tensor_shape.TensorShape(spectrum.shape) = [B1,...,Bb, N1, N2]
    # tensor_shape.TensorShape(self.shape) = [B1,...,Bb, N, N], with N1 * N2 = N.
    # tensor_shape.TensorShape(re_d_value.shape) = [B1,...,Bb]
    re_d_value = math_ops.reduce_sum(math_ops.real(self.spectrum), axis=axis)

    if not np.issubdtype(self.dtype, np.complexfloating):
      return _ops.cast(re_d_value, self.dtype)

    # Imaginary part, "im_d".
    if self.is_self_adjoint:
      im_d_value = array_ops.zeros_like(re_d_value)
    else:
      im_d_value = math_ops.reduce_sum(math_ops.imag(self.spectrum), axis=axis)

    return _ops.cast(math_ops.complex(re_d_value, im_d_value), self.dtype)
Exemple #2
0
def assert_zero_imag_part(x, message=None, name="assert_zero_imag_part"):
  """Returns `Op` that asserts Tensor `x` has no non-zero imaginary parts.

  Args:
    x:  Numeric `Tensor`, real, integer, or complex.
    message:  A string message to prepend to failure message.
    name:  A name to give this `Op`.

  Returns:
    An `Op` that asserts `x` has no entries with modulus zero.
  """
  with ops.name_scope(name, values=[x]):
    x = ops.convert_to_tensor(x, name="x")
    dtype = x.dtype

    if dtype.is_floating:
      return control_flow_ops.no_op()

    zero = ops.convert_to_tensor(0, dtype=dtypes.real_dtype(dtype))
    return check_ops.assert_equal(zero, math_ops.imag(x), message=message)
Exemple #3
0
    def assert_hermitian_spectrum(self, name="assert_hermitian_spectrum"):
        """Returns an `Op` that asserts this operator has Hermitian spectrum.

    This operator corresponds to a real-valued matrix if and only if its
    spectrum is Hermitian.

    Args:
      name:  A name to give this `Op`.

    Returns:
      An `Op` that asserts this operator has Hermitian spectrum.
    """
        eps = np.finfo(dtypes.real_dtype(self.dtype)).eps
        with self._name_scope(name):  # pylint: disable=not-callable
            # Assume linear accumulation of error.
            max_err = eps * self.domain_dimension_tensor()
            imag_convolution_kernel = math_ops.imag(self.convolution_kernel())
            return check_ops.assert_less(math_ops.abs(imag_convolution_kernel),
                                         max_err,
                                         message="Spectrum was not Hermitian")
 def _assert_self_adjoint(self):
     imag_multiplier = math_ops.imag(self.multiplier)
     return check_ops.assert_equal(
         array_ops.zeros_like(imag_multiplier),
         imag_multiplier,
         message="LinearOperator was not self-adjoint")