Skip to content

linspace behavior is underspecified for integer dtypes #392

Closed
@kgryte

Description

@kgryte

The specification for linspace is currently underspecified for integer output array dtypes. Namely, the specification is silent concerning the following scenarios:

  1. what should happen start and stop are floating-point numbers with non-integral values and dtype is an integer data type?

    linspace( 1.4, 100.75, num=50, dtype="int32" )
  2. what should happen when start and stop are Python ints and dtype is an integer data type, but the computed spacing between adjacent elements is not an integral value?

    linspace( 0, 10, num=100, dtype="int32" )

For both scenarios, one option is to add a note to the specification stating that behavior in these instances is implementation-dependent--a conforming implementation would be free to round/truncate, raise an exception, or something else.

Otherwise, for (1), this could be explicitly disallowed in the specification; i.e., if start and stop are floating-point, then only floating-point dtypes are allowed.

For (2), this is somewhat trickier to resolve as the spacing between adjacent elements is an implicit variable which users may find difficult to reason about without explicitly computing the spacing and determining whether, say, a specific argument combination might trigger an exception. However, we could opt to be pedantic and only allow integer dtypes when start, stop, and the computed spacing are all integer values. Otherwise, an exception should be raised.

A final option is that linspace could be restricted to only floating-point data types. If a user wants to return an output array with an integer data type, they could use arange and explicitly specify the step.

Prior Art

  • NumPy's linspace floors non-integral values when the output array data type is an integer dtype.

    >>> np.linspace(1.0,10,21,dtype="int32")                                                            
    array([ 1,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  5,  6,  6,  7,  7,  8,
        8,  9,  9, 10], dtype=int32)
  • TensorFlow's linspace only supports floating-point data types.

  • PyTorch's linspace floors non-integral values when the output array data type is an integer dtype.

    >>> torch.linspace(1.0,10,21,dtype=torch.int32)
    tensor([ 1,  1,  1,  2,  2,  3,  3,  4,  4,  4,  4,  5,  5,  6,  6,  7,  8,  8,
         9,  9, 10], dtype=torch.int32)
  • MXNet's np.linspace attempts to match NumPy's API.

Observations

In general, returning non-evenly spaced values due to integer rounding seems generally undesired and not particularly useful. If the specification was more restrictive, users wanting to replicate the current functionality of NumPy and PyTorch could generate a floating-point output array using linspace and then perform an explicit cast to the desired integer data type.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions