Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Change default values for "domain" and "window" parameters of Polynomial class #24568

Open
KrisMinchev opened this issue Aug 28, 2023 · 1 comment

Comments

@KrisMinchev
Copy link
Contributor

Proposed new feature or change:

The current default values for both domain and window parameters are both np.array([-1, 1]). On the other hand, if we call __init__ with 3 parameters, then domain and window always get cast to double. This leads to the following behaviour:

>>> p1 = P(np.array([1,2,3]))
>>> p1
Polynomial([1., 2., 3.], domain=[-1,  1], window=[-1,  1], symbol='x')
>>> p2 = P(np.array([1,2,3]), np.array([-1, 1]), np.array([-1,1]))
>>> p2
Polynomial([1., 2., 3.], domain=[-1.,  1.], window=[-1.,  1.], symbol='x')
>>> p1.domain.dtype
dtype('int64')
>>> p2.domain.dtype
dtype('float64')

Changing the default values of the parameters domain and window to np.array([-1., 1.]) will increase consistency between constructors Polynomial(coef) and Polynomial(coef, domain, window).

@eendebakpt
Copy link
Contributor

The conversion of the input arguments happens in numpy.polynomial.polyutils.as_series. Besides checking dimensions, it converts all input to a numpy array of type double, complex double or object.

Note that also numpy.polynomial.polyzero is of integer type, even though the zero polynomial has coefficients np.array([0.]). (similar for numpy.polynomial.polyone and numpy.polynomial.polyx).

It is indeed odd that one cannot create the polynomial p1 by setting the domain and window directly. Changing the code (e.g. main...eendebakpt:polynomial_float_domain) and running unit testing results in no errors (expect for a test on the representation).

Maybe there are cases with custom objects where the difference matters, but I could not find any examples. I tried creating something with fractions.Fraction, but that seems to work exactly the same (with either integer or float domain). For example

import fractions
from numpy.polynomial import Polynomial

f=fractions.Fraction(2,3)
one=fractions.Fraction(1,1)
zero=fractions.Fraction(0,1)
p=Polynomial([f, f])
print(p)
print(p.domain)
y=p(f)
print(y)
print(type(y))

p=Polynomial([f, f], domain=[zero, one], window=[zero, one])
print(p)
print(p.domain)
y=p(f)
print(y)
print(type(y))

has output

2/3 + 2/3 x
[-1  1]
1.1111111111111112
<class 'numpy.float64'>
2/3 + 2/3 x
[Fraction(0, 1) Fraction(1, 1)]
10/9
<class 'fractions.Fraction'>

KrisMinchev added a commit to KrisMinchev/numpy that referenced this issue Sep 19, 2023
Change default values for domain and window
parameters for all convenience classes in
numpy.polynomial, as discussed in issue numpy#24568.
seberg pushed a commit that referenced this issue Jul 6, 2024
* Make sure evaluation of a Polynomial respects nep50 for scalar input:
```
import numpy as np

p=np.polynomial.Polynomial(np.array([1, 2], dtype=np.float32))
print(type(p(2))) # np.float64
# correct, since the domain argument is the default which maps to [-1., 1.]

w=np.array([-1,1], dtype=np.float32)
p=np.polynomial.Polynomial(np.array([1, 2], dtype=np.float32), domain=w, window=w)
print(type(p(2))) # np.float32 (was float64 on main)
```

* Update documentation of the various polynomial classes for the updated domain and window (was changed in #24568)
* Not addressed:
```
import numpy as np
arr = np.polydiv(1, np.float32(1))
arr.dtype # float64
```
The input here are polynomial coefficients, which are really an array and not a scalar. So the output type seems correct, even though `1` looks like a scalar input.
eagunn pushed a commit to eagunn/numpy that referenced this issue Jul 9, 2024
* Make sure evaluation of a Polynomial respects nep50 for scalar input:
```
import numpy as np

p=np.polynomial.Polynomial(np.array([1, 2], dtype=np.float32))
print(type(p(2))) # np.float64
# correct, since the domain argument is the default which maps to [-1., 1.]

w=np.array([-1,1], dtype=np.float32)
p=np.polynomial.Polynomial(np.array([1, 2], dtype=np.float32), domain=w, window=w)
print(type(p(2))) # np.float32 (was float64 on main)
```

* Update documentation of the various polynomial classes for the updated domain and window (was changed in numpy#24568)
* Not addressed:
```
import numpy as np
arr = np.polydiv(1, np.float32(1))
arr.dtype # float64
```
The input here are polynomial coefficients, which are really an array and not a scalar. So the output type seems correct, even though `1` looks like a scalar input.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants