Polynomial evaluation inconsistencies
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
Hi, I noticed some frustrating inconsistencies in the various ways to evaluate polynomials using numpy. Numpy has three ways of evaluating polynomials (that I know of) and each of them has a different syntax: - numpy.polynomial.polynomial.Polynomial <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polynomial...>: You define a polynomial by a list of coefficients *in order of increasing degree*, and then use the class’s call() function. - np.polyval <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polyval.ht...>: Evaluates a polynomial at a point. *First* argument is the polynomial, or list of coefficients *in order of decreasing degree*, and the *second* argument is the point to evaluate at. - np.polynomial.polynomial.polyval <https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.polynomial...>: Also evaluates a polynomial at a point, but has more support for vectorization. *First* argument is the point to evaluate at, and *second* argument the list of coefficients *in order of increasing degree*. Not only the order of arguments is changed between different methods, but the order of the coefficients is reversed as well, leading to puzzling bugs (in my experience). What could be the reason for this madness? As polyval is a shameless ripoff of Matlab’s function of the same name <https://www.mathworks.com/help/matlab/ref/polyval.html> anyway, why not just use matlab’s syntax (polyval([c0, c1, c2...], x)) across the board?
![](https://secure.gravatar.com/avatar/96dd777e397ab128fedab46af97a3a4a.jpg?s=120&d=mm&r=g)
On Fri, Jun 29, 2018 at 8:21 PM, Maxwell Aifer <maifer@haverford.edu> wrote:
Hi, I noticed some frustrating inconsistencies in the various ways to evaluate polynomials using numpy. Numpy has three ways of evaluating polynomials (that I know of) and each of them has a different syntax:
-
numpy.polynomial.polynomial.Polynomial <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polynomial...>: You define a polynomial by a list of coefficients *in order of increasing degree*, and then use the class’s call() function. -
np.polyval <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polyval.ht...>: Evaluates a polynomial at a point. *First* argument is the polynomial, or list of coefficients *in order of decreasing degree*, and the *second* argument is the point to evaluate at. -
np.polynomial.polynomial.polyval <https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.polynomial...>: Also evaluates a polynomial at a point, but has more support for vectorization. *First* argument is the point to evaluate at, and *second* argument the list of coefficients *in order of increasing degree*.
Not only the order of arguments is changed between different methods, but the order of the coefficients is reversed as well, leading to puzzling bugs (in my experience). What could be the reason for this madness? As polyval is a shameless ripoff of Matlab’s function of the same name <https://www.mathworks.com/help/matlab/ref/polyval.html> anyway, why not just use matlab’s syntax (polyval([c0, c1, c2...], x)) across the board?
The polynomial package, with its various basis, deals with series, and especially with the truncated series approximations that are used in numerical work. Series are universally written in increasing order of the degree. The Polynomial class is efficient in a single variable, while the numpy.polynomial.polynomial.polyval function is intended as a building block and can also deal with multivariate polynomials or multidimensional arrays of polynomials, or a mix. See the simple implementation of polyval3d for an example. If you are just dealing with a single variable, use Polynomial, which will also track scaling and offsets for numerical stability and is generally much superior to the simple polyval function from a numerical point of view. As to the ordering of the degrees, learning that the degree matches the index is pretty easy and is a more natural fit for the implementation code, especially as the number of variables increases. I note that Matlab has ones based indexing, so that was really not an option for them. Chuck
![](https://secure.gravatar.com/avatar/209654202cde8ec709dee0a4d23c717d.jpg?s=120&d=mm&r=g)
Here's my take on this, but it may not be an accurate summary of the history. `np.poly<func>` is part of the original matlab-style API, built around `poly1d` objects. This isn't a great design, because they represent: p(x) = c[0] * x^2 + c[1] * x^1 + c[2] * x^0 For this reason, among others, the `np.polynomial` module was created, starting with a clean slate. The core of this is `np.polynomial.Polynomial`. There, everything uses the convention p(x) = c[0] * x^0 + c[1] * x^1 + c[2] * x^2 It sounds like we might need clearer docs explaining the difference, and pointing users to the more sensible `np.polynomial.Polynomial` Eric On Fri, 29 Jun 2018 at 20:10 Charles R Harris <charlesr.harris@gmail.com> wrote:
On Fri, Jun 29, 2018 at 8:21 PM, Maxwell Aifer <maifer@haverford.edu> wrote:
Hi, I noticed some frustrating inconsistencies in the various ways to evaluate polynomials using numpy. Numpy has three ways of evaluating polynomials (that I know of) and each of them has a different syntax:
-
numpy.polynomial.polynomial.Polynomial <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polynomial...>: You define a polynomial by a list of coefficients *in order of increasing degree*, and then use the class’s call() function. -
np.polyval <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polyval.ht...>: Evaluates a polynomial at a point. *First* argument is the polynomial, or list of coefficients *in order of decreasing degree*, and the *second* argument is the point to evaluate at. -
np.polynomial.polynomial.polyval <https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.polynomial...>: Also evaluates a polynomial at a point, but has more support for vectorization. *First* argument is the point to evaluate at, and *second* argument the list of coefficients *in order of increasing degree*.
Not only the order of arguments is changed between different methods, but the order of the coefficients is reversed as well, leading to puzzling bugs (in my experience). What could be the reason for this madness? As polyval is a shameless ripoff of Matlab’s function of the same name <https://www.mathworks.com/help/matlab/ref/polyval.html> anyway, why not just use matlab’s syntax (polyval([c0, c1, c2...], x)) across the board?
The polynomial package, with its various basis, deals with series, and especially with the truncated series approximations that are used in numerical work. Series are universally written in increasing order of the degree. The Polynomial class is efficient in a single variable, while the numpy.polynomial.polynomial.polyval function is intended as a building block and can also deal with multivariate polynomials or multidimensional arrays of polynomials, or a mix. See the simple implementation of polyval3d for an example. If you are just dealing with a single variable, use Polynomial, which will also track scaling and offsets for numerical stability and is generally much superior to the simple polyval function from a numerical point of view.
As to the ordering of the degrees, learning that the degree matches the index is pretty easy and is a more natural fit for the implementation code, especially as the number of variables increases. I note that Matlab has ones based indexing, so that was really not an option for them.
Chuck _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
Thanks, that explains a lot! I didn't realize the reverse ordering actually originated with matlab's polyval, but that makes sense given the one-based indexing. I see why it is the way it is, but I still think it would make more sense for np.polyval() to use conventional indexing (c[0] * x^0 + c[1] * x^1 + c[2] * x^2). np.polyval() can be convenient when a polynomial object is just not needed, but if a single program uses both np.polyval() and np.polynomail.Polynomial, it seems bound to cause unnecessary confusion. Max On Fri, Jun 29, 2018 at 11:23 PM, Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
Here's my take on this, but it may not be an accurate summary of the history.
`np.poly<func>` is part of the original matlab-style API, built around `poly1d` objects. This isn't a great design, because they represent:
p(x) = c[0] * x^2 + c[1] * x^1 + c[2] * x^0
For this reason, among others, the `np.polynomial` module was created, starting with a clean slate. The core of this is `np.polynomial.Polynomial`. There, everything uses the convention
p(x) = c[0] * x^0 + c[1] * x^1 + c[2] * x^2
It sounds like we might need clearer docs explaining the difference, and pointing users to the more sensible `np.polynomial.Polynomial`
Eric
On Fri, 29 Jun 2018 at 20:10 Charles R Harris <charlesr.harris@gmail.com> wrote:
On Fri, Jun 29, 2018 at 8:21 PM, Maxwell Aifer <maifer@haverford.edu> wrote:
Hi, I noticed some frustrating inconsistencies in the various ways to evaluate polynomials using numpy. Numpy has three ways of evaluating polynomials (that I know of) and each of them has a different syntax:
-
numpy.polynomial.polynomial.Polynomial <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polynomial...>: You define a polynomial by a list of coefficients *in order of increasing degree*, and then use the class’s call() function. -
np.polyval <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polyval.ht...>: Evaluates a polynomial at a point. *First* argument is the polynomial, or list of coefficients *in order of decreasing degree*, and the *second* argument is the point to evaluate at. -
np.polynomial.polynomial.polyval <https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.polynomial...>: Also evaluates a polynomial at a point, but has more support for vectorization. *First* argument is the point to evaluate at, and *second* argument the list of coefficients *in order of increasing degree*.
Not only the order of arguments is changed between different methods, but the order of the coefficients is reversed as well, leading to puzzling bugs (in my experience). What could be the reason for this madness? As polyval is a shameless ripoff of Matlab’s function of the same name <https://www.mathworks.com/help/matlab/ref/polyval.html> anyway, why not just use matlab’s syntax (polyval([c0, c1, c2...], x)) across the board?
The polynomial package, with its various basis, deals with series, and especially with the truncated series approximations that are used in numerical work. Series are universally written in increasing order of the degree. The Polynomial class is efficient in a single variable, while the numpy.polynomial.polynomial.polyval function is intended as a building block and can also deal with multivariate polynomials or multidimensional arrays of polynomials, or a mix. See the simple implementation of polyval3d for an example. If you are just dealing with a single variable, use Polynomial, which will also track scaling and offsets for numerical stability and is generally much superior to the simple polyval function from a numerical point of view.
As to the ordering of the degrees, learning that the degree matches the index is pretty easy and is a more natural fit for the implementation code, especially as the number of variables increases. I note that Matlab has ones based indexing, so that was really not an option for them.
Chuck _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/209654202cde8ec709dee0a4d23c717d.jpg?s=120&d=mm&r=g)
if a single program uses both np.polyval() and np.polynomail.Polynomial, it seems bound to cause unnecessary confusion.
Yes, I would recommend definitely not doing that!
I still think it would make more sense for np.polyval() to use conventional indexing
Unfortunately, it's too late for "making sense" to factor into the design. `polyval` is being used in the wild, so we're stuck with it behaving the way it does. At best, we can deprecate it and start telling people to move from `np.polyval` over to `np.polynomial.polynomial.polyval`. Perhaps we need to make this namespace less cumbersome in order for that to be a reasonable option. I also wonder if we want a more lightweight polynomial object without the extra domain and range information, which seem like they make `Polynomial` a more questionable drop-in replacement for `poly1d`. Eric On Sat, 30 Jun 2018 at 09:14 Maxwell Aifer <maifer@haverford.edu> wrote:
Thanks, that explains a lot! I didn't realize the reverse ordering actually originated with matlab's polyval, but that makes sense given the one-based indexing. I see why it is the way it is, but I still think it would make more sense for np.polyval() to use conventional indexing (c[0] * x^0 + c[1] * x^1 + c[2] * x^2). np.polyval() can be convenient when a polynomial object is just not needed, but if a single program uses both np.polyval() and np.polynomail.Polynomial, it seems bound to cause unnecessary confusion.
Max
On Fri, Jun 29, 2018 at 11:23 PM, Eric Wieser <wieser.eric+numpy@gmail.com
wrote:
Here's my take on this, but it may not be an accurate summary of the history.
`np.poly<func>` is part of the original matlab-style API, built around `poly1d` objects. This isn't a great design, because they represent:
p(x) = c[0] * x^2 + c[1] * x^1 + c[2] * x^0
For this reason, among others, the `np.polynomial` module was created, starting with a clean slate. The core of this is `np.polynomial.Polynomial`. There, everything uses the convention
p(x) = c[0] * x^0 + c[1] * x^1 + c[2] * x^2
It sounds like we might need clearer docs explaining the difference, and pointing users to the more sensible `np.polynomial.Polynomial`
Eric
On Fri, 29 Jun 2018 at 20:10 Charles R Harris <charlesr.harris@gmail.com> wrote:
On Fri, Jun 29, 2018 at 8:21 PM, Maxwell Aifer <maifer@haverford.edu> wrote:
Hi, I noticed some frustrating inconsistencies in the various ways to evaluate polynomials using numpy. Numpy has three ways of evaluating polynomials (that I know of) and each of them has a different syntax:
-
numpy.polynomial.polynomial.Polynomial <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polynomial...>: You define a polynomial by a list of coefficients *in order of increasing degree*, and then use the class’s call() function. -
np.polyval <https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.polyval.ht...>: Evaluates a polynomial at a point. *First* argument is the polynomial, or list of coefficients *in order of decreasing degree*, and the *second* argument is the point to evaluate at. -
np.polynomial.polynomial.polyval <https://docs.scipy.org/doc/numpy-1.12.0/reference/generated/numpy.polynomial...>: Also evaluates a polynomial at a point, but has more support for vectorization. *First* argument is the point to evaluate at, and *second* argument the list of coefficients *in order of increasing degree*.
Not only the order of arguments is changed between different methods, but the order of the coefficients is reversed as well, leading to puzzling bugs (in my experience). What could be the reason for this madness? As polyval is a shameless ripoff of Matlab’s function of the same name <https://www.mathworks.com/help/matlab/ref/polyval.html> anyway, why not just use matlab’s syntax (polyval([c0, c1, c2...], x)) across the board?
The polynomial package, with its various basis, deals with series, and especially with the truncated series approximations that are used in numerical work. Series are universally written in increasing order of the degree. The Polynomial class is efficient in a single variable, while the numpy.polynomial.polynomial.polyval function is intended as a building block and can also deal with multivariate polynomials or multidimensional arrays of polynomials, or a mix. See the simple implementation of polyval3d for an example. If you are just dealing with a single variable, use Polynomial, which will also track scaling and offsets for numerical stability and is generally much superior to the simple polyval function from a numerical point of view.
As to the ordering of the degrees, learning that the degree matches the index is pretty easy and is a more natural fit for the implementation code, especially as the number of variables increases. I note that Matlab has ones based indexing, so that was really not an option for them.
Chuck _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/96dd777e397ab128fedab46af97a3a4a.jpg?s=120&d=mm&r=g)
On Sat, Jun 30, 2018 at 12:09 PM, Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
if a single program uses both np.polyval() and np.polynomail.Polynomial, it seems bound to cause unnecessary confusion.
Yes, I would recommend definitely not doing that!
I still think it would make more sense for np.polyval() to use conventional indexing
Unfortunately, it's too late for "making sense" to factor into the design. `polyval` is being used in the wild, so we're stuck with it behaving the way it does. At best, we can deprecate it and start telling people to move from `np.polyval` over to `np.polynomial.polynomial.polyval`. Perhaps we need to make this namespace less cumbersome in order for that to be a reasonable option.
I also wonder if we want a more lightweight polynomial object without the extra domain and range information, which seem like they make `Polynomial` a more questionable drop-in replacement for `poly1d`.
The defaults for domain and window make it like a regular polynomial. For fitting, it does adjust the range, but the usual form can be recovered with `p.convert()` and will usually have more accurate coefficients due to using a better conditioned matrix during the fit. In [1]: from numpy.polynomial import Polynomial as P In [2]: p = P([1, 2, 3], domain=(0,2)) In [3]: p(0) Out[3]: 2.0 In [4]: p.convert() Out[4]: Polynomial([ 2., -4., 3.], domain=[-1., 1.], window=[-1., 1.]) In [5]: p.convert()(0) Out[5]: 2.0 Chuck
![](https://secure.gravatar.com/avatar/81e62cb212edf2a8402c842b120d9f31.jpg?s=120&d=mm&r=g)
I think restricting polynomials to time series is not a generic way and quite specific. Apart from the series and certain filter design actual usage of polynomials are always presented with decreasing order (control and signal processing included because they use powers of s and inverse powers of z if needed). So if that is the use case then probably it should go under a namespace of `TimeSeries` or at least require an option to present it in reverse. In my opinion polynomials are way more general than that domain and to everyone else it seems to me that "the intuitive way" is the decreasing powers. For the design
This isn't a great design, because they represent: p(x) = c[0] * x^2 + c[1] * x^1 + c[2] * x^0
I don't see the problem actually. If I ask someone to write down the coefficients of a polynomial I don't think anyone would start from c[2]. On Sat, Jun 30, 2018 at 8:30 PM, Charles R Harris <charlesr.harris@gmail.com
wrote:
On Sat, Jun 30, 2018 at 12:09 PM, Eric Wieser <wieser.eric+numpy@gmail.com
wrote:
if a single program uses both np.polyval() and np.polynomail.Polynomial, it seems bound to cause unnecessary confusion.
Yes, I would recommend definitely not doing that!
I still think it would make more sense for np.polyval() to use conventional indexing
Unfortunately, it's too late for "making sense" to factor into the design. `polyval` is being used in the wild, so we're stuck with it behaving the way it does. At best, we can deprecate it and start telling people to move from `np.polyval` over to `np.polynomial.polynomial.polyval`. Perhaps we need to make this namespace less cumbersome in order for that to be a reasonable option.
I also wonder if we want a more lightweight polynomial object without the extra domain and range information, which seem like they make `Polynomial` a more questionable drop-in replacement for `poly1d`.
The defaults for domain and window make it like a regular polynomial. For fitting, it does adjust the range, but the usual form can be recovered with `p.convert()` and will usually have more accurate coefficients due to using a better conditioned matrix during the fit.
In [1]: from numpy.polynomial import Polynomial as P
In [2]: p = P([1, 2, 3], domain=(0,2))
In [3]: p(0) Out[3]: 2.0
In [4]: p.convert() Out[4]: Polynomial([ 2., -4., 3.], domain=[-1., 1.], window=[-1., 1.])
In [5]: p.convert()(0) Out[5]: 2.0
Chuck
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/96dd777e397ab128fedab46af97a3a4a.jpg?s=120&d=mm&r=g)
On Sat, Jun 30, 2018 at 1:08 PM, Ilhan Polat <ilhanpolat@gmail.com> wrote:
I think restricting polynomials to time series is not a generic way and quite specific.
I think more of complex analysis and it's use of series.
Apart from the series and certain filter design actual usage of polynomials are always presented with decreasing order (control and signal processing included because they use powers of s and inverse powers of z if needed). So if that is the use case then probably it should go under a namespace of `TimeSeries` or at least require an option to present it in reverse. In my opinion polynomials are way more general than that domain and to everyone else it seems to me that "the intuitive way" is the decreasing powers.
In approximation, say by Chebyshev polynomials, the coefficients will typically drop off sharply above a certain degree. This has two effects, first, the coefficients that one really cares about are of low degree and should come first, and second, one can truncate the coefficients easily with c[:n]. So in this usage ordering by increasing degree is natural. This is the series idea, fundamental to analysis. Algebraically, interest centers on the degree of the polynomial, which determines the number of zeros and general shape, consequently from the point of view of the algebraist, working with polynomials of finite predetermined degree, arranging the coefficients in order of decreasing degree makes sense and is traditional. That said, I am not actually sure where the high to low ordering of polynomials came from. It could even be like the Arabic numeral system, which when read properly from right to left, has its terms arranged from small to greater. It may even be that the polynomial convention derives that of the Arabic numerals. <snip> Chuck
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
Interesting, I wasn't aware that both conventions were widely used. Speaking of series with inverse powers (i.e. Laurent series), I wonder how useful it would be to create a class to represent expressions with integral powers from -m to n. These come up in my work sometimes, and I usually represent them with coefficient arrays ordered like this: c[0]*x^0 + ... + c[n]*x^n + c[n+1]x^-m + ... + c[n+m+1]*x^-1 Because then with negative indexing you have: c[-m]*x^-m + ... + c[n]*x^n Still, these objects can't be manipulated as nicely as polynomials because they aren't closed under integration and differentiation (you get log terms). Max On Sat, Jun 30, 2018 at 4:56 PM, Charles R Harris <charlesr.harris@gmail.com
wrote:
On Sat, Jun 30, 2018 at 1:08 PM, Ilhan Polat <ilhanpolat@gmail.com> wrote:
I think restricting polynomials to time series is not a generic way and quite specific.
I think more of complex analysis and it's use of series.
Apart from the series and certain filter design actual usage of polynomials are always presented with decreasing order (control and signal processing included because they use powers of s and inverse powers of z if needed). So if that is the use case then probably it should go under a namespace of `TimeSeries` or at least require an option to present it in reverse. In my opinion polynomials are way more general than that domain and to everyone else it seems to me that "the intuitive way" is the decreasing powers.
In approximation, say by Chebyshev polynomials, the coefficients will typically drop off sharply above a certain degree. This has two effects, first, the coefficients that one really cares about are of low degree and should come first, and second, one can truncate the coefficients easily with c[:n]. So in this usage ordering by increasing degree is natural. This is the series idea, fundamental to analysis.
Algebraically, interest centers on the degree of the polynomial, which determines the number of zeros and general shape, consequently from the point of view of the algebraist, working with polynomials of finite predetermined degree, arranging the coefficients in order of decreasing degree makes sense and is traditional.
That said, I am not actually sure where the high to low ordering of polynomials came from. It could even be like the Arabic numeral system, which when read properly from right to left, has its terms arranged from small to greater. It may even be that the polynomial convention derives that of the Arabic numerals.
<snip>
Chuck
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/209654202cde8ec709dee0a4d23c717d.jpg?s=120&d=mm&r=g)
“the intuitive way” is the decreasing powers. An argument against this is that accessing the ith power of x is spelt: - x.coeffs[i] for increasing powers - x.coeffs[-i-1] for decreasing powers The former is far more natural than the latter, and avoids a potential off-by-one error If I ask someone to write down the coefficients of a polynomial I don’t think anyone would start from c[2] You wouldn’t? I’d expect to see [image: f(x) = a_3x^3 + a_2x^2 + a_1x + a_0] rather than [image: f(x) = a_0x^3 + a_1x^2 + a_2x + a_3] Sure, I’d write it starting with the highest power, but I’d still number my coefficients to match the powers. Eric
![](https://secure.gravatar.com/avatar/209654202cde8ec709dee0a4d23c717d.jpg?s=120&d=mm&r=g)
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0) (And add a constructor that calls the lambda with Polynomial(1)) Eric On Sat, 30 Jun 2018 at 14:30 Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
“the intuitive way” is the decreasing powers.
An argument against this is that accessing the ith power of x is spelt:
- x.coeffs[i] for increasing powers - x.coeffs[-i-1] for decreasing powers
The former is far more natural than the latter, and avoids a potential off-by-one error
If I ask someone to write down the coefficients of a polynomial I don’t think anyone would start from c[2]
You wouldn’t? I’d expect to see
[image: f(x) = a_3x^3 + a_2x^2 + a_1x + a_0]
rather than
[image: f(x) = a_0x^3 + a_1x^2 + a_2x + a_3]
Sure, I’d write it starting with the highest power, but I’d still number my coefficients to match the powers.
Eric
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
Oh, clever... yeah I think that would be very cool. But shouldn't it call the constructor with Polynomial([0,1])? On Sat, Jun 30, 2018 at 5:41 PM, Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
On Sat, 30 Jun 2018 at 14:30 Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
“the intuitive way” is the decreasing powers.
An argument against this is that accessing the ith power of x is spelt:
- x.coeffs[i] for increasing powers - x.coeffs[-i-1] for decreasing powers
The former is far more natural than the latter, and avoids a potential off-by-one error
If I ask someone to write down the coefficients of a polynomial I don’t think anyone would start from c[2]
You wouldn’t? I’d expect to see
[image: f(x) = a_3x^3 + a_2x^2 + a_1x + a_0]
rather than
[image: f(x) = a_0x^3 + a_1x^2 + a_2x + a_3]
Sure, I’d write it starting with the highest power, but I’d still number my coefficients to match the powers.
Eric
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
*shouldn't the constructor call the lambda with Polynomial([0,1[) On Sat, Jun 30, 2018 at 6:05 PM, Maxwell Aifer <maifer@haverford.edu> wrote:
Oh, clever... yeah I think that would be very cool. But shouldn't it call the constructor with Polynomial([0,1])?
On Sat, Jun 30, 2018 at 5:41 PM, Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
On Sat, 30 Jun 2018 at 14:30 Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
“the intuitive way” is the decreasing powers.
An argument against this is that accessing the ith power of x is spelt:
- x.coeffs[i] for increasing powers - x.coeffs[-i-1] for decreasing powers
The former is far more natural than the latter, and avoids a potential off-by-one error
If I ask someone to write down the coefficients of a polynomial I don’t think anyone would start from c[2]
You wouldn’t? I’d expect to see
[image: f(x) = a_3x^3 + a_2x^2 + a_1x + a_0]
rather than
[image: f(x) = a_0x^3 + a_1x^2 + a_2x + a_3]
Sure, I’d write it starting with the highest power, but I’d still number my coefficients to match the powers.
Eric
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/209654202cde8ec709dee0a4d23c717d.jpg?s=120&d=mm&r=g)
Good catch, it would do that On Sat, 30 Jun 2018 at 15:07 Maxwell Aifer <maifer@haverford.edu> wrote:
*shouldn't the constructor call the lambda with Polynomial([0,1[)
On Sat, Jun 30, 2018 at 6:05 PM, Maxwell Aifer <maifer@haverford.edu> wrote:
Oh, clever... yeah I think that would be very cool. But shouldn't it call the constructor with Polynomial([0,1])?
On Sat, Jun 30, 2018 at 5:41 PM, Eric Wieser <wieser.eric+numpy@gmail.com
wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
On Sat, 30 Jun 2018 at 14:30 Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
“the intuitive way” is the decreasing powers.
An argument against this is that accessing the ith power of x is spelt:
- x.coeffs[i] for increasing powers - x.coeffs[-i-1] for decreasing powers
The former is far more natural than the latter, and avoids a potential off-by-one error
If I ask someone to write down the coefficients of a polynomial I don’t think anyone would start from c[2]
You wouldn’t? I’d expect to see
[image: f(x) = a_3x^3 + a_2x^2 + a_1x + a_0]
rather than
[image: f(x) = a_0x^3 + a_1x^2 + a_2x + a_3]
Sure, I’d write it starting with the highest power, but I’d still number my coefficients to match the powers.
Eric
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/96dd777e397ab128fedab46af97a3a4a.jpg?s=120&d=mm&r=g)
On Sat, Jun 30, 2018 at 3:41 PM, Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
IIRC there was a proposal for that. There is the possibility of adding renderers for latex and html that could be used by Jupyter, and I think the ordering was an option. Chuck
![](https://secure.gravatar.com/avatar/96dd777e397ab128fedab46af97a3a4a.jpg?s=120&d=mm&r=g)
On Sat, Jun 30, 2018 at 4:42 PM, Charles R Harris <charlesr.harris@gmail.com
wrote:
On Sat, Jun 30, 2018 at 3:41 PM, Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
IIRC there was a proposal for that. There is the possibility of adding renderers for latex and html that could be used by Jupyter, and I think the ordering was an option.
See https://github.com/numpy/numpy/issues/8893 for the proposal. BTW, if someone would like to work on this, go for it. Chuck
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
Say we add a constructor to the polynomial base class that looks something like this: ------------------------------------------------------------------------------------------- @classmethod def literal(cls, f): def basis_function_getter(self, deg): coefs = [0]*deg + [1] return lambda _: cls(coefs) basis = type('',(object,),{'__getitem__': basis_function_getter})() return f(basis, None) ------------------------------------------------------------------------------------------- Then the repr for, say, a Chebyshev polynomial could look like this:
Chebyshev.literal(lambda T,x: 1*T[0](x) + 2*T[1](x) + 3*T[2](x))
Does this sound like a good idea to anyone? Max On Sat, Jun 30, 2018 at 6:47 PM, Charles R Harris <charlesr.harris@gmail.com
wrote:
On Sat, Jun 30, 2018 at 4:42 PM, Charles R Harris < charlesr.harris@gmail.com> wrote:
On Sat, Jun 30, 2018 at 3:41 PM, Eric Wieser <wieser.eric+numpy@gmail.com
wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
IIRC there was a proposal for that. There is the possibility of adding renderers for latex and html that could be used by Jupyter, and I think the ordering was an option.
See https://github.com/numpy/numpy/issues/8893 for the proposal. BTW, if someone would like to work on this, go for it.
Chuck
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/209654202cde8ec709dee0a4d23c717d.jpg?s=120&d=mm&r=g)
I think the `x` is just noise there, especially if it's ignored (that is, `T[0](x*2)` doesn't do anything reasonable). Chebyshev.literal(lambda T: 1*T[0] + 2*T[1] + 3*T[2]) Would work, but honestly I don't think that provides much clarity. I think the value here is mainly for "simple" polynomials. On Sun, 1 Jul 2018 at 23:42 Maxwell Aifer <maifer@haverford.edu> wrote:
Say we add a constructor to the polynomial base class that looks something like this:
------------------------------------------------------------------------------------------- @classmethod def literal(cls, f): def basis_function_getter(self, deg): coefs = [0]*deg + [1] return lambda _: cls(coefs) basis = type('',(object,),{'__getitem__': basis_function_getter})() return f(basis, None)
-------------------------------------------------------------------------------------------
Then the repr for, say, a Chebyshev polynomial could look like this:
Chebyshev.literal(lambda T,x: 1*T[0](x) + 2*T[1](x) + 3*T[2](x))
Does this sound like a good idea to anyone?
Max
On Sat, Jun 30, 2018 at 6:47 PM, Charles R Harris < charlesr.harris@gmail.com> wrote:
On Sat, Jun 30, 2018 at 4:42 PM, Charles R Harris < charlesr.harris@gmail.com> wrote:
On Sat, Jun 30, 2018 at 3:41 PM, Eric Wieser < wieser.eric+numpy@gmail.com> wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
IIRC there was a proposal for that. There is the possibility of adding renderers for latex and html that could be used by Jupyter, and I think the ordering was an option.
See https://github.com/numpy/numpy/issues/8893 for the proposal. BTW, if someone would like to work on this, go for it.
Chuck
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________
NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/784092175992ce3ce3ea5dabe0532ab8.jpg?s=120&d=mm&r=g)
Ok I see what you mean. If people really want math-like symbolic representations for everything it’s probably better to use sympy or something On Mon, Jul 2, 2018 at 2:59 AM Eric Wieser <wieser.eric+numpy@gmail.com> wrote:
I think the `x` is just noise there, especially if it's ignored (that is, `T[0](x*2)` doesn't do anything reasonable).
Chebyshev.literal(lambda T: 1*T[0] + 2*T[1] + 3*T[2])
Would work, but honestly I don't think that provides much clarity. I think the value here is mainly for "simple" polynomials.
On Sun, 1 Jul 2018 at 23:42 Maxwell Aifer <maifer@haverford.edu> wrote:
Say we add a constructor to the polynomial base class that looks something like this:
------------------------------------------------------------------------------------------- @classmethod def literal(cls, f): def basis_function_getter(self, deg): coefs = [0]*deg + [1] return lambda _: cls(coefs) basis = type('',(object,),{'__getitem__': basis_function_getter})() return f(basis, None)
-------------------------------------------------------------------------------------------
Then the repr for, say, a Chebyshev polynomial could look like this:
Chebyshev.literal(lambda T,x: 1*T[0](x) + 2*T[1](x) + 3*T[2](x))
Does this sound like a good idea to anyone?
Max
On Sat, Jun 30, 2018 at 6:47 PM, Charles R Harris < charlesr.harris@gmail.com> wrote:
On Sat, Jun 30, 2018 at 4:42 PM, Charles R Harris < charlesr.harris@gmail.com> wrote:
On Sat, Jun 30, 2018 at 3:41 PM, Eric Wieser < wieser.eric+numpy@gmail.com> wrote:
Since the one of the arguments for the decreasing order seems to just be textual representation - do we want to tweak the repr to something like
Polynomial(lambda x: 2*x**3 + 3*x**2 + x + 0)
(And add a constructor that calls the lambda with Polynomial(1))
Eric
IIRC there was a proposal for that. There is the possibility of adding renderers for latex and html that could be used by Jupyter, and I think the ordering was an option.
See https://github.com/numpy/numpy/issues/8893 for the proposal. BTW, if someone would like to work on this, go for it.
Chuck
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________
NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
participants (4)
-
Charles R Harris
-
Eric Wieser
-
Ilhan Polat
-
Maxwell Aifer