@tf_export('math.reduce_logsumexp', 'reduce_logsumexp', v1=[])
def reduce_logsumexp(input_tensor, axis=None, keepdims=False, name=None):
    'Computes log(sum(exp(elements across dimensions of a tensor))).\n\n  Reduces `input_tensor` along the dimensions given in `axis`.\n  Unless `keepdims` is true, the rank of the tensor is reduced by 1 for each\n  entry in `axis`. If `keepdims` is true, the reduced dimensions\n  are retained with length 1.\n\n  If `axis` has no entries, all dimensions are reduced, and a\n  tensor with a single element is returned.\n\n  This function is more numerically stable than log(sum(exp(input))). It avoids\n  overflows caused by taking the exp of large inputs and underflows caused by\n  taking the log of small inputs.\n\n  For example:\n\n  ```python\n  x = tf.constant([[0., 0., 0.], [0., 0., 0.]])\n  tf.reduce_logsumexp(x)  # log(6)\n  tf.reduce_logsumexp(x, 0)  # [log(2), log(2), log(2)]\n  tf.reduce_logsumexp(x, 1)  # [log(3), log(3)]\n  tf.reduce_logsumexp(x, 1, keepdims=True)  # [[log(3)], [log(3)]]\n  tf.reduce_logsumexp(x, [0, 1])  # log(6)\n  ```\n\n  Args:\n    input_tensor: The tensor to reduce. Should have numeric type.\n    axis: The dimensions to reduce. If `None` (the default), reduces all\n      dimensions. Must be in the range `[-rank(input_tensor),\n      rank(input_tensor))`.\n    keepdims: If true, retains reduced dimensions with length 1.\n    name: A name for the operation (optional).\n\n  Returns:\n    The reduced tensor.\n  '
    keepdims = (False if (keepdims is None) else keepdims)
    input_tensor = ops.convert_to_tensor(input_tensor)
    with ops.name_scope(name, 'ReduceLogSumExp', [input_tensor]) as name:
        raw_max = reduce_max(input_tensor, axis=axis, keepdims=True)
        my_max = array_ops.stop_gradient(array_ops.where(gen_math_ops.is_finite(raw_max), raw_max, array_ops.zeros_like(raw_max)))
        result = gen_math_ops.log(reduce_sum(gen_math_ops.exp(gen_math_ops.sub(input_tensor, my_max)), axis, keepdims=keepdims))
        if (not keepdims):
            my_max = array_ops.reshape(my_max, array_ops.shape(result))
        result = gen_math_ops.add(result, my_max)
        return _may_reduce_to_scalar(keepdims, axis, result)
Computes log(sum(exp(elements across dimensions of a tensor))).

Reduces `input_tensor` along the dimensions given in `axis`.
Unless `keepdims` is true, the rank of the tensor is reduced by 1 for each
entry in `axis`. If `keepdims` is true, the reduced dimensions
are retained with length 1.

If `axis` has no entries, all dimensions are reduced, and a
tensor with a single element is returned.

This function is more numerically stable than log(sum(exp(input))). It avoids
overflows caused by taking the exp of large inputs and underflows caused by
taking the log of small inputs.

For example:

```python
x = tf.constant([[0., 0., 0.], [0., 0., 0.]])
tf.reduce_logsumexp(x)  # log(6)
tf.reduce_logsumexp(x, 0)  # [log(2), log(2), log(2)]
tf.reduce_logsumexp(x, 1)  # [log(3), log(3)]
tf.reduce_logsumexp(x, 1, keepdims=True)  # [[log(3)], [log(3)]]
tf.reduce_logsumexp(x, [0, 1])  # log(6)
```

Args:
  input_tensor: The tensor to reduce. Should have numeric type.
  axis: The dimensions to reduce. If `None` (the default), reduces all
    dimensions. Must be in the range `[-rank(input_tensor),
    rank(input_tensor))`.
  keepdims: If true, retains reduced dimensions with length 1.
  name: A name for the operation (optional).

Returns:
  The reduced tensor.
@tf_export('math.reduce_logsumexp', 'reduce_logsumexp', v1=[])
def reduce_logsumexp(input_tensor, axis=None, keepdims=False, name=None):
    'Computes log(sum(exp(elements across dimensions of a tensor))).\n\n  Reduces `input_tensor` along the dimensions given in `axis`.\n  Unless `keepdims` is true, the rank of the tensor is reduced by 1 for each\n  entry in `axis`. If `keepdims` is true, the reduced dimensions\n  are retained with length 1.\n\n  If `axis` has no entries, all dimensions are reduced, and a\n  tensor with a single element is returned.\n\n  This function is more numerically stable than log(sum(exp(input))). It avoids\n  overflows caused by taking the exp of large inputs and underflows caused by\n  taking the log of small inputs.\n\n  For example:\n\n  ```python\n  x = tf.constant([[0., 0., 0.], [0., 0., 0.]])\n  tf.reduce_logsumexp(x)  # log(6)\n  tf.reduce_logsumexp(x, 0)  # [log(2), log(2), log(2)]\n  tf.reduce_logsumexp(x, 1)  # [log(3), log(3)]\n  tf.reduce_logsumexp(x, 1, keepdims=True)  # [[log(3)], [log(3)]]\n  tf.reduce_logsumexp(x, [0, 1])  # log(6)\n  ```\n\n  Args:\n    input_tensor: The tensor to reduce. Should have numeric type.\n    axis: The dimensions to reduce. If `None` (the default), reduces all\n      dimensions. Must be in the range `[-rank(input_tensor),\n      rank(input_tensor))`.\n    keepdims: If true, retains reduced dimensions with length 1.\n    name: A name for the operation (optional).\n\n  Returns:\n    The reduced tensor.\n  '
    keepdims = (False if (keepdims is None) else keepdims)
    input_tensor = ops.convert_to_tensor(input_tensor)
    with ops.name_scope(name, 'ReduceLogSumExp', [input_tensor]) as name:
        raw_max = reduce_max(input_tensor, axis=axis, keepdims=True)
        my_max = array_ops.stop_gradient(array_ops.where(gen_math_ops.is_finite(raw_max), raw_max, array_ops.zeros_like(raw_max)))
        result = gen_math_ops.log(reduce_sum(gen_math_ops.exp(gen_math_ops.sub(input_tensor, my_max)), axis, keepdims=keepdims))
        if (not keepdims):
            my_max = array_ops.reshape(my_max, array_ops.shape(result))
        result = gen_math_ops.add(result, my_max)
        return _may_reduce_to_scalar(keepdims, axis, result)