[Numpy-discussion] Polynomial evaluation inconsistencies (original) (raw)

Eric Wieser wieser.eric+numpy at gmail.com
Sat Jun 30 14:09:56 EDT 2018


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 at 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 at 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 at gmail.com> wrote: On Fri, Jun 29, 2018 at 8:21 PM, Maxwell Aifer <maifer at 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.polynomial.Polynomial.html#numpy.polynomial.polynomial.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.html>: 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.polynomial.polyval.html>: 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 at python.org https://mail.python.org/mailman/listinfo/numpy-discussion


NumPy-Discussion mailing list NumPy-Discussion at python.org https://mail.python.org/mailman/listinfo/numpy-discussion


NumPy-Discussion mailing list NumPy-Discussion at python.org https://mail.python.org/mailman/listinfo/numpy-discussion -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20180630/956a93bd/attachment-0001.html>



More information about the NumPy-Discussion mailing list