def assert_no_entries_with_modulus_zero( x, message=None, name="assert_no_entries_with_modulus_zero"): """Returns `Op` that asserts Tensor `x` has no entries with modulus zero. 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 should_be_nonzero = math_ops.abs(x) zero = ops.convert_to_tensor(0, dtype=dtypes.real_dtype(dtype)) return check_ops.assert_less(zero, should_be_nonzero, message=message)
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)
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 __init__(self, num_rows, multiplier, is_non_singular=None, is_self_adjoint=None, is_positive_definite=None, is_square=True, assert_proper_shapes=False, name="LinearOperatorScaledIdentity"): r"""Initialize a `LinearOperatorScaledIdentity`. The `LinearOperatorScaledIdentity` is initialized with `num_rows`, which determines the size of each identity matrix, and a `multiplier`, which defines `dtype`, batch shape, and scale of each matrix. This operator is able to broadcast the leading (batch) dimensions. Args: num_rows: Scalar non-negative integer `Tensor`. Number of rows in the corresponding identity matrix. multiplier: `Tensor` of shape `[B1,...,Bb]`, or `[]` (a scalar). is_non_singular: Expect that this operator is non-singular. is_self_adjoint: Expect that this operator is equal to its hermitian transpose. 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. assert_proper_shapes: Python `bool`. If `False`, only perform static checks that initialization and method arguments have proper shape. If `True`, and static checks are inconclusive, add asserts to the graph. name: A name for this `LinearOperator` Raises: ValueError: If `num_rows` is determined statically to be non-scalar, or negative. """ self._assert_proper_shapes = assert_proper_shapes with ops.name_scope(name, values=[multiplier, num_rows]): self._multiplier = linear_operator_util.convert_nonref_to_tensor( multiplier, name="multiplier") # Check and auto-set hints. if not np.issubdtype(self._multiplier.dtype, np.complexfloating): if is_self_adjoint is False: # pylint: disable=g-bool-id-comparison raise ValueError( "A real diagonal operator is always self adjoint.") else: is_self_adjoint = True if not is_square: raise ValueError("A ScaledIdentity operator is always square.") linear_operator_util.assert_not_ref_type(num_rows, "num_rows") super(LinearOperatorScaledIdentity, self).__init__(dtype=self._multiplier.dtype, is_non_singular=is_non_singular, is_self_adjoint=is_self_adjoint, is_positive_definite=is_positive_definite, is_square=is_square, name=name) self._num_rows = linear_operator_util.shape_tensor(num_rows, name="num_rows") self._num_rows_static = (self._num_rows) self._check_num_rows_possibly_add_asserts() self._num_rows_cast_to_dtype = _ops.cast(self._num_rows, self.dtype) self._num_rows_cast_to_real_dtype = _ops.cast( self._num_rows, dtypes.real_dtype(self.dtype))