aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/python/ops/math_ops.py
diff options
context:
space:
mode:
Diffstat (limited to 'tensorflow/python/ops/math_ops.py')
-rw-r--r--tensorflow/python/ops/math_ops.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/tensorflow/python/ops/math_ops.py b/tensorflow/python/ops/math_ops.py
index 0063de52c7..0b3509360e 100644
--- a/tensorflow/python/ops/math_ops.py
+++ b/tensorflow/python/ops/math_ops.py
@@ -129,6 +129,9 @@ See the @{$python/math_ops} guide.
@@segment_mean
@@unsorted_segment_sum
@@unsorted_segment_max
+@@unsorted_segment_min
+@@unsorted_segment_prod
+@@unsorted_segment_sqrt_n
@@sparse_segment_sum
@@sparse_segment_mean
@@sparse_segment_sqrt_n
@@ -898,6 +901,40 @@ def to_bfloat16(x, name="ToBFloat16"):
return cast(x, dtypes.bfloat16, name=name)
+@tf_export("to_complex64")
+def to_complex64(x, name="ToComplex64"):
+ """Casts a tensor to type `complex64`.
+
+ Args:
+ x: A `Tensor` or `SparseTensor`.
+ name: A name for the operation (optional).
+
+ Returns:
+ A `Tensor` or `SparseTensor` with same shape as `x` with type `complex64`.
+
+ Raises:
+ TypeError: If `x` cannot be cast to the `complex64`.
+ """
+ return cast(x, dtypes.complex64, name=name)
+
+
+@tf_export("to_complex128")
+def to_complex128(x, name="ToComplex128"):
+ """Casts a tensor to type `complex128`.
+
+ Args:
+ x: A `Tensor` or `SparseTensor`.
+ name: A name for the operation (optional).
+
+ Returns:
+ A `Tensor` or `SparseTensor` with same shape as `x` with type `complex128`.
+
+ Raises:
+ TypeError: If `x` cannot be cast to the `complex128`.
+ """
+ return cast(x, dtypes.complex128, name=name)
+
+
ops.Tensor._override_operator("__neg__", gen_math_ops.neg)
ops.Tensor._override_operator("__abs__", abs)
# __invert__ corresponds to the ~ operator. Here we follow the numpy convention
@@ -2559,6 +2596,87 @@ def reduced_shape(input_shape, axes):
]) # [1, 1]
+def _unsorted_segment_N(data, segment_ids, num_segments):
+ """ Helper function for unsorted_segment_mean/_sqrtN. Computes the number
+ of segment entries with 0-entries set to 1 to allow division by N.
+ """
+ # bincount doesn't support negative indices so we use unsorted_segment_sum
+ ones_tensor = array_ops.ones(segment_ids.shape, dtype=data.dtype)
+ N = gen_math_ops.unsorted_segment_sum(ones_tensor, segment_ids, num_segments)
+ # add dimensions for all non-reduced axes
+ ndims_output = data.shape.ndims - segment_ids.shape.ndims
+ broadcast_shape = [num_segments] + [1] * ndims_output
+ N = array_ops.reshape(N, broadcast_shape)
+ return gen_math_ops.maximum(N, 1)
+
+
+@tf_export("unsorted_segment_mean")
+def unsorted_segment_mean(data, segment_ids, num_segments, name=None):
+ r""" Computes the mean along segments of a tensor.
+
+ Read @{$math_ops#segmentation$the section on segmentation} for an explanation
+ of segments.
+
+ This operator is similar to the unsorted segment sum operator found
+ [here](../../../api_docs/python/math_ops.md#UnsortedSegmentSum).
+ Instead of computing the sum over segments, it computes the mean of all
+ entries belonging to a segment such that:
+
+ \\(output_i = 1/N_i \sum data_j\\) where the sum is over `j` such
+ that `segment_ids[j] == i` with \\N_i\\ being the number of occurrences
+ of id \\i\\.
+
+ If there is no entry for a given segment ID `i`, it outputs 0.
+
+ segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s
+ first dimension.
+
+ output: Has same shape as data, except for dimension 0 which
+ has size `num_segments`.
+ """
+ with ops.name_scope(name, "UnsortedSegmentMean"):
+ data = ops.convert_to_tensor(data)
+ segment_ids = ops.convert_to_tensor(segment_ids)
+ N = _unsorted_segment_N(data, segment_ids, num_segments)
+ summed = gen_math_ops.unsorted_segment_sum(data, segment_ids, num_segments)
+ return summed / N
+
+
+@tf_export("unsorted_segment_sqrt_n")
+def unsorted_segment_sqrt_n(data, segment_ids, num_segments, name=None):
+ r"""Computes the sum along segments of a tensor divided by the sqrt(N).
+
+ Read @{$math_ops#segmentation$the section on segmentation} for an explanation
+ of segments.
+
+ This operator is similar to the unsorted segment sum operator found
+ [here](../../../api_docs/python/math_ops.md#UnsortedSegmentSum).
+ Additionally to computing the sum over segments, it divides the results by
+ sqrt(N).
+
+ \\(output_i = 1/sqrt(N_i) \sum data_j\\) where the sum is over `j` such
+ that `segment_ids[j] == i` with \\N_i\\ being the number of occurrences
+ of id \\i\\.
+
+ If there is no entry for a given segment ID `i`, it outputs 0.
+
+ Note that this op only supports floating point and complex dtypes,
+ due to tf.sqrt only supporting these types.
+
+ segment_ids: A 1-D tensor whose rank is equal to the rank of `data`'s
+ first dimension.
+
+ output: Has same shape as data, except for dimension 0 which
+ has size `num_segments`.
+ """
+ with ops.name_scope(name, "UnsortedSegmentSqrtN"):
+ data = ops.convert_to_tensor(data)
+ segment_ids = ops.convert_to_tensor(segment_ids)
+ N = _unsorted_segment_N(data, segment_ids, num_segments)
+ summed = gen_math_ops.unsorted_segment_sum(data, segment_ids, num_segments)
+ return summed / gen_math_ops.sqrt(N)
+
+
@tf_export("sparse_segment_sum")
def sparse_segment_sum(data, indices, segment_ids, name=None,
num_segments=None):