def sufficient_statistics(x, axes, shift=None, keep_dims=False, name=None):
    "Calculate the sufficient statistics for the mean and variance of `x`.\n\n  These sufficient statistics are computed using the one pass algorithm on\n  an input that's optionally shifted. See:\n  https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Computing_shifted_data\n\n  Args:\n    x: A `Tensor`.\n    axes: Array of ints. Axes along which to compute mean and variance.\n    shift: A `Tensor` containing the value by which to shift the data for\n      numerical stability, or `None` if no shift is to be performed. A shift\n      close to the true mean provides the most numerically stable results.\n    keep_dims: produce statistics with the same dimensionality as the input.\n    name: Name used to scope the operations that compute the sufficient stats.\n\n  Returns:\n    Four `Tensor` objects of the same type as `x`:\n    * the count (number of elements to average over).\n    * the (possibly shifted) sum of the elements in the array.\n    * the (possibly shifted) sum of squares of the elements in the array.\n    * the shift by which the mean must be corrected or None if `shift` is None.\n  "
    with ops.op_scope([x, axes, shift], name, 'sufficient_statistics'):
        x = ops.convert_to_tensor(x, name='x')
        x_shape = x.get_shape()
        if x_shape.is_fully_defined():
            counts = 1
            m_shape = []
            for d in xrange(x_shape.ndims):
                dim = x_shape[d].value
                if (d in set(axes)):
                    counts *= dim
                    dim = 1
                m_shape.append(dim)
            counts = constant_op.constant(counts, dtype=x.dtype)
        else:
            x_shape = array_ops.shape(x)
            select_axes = sparse_ops.sparse_to_dense(axes, array_ops.shape(x_shape), True, False)
            m_shape = math_ops.select(select_axes, array_ops.ones_like(x_shape), x_shape)
            counts = math_ops.cast(math_ops.reduce_prod((x_shape / m_shape)), x.dtype, name='count')
        if (shift is not None):
            shift = ops.convert_to_tensor(shift, name='shift')
            m_ss = math_ops.sub(x, shift)
            v_ss = math_ops.squared_difference(x, shift)
        else:
            m_ss = x
            v_ss = math_ops.square(x)
        m_ss = math_ops.reduce_sum(m_ss, axes, keep_dims=keep_dims, name='mean_ss')
        v_ss = math_ops.reduce_sum(v_ss, axes, keep_dims=keep_dims, name='var_ss')
    return (counts, m_ss, v_ss, shift)
Calculate the sufficient statistics for the mean and variance of `x`.

These sufficient statistics are computed using the one pass algorithm on
an input that's optionally shifted. See:
https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Computing_shifted_data

Args:
  x: A `Tensor`.
  axes: Array of ints. Axes along which to compute mean and variance.
  shift: A `Tensor` containing the value by which to shift the data for
    numerical stability, or `None` if no shift is to be performed. A shift
    close to the true mean provides the most numerically stable results.
  keep_dims: produce statistics with the same dimensionality as the input.
  name: Name used to scope the operations that compute the sufficient stats.

Returns:
  Four `Tensor` objects of the same type as `x`:
  * the count (number of elements to average over).
  * the (possibly shifted) sum of the elements in the array.
  * the (possibly shifted) sum of squares of the elements in the array.
  * the shift by which the mean must be corrected or None if `shift` is None.
def sufficient_statistics(x, axes, shift=None, keep_dims=False, name=None):
    "Calculate the sufficient statistics for the mean and variance of `x`.\n\n  These sufficient statistics are computed using the one pass algorithm on\n  an input that's optionally shifted. See:\n  https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Computing_shifted_data\n\n  Args:\n    x: A `Tensor`.\n    axes: Array of ints. Axes along which to compute mean and variance.\n    shift: A `Tensor` containing the value by which to shift the data for\n      numerical stability, or `None` if no shift is to be performed. A shift\n      close to the true mean provides the most numerically stable results.\n    keep_dims: produce statistics with the same dimensionality as the input.\n    name: Name used to scope the operations that compute the sufficient stats.\n\n  Returns:\n    Four `Tensor` objects of the same type as `x`:\n    * the count (number of elements to average over).\n    * the (possibly shifted) sum of the elements in the array.\n    * the (possibly shifted) sum of squares of the elements in the array.\n    * the shift by which the mean must be corrected or None if `shift` is None.\n  "
    with ops.op_scope([x, axes, shift], name, 'sufficient_statistics'):
        x = ops.convert_to_tensor(x, name='x')
        x_shape = x.get_shape()
        if x_shape.is_fully_defined():
            counts = 1
            m_shape = []
            for d in xrange(x_shape.ndims):
                dim = x_shape[d].value
                if (d in set(axes)):
                    counts *= dim
                    dim = 1
                m_shape.append(dim)
            counts = constant_op.constant(counts, dtype=x.dtype)
        else:
            x_shape = array_ops.shape(x)
            select_axes = sparse_ops.sparse_to_dense(axes, array_ops.shape(x_shape), True, False)
            m_shape = math_ops.select(select_axes, array_ops.ones_like(x_shape), x_shape)
            counts = math_ops.cast(math_ops.reduce_prod((x_shape / m_shape)), x.dtype, name='count')
        if (shift is not None):
            shift = ops.convert_to_tensor(shift, name='shift')
            m_ss = math_ops.sub(x, shift)
            v_ss = math_ops.squared_difference(x, shift)
        else:
            m_ss = x
            v_ss = math_ops.square(x)
        m_ss = math_ops.reduce_sum(m_ss, axes, keep_dims=keep_dims, name='mean_ss')
        v_ss = math_ops.reduce_sum(v_ss, axes, keep_dims=keep_dims, name='var_ss')
    return (counts, m_ss, v_ss, shift)