Normalize inputs to two arg functions to fix type promotion rules NumPy deviates from the spec type promotion rules in cases where one argument is 0-dimensional and the other is not. For example: >>> import numpy as np >>> a = np.array([1.0], dtype=np.float
(x1, x2)
| 221 | |
| 222 | @staticmethod |
| 223 | def _normalize_two_args(x1, x2) -> Tuple[Array, Array]: |
| 224 | """ |
| 225 | Normalize inputs to two arg functions to fix type promotion rules |
| 226 | |
| 227 | NumPy deviates from the spec type promotion rules in cases where one |
| 228 | argument is 0-dimensional and the other is not. For example: |
| 229 | |
| 230 | >>> import numpy as np |
| 231 | >>> a = np.array([1.0], dtype=np.float32) |
| 232 | >>> b = np.array(1.0, dtype=np.float64) |
| 233 | >>> np.add(a, b) # The spec says this should be float64 |
| 234 | array([2.], dtype=float32) |
| 235 | |
| 236 | To fix this, we add a dimension to the 0-dimension array before passing it |
| 237 | through. This works because a dimension would be added anyway from |
| 238 | broadcasting, so the resulting shape is the same, but this prevents NumPy |
| 239 | from not promoting the dtype. |
| 240 | """ |
| 241 | # Another option would be to use signature=(x1.dtype, x2.dtype, None), |
| 242 | # but that only works for ufuncs, so we would have to call the ufuncs |
| 243 | # directly in the operator methods. One should also note that this |
| 244 | # sort of trick wouldn't work for functions like searchsorted, which |
| 245 | # don't do normal broadcasting, but there aren't any functions like |
| 246 | # that in the array API namespace. |
| 247 | if x1.ndim == 0 and x2.ndim != 0: |
| 248 | # The _array[None] workaround was chosen because it is relatively |
| 249 | # performant. broadcast_to(x1._array, x2.shape) is much slower. We |
| 250 | # could also manually type promote x2, but that is more complicated |
| 251 | # and about the same performance as this. |
| 252 | x1 = Array._new(x1._array[None]) |
| 253 | elif x2.ndim == 0 and x1.ndim != 0: |
| 254 | x2 = Array._new(x2._array[None]) |
| 255 | return (x1, x2) |
| 256 | |
| 257 | # Note: A large fraction of allowed indices are disallowed here (see the |
| 258 | # docstring below) |
no test coverage detected