Skip to content

DOC: numpy.result_type promotion "algorithm" is outdated #29821

Description

@MustafaYounes1

Describe the issue:

According to the API Reference, the algorithm of numpy.result_type determines the output type following these steps:

  1. Categories are determined by first checking which of boolean, integer (int/uint), or floating point (float/complex) the maximum kind of all the arrays and the scalars are.

  2. If there are only scalars or the maximum category of the scalars is higher than the maximum category of the arrays, the data types are combined with promote_types to produce the return value.

  3. Otherwise, min_scalar_type is called on each scalar, and the resulting data types are all combined with promote_types to produce the return value.

However, when it's provided with a Python scalar and an ndarray of the same category (e.g., int), it seems it completely ignores the scalar and outputs whatever datatype the ndarray has (and that contradicts the third point above; according to the doc, it should apply min_scalar_type on the scalar, and follow that with a call to promote_types).

However, when the provided scalar is a NumPy scalar, the behavior is different: what it seemingly does is only a call to promote_types

So, I'm wondering why the behavior is inconsistent on NumPy/Python scalars, and what exactly the role of min_scalar_type is in this context?

Please take a look at the provided code that shows this unexpected behaviour with a couple of examples.

Reproduce the code example:

importnumpyasnp############## Example 1 ############### Both the ndarray and the scalar are of the same category (int)s=-129a=np.empty(1, dtype='i1')
# Python Scalar & ndarray# The following outputs 'int8' (completely ignoring the scalar)print(np.result_type(s, a))
# according to the doc; it should have called:print(np.promote_types(np.min_scalar_type(s), a.dtype)) # gives int16# NumPy Scalar & ndarray# gives 'int16' (seemingly only calls np.promote_types)print(np.result_type(np.int16(s), a)) ############## Example 2 ############### The ndarray has a higher category (float vs int)s=np.iinfo(np.int64).maxa=np.empty(1, np.float32)
# Python Scalar & ndarray# The following outputs 'float32' (completely ignoring the scalar)print(np.result_type(s, a))
# according to the doc; it should have called:print(np.promote_types(np.min_scalar_type(s), a.dtype)) # gives float64# NumPy Scalar & ndarray# gives 'float64' (seemingly only calls np.promote_types)print(np.result_type(np.int64(1), a))
# Pay attention to the following: (np.min_scalar_type is not used at all)print(np.min_scalar_type(np.int64(1))) # gives uint8print(np.promote_types(np.min_scalar_type(np.int64(1)), a.dtype)) # gives float32

Python and NumPy Versions:

Python: 3.11.5
NumPy: 2.3.1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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