def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None): """Returns `num` values sampled evenly on a log scale. Equivalent to `base ** linspace(start, stop, num, endpoint)`. Args: start: base**start is the start of the output sequence. stop: If `endpoint` is true and num > 1, base ** stop is included in the output. If `endpoint` is false, `num` + 1 values are linearly sampled in [start, stop] both inclusive and the last value is ignored before raising to power of `base`. num: Number of values to sample. Defaults to 50. endpoint: When to include `base ** stop` in the output. Defaults to true. base: Base of the log space. dtype: Optional. Type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. If not provided, it is figured from input args. """ # TODO(srbs): Check whether dtype is handled properly. if dtype: dtype = utils.to_tf_type(dtype) result = linspace(start, stop, num=num, endpoint=endpoint) result = tf.pow(base, result.data) if dtype: result = utils.maybe_cast(result, dtype) return utils.tensor_to_ndarray(result)
def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=float): """Returns `num` uniformly spread values in a range. Args: start: Start of the interval. Always included in the output. stop: If `endpoint` is true and num > 1, this is included in the output. If `endpoint` is false, `num` + 1 values are sampled in [start, stop] both inclusive and the last value is ignored. num: Number of values to sample. Defaults to 50. endpoint: When to include `stop` in the output. Defaults to true. retstep: Whether to return the step size alongside the output samples. dtype: Optional, defaults to float. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. Returns: An ndarray of output sequence if retstep is False else a 2-tuple of (array, step_size). Raises: ValueError: if `num` is negative. """ # TODO(srbs): Check whether dtype is handled properly. if dtype: dtype = utils.to_tf_type(dtype) start = array(start, copy=False, dtype=dtype) stop = array(stop, copy=False, dtype=dtype) if num == 0: return empty(dtype) if num < 0: raise ValueError( 'Number of samples {} must be non-negative.'.format(num)) step = np_nan if endpoint: result = tf.linspace(start.data, stop.data, num) if num > 1: step = (stop - start) / (num - 1) else: # tf.linspace does not support endpoint=False so we manually handle it # here. if num > 1: step = (stop - start) / num result = tf.linspace(start.data, (stop - step).data, num) else: result = tf.linspace(start.data, stop.data, num) result = utils.maybe_cast(result, dtype) if retstep: return utils.tensor_to_ndarray(result), step else: return utils.tensor_to_ndarray(result)
def array(val, dtype=None, copy=True, ndmin=0): """Creates an ndarray with the contents of val. Args: val: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. dtype: Optional, defaults to dtype of the `val`. The type of the resulting ndarray. Could be a python type, a NumPy type or a TensorFlow `DType`. copy: Determines whether to create a copy of the backing buffer. Since Tensors are immutable, a copy is made only if val is placed on a different device than the current one. Even if `copy` is False, a new Tensor may need to be built to satisfy `dtype` and `ndim`. This is used only if `val` is an ndarray or a Tensor. ndmin: The minimum rank of the returned array. Returns: An ndarray. """ if dtype: dtype = utils.to_tf_type(dtype) if isinstance(val, arrays.ndarray): result_t = val.data else: result_t = val if isinstance(result_t, tf.Tensor): # Copy only if copy=True and a copy would not otherwise be made to satisfy # dtype or ndmin. if (copy and (dtype is None or dtype == utils.array_dtype(val)) and val.ndim >= ndmin): # Note: In eager mode, a copy of `result_t` is made only if it is not on # the context device. result_t = tf.identity(result_t) if not isinstance(result_t, tf.Tensor): # Note: We don't just call tf.convert_to_tensor because, unlike NumPy, # TensorFlow prefers int32 and float32 over int64 and float64. So we compute # the NumPy type of `result_t` and create a tensor of that type instead. if not dtype: dtype = utils.array_dtype(result_t) result_t = tf.convert_to_tensor(result_t) result_t = tf.cast(result_t, dtype=dtype) elif dtype: result_t = utils.maybe_cast(result_t, dtype) ndims = len(result_t.shape) if ndmin > ndims: old_shape = list(result_t.shape) new_shape = [1 for _ in range(ndmin - ndims)] + old_shape result_t = tf.reshape(result_t, new_shape) return utils.tensor_to_ndarray(result_t)
def mean(a, axis=None, dtype=None, keepdims=None): """Computes the mean of elements across dimensions of a tensor. Uses `tf.reduce_mean`. Note that the output dtype for this is different from tf.reduce_mean. For integer arrays, the output type is float64 whereas for float arrays it is the same as the array type. The output type for tf.reduce_mean is always the same as the input array. ```python tf.reduce_mean([1,2,3]) # 2 np.mean([1,2,3]) # 2. ``` Args: a: Instance of ndarray or numpy array_like. axis: Optional 0-d or 1-d array_like. Axes along which to compute mean. If None, operation is performed on flattened array. dtype: Optional. Type of the output array. If None, defaults to the dtype of `a`, unless `a` is an integer type in which case this defaults to `float64`. keepdims: If true, retains reduced dimensions with length 1. Returns: An ndarray. """ a = array_creation.asarray(a) if dtype: dtype = utils.to_tf_type(dtype) else: tf_dtype = tf.as_dtype(a.dtype) if tf_dtype.is_integer or tf_dtype.is_bool: dtype = tf.float64 a_t = utils.maybe_cast(a.data, dtype) return utils.tensor_to_ndarray( tf.reduce_mean(input_tensor=a_t, axis=axis, keepdims=keepdims))