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

Eric Wieser wieser.eric+numpy at gmail.com
Fri Jun 29 23:23:48 EDT 2018


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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20180629/82330581/attachment.html>



More information about the NumPy-Discussion mailing list