| """ |
| ================================================= |
| Power Series (:mod:`numpy.polynomial.polynomial`) |
| ================================================= |
| |
| This module provides a number of objects (mostly functions) useful for |
| dealing with polynomials, including a `Polynomial` class that |
| encapsulates the usual arithmetic operations. (General information |
| on how this module represents and works with polynomial objects is in |
| the docstring for its "parent" sub-package, `numpy.polynomial`). |
| |
| Classes |
| ------- |
| .. autosummary:: |
| :toctree: generated/ |
| |
| Polynomial |
| |
| Constants |
| --------- |
| .. autosummary:: |
| :toctree: generated/ |
| |
| polydomain |
| polyzero |
| polyone |
| polyx |
| |
| Arithmetic |
| ---------- |
| .. autosummary:: |
| :toctree: generated/ |
| |
| polyadd |
| polysub |
| polymulx |
| polymul |
| polydiv |
| polypow |
| polyval |
| polyval2d |
| polyval3d |
| polygrid2d |
| polygrid3d |
| |
| Calculus |
| -------- |
| .. autosummary:: |
| :toctree: generated/ |
| |
| polyder |
| polyint |
| |
| Misc Functions |
| -------------- |
| .. autosummary:: |
| :toctree: generated/ |
| |
| polyfromroots |
| polyroots |
| polyvalfromroots |
| polyvander |
| polyvander2d |
| polyvander3d |
| polycompanion |
| polyfit |
| polytrim |
| polyline |
| |
| See Also |
| -------- |
| `numpy.polynomial` |
| |
| """ |
| __all__ = [ |
| 'polyzero', 'polyone', 'polyx', 'polydomain', 'polyline', 'polyadd', |
| 'polysub', 'polymulx', 'polymul', 'polydiv', 'polypow', 'polyval', |
| 'polyvalfromroots', 'polyder', 'polyint', 'polyfromroots', 'polyvander', |
| 'polyfit', 'polytrim', 'polyroots', 'Polynomial', 'polyval2d', 'polyval3d', |
| 'polygrid2d', 'polygrid3d', 'polyvander2d', 'polyvander3d'] |
| |
| import numpy as np |
| import numpy.linalg as la |
| from numpy.core.multiarray import normalize_axis_index |
| |
| from . import polyutils as pu |
| from ._polybase import ABCPolyBase |
| |
| polytrim = pu.trimcoef |
| |
| # |
| # These are constant arrays are of integer type so as to be compatible |
| # with the widest range of other types, such as Decimal. |
| # |
| |
| # Polynomial default domain. |
| polydomain = np.array([-1, 1]) |
| |
| # Polynomial coefficients representing zero. |
| polyzero = np.array([0]) |
| |
| # Polynomial coefficients representing one. |
| polyone = np.array([1]) |
| |
| # Polynomial coefficients representing the identity x. |
| polyx = np.array([0, 1]) |
| |
| # |
| # Polynomial series functions |
| # |
| |
| |
| def polyline(off, scl): |
| """ |
| Returns an array representing a linear polynomial. |
| |
| Parameters |
| ---------- |
| off, scl : scalars |
| The "y-intercept" and "slope" of the line, respectively. |
| |
| Returns |
| ------- |
| y : ndarray |
| This module's representation of the linear polynomial ``off + |
| scl*x``. |
| |
| See Also |
| -------- |
| numpy.polynomial.chebyshev.chebline |
| numpy.polynomial.legendre.legline |
| numpy.polynomial.laguerre.lagline |
| numpy.polynomial.hermite.hermline |
| numpy.polynomial.hermite_e.hermeline |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> P.polyline(1,-1) |
| array([ 1, -1]) |
| >>> P.polyval(1, P.polyline(1,-1)) # should be 0 |
| 0.0 |
| |
| """ |
| if scl != 0: |
| return np.array([off, scl]) |
| else: |
| return np.array([off]) |
| |
| |
| def polyfromroots(roots): |
| """ |
| Generate a monic polynomial with given roots. |
| |
| Return the coefficients of the polynomial |
| |
| .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), |
| |
| where the ``r_n`` are the roots specified in `roots`. If a zero has |
| multiplicity n, then it must appear in `roots` n times. For instance, |
| if 2 is a root of multiplicity three and 3 is a root of multiplicity 2, |
| then `roots` looks something like [2, 2, 2, 3, 3]. The roots can appear |
| in any order. |
| |
| If the returned coefficients are `c`, then |
| |
| .. math:: p(x) = c_0 + c_1 * x + ... + x^n |
| |
| The coefficient of the last term is 1 for monic polynomials in this |
| form. |
| |
| Parameters |
| ---------- |
| roots : array_like |
| Sequence containing the roots. |
| |
| Returns |
| ------- |
| out : ndarray |
| 1-D array of the polynomial's coefficients If all the roots are |
| real, then `out` is also real, otherwise it is complex. (see |
| Examples below). |
| |
| See Also |
| -------- |
| numpy.polynomial.chebyshev.chebfromroots |
| numpy.polynomial.legendre.legfromroots |
| numpy.polynomial.laguerre.lagfromroots |
| numpy.polynomial.hermite.hermfromroots |
| numpy.polynomial.hermite_e.hermefromroots |
| |
| Notes |
| ----- |
| The coefficients are determined by multiplying together linear factors |
| of the form ``(x - r_i)``, i.e. |
| |
| .. math:: p(x) = (x - r_0) (x - r_1) ... (x - r_n) |
| |
| where ``n == len(roots) - 1``; note that this implies that ``1`` is always |
| returned for :math:`a_n`. |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> P.polyfromroots((-1,0,1)) # x(x - 1)(x + 1) = x^3 - x |
| array([ 0., -1., 0., 1.]) |
| >>> j = complex(0,1) |
| >>> P.polyfromroots((-j,j)) # complex returned, though values are real |
| array([1.+0.j, 0.+0.j, 1.+0.j]) |
| |
| """ |
| return pu._fromroots(polyline, polymul, roots) |
| |
| |
| def polyadd(c1, c2): |
| """ |
| Add one polynomial to another. |
| |
| Returns the sum of two polynomials `c1` + `c2`. The arguments are |
| sequences of coefficients from lowest order term to highest, i.e., |
| [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``. |
| |
| Parameters |
| ---------- |
| c1, c2 : array_like |
| 1-D arrays of polynomial coefficients ordered from low to high. |
| |
| Returns |
| ------- |
| out : ndarray |
| The coefficient array representing their sum. |
| |
| See Also |
| -------- |
| polysub, polymulx, polymul, polydiv, polypow |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> c1 = (1,2,3) |
| >>> c2 = (3,2,1) |
| >>> sum = P.polyadd(c1,c2); sum |
| array([4., 4., 4.]) |
| >>> P.polyval(2, sum) # 4 + 4(2) + 4(2**2) |
| 28.0 |
| |
| """ |
| return pu._add(c1, c2) |
| |
| |
| def polysub(c1, c2): |
| """ |
| Subtract one polynomial from another. |
| |
| Returns the difference of two polynomials `c1` - `c2`. The arguments |
| are sequences of coefficients from lowest order term to highest, i.e., |
| [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``. |
| |
| Parameters |
| ---------- |
| c1, c2 : array_like |
| 1-D arrays of polynomial coefficients ordered from low to |
| high. |
| |
| Returns |
| ------- |
| out : ndarray |
| Of coefficients representing their difference. |
| |
| See Also |
| -------- |
| polyadd, polymulx, polymul, polydiv, polypow |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> c1 = (1,2,3) |
| >>> c2 = (3,2,1) |
| >>> P.polysub(c1,c2) |
| array([-2., 0., 2.]) |
| >>> P.polysub(c2,c1) # -P.polysub(c1,c2) |
| array([ 2., 0., -2.]) |
| |
| """ |
| return pu._sub(c1, c2) |
| |
| |
| def polymulx(c): |
| """Multiply a polynomial by x. |
| |
| Multiply the polynomial `c` by x, where x is the independent |
| variable. |
| |
| |
| Parameters |
| ---------- |
| c : array_like |
| 1-D array of polynomial coefficients ordered from low to |
| high. |
| |
| Returns |
| ------- |
| out : ndarray |
| Array representing the result of the multiplication. |
| |
| See Also |
| -------- |
| polyadd, polysub, polymul, polydiv, polypow |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.5.0 |
| |
| """ |
| # c is a trimmed copy |
| [c] = pu.as_series([c]) |
| # The zero series needs special treatment |
| if len(c) == 1 and c[0] == 0: |
| return c |
| |
| prd = np.empty(len(c) + 1, dtype=c.dtype) |
| prd[0] = c[0]*0 |
| prd[1:] = c |
| return prd |
| |
| |
| def polymul(c1, c2): |
| """ |
| Multiply one polynomial by another. |
| |
| Returns the product of two polynomials `c1` * `c2`. The arguments are |
| sequences of coefficients, from lowest order term to highest, e.g., |
| [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2.`` |
| |
| Parameters |
| ---------- |
| c1, c2 : array_like |
| 1-D arrays of coefficients representing a polynomial, relative to the |
| "standard" basis, and ordered from lowest order term to highest. |
| |
| Returns |
| ------- |
| out : ndarray |
| Of the coefficients of their product. |
| |
| See Also |
| -------- |
| polyadd, polysub, polymulx, polydiv, polypow |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> c1 = (1,2,3) |
| >>> c2 = (3,2,1) |
| >>> P.polymul(c1,c2) |
| array([ 3., 8., 14., 8., 3.]) |
| |
| """ |
| # c1, c2 are trimmed copies |
| [c1, c2] = pu.as_series([c1, c2]) |
| ret = np.convolve(c1, c2) |
| return pu.trimseq(ret) |
| |
| |
| def polydiv(c1, c2): |
| """ |
| Divide one polynomial by another. |
| |
| Returns the quotient-with-remainder of two polynomials `c1` / `c2`. |
| The arguments are sequences of coefficients, from lowest order term |
| to highest, e.g., [1,2,3] represents ``1 + 2*x + 3*x**2``. |
| |
| Parameters |
| ---------- |
| c1, c2 : array_like |
| 1-D arrays of polynomial coefficients ordered from low to high. |
| |
| Returns |
| ------- |
| [quo, rem] : ndarrays |
| Of coefficient series representing the quotient and remainder. |
| |
| See Also |
| -------- |
| polyadd, polysub, polymulx, polymul, polypow |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> c1 = (1,2,3) |
| >>> c2 = (3,2,1) |
| >>> P.polydiv(c1,c2) |
| (array([3.]), array([-8., -4.])) |
| >>> P.polydiv(c2,c1) |
| (array([ 0.33333333]), array([ 2.66666667, 1.33333333])) # may vary |
| |
| """ |
| # c1, c2 are trimmed copies |
| [c1, c2] = pu.as_series([c1, c2]) |
| if c2[-1] == 0: |
| raise ZeroDivisionError() |
| |
| # note: this is more efficient than `pu._div(polymul, c1, c2)` |
| lc1 = len(c1) |
| lc2 = len(c2) |
| if lc1 < lc2: |
| return c1[:1]*0, c1 |
| elif lc2 == 1: |
| return c1/c2[-1], c1[:1]*0 |
| else: |
| dlen = lc1 - lc2 |
| scl = c2[-1] |
| c2 = c2[:-1]/scl |
| i = dlen |
| j = lc1 - 1 |
| while i >= 0: |
| c1[i:j] -= c2*c1[j] |
| i -= 1 |
| j -= 1 |
| return c1[j+1:]/scl, pu.trimseq(c1[:j+1]) |
| |
| |
| def polypow(c, pow, maxpower=None): |
| """Raise a polynomial to a power. |
| |
| Returns the polynomial `c` raised to the power `pow`. The argument |
| `c` is a sequence of coefficients ordered from low to high. i.e., |
| [1,2,3] is the series ``1 + 2*x + 3*x**2.`` |
| |
| Parameters |
| ---------- |
| c : array_like |
| 1-D array of array of series coefficients ordered from low to |
| high degree. |
| pow : integer |
| Power to which the series will be raised |
| maxpower : integer, optional |
| Maximum power allowed. This is mainly to limit growth of the series |
| to unmanageable size. Default is 16 |
| |
| Returns |
| ------- |
| coef : ndarray |
| Power series of power. |
| |
| See Also |
| -------- |
| polyadd, polysub, polymulx, polymul, polydiv |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> P.polypow([1,2,3], 2) |
| array([ 1., 4., 10., 12., 9.]) |
| |
| """ |
| # note: this is more efficient than `pu._pow(polymul, c1, c2)`, as it |
| # avoids calling `as_series` repeatedly |
| return pu._pow(np.convolve, c, pow, maxpower) |
| |
| |
| def polyder(c, m=1, scl=1, axis=0): |
| """ |
| Differentiate a polynomial. |
| |
| Returns the polynomial coefficients `c` differentiated `m` times along |
| `axis`. At each iteration the result is multiplied by `scl` (the |
| scaling factor is for use in a linear change of variable). The |
| argument `c` is an array of coefficients from low to high degree along |
| each axis, e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2`` |
| while [[1,2],[1,2]] represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is |
| ``x`` and axis=1 is ``y``. |
| |
| Parameters |
| ---------- |
| c : array_like |
| Array of polynomial coefficients. If c is multidimensional the |
| different axis correspond to different variables with the degree |
| in each axis given by the corresponding index. |
| m : int, optional |
| Number of derivatives taken, must be non-negative. (Default: 1) |
| scl : scalar, optional |
| Each differentiation is multiplied by `scl`. The end result is |
| multiplication by ``scl**m``. This is for use in a linear change |
| of variable. (Default: 1) |
| axis : int, optional |
| Axis over which the derivative is taken. (Default: 0). |
| |
| .. versionadded:: 1.7.0 |
| |
| Returns |
| ------- |
| der : ndarray |
| Polynomial coefficients of the derivative. |
| |
| See Also |
| -------- |
| polyint |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> c = (1,2,3,4) # 1 + 2x + 3x**2 + 4x**3 |
| >>> P.polyder(c) # (d/dx)(c) = 2 + 6x + 12x**2 |
| array([ 2., 6., 12.]) |
| >>> P.polyder(c,3) # (d**3/dx**3)(c) = 24 |
| array([24.]) |
| >>> P.polyder(c,scl=-1) # (d/d(-x))(c) = -2 - 6x - 12x**2 |
| array([ -2., -6., -12.]) |
| >>> P.polyder(c,2,-1) # (d**2/d(-x)**2)(c) = 6 + 24x |
| array([ 6., 24.]) |
| |
| """ |
| c = np.array(c, ndmin=1, copy=True) |
| if c.dtype.char in '?bBhHiIlLqQpP': |
| # astype fails with NA |
| c = c + 0.0 |
| cdt = c.dtype |
| cnt = pu._deprecate_as_int(m, "the order of derivation") |
| iaxis = pu._deprecate_as_int(axis, "the axis") |
| if cnt < 0: |
| raise ValueError("The order of derivation must be non-negative") |
| iaxis = normalize_axis_index(iaxis, c.ndim) |
| |
| if cnt == 0: |
| return c |
| |
| c = np.moveaxis(c, iaxis, 0) |
| n = len(c) |
| if cnt >= n: |
| c = c[:1]*0 |
| else: |
| for i in range(cnt): |
| n = n - 1 |
| c *= scl |
| der = np.empty((n,) + c.shape[1:], dtype=cdt) |
| for j in range(n, 0, -1): |
| der[j - 1] = j*c[j] |
| c = der |
| c = np.moveaxis(c, 0, iaxis) |
| return c |
| |
| |
| def polyint(c, m=1, k=[], lbnd=0, scl=1, axis=0): |
| """ |
| Integrate a polynomial. |
| |
| Returns the polynomial coefficients `c` integrated `m` times from |
| `lbnd` along `axis`. At each iteration the resulting series is |
| **multiplied** by `scl` and an integration constant, `k`, is added. |
| The scaling factor is for use in a linear change of variable. ("Buyer |
| beware": note that, depending on what one is doing, one may want `scl` |
| to be the reciprocal of what one might expect; for more information, |
| see the Notes section below.) The argument `c` is an array of |
| coefficients, from low to high degree along each axis, e.g., [1,2,3] |
| represents the polynomial ``1 + 2*x + 3*x**2`` while [[1,2],[1,2]] |
| represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is ``x`` and axis=1 is |
| ``y``. |
| |
| Parameters |
| ---------- |
| c : array_like |
| 1-D array of polynomial coefficients, ordered from low to high. |
| m : int, optional |
| Order of integration, must be positive. (Default: 1) |
| k : {[], list, scalar}, optional |
| Integration constant(s). The value of the first integral at zero |
| is the first value in the list, the value of the second integral |
| at zero is the second value, etc. If ``k == []`` (the default), |
| all constants are set to zero. If ``m == 1``, a single scalar can |
| be given instead of a list. |
| lbnd : scalar, optional |
| The lower bound of the integral. (Default: 0) |
| scl : scalar, optional |
| Following each integration the result is *multiplied* by `scl` |
| before the integration constant is added. (Default: 1) |
| axis : int, optional |
| Axis over which the integral is taken. (Default: 0). |
| |
| .. versionadded:: 1.7.0 |
| |
| Returns |
| ------- |
| S : ndarray |
| Coefficient array of the integral. |
| |
| Raises |
| ------ |
| ValueError |
| If ``m < 1``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or |
| ``np.ndim(scl) != 0``. |
| |
| See Also |
| -------- |
| polyder |
| |
| Notes |
| ----- |
| Note that the result of each integration is *multiplied* by `scl`. Why |
| is this important to note? Say one is making a linear change of |
| variable :math:`u = ax + b` in an integral relative to `x`. Then |
| :math:`dx = du/a`, so one will need to set `scl` equal to |
| :math:`1/a` - perhaps not what one would have first thought. |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial import polynomial as P |
| >>> c = (1,2,3) |
| >>> P.polyint(c) # should return array([0, 1, 1, 1]) |
| array([0., 1., 1., 1.]) |
| >>> P.polyint(c,3) # should return array([0, 0, 0, 1/6, 1/12, 1/20]) |
| array([ 0. , 0. , 0. , 0.16666667, 0.08333333, # may vary |
| 0.05 ]) |
| >>> P.polyint(c,k=3) # should return array([3, 1, 1, 1]) |
| array([3., 1., 1., 1.]) |
| >>> P.polyint(c,lbnd=-2) # should return array([6, 1, 1, 1]) |
| array([6., 1., 1., 1.]) |
| >>> P.polyint(c,scl=-2) # should return array([0, -2, -2, -2]) |
| array([ 0., -2., -2., -2.]) |
| |
| """ |
| c = np.array(c, ndmin=1, copy=True) |
| if c.dtype.char in '?bBhHiIlLqQpP': |
| # astype doesn't preserve mask attribute. |
| c = c + 0.0 |
| cdt = c.dtype |
| if not np.iterable(k): |
| k = [k] |
| cnt = pu._deprecate_as_int(m, "the order of integration") |
| iaxis = pu._deprecate_as_int(axis, "the axis") |
| if cnt < 0: |
| raise ValueError("The order of integration must be non-negative") |
| if len(k) > cnt: |
| raise ValueError("Too many integration constants") |
| if np.ndim(lbnd) != 0: |
| raise ValueError("lbnd must be a scalar.") |
| if np.ndim(scl) != 0: |
| raise ValueError("scl must be a scalar.") |
| iaxis = normalize_axis_index(iaxis, c.ndim) |
| |
| if cnt == 0: |
| return c |
| |
| k = list(k) + [0]*(cnt - len(k)) |
| c = np.moveaxis(c, iaxis, 0) |
| for i in range(cnt): |
| n = len(c) |
| c *= scl |
| if n == 1 and np.all(c[0] == 0): |
| c[0] += k[i] |
| else: |
| tmp = np.empty((n + 1,) + c.shape[1:], dtype=cdt) |
| tmp[0] = c[0]*0 |
| tmp[1] = c[0] |
| for j in range(1, n): |
| tmp[j + 1] = c[j]/(j + 1) |
| tmp[0] += k[i] - polyval(lbnd, tmp) |
| c = tmp |
| c = np.moveaxis(c, 0, iaxis) |
| return c |
| |
| |
| def polyval(x, c, tensor=True): |
| """ |
| Evaluate a polynomial at points x. |
| |
| If `c` is of length `n + 1`, this function returns the value |
| |
| .. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n |
| |
| The parameter `x` is converted to an array only if it is a tuple or a |
| list, otherwise it is treated as a scalar. In either case, either `x` |
| or its elements must support multiplication and addition both with |
| themselves and with the elements of `c`. |
| |
| If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If |
| `c` is multidimensional, then the shape of the result depends on the |
| value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + |
| x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that |
| scalars have shape (,). |
| |
| Trailing zeros in the coefficients will be used in the evaluation, so |
| they should be avoided if efficiency is a concern. |
| |
| Parameters |
| ---------- |
| x : array_like, compatible object |
| If `x` is a list or tuple, it is converted to an ndarray, otherwise |
| it is left unchanged and treated as a scalar. In either case, `x` |
| or its elements must support addition and multiplication with |
| with themselves and with the elements of `c`. |
| c : array_like |
| Array of coefficients ordered so that the coefficients for terms of |
| degree n are contained in c[n]. If `c` is multidimensional the |
| remaining indices enumerate multiple polynomials. In the two |
| dimensional case the coefficients may be thought of as stored in |
| the columns of `c`. |
| tensor : boolean, optional |
| If True, the shape of the coefficient array is extended with ones |
| on the right, one for each dimension of `x`. Scalars have dimension 0 |
| for this action. The result is that every column of coefficients in |
| `c` is evaluated for every element of `x`. If False, `x` is broadcast |
| over the columns of `c` for the evaluation. This keyword is useful |
| when `c` is multidimensional. The default value is True. |
| |
| .. versionadded:: 1.7.0 |
| |
| Returns |
| ------- |
| values : ndarray, compatible object |
| The shape of the returned array is described above. |
| |
| See Also |
| -------- |
| polyval2d, polygrid2d, polyval3d, polygrid3d |
| |
| Notes |
| ----- |
| The evaluation uses Horner's method. |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial.polynomial import polyval |
| >>> polyval(1, [1,2,3]) |
| 6.0 |
| >>> a = np.arange(4).reshape(2,2) |
| >>> a |
| array([[0, 1], |
| [2, 3]]) |
| >>> polyval(a, [1,2,3]) |
| array([[ 1., 6.], |
| [17., 34.]]) |
| >>> coef = np.arange(4).reshape(2,2) # multidimensional coefficients |
| >>> coef |
| array([[0, 1], |
| [2, 3]]) |
| >>> polyval([1,2], coef, tensor=True) |
| array([[2., 4.], |
| [4., 7.]]) |
| >>> polyval([1,2], coef, tensor=False) |
| array([2., 7.]) |
| |
| """ |
| c = np.array(c, ndmin=1, copy=False) |
| if c.dtype.char in '?bBhHiIlLqQpP': |
| # astype fails with NA |
| c = c + 0.0 |
| if isinstance(x, (tuple, list)): |
| x = np.asarray(x) |
| if isinstance(x, np.ndarray) and tensor: |
| c = c.reshape(c.shape + (1,)*x.ndim) |
| |
| c0 = c[-1] + x*0 |
| for i in range(2, len(c) + 1): |
| c0 = c[-i] + c0*x |
| return c0 |
| |
| |
| def polyvalfromroots(x, r, tensor=True): |
| """ |
| Evaluate a polynomial specified by its roots at points x. |
| |
| If `r` is of length `N`, this function returns the value |
| |
| .. math:: p(x) = \\prod_{n=1}^{N} (x - r_n) |
| |
| The parameter `x` is converted to an array only if it is a tuple or a |
| list, otherwise it is treated as a scalar. In either case, either `x` |
| or its elements must support multiplication and addition both with |
| themselves and with the elements of `r`. |
| |
| If `r` is a 1-D array, then `p(x)` will have the same shape as `x`. If `r` |
| is multidimensional, then the shape of the result depends on the value of |
| `tensor`. If `tensor` is ``True`` the shape will be r.shape[1:] + x.shape; |
| that is, each polynomial is evaluated at every value of `x`. If `tensor` is |
| ``False``, the shape will be r.shape[1:]; that is, each polynomial is |
| evaluated only for the corresponding broadcast value of `x`. Note that |
| scalars have shape (,). |
| |
| .. versionadded:: 1.12 |
| |
| Parameters |
| ---------- |
| x : array_like, compatible object |
| If `x` is a list or tuple, it is converted to an ndarray, otherwise |
| it is left unchanged and treated as a scalar. In either case, `x` |
| or its elements must support addition and multiplication with |
| with themselves and with the elements of `r`. |
| r : array_like |
| Array of roots. If `r` is multidimensional the first index is the |
| root index, while the remaining indices enumerate multiple |
| polynomials. For instance, in the two dimensional case the roots |
| of each polynomial may be thought of as stored in the columns of `r`. |
| tensor : boolean, optional |
| If True, the shape of the roots array is extended with ones on the |
| right, one for each dimension of `x`. Scalars have dimension 0 for this |
| action. The result is that every column of coefficients in `r` is |
| evaluated for every element of `x`. If False, `x` is broadcast over the |
| columns of `r` for the evaluation. This keyword is useful when `r` is |
| multidimensional. The default value is True. |
| |
| Returns |
| ------- |
| values : ndarray, compatible object |
| The shape of the returned array is described above. |
| |
| See Also |
| -------- |
| polyroots, polyfromroots, polyval |
| |
| Examples |
| -------- |
| >>> from numpy.polynomial.polynomial import polyvalfromroots |
| >>> polyvalfromroots(1, [1,2,3]) |
| 0.0 |
| >>> a = np.arange(4).reshape(2,2) |
| >>> a |
| array([[0, 1], |
| [2, 3]]) |
| >>> polyvalfromroots(a, [-1, 0, 1]) |
| array([[-0., 0.], |
| [ 6., 24.]]) |
| >>> r = np.arange(-2, 2).reshape(2,2) # multidimensional coefficients |
| >>> r # each column of r defines one polynomial |
| array([[-2, -1], |
| [ 0, 1]]) |
| >>> b = [-2, 1] |
| >>> polyvalfromroots(b, r, tensor=True) |
| array([[-0., 3.], |
| [ 3., 0.]]) |
| >>> polyvalfromroots(b, r, tensor=False) |
| array([-0., 0.]) |
| """ |
| r = np.array(r, ndmin=1, copy=False) |
| if r.dtype.char in '?bBhHiIlLqQpP': |
| r = r.astype(np.double) |
| if isinstance(x, (tuple, list)): |
| x = np.asarray(x) |
| if isinstance(x, np.ndarray): |
| if tensor: |
| r = r.reshape(r.shape + (1,)*x.ndim) |
| elif x.ndim >= r.ndim: |
| raise ValueError("x.ndim must be < r.ndim when tensor == False") |
| return np.prod(x - r, axis=0) |
| |
| |
| def polyval2d(x, y, c): |
| """ |
| Evaluate a 2-D polynomial at points (x, y). |
| |
| This function returns the value |
| |
| .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * x^i * y^j |
| |
| The parameters `x` and `y` are converted to arrays only if they are |
| tuples or a lists, otherwise they are treated as a scalars and they |
| must have the same shape after conversion. In either case, either `x` |
| and `y` or their elements must support multiplication and addition both |
| with themselves and with the elements of `c`. |
| |
| If `c` has fewer than two dimensions, ones are implicitly appended to |
| its shape to make it 2-D. The shape of the result will be c.shape[2:] + |
| x.shape. |
| |
| Parameters |
| ---------- |
| x, y : array_like, compatible objects |
| The two dimensional series is evaluated at the points `(x, y)`, |
| where `x` and `y` must have the same shape. If `x` or `y` is a list |
| or tuple, it is first converted to an ndarray, otherwise it is left |
| unchanged and, if it isn't an ndarray, it is treated as a scalar. |
| c : array_like |
| Array of coefficients ordered so that the coefficient of the term |
| of multi-degree i,j is contained in `c[i,j]`. If `c` has |
| dimension greater than two the remaining indices enumerate multiple |
| sets of coefficients. |
| |
| Returns |
| ------- |
| values : ndarray, compatible object |
| The values of the two dimensional polynomial at points formed with |
| pairs of corresponding values from `x` and `y`. |
| |
| See Also |
| -------- |
| polyval, polygrid2d, polyval3d, polygrid3d |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.7.0 |
| |
| """ |
| return pu._valnd(polyval, c, x, y) |
| |
| |
| def polygrid2d(x, y, c): |
| """ |
| Evaluate a 2-D polynomial on the Cartesian product of x and y. |
| |
| This function returns the values: |
| |
| .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * a^i * b^j |
| |
| where the points `(a, b)` consist of all pairs formed by taking |
| `a` from `x` and `b` from `y`. The resulting points form a grid with |
| `x` in the first dimension and `y` in the second. |
| |
| The parameters `x` and `y` are converted to arrays only if they are |
| tuples or a lists, otherwise they are treated as a scalars. In either |
| case, either `x` and `y` or their elements must support multiplication |
| and addition both with themselves and with the elements of `c`. |
| |
| If `c` has fewer than two dimensions, ones are implicitly appended to |
| its shape to make it 2-D. The shape of the result will be c.shape[2:] + |
| x.shape + y.shape. |
| |
| Parameters |
| ---------- |
| x, y : array_like, compatible objects |
| The two dimensional series is evaluated at the points in the |
| Cartesian product of `x` and `y`. If `x` or `y` is a list or |
| tuple, it is first converted to an ndarray, otherwise it is left |
| unchanged and, if it isn't an ndarray, it is treated as a scalar. |
| c : array_like |
| Array of coefficients ordered so that the coefficients for terms of |
| degree i,j are contained in ``c[i,j]``. If `c` has dimension |
| greater than two the remaining indices enumerate multiple sets of |
| coefficients. |
| |
| Returns |
| ------- |
| values : ndarray, compatible object |
| The values of the two dimensional polynomial at points in the Cartesian |
| product of `x` and `y`. |
| |
| See Also |
| -------- |
| polyval, polyval2d, polyval3d, polygrid3d |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.7.0 |
| |
| """ |
| return pu._gridnd(polyval, c, x, y) |
| |
| |
| def polyval3d(x, y, z, c): |
| """ |
| Evaluate a 3-D polynomial at points (x, y, z). |
| |
| This function returns the values: |
| |
| .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * x^i * y^j * z^k |
| |
| The parameters `x`, `y`, and `z` are converted to arrays only if |
| they are tuples or a lists, otherwise they are treated as a scalars and |
| they must have the same shape after conversion. In either case, either |
| `x`, `y`, and `z` or their elements must support multiplication and |
| addition both with themselves and with the elements of `c`. |
| |
| If `c` has fewer than 3 dimensions, ones are implicitly appended to its |
| shape to make it 3-D. The shape of the result will be c.shape[3:] + |
| x.shape. |
| |
| Parameters |
| ---------- |
| x, y, z : array_like, compatible object |
| The three dimensional series is evaluated at the points |
| `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If |
| any of `x`, `y`, or `z` is a list or tuple, it is first converted |
| to an ndarray, otherwise it is left unchanged and if it isn't an |
| ndarray it is treated as a scalar. |
| c : array_like |
| Array of coefficients ordered so that the coefficient of the term of |
| multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension |
| greater than 3 the remaining indices enumerate multiple sets of |
| coefficients. |
| |
| Returns |
| ------- |
| values : ndarray, compatible object |
| The values of the multidimensional polynomial on points formed with |
| triples of corresponding values from `x`, `y`, and `z`. |
| |
| See Also |
| -------- |
| polyval, polyval2d, polygrid2d, polygrid3d |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.7.0 |
| |
| """ |
| return pu._valnd(polyval, c, x, y, z) |
| |
| |
| def polygrid3d(x, y, z, c): |
| """ |
| Evaluate a 3-D polynomial on the Cartesian product of x, y and z. |
| |
| This function returns the values: |
| |
| .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * a^i * b^j * c^k |
| |
| where the points `(a, b, c)` consist of all triples formed by taking |
| `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form |
| a grid with `x` in the first dimension, `y` in the second, and `z` in |
| the third. |
| |
| The parameters `x`, `y`, and `z` are converted to arrays only if they |
| are tuples or a lists, otherwise they are treated as a scalars. In |
| either case, either `x`, `y`, and `z` or their elements must support |
| multiplication and addition both with themselves and with the elements |
| of `c`. |
| |
| If `c` has fewer than three dimensions, ones are implicitly appended to |
| its shape to make it 3-D. The shape of the result will be c.shape[3:] + |
| x.shape + y.shape + z.shape. |
| |
| Parameters |
| ---------- |
| x, y, z : array_like, compatible objects |
| The three dimensional series is evaluated at the points in the |
| Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a |
| list or tuple, it is first converted to an ndarray, otherwise it is |
| left unchanged and, if it isn't an ndarray, it is treated as a |
| scalar. |
| c : array_like |
| Array of coefficients ordered so that the coefficients for terms of |
| degree i,j are contained in ``c[i,j]``. If `c` has dimension |
| greater than two the remaining indices enumerate multiple sets of |
| coefficients. |
| |
| Returns |
| ------- |
| values : ndarray, compatible object |
| The values of the two dimensional polynomial at points in the Cartesian |
| product of `x` and `y`. |
| |
| See Also |
| -------- |
| polyval, polyval2d, polygrid2d, polyval3d |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.7.0 |
| |
| """ |
| return pu._gridnd(polyval, c, x, y, z) |
| |
| |
| def polyvander(x, deg): |
| """Vandermonde matrix of given degree. |
| |
| Returns the Vandermonde matrix of degree `deg` and sample points |
| `x`. The Vandermonde matrix is defined by |
| |
| .. math:: V[..., i] = x^i, |
| |
| where `0 <= i <= deg`. The leading indices of `V` index the elements of |
| `x` and the last index is the power of `x`. |
| |
| If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the |
| matrix ``V = polyvander(x, n)``, then ``np.dot(V, c)`` and |
| ``polyval(x, c)`` are the same up to roundoff. This equivalence is |
| useful both for least squares fitting and for the evaluation of a large |
| number of polynomials of the same degree and sample points. |
| |
| Parameters |
| ---------- |
| x : array_like |
| Array of points. The dtype is converted to float64 or complex128 |
| depending on whether any of the elements are complex. If `x` is |
| scalar it is converted to a 1-D array. |
| deg : int |
| Degree of the resulting matrix. |
| |
| Returns |
| ------- |
| vander : ndarray. |
| The Vandermonde matrix. The shape of the returned matrix is |
| ``x.shape + (deg + 1,)``, where the last index is the power of `x`. |
| The dtype will be the same as the converted `x`. |
| |
| See Also |
| -------- |
| polyvander2d, polyvander3d |
| |
| """ |
| ideg = pu._deprecate_as_int(deg, "deg") |
| if ideg < 0: |
| raise ValueError("deg must be non-negative") |
| |
| x = np.array(x, copy=False, ndmin=1) + 0.0 |
| dims = (ideg + 1,) + x.shape |
| dtyp = x.dtype |
| v = np.empty(dims, dtype=dtyp) |
| v[0] = x*0 + 1 |
| if ideg > 0: |
| v[1] = x |
| for i in range(2, ideg + 1): |
| v[i] = v[i-1]*x |
| return np.moveaxis(v, 0, -1) |
| |
| |
| def polyvander2d(x, y, deg): |
| """Pseudo-Vandermonde matrix of given degrees. |
| |
| Returns the pseudo-Vandermonde matrix of degrees `deg` and sample |
| points `(x, y)`. The pseudo-Vandermonde matrix is defined by |
| |
| .. math:: V[..., (deg[1] + 1)*i + j] = x^i * y^j, |
| |
| where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of |
| `V` index the points `(x, y)` and the last index encodes the powers of |
| `x` and `y`. |
| |
| If ``V = polyvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` |
| correspond to the elements of a 2-D coefficient array `c` of shape |
| (xdeg + 1, ydeg + 1) in the order |
| |
| .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... |
| |
| and ``np.dot(V, c.flat)`` and ``polyval2d(x, y, c)`` will be the same |
| up to roundoff. This equivalence is useful both for least squares |
| fitting and for the evaluation of a large number of 2-D polynomials |
| of the same degrees and sample points. |
| |
| Parameters |
| ---------- |
| x, y : array_like |
| Arrays of point coordinates, all of the same shape. The dtypes |
| will be converted to either float64 or complex128 depending on |
| whether any of the elements are complex. Scalars are converted to |
| 1-D arrays. |
| deg : list of ints |
| List of maximum degrees of the form [x_deg, y_deg]. |
| |
| Returns |
| ------- |
| vander2d : ndarray |
| The shape of the returned matrix is ``x.shape + (order,)``, where |
| :math:`order = (deg[0]+1)*(deg([1]+1)`. The dtype will be the same |
| as the converted `x` and `y`. |
| |
| See Also |
| -------- |
| polyvander, polyvander3d, polyval2d, polyval3d |
| |
| """ |
| return pu._vander_nd_flat((polyvander, polyvander), (x, y), deg) |
| |
| |
| def polyvander3d(x, y, z, deg): |
| """Pseudo-Vandermonde matrix of given degrees. |
| |
| Returns the pseudo-Vandermonde matrix of degrees `deg` and sample |
| points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, |
| then The pseudo-Vandermonde matrix is defined by |
| |
| .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = x^i * y^j * z^k, |
| |
| where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading |
| indices of `V` index the points `(x, y, z)` and the last index encodes |
| the powers of `x`, `y`, and `z`. |
| |
| If ``V = polyvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns |
| of `V` correspond to the elements of a 3-D coefficient array `c` of |
| shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order |
| |
| .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... |
| |
| and ``np.dot(V, c.flat)`` and ``polyval3d(x, y, z, c)`` will be the |
| same up to roundoff. This equivalence is useful both for least squares |
| fitting and for the evaluation of a large number of 3-D polynomials |
| of the same degrees and sample points. |
| |
| Parameters |
| ---------- |
| x, y, z : array_like |
| Arrays of point coordinates, all of the same shape. The dtypes will |
| be converted to either float64 or complex128 depending on whether |
| any of the elements are complex. Scalars are converted to 1-D |
| arrays. |
| deg : list of ints |
| List of maximum degrees of the form [x_deg, y_deg, z_deg]. |
| |
| Returns |
| ------- |
| vander3d : ndarray |
| The shape of the returned matrix is ``x.shape + (order,)``, where |
| :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`. The dtype will |
| be the same as the converted `x`, `y`, and `z`. |
| |
| See Also |
| -------- |
| polyvander, polyvander3d, polyval2d, polyval3d |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.7.0 |
| |
| """ |
| return pu._vander_nd_flat((polyvander, polyvander, polyvander), (x, y, z), deg) |
| |
| |
| def polyfit(x, y, deg, rcond=None, full=False, w=None): |
| """ |
| Least-squares fit of a polynomial to data. |
| |
| Return the coefficients of a polynomial of degree `deg` that is the |
| least squares fit to the data values `y` given at points `x`. If `y` is |
| 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple |
| fits are done, one for each column of `y`, and the resulting |
| coefficients are stored in the corresponding columns of a 2-D return. |
| The fitted polynomial(s) are in the form |
| |
| .. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n, |
| |
| where `n` is `deg`. |
| |
| Parameters |
| ---------- |
| x : array_like, shape (`M`,) |
| x-coordinates of the `M` sample (data) points ``(x[i], y[i])``. |
| y : array_like, shape (`M`,) or (`M`, `K`) |
| y-coordinates of the sample points. Several sets of sample points |
| sharing the same x-coordinates can be (independently) fit with one |
| call to `polyfit` by passing in for `y` a 2-D array that contains |
| one data set per column. |
| deg : int or 1-D array_like |
| Degree(s) of the fitting polynomials. If `deg` is a single integer |
| all terms up to and including the `deg`'th term are included in the |
| fit. For NumPy versions >= 1.11.0 a list of integers specifying the |
| degrees of the terms to include may be used instead. |
| rcond : float, optional |
| Relative condition number of the fit. Singular values smaller |
| than `rcond`, relative to the largest singular value, will be |
| ignored. The default value is ``len(x)*eps``, where `eps` is the |
| relative precision of the platform's float type, about 2e-16 in |
| most cases. |
| full : bool, optional |
| Switch determining the nature of the return value. When ``False`` |
| (the default) just the coefficients are returned; when ``True``, |
| diagnostic information from the singular value decomposition (used |
| to solve the fit's matrix equation) is also returned. |
| w : array_like, shape (`M`,), optional |
| Weights. If not None, the weight ``w[i]`` applies to the unsquared |
| residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are |
| chosen so that the errors of the products ``w[i]*y[i]`` all have the |
| same variance. When using inverse-variance weighting, use |
| ``w[i] = 1/sigma(y[i])``. The default value is None. |
| |
| .. versionadded:: 1.5.0 |
| |
| Returns |
| ------- |
| coef : ndarray, shape (`deg` + 1,) or (`deg` + 1, `K`) |
| Polynomial coefficients ordered from low to high. If `y` was 2-D, |
| the coefficients in column `k` of `coef` represent the polynomial |
| fit to the data in `y`'s `k`-th column. |
| |
| [residuals, rank, singular_values, rcond] : list |
| These values are only returned if ``full == True`` |
| |
| - residuals -- sum of squared residuals of the least squares fit |
| - rank -- the numerical rank of the scaled Vandermonde matrix |
| - singular_values -- singular values of the scaled Vandermonde matrix |
| - rcond -- value of `rcond`. |
| |
| For more details, see `numpy.linalg.lstsq`. |
| |
| Raises |
| ------ |
| RankWarning |
| Raised if the matrix in the least-squares fit is rank deficient. |
| The warning is only raised if ``full == False``. The warnings can |
| be turned off by: |
| |
| >>> import warnings |
| >>> warnings.simplefilter('ignore', np.RankWarning) |
| |
| See Also |
| -------- |
| numpy.polynomial.chebyshev.chebfit |
| numpy.polynomial.legendre.legfit |
| numpy.polynomial.laguerre.lagfit |
| numpy.polynomial.hermite.hermfit |
| numpy.polynomial.hermite_e.hermefit |
| polyval : Evaluates a polynomial. |
| polyvander : Vandermonde matrix for powers. |
| numpy.linalg.lstsq : Computes a least-squares fit from the matrix. |
| scipy.interpolate.UnivariateSpline : Computes spline fits. |
| |
| Notes |
| ----- |
| The solution is the coefficients of the polynomial `p` that minimizes |
| the sum of the weighted squared errors |
| |
| .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, |
| |
| where the :math:`w_j` are the weights. This problem is solved by |
| setting up the (typically) over-determined matrix equation: |
| |
| .. math:: V(x) * c = w * y, |
| |
| where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the |
| coefficients to be solved for, `w` are the weights, and `y` are the |
| observed values. This equation is then solved using the singular value |
| decomposition of `V`. |
| |
| If some of the singular values of `V` are so small that they are |
| neglected (and `full` == ``False``), a `RankWarning` will be raised. |
| This means that the coefficient values may be poorly determined. |
| Fitting to a lower order polynomial will usually get rid of the warning |
| (but may not be what you want, of course; if you have independent |
| reason(s) for choosing the degree which isn't working, you may have to: |
| a) reconsider those reasons, and/or b) reconsider the quality of your |
| data). The `rcond` parameter can also be set to a value smaller than |
| its default, but the resulting fit may be spurious and have large |
| contributions from roundoff error. |
| |
| Polynomial fits using double precision tend to "fail" at about |
| (polynomial) degree 20. Fits using Chebyshev or Legendre series are |
| generally better conditioned, but much can still depend on the |
| distribution of the sample points and the smoothness of the data. If |
| the quality of the fit is inadequate, splines may be a good |
| alternative. |
| |
| Examples |
| -------- |
| >>> np.random.seed(123) |
| >>> from numpy.polynomial import polynomial as P |
| >>> x = np.linspace(-1,1,51) # x "data": [-1, -0.96, ..., 0.96, 1] |
| >>> y = x**3 - x + np.random.randn(len(x)) # x^3 - x + Gaussian noise |
| >>> c, stats = P.polyfit(x,y,3,full=True) |
| >>> np.random.seed(123) |
| >>> c # c[0], c[2] should be approx. 0, c[1] approx. -1, c[3] approx. 1 |
| array([ 0.01909725, -1.30598256, -0.00577963, 1.02644286]) # may vary |
| >>> stats # note the large SSR, explaining the rather poor results |
| [array([ 38.06116253]), 4, array([ 1.38446749, 1.32119158, 0.50443316, # may vary |
| 0.28853036]), 1.1324274851176597e-014] |
| |
| Same thing without the added noise |
| |
| >>> y = x**3 - x |
| >>> c, stats = P.polyfit(x,y,3,full=True) |
| >>> c # c[0], c[2] should be "very close to 0", c[1] ~= -1, c[3] ~= 1 |
| array([-6.36925336e-18, -1.00000000e+00, -4.08053781e-16, 1.00000000e+00]) |
| >>> stats # note the minuscule SSR |
| [array([ 7.46346754e-31]), 4, array([ 1.38446749, 1.32119158, # may vary |
| 0.50443316, 0.28853036]), 1.1324274851176597e-014] |
| |
| """ |
| return pu._fit(polyvander, x, y, deg, rcond, full, w) |
| |
| |
| def polycompanion(c): |
| """ |
| Return the companion matrix of c. |
| |
| The companion matrix for power series cannot be made symmetric by |
| scaling the basis, so this function differs from those for the |
| orthogonal polynomials. |
| |
| Parameters |
| ---------- |
| c : array_like |
| 1-D array of polynomial coefficients ordered from low to high |
| degree. |
| |
| Returns |
| ------- |
| mat : ndarray |
| Companion matrix of dimensions (deg, deg). |
| |
| Notes |
| ----- |
| |
| .. versionadded:: 1.7.0 |
| |
| """ |
| # c is a trimmed copy |
| [c] = pu.as_series([c]) |
| if len(c) < 2: |
| raise ValueError('Series must have maximum degree of at least 1.') |
| if len(c) == 2: |
| return np.array([[-c[0]/c[1]]]) |
| |
| n = len(c) - 1 |
| mat = np.zeros((n, n), dtype=c.dtype) |
| bot = mat.reshape(-1)[n::n+1] |
| bot[...] = 1 |
| mat[:, -1] -= c[:-1]/c[-1] |
| return mat |
| |
| |
| def polyroots(c): |
| """ |
| Compute the roots of a polynomial. |
| |
| Return the roots (a.k.a. "zeros") of the polynomial |
| |
| .. math:: p(x) = \\sum_i c[i] * x^i. |
| |
| Parameters |
| ---------- |
| c : 1-D array_like |
| 1-D array of polynomial coefficients. |
| |
| Returns |
| ------- |
| out : ndarray |
| Array of the roots of the polynomial. If all the roots are real, |
| then `out` is also real, otherwise it is complex. |
| |
| See Also |
| -------- |
| numpy.polynomial.chebyshev.chebroots |
| numpy.polynomial.legendre.legroots |
| numpy.polynomial.laguerre.lagroots |
| numpy.polynomial.hermite.hermroots |
| numpy.polynomial.hermite_e.hermeroots |
| |
| Notes |
| ----- |
| The root estimates are obtained as the eigenvalues of the companion |
| matrix, Roots far from the origin of the complex plane may have large |
| errors due to the numerical instability of the power series for such |
| values. Roots with multiplicity greater than 1 will also show larger |
| errors as the value of the series near such points is relatively |
| insensitive to errors in the roots. Isolated roots near the origin can |
| be improved by a few iterations of Newton's method. |
| |
| Examples |
| -------- |
| >>> import numpy.polynomial.polynomial as poly |
| >>> poly.polyroots(poly.polyfromroots((-1,0,1))) |
| array([-1., 0., 1.]) |
| >>> poly.polyroots(poly.polyfromroots((-1,0,1))).dtype |
| dtype('float64') |
| >>> j = complex(0,1) |
| >>> poly.polyroots(poly.polyfromroots((-j,0,j))) |
| array([ 0.00000000e+00+0.j, 0.00000000e+00+1.j, 2.77555756e-17-1.j]) # may vary |
| |
| """ |
| # c is a trimmed copy |
| [c] = pu.as_series([c]) |
| if len(c) < 2: |
| return np.array([], dtype=c.dtype) |
| if len(c) == 2: |
| return np.array([-c[0]/c[1]]) |
| |
| # rotated companion matrix reduces error |
| m = polycompanion(c)[::-1,::-1] |
| r = la.eigvals(m) |
| r.sort() |
| return r |
| |
| |
| # |
| # polynomial class |
| # |
| |
| class Polynomial(ABCPolyBase): |
| """A power series class. |
| |
| The Polynomial class provides the standard Python numerical methods |
| '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the |
| attributes and methods listed in the `ABCPolyBase` documentation. |
| |
| Parameters |
| ---------- |
| coef : array_like |
| Polynomial coefficients in order of increasing degree, i.e., |
| ``(1, 2, 3)`` give ``1 + 2*x + 3*x**2``. |
| domain : (2,) array_like, optional |
| Domain to use. The interval ``[domain[0], domain[1]]`` is mapped |
| to the interval ``[window[0], window[1]]`` by shifting and scaling. |
| The default value is [-1, 1]. |
| window : (2,) array_like, optional |
| Window, see `domain` for its use. The default value is [-1, 1]. |
| |
| .. versionadded:: 1.6.0 |
| symbol : str, optional |
| Symbol used to represent the independent variable in string |
| representations of the polynomial expression, e.g. for printing. |
| The symbol must be a valid Python identifier. Default value is 'x'. |
| |
| .. versionadded:: 1.24 |
| |
| """ |
| # Virtual Functions |
| _add = staticmethod(polyadd) |
| _sub = staticmethod(polysub) |
| _mul = staticmethod(polymul) |
| _div = staticmethod(polydiv) |
| _pow = staticmethod(polypow) |
| _val = staticmethod(polyval) |
| _int = staticmethod(polyint) |
| _der = staticmethod(polyder) |
| _fit = staticmethod(polyfit) |
| _line = staticmethod(polyline) |
| _roots = staticmethod(polyroots) |
| _fromroots = staticmethod(polyfromroots) |
| |
| # Virtual properties |
| domain = np.array(polydomain) |
| window = np.array(polydomain) |
| basis_name = None |
| |
| @classmethod |
| def _str_term_unicode(cls, i, arg_str): |
| if i == '1': |
| return f"·{arg_str}" |
| else: |
| return f"·{arg_str}{i.translate(cls._superscript_mapping)}" |
| |
| @staticmethod |
| def _str_term_ascii(i, arg_str): |
| if i == '1': |
| return f" {arg_str}" |
| else: |
| return f" {arg_str}**{i}" |
| |
| @staticmethod |
| def _repr_latex_term(i, arg_str, needs_parens): |
| if needs_parens: |
| arg_str = rf"\left({arg_str}\right)" |
| if i == 0: |
| return '1' |
| elif i == 1: |
| return arg_str |
| else: |
| return f"{arg_str}^{{{i}}}" |