Buckets:
| """ | |
| Functions to operate on polynomials. | |
| """ | |
| __all__ = ['poly', 'roots', 'polyint', 'polyder', 'polyadd', | |
| 'polysub', 'polymul', 'polydiv', 'polyval', 'poly1d', | |
| 'polyfit'] | |
| import functools | |
| import re | |
| import warnings | |
| import numpy._core.numeric as NX | |
| from numpy._core import ( | |
| abs, | |
| array, | |
| atleast_1d, | |
| dot, | |
| finfo, | |
| hstack, | |
| isscalar, | |
| ones, | |
| overrides, | |
| ) | |
| from numpy._utils import set_module | |
| from numpy.exceptions import RankWarning | |
| from numpy.lib._function_base_impl import trim_zeros | |
| from numpy.lib._twodim_base_impl import diag, vander | |
| from numpy.lib._type_check_impl import imag, iscomplex, mintypecode, real | |
| from numpy.linalg import eigvals, inv, lstsq | |
| array_function_dispatch = functools.partial( | |
| overrides.array_function_dispatch, module='numpy') | |
| def _poly_dispatcher(seq_of_zeros): | |
| return seq_of_zeros | |
| def poly(seq_of_zeros): | |
| """ | |
| Find the coefficients of a polynomial with the given sequence of roots. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| Returns the coefficients of the polynomial whose leading coefficient | |
| is one for the given sequence of zeros (multiple roots must be included | |
| in the sequence as many times as their multiplicity; see Examples). | |
| A square matrix (or array, which will be treated as a matrix) can also | |
| be given, in which case the coefficients of the characteristic polynomial | |
| of the matrix are returned. | |
| Parameters | |
| ---------- | |
| seq_of_zeros : array_like, shape (N,) or (N, N) | |
| A sequence of polynomial roots, or a square array or matrix object. | |
| Returns | |
| ------- | |
| c : ndarray | |
| 1D array of polynomial coefficients from highest to lowest degree: | |
| ``c[0] * x**(N) + c[1] * x**(N-1) + ... + c[N-1] * x + c[N]`` | |
| where c[0] always equals 1. | |
| Raises | |
| ------ | |
| ValueError | |
| If input is the wrong shape (the input must be a 1-D or square | |
| 2-D array). | |
| See Also | |
| -------- | |
| polyval : Compute polynomial values. | |
| roots : Return the roots of a polynomial. | |
| polyfit : Least squares polynomial fit. | |
| poly1d : A one-dimensional polynomial class. | |
| Notes | |
| ----- | |
| Specifying the roots of a polynomial still leaves one degree of | |
| freedom, typically represented by an undetermined leading | |
| coefficient. [1]_ In the case of this function, that coefficient - | |
| the first one in the returned array - is always taken as one. (If | |
| for some reason you have one other point, the only automatic way | |
| presently to leverage that information is to use ``polyfit``.) | |
| The characteristic polynomial, :math:`p_a(t)`, of an `n`-by-`n` | |
| matrix **A** is given by | |
| :math:`p_a(t) = \\mathrm{det}(t\\, \\mathbf{I} - \\mathbf{A})`, | |
| where **I** is the `n`-by-`n` identity matrix. [2]_ | |
| References | |
| ---------- | |
| .. [1] M. Sullivan and M. Sullivan, III, "Algebra and Trigonometry, | |
| Enhanced With Graphing Utilities," Prentice-Hall, pg. 318, 1996. | |
| .. [2] G. Strang, "Linear Algebra and Its Applications, 2nd Edition," | |
| Academic Press, pg. 182, 1980. | |
| Examples | |
| -------- | |
| Given a sequence of a polynomial's zeros: | |
| >>> import numpy as np | |
| >>> np.poly((0, 0, 0)) # Multiple root example | |
| array([1., 0., 0., 0.]) | |
| The line above represents z**3 + 0*z**2 + 0*z + 0. | |
| >>> np.poly((-1./2, 0, 1./2)) | |
| array([ 1. , 0. , -0.25, 0. ]) | |
| The line above represents z**3 - z/4 | |
| >>> np.poly((np.random.random(1)[0], 0, np.random.random(1)[0])) | |
| array([ 1. , -0.77086955, 0.08618131, 0. ]) # random | |
| Given a square array object: | |
| >>> P = np.array([[0, 1./3], [-1./2, 0]]) | |
| >>> np.poly(P) | |
| array([1. , 0. , 0.16666667]) | |
| Note how in all cases the leading coefficient is always 1. | |
| """ | |
| seq_of_zeros = atleast_1d(seq_of_zeros) | |
| sh = seq_of_zeros.shape | |
| if len(sh) == 2 and sh[0] == sh[1] and sh[0] != 0: | |
| seq_of_zeros = eigvals(seq_of_zeros) | |
| elif len(sh) == 1: | |
| dt = seq_of_zeros.dtype | |
| # Let object arrays slip through, e.g. for arbitrary precision | |
| if dt != object: | |
| seq_of_zeros = seq_of_zeros.astype(mintypecode(dt.char)) | |
| else: | |
| raise ValueError("input must be 1d or non-empty square 2d array.") | |
| if len(seq_of_zeros) == 0: | |
| return 1.0 | |
| dt = seq_of_zeros.dtype | |
| a = ones((1,), dtype=dt) | |
| for zero in seq_of_zeros: | |
| a = NX.convolve(a, array([1, -zero], dtype=dt), mode='full') | |
| if issubclass(a.dtype.type, NX.complexfloating): | |
| # if complex roots are all complex conjugates, the roots are real. | |
| roots = NX.asarray(seq_of_zeros, complex) | |
| if NX.all(NX.sort(roots) == NX.sort(roots.conjugate())): | |
| a = a.real.copy() | |
| return a | |
| def _roots_dispatcher(p): | |
| return p | |
| def roots(p): | |
| """ | |
| Return the roots of a polynomial with coefficients given in p. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| The values in the rank-1 array `p` are coefficients of a polynomial. | |
| If the length of `p` is n+1 then the polynomial is described by:: | |
| p[0] * x**n + p[1] * x**(n-1) + ... + p[n-1]*x + p[n] | |
| Parameters | |
| ---------- | |
| p : array_like | |
| Rank-1 array of polynomial coefficients. | |
| Returns | |
| ------- | |
| out : ndarray | |
| An array containing the roots of the polynomial. | |
| Raises | |
| ------ | |
| ValueError | |
| When `p` cannot be converted to a rank-1 array. | |
| See also | |
| -------- | |
| poly : Find the coefficients of a polynomial with a given sequence | |
| of roots. | |
| polyval : Compute polynomial values. | |
| polyfit : Least squares polynomial fit. | |
| poly1d : A one-dimensional polynomial class. | |
| Notes | |
| ----- | |
| The algorithm relies on computing the eigenvalues of the | |
| companion matrix [1]_. | |
| References | |
| ---------- | |
| .. [1] R. A. Horn & C. R. Johnson, *Matrix Analysis*. Cambridge, UK: | |
| Cambridge University Press, 1999, pp. 146-7. | |
| Examples | |
| -------- | |
| >>> import numpy as np | |
| >>> coeff = [3.2, 2, 1] | |
| >>> np.roots(coeff) | |
| array([-0.3125+0.46351241j, -0.3125-0.46351241j]) | |
| """ | |
| # If input is scalar, this makes it an array | |
| p = atleast_1d(p) | |
| if p.ndim != 1: | |
| raise ValueError("Input must be a rank-1 array.") | |
| # find non-zero array entries | |
| non_zero = NX.nonzero(NX.ravel(p))[0] | |
| # Return an empty array if polynomial is all zeros | |
| if len(non_zero) == 0: | |
| return NX.array([]) | |
| # find the number of trailing zeros -- this is the number of roots at 0. | |
| trailing_zeros = len(p) - non_zero[-1] - 1 | |
| # strip leading and trailing zeros | |
| p = p[int(non_zero[0]):int(non_zero[-1]) + 1] | |
| # casting: if incoming array isn't floating point, make it floating point. | |
| if not issubclass(p.dtype.type, (NX.floating, NX.complexfloating)): | |
| p = p.astype(float) | |
| N = len(p) | |
| if N > 1: | |
| # build companion matrix and find its eigenvalues (the roots) | |
| A = diag(NX.ones((N - 2,), p.dtype), -1) | |
| A[0, :] = -p[1:] / p[0] | |
| roots = eigvals(A) | |
| else: | |
| roots = NX.array([]) | |
| # tack any zeros onto the back of the array | |
| roots = hstack((roots, NX.zeros(trailing_zeros, roots.dtype))) | |
| return roots | |
| def _polyint_dispatcher(p, m=None, k=None): | |
| return (p,) | |
| def polyint(p, m=1, k=None): | |
| """ | |
| Return an antiderivative (indefinite integral) of a polynomial. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| The returned order `m` antiderivative `P` of polynomial `p` satisfies | |
| :math:`\\frac{d^m}{dx^m}P(x) = p(x)` and is defined up to `m - 1` | |
| integration constants `k`. The constants determine the low-order | |
| polynomial part | |
| .. math:: \\frac{k_{m-1}}{0!} x^0 + \\ldots + \\frac{k_0}{(m-1)!}x^{m-1} | |
| of `P` so that :math:`P^{(j)}(0) = k_{m-j-1}`. | |
| Parameters | |
| ---------- | |
| p : array_like or poly1d | |
| Polynomial to integrate. | |
| A sequence is interpreted as polynomial coefficients, see `poly1d`. | |
| m : int, optional | |
| Order of the antiderivative. (Default: 1) | |
| k : list of `m` scalars or scalar, optional | |
| Integration constants. They are given in the order of integration: | |
| those corresponding to highest-order terms come first. | |
| If ``None`` (default), all constants are assumed to be zero. | |
| If `m = 1`, a single scalar can be given instead of a list. | |
| See Also | |
| -------- | |
| polyder : derivative of a polynomial | |
| poly1d.integ : equivalent method | |
| Examples | |
| -------- | |
| The defining property of the antiderivative: | |
| >>> import numpy as np | |
| >>> p = np.poly1d([1,1,1]) | |
| >>> P = np.polyint(p) | |
| >>> P | |
| poly1d([ 0.33333333, 0.5 , 1. , 0. ]) # may vary | |
| >>> np.polyder(P) == p | |
| True | |
| The integration constants default to zero, but can be specified: | |
| >>> P = np.polyint(p, 3) | |
| >>> P(0) | |
| 0.0 | |
| >>> np.polyder(P)(0) | |
| 0.0 | |
| >>> np.polyder(P, 2)(0) | |
| 0.0 | |
| >>> P = np.polyint(p, 3, k=[6,5,3]) | |
| >>> P | |
| poly1d([ 0.01666667, 0.04166667, 0.16666667, 3. , 5. , 3. ]) # may vary | |
| Note that 3 = 6 / 2!, and that the constants are given in the order of | |
| integrations. Constant of the highest-order polynomial term comes first: | |
| >>> np.polyder(P, 2)(0) | |
| 6.0 | |
| >>> np.polyder(P, 1)(0) | |
| 5.0 | |
| >>> P(0) | |
| 3.0 | |
| """ | |
| m = int(m) | |
| if m < 0: | |
| raise ValueError("Order of integral must be positive (see polyder)") | |
| if k is None: | |
| k = NX.zeros(m, float) | |
| k = atleast_1d(k) | |
| if len(k) == 1 and m > 1: | |
| k = k[0] * NX.ones(m, float) | |
| if len(k) < m: | |
| raise ValueError( | |
| "k must be a scalar or a rank-1 array of length 1 or >m.") | |
| truepoly = isinstance(p, poly1d) | |
| p = NX.asarray(p) | |
| if m == 0: | |
| if truepoly: | |
| return poly1d(p) | |
| return p | |
| else: | |
| # Note: this must work also with object and integer arrays | |
| y = NX.concatenate((p.__truediv__(NX.arange(len(p), 0, -1)), [k[0]])) | |
| val = polyint(y, m - 1, k=k[1:]) | |
| if truepoly: | |
| return poly1d(val) | |
| return val | |
| def _polyder_dispatcher(p, m=None): | |
| return (p,) | |
| def polyder(p, m=1): | |
| """ | |
| Return the derivative of the specified order of a polynomial. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| Parameters | |
| ---------- | |
| p : poly1d or sequence | |
| Polynomial to differentiate. | |
| A sequence is interpreted as polynomial coefficients, see `poly1d`. | |
| m : int, optional | |
| Order of differentiation (default: 1) | |
| Returns | |
| ------- | |
| der : poly1d | |
| A new polynomial representing the derivative. | |
| See Also | |
| -------- | |
| polyint : Anti-derivative of a polynomial. | |
| poly1d : Class for one-dimensional polynomials. | |
| Examples | |
| -------- | |
| The derivative of the polynomial :math:`x^3 + x^2 + x^1 + 1` is: | |
| >>> import numpy as np | |
| >>> p = np.poly1d([1,1,1,1]) | |
| >>> p2 = np.polyder(p) | |
| >>> p2 | |
| poly1d([3, 2, 1]) | |
| which evaluates to: | |
| >>> p2(2.) | |
| 17.0 | |
| We can verify this, approximating the derivative with | |
| ``(f(x + h) - f(x))/h``: | |
| >>> (p(2. + 0.001) - p(2.)) / 0.001 | |
| 17.007000999997857 | |
| The fourth-order derivative of a 3rd-order polynomial is zero: | |
| >>> np.polyder(p, 2) | |
| poly1d([6, 2]) | |
| >>> np.polyder(p, 3) | |
| poly1d([6]) | |
| >>> np.polyder(p, 4) | |
| poly1d([0]) | |
| """ | |
| m = int(m) | |
| if m < 0: | |
| raise ValueError("Order of derivative must be positive (see polyint)") | |
| truepoly = isinstance(p, poly1d) | |
| p = NX.asarray(p) | |
| n = len(p) - 1 | |
| y = p[:-1] * NX.arange(n, 0, -1) | |
| if m == 0: | |
| val = p | |
| else: | |
| val = polyder(y, m - 1) | |
| if truepoly: | |
| val = poly1d(val) | |
| return val | |
| def _polyfit_dispatcher(x, y, deg, rcond=None, full=None, w=None, cov=None): | |
| return (x, y, w) | |
| def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False): | |
| """ | |
| Least squares polynomial fit. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| Fit a polynomial ``p[0] * x**deg + ... + p[deg]`` of degree `deg` | |
| to points `(x, y)`. Returns a vector of coefficients `p` that minimises | |
| the squared error in the order `deg`, `deg-1`, ... `0`. | |
| The `Polynomial.fit <numpy.polynomial.polynomial.Polynomial.fit>` class | |
| method is recommended for new code as it is more stable numerically. See | |
| the documentation of the method for more information. | |
| Parameters | |
| ---------- | |
| x : array_like, shape (M,) | |
| x-coordinates of the M sample points ``(x[i], y[i])``. | |
| y : array_like, shape (M,) or (M, K) | |
| y-coordinates of the sample points. Several data sets of sample | |
| points sharing the same x-coordinates can be fitted at once by | |
| passing in a 2D-array that contains one dataset per column. | |
| deg : int | |
| Degree of the fitting polynomial | |
| rcond : float, optional | |
| Relative condition number of the fit. Singular values smaller than | |
| this relative to the largest singular value will be ignored. The | |
| default value is len(x)*eps, where eps is the relative precision of | |
| the float type, about 2e-16 in most cases. | |
| full : bool, optional | |
| Switch determining nature of return value. When it is False (the | |
| default) just the coefficients are returned, when True diagnostic | |
| information from the singular value decomposition 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. | |
| cov : bool or str, optional | |
| If given and not `False`, return not just the estimate but also its | |
| covariance matrix. By default, the covariance are scaled by | |
| chi2/dof, where dof = M - (deg + 1), i.e., the weights are presumed | |
| to be unreliable except in a relative sense and everything is scaled | |
| such that the reduced chi2 is unity. This scaling is omitted if | |
| ``cov='unscaled'``, as is relevant for the case that the weights are | |
| w = 1/sigma, with sigma known to be a reliable estimate of the | |
| uncertainty. | |
| Returns | |
| ------- | |
| p : ndarray, shape (deg + 1,) or (deg + 1, K) | |
| Polynomial coefficients, highest power first. If `y` was 2-D, the | |
| coefficients for `k`-th data set are in ``p[:,k]``. | |
| residuals, rank, singular_values, rcond | |
| These values are only returned if ``full == True`` | |
| - residuals -- sum of squared residuals of the least squares fit | |
| - rank -- the effective rank of the scaled Vandermonde | |
| coefficient matrix | |
| - singular_values -- singular values of the scaled Vandermonde | |
| coefficient matrix | |
| - rcond -- value of `rcond`. | |
| For more details, see `numpy.linalg.lstsq`. | |
| V : ndarray, shape (deg + 1, deg + 1) or (deg + 1, deg + 1, K) | |
| Present only if ``full == False`` and ``cov == True``. The covariance | |
| matrix of the polynomial coefficient estimates. The diagonal of | |
| this matrix are the variance estimates for each coefficient. If y | |
| is a 2-D array, then the covariance matrix for the `k`-th data set | |
| are in ``V[:,:,k]`` | |
| Warns | |
| ----- | |
| RankWarning | |
| The rank of the coefficient matrix in the least-squares fit is | |
| deficient. The warning is only raised if ``full == False``. | |
| The warnings can be turned off by | |
| >>> import warnings | |
| >>> warnings.simplefilter('ignore', np.exceptions.RankWarning) | |
| See Also | |
| -------- | |
| polyval : Compute polynomial values. | |
| linalg.lstsq : Computes a least-squares fit. | |
| scipy.interpolate.UnivariateSpline : Computes spline fits. | |
| Notes | |
| ----- | |
| The solution minimizes the squared error | |
| .. math:: | |
| E = \\sum_{j=0}^k |p(x_j) - y_j|^2 | |
| in the equations:: | |
| x[0]**n * p[0] + ... + x[0] * p[n-1] + p[n] = y[0] | |
| x[1]**n * p[0] + ... + x[1] * p[n-1] + p[n] = y[1] | |
| ... | |
| x[k]**n * p[0] + ... + x[k] * p[n-1] + p[n] = y[k] | |
| The coefficient matrix of the coefficients `p` is a Vandermonde matrix. | |
| `polyfit` issues a `~exceptions.RankWarning` when the least-squares fit is | |
| badly conditioned. This implies that the best fit is not well-defined due | |
| to numerical error. The results may be improved by lowering the polynomial | |
| degree or by replacing `x` by `x` - `x`.mean(). The `rcond` parameter | |
| can also be set to a value smaller than its default, but the resulting | |
| fit may be spurious: including contributions from the small singular | |
| values can add numerical noise to the result. | |
| Note that fitting polynomial coefficients is inherently badly conditioned | |
| when the degree of the polynomial is large or the interval of sample points | |
| is badly centered. The quality of the fit should always be checked in these | |
| cases. When polynomial fits are not satisfactory, splines may be a good | |
| alternative. | |
| References | |
| ---------- | |
| .. [1] Wikipedia, "Curve fitting", | |
| https://en.wikipedia.org/wiki/Curve_fitting | |
| .. [2] Wikipedia, "Polynomial interpolation", | |
| https://en.wikipedia.org/wiki/Polynomial_interpolation | |
| Examples | |
| -------- | |
| >>> import numpy as np | |
| >>> import warnings | |
| >>> x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]) | |
| >>> y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0]) | |
| >>> z = np.polyfit(x, y, 3) | |
| >>> z | |
| array([ 0.08703704, -0.81349206, 1.69312169, -0.03968254]) # may vary | |
| It is convenient to use `poly1d` objects for dealing with polynomials: | |
| >>> p = np.poly1d(z) | |
| >>> p(0.5) | |
| 0.6143849206349179 # may vary | |
| >>> p(3.5) | |
| -0.34732142857143039 # may vary | |
| >>> p(10) | |
| 22.579365079365115 # may vary | |
| High-order polynomials may oscillate wildly: | |
| >>> with warnings.catch_warnings(): | |
| ... warnings.simplefilter('ignore', np.exceptions.RankWarning) | |
| ... p30 = np.poly1d(np.polyfit(x, y, 30)) | |
| ... | |
| >>> p30(4) | |
| -0.80000000000000204 # may vary | |
| >>> p30(5) | |
| -0.99999999999999445 # may vary | |
| >>> p30(4.5) | |
| -0.10547061179440398 # may vary | |
| Illustration: | |
| >>> import matplotlib.pyplot as plt | |
| >>> xp = np.linspace(-2, 6, 100) | |
| >>> _ = plt.plot(x, y, '.', xp, p(xp), '-', xp, p30(xp), '--') | |
| >>> plt.ylim(-2,2) | |
| (-2, 2) | |
| >>> plt.show() | |
| """ | |
| order = int(deg) + 1 | |
| x = NX.asarray(x) + 0.0 | |
| y = NX.asarray(y) + 0.0 | |
| # check arguments. | |
| if deg < 0: | |
| raise ValueError("expected deg >= 0") | |
| if x.ndim != 1: | |
| raise TypeError("expected 1D vector for x") | |
| if x.size == 0: | |
| raise TypeError("expected non-empty vector for x") | |
| if y.ndim < 1 or y.ndim > 2: | |
| raise TypeError("expected 1D or 2D array for y") | |
| if x.shape[0] != y.shape[0]: | |
| raise TypeError("expected x and y to have same length") | |
| # set rcond | |
| if rcond is None: | |
| rcond = len(x) * finfo(x.dtype).eps | |
| # set up least squares equation for powers of x | |
| lhs = vander(x, order) | |
| rhs = y | |
| # apply weighting | |
| if w is not None: | |
| w = NX.asarray(w) + 0.0 | |
| if w.ndim != 1: | |
| raise TypeError("expected a 1-d array for weights") | |
| if w.shape[0] != y.shape[0]: | |
| raise TypeError("expected w and y to have the same length") | |
| lhs *= w[:, NX.newaxis] | |
| if rhs.ndim == 2: | |
| rhs *= w[:, NX.newaxis] | |
| else: | |
| rhs *= w | |
| # scale lhs to improve condition number and solve | |
| scale = NX.sqrt((lhs * lhs).sum(axis=0)) | |
| lhs /= scale | |
| c, resids, rank, s = lstsq(lhs, rhs, rcond) | |
| c = (c.T / scale).T # broadcast scale coefficients | |
| # warn on rank reduction, which indicates an ill conditioned matrix | |
| if rank != order and not full: | |
| msg = "Polyfit may be poorly conditioned" | |
| warnings.warn(msg, RankWarning, stacklevel=2) | |
| if full: | |
| return c, resids, rank, s, rcond | |
| elif cov: | |
| Vbase = inv(dot(lhs.T, lhs)) | |
| Vbase /= NX.outer(scale, scale) | |
| if cov == "unscaled": | |
| fac = 1 | |
| else: | |
| if len(x) <= order: | |
| raise ValueError("the number of data points must exceed order " | |
| "to scale the covariance matrix") | |
| # note, this used to be: fac = resids / (len(x) - order - 2.0) | |
| # it was decided that the "- 2" (originally justified by "Bayesian | |
| # uncertainty analysis") is not what the user expects | |
| # (see gh-11196 and gh-11197) | |
| fac = resids / (len(x) - order) | |
| if y.ndim == 1: | |
| return c, Vbase * fac | |
| else: | |
| return c, Vbase[:, :, NX.newaxis] * fac | |
| else: | |
| return c | |
| def _polyval_dispatcher(p, x): | |
| return (p, x) | |
| def polyval(p, x): | |
| """ | |
| Evaluate a polynomial at specific values. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| If `p` is of length N, this function returns the value:: | |
| p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1] | |
| If `x` is a sequence, then ``p(x)`` is returned for each element of ``x``. | |
| If `x` is another polynomial then the composite polynomial ``p(x(t))`` | |
| is returned. | |
| Parameters | |
| ---------- | |
| p : array_like or poly1d object | |
| 1D array of polynomial coefficients (including coefficients equal | |
| to zero) from highest degree to the constant term, or an | |
| instance of poly1d. | |
| x : array_like or poly1d object | |
| A number, an array of numbers, or an instance of poly1d, at | |
| which to evaluate `p`. | |
| Returns | |
| ------- | |
| values : ndarray or poly1d | |
| If `x` is a poly1d instance, the result is the composition of the two | |
| polynomials, i.e., `x` is "substituted" in `p` and the simplified | |
| result is returned. In addition, the type of `x` - array_like or | |
| poly1d - governs the type of the output: `x` array_like => `values` | |
| array_like, `x` a poly1d object => `values` is also. | |
| See Also | |
| -------- | |
| poly1d: A polynomial class. | |
| Notes | |
| ----- | |
| Horner's scheme [1]_ is used to evaluate the polynomial. Even so, | |
| for polynomials of high degree the values may be inaccurate due to | |
| rounding errors. Use carefully. | |
| If `x` is a subtype of `ndarray` the return value will be of the same type. | |
| References | |
| ---------- | |
| .. [1] I. N. Bronshtein, K. A. Semendyayev, and K. A. Hirsch (Eng. | |
| trans. Ed.), *Handbook of Mathematics*, New York, Van Nostrand | |
| Reinhold Co., 1985, pg. 720. | |
| Examples | |
| -------- | |
| >>> import numpy as np | |
| >>> np.polyval([3,0,1], 5) # 3 * 5**2 + 0 * 5**1 + 1 | |
| 76 | |
| >>> np.polyval([3,0,1], np.poly1d(5)) | |
| poly1d([76]) | |
| >>> np.polyval(np.poly1d([3,0,1]), 5) | |
| 76 | |
| >>> np.polyval(np.poly1d([3,0,1]), np.poly1d(5)) | |
| poly1d([76]) | |
| """ | |
| p = NX.asarray(p) | |
| if isinstance(x, poly1d): | |
| y = 0 | |
| else: | |
| x = NX.asanyarray(x) | |
| y = NX.zeros_like(x) | |
| for pv in p: | |
| y = y * x + pv | |
| return y | |
| def _binary_op_dispatcher(a1, a2): | |
| return (a1, a2) | |
| def polyadd(a1, a2): | |
| """ | |
| Find the sum of two polynomials. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| Returns the polynomial resulting from the sum of two input polynomials. | |
| Each input must be either a poly1d object or a 1D sequence of polynomial | |
| coefficients, from highest to lowest degree. | |
| Parameters | |
| ---------- | |
| a1, a2 : array_like or poly1d object | |
| Input polynomials. | |
| Returns | |
| ------- | |
| out : ndarray or poly1d object | |
| The sum of the inputs. If either input is a poly1d object, then the | |
| output is also a poly1d object. Otherwise, it is a 1D array of | |
| polynomial coefficients from highest to lowest degree. | |
| See Also | |
| -------- | |
| poly1d : A one-dimensional polynomial class. | |
| poly, polyadd, polyder, polydiv, polyfit, polyint, polysub, polyval | |
| Examples | |
| -------- | |
| >>> import numpy as np | |
| >>> np.polyadd([1, 2], [9, 5, 4]) | |
| array([9, 6, 6]) | |
| Using poly1d objects: | |
| >>> p1 = np.poly1d([1, 2]) | |
| >>> p2 = np.poly1d([9, 5, 4]) | |
| >>> print(p1) | |
| 1 x + 2 | |
| >>> print(p2) | |
| 2 | |
| 9 x + 5 x + 4 | |
| >>> print(np.polyadd(p1, p2)) | |
| 2 | |
| 9 x + 6 x + 6 | |
| """ | |
| truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d)) | |
| a1 = atleast_1d(a1) | |
| a2 = atleast_1d(a2) | |
| diff = len(a2) - len(a1) | |
| if diff == 0: | |
| val = a1 + a2 | |
| elif diff > 0: | |
| zr = NX.zeros(diff, a1.dtype) | |
| val = NX.concatenate((zr, a1)) + a2 | |
| else: | |
| zr = NX.zeros(abs(diff), a2.dtype) | |
| val = a1 + NX.concatenate((zr, a2)) | |
| if truepoly: | |
| val = poly1d(val) | |
| return val | |
| def polysub(a1, a2): | |
| """ | |
| Difference (subtraction) of two polynomials. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| Given two polynomials `a1` and `a2`, returns ``a1 - a2``. | |
| `a1` and `a2` can be either array_like sequences of the polynomials' | |
| coefficients (including coefficients equal to zero), or `poly1d` objects. | |
| Parameters | |
| ---------- | |
| a1, a2 : array_like or poly1d | |
| Minuend and subtrahend polynomials, respectively. | |
| Returns | |
| ------- | |
| out : ndarray or poly1d | |
| Array or `poly1d` object of the difference polynomial's coefficients. | |
| See Also | |
| -------- | |
| polyval, polydiv, polymul, polyadd | |
| Examples | |
| -------- | |
| .. math:: (2 x^2 + 10 x - 2) - (3 x^2 + 10 x -4) = (-x^2 + 2) | |
| >>> import numpy as np | |
| >>> np.polysub([2, 10, -2], [3, 10, -4]) | |
| array([-1, 0, 2]) | |
| """ | |
| truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d)) | |
| a1 = atleast_1d(a1) | |
| a2 = atleast_1d(a2) | |
| diff = len(a2) - len(a1) | |
| if diff == 0: | |
| val = a1 - a2 | |
| elif diff > 0: | |
| zr = NX.zeros(diff, a1.dtype) | |
| val = NX.concatenate((zr, a1)) - a2 | |
| else: | |
| zr = NX.zeros(abs(diff), a2.dtype) | |
| val = a1 - NX.concatenate((zr, a2)) | |
| if truepoly: | |
| val = poly1d(val) | |
| return val | |
| def polymul(a1, a2): | |
| """ | |
| Find the product of two polynomials. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| Finds the polynomial resulting from the multiplication of the two input | |
| polynomials. Each input must be either a poly1d object or a 1D sequence | |
| of polynomial coefficients, from highest to lowest degree. | |
| Parameters | |
| ---------- | |
| a1, a2 : array_like or poly1d object | |
| Input polynomials. | |
| Returns | |
| ------- | |
| out : ndarray or poly1d object | |
| The polynomial resulting from the multiplication of the inputs. If | |
| either inputs is a poly1d object, then the output is also a poly1d | |
| object. Otherwise, it is a 1D array of polynomial coefficients from | |
| highest to lowest degree. | |
| See Also | |
| -------- | |
| poly1d : A one-dimensional polynomial class. | |
| poly, polyadd, polyder, polydiv, polyfit, polyint, polysub, polyval | |
| convolve : Array convolution. Same output as polymul, but has parameter | |
| for overlap mode. | |
| Examples | |
| -------- | |
| >>> import numpy as np | |
| >>> np.polymul([1, 2, 3], [9, 5, 1]) | |
| array([ 9, 23, 38, 17, 3]) | |
| Using poly1d objects: | |
| >>> p1 = np.poly1d([1, 2, 3]) | |
| >>> p2 = np.poly1d([9, 5, 1]) | |
| >>> print(p1) | |
| 2 | |
| 1 x + 2 x + 3 | |
| >>> print(p2) | |
| 2 | |
| 9 x + 5 x + 1 | |
| >>> print(np.polymul(p1, p2)) | |
| 4 3 2 | |
| 9 x + 23 x + 38 x + 17 x + 3 | |
| """ | |
| truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d)) | |
| a1, a2 = poly1d(a1), poly1d(a2) | |
| val = NX.convolve(a1, a2) | |
| if truepoly: | |
| val = poly1d(val) | |
| return val | |
| def _polydiv_dispatcher(u, v): | |
| return (u, v) | |
| def polydiv(u, v): | |
| """ | |
| Returns the quotient and remainder of polynomial division. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| The input arrays are the coefficients (including any coefficients | |
| equal to zero) of the "numerator" (dividend) and "denominator" | |
| (divisor) polynomials, respectively. | |
| Parameters | |
| ---------- | |
| u : array_like or poly1d | |
| Dividend polynomial's coefficients. | |
| v : array_like or poly1d | |
| Divisor polynomial's coefficients. | |
| Returns | |
| ------- | |
| q : ndarray | |
| Coefficients, including those equal to zero, of the quotient. | |
| r : ndarray | |
| Coefficients, including those equal to zero, of the remainder. | |
| See Also | |
| -------- | |
| poly, polyadd, polyder, polydiv, polyfit, polyint, polymul, polysub | |
| polyval | |
| Notes | |
| ----- | |
| Both `u` and `v` must be 0-d or 1-d (ndim = 0 or 1), but `u.ndim` need | |
| not equal `v.ndim`. In other words, all four possible combinations - | |
| ``u.ndim = v.ndim = 0``, ``u.ndim = v.ndim = 1``, | |
| ``u.ndim = 1, v.ndim = 0``, and ``u.ndim = 0, v.ndim = 1`` - work. | |
| Examples | |
| -------- | |
| .. math:: \\frac{3x^2 + 5x + 2}{2x + 1} = 1.5x + 1.75, remainder 0.25 | |
| >>> import numpy as np | |
| >>> x = np.array([3.0, 5.0, 2.0]) | |
| >>> y = np.array([2.0, 1.0]) | |
| >>> np.polydiv(x, y) | |
| (array([1.5 , 1.75]), array([0.25])) | |
| """ | |
| truepoly = (isinstance(u, poly1d) or isinstance(v, poly1d)) | |
| u = atleast_1d(u) + 0.0 | |
| v = atleast_1d(v) + 0.0 | |
| # w has the common type | |
| w = u[0] + v[0] | |
| m = len(u) - 1 | |
| n = len(v) - 1 | |
| scale = 1. / v[0] | |
| q = NX.zeros((max(m - n + 1, 1),), w.dtype) | |
| r = u.astype(w.dtype) | |
| for k in range(m - n + 1): | |
| d = scale * r[k] | |
| q[k] = d | |
| r[k:k + n + 1] -= d * v | |
| while NX.allclose(r[0], 0, rtol=1e-14) and (r.shape[-1] > 1): | |
| r = r[1:] | |
| if truepoly: | |
| return poly1d(q), poly1d(r) | |
| return q, r | |
| _poly_mat = re.compile(r"\*\*([0-9]*)") | |
| def _raise_power(astr, wrap=70): | |
| n = 0 | |
| line1 = '' | |
| line2 = '' | |
| output = ' ' | |
| while True: | |
| mat = _poly_mat.search(astr, n) | |
| if mat is None: | |
| break | |
| span = mat.span() | |
| power = mat.groups()[0] | |
| partstr = astr[n:span[0]] | |
| n = span[1] | |
| toadd2 = partstr + ' ' * (len(power) - 1) | |
| toadd1 = ' ' * (len(partstr) - 1) + power | |
| if ((len(line2) + len(toadd2) > wrap) or | |
| (len(line1) + len(toadd1) > wrap)): | |
| output += line1 + "\n" + line2 + "\n " | |
| line1 = toadd1 | |
| line2 = toadd2 | |
| else: | |
| line2 += partstr + ' ' * (len(power) - 1) | |
| line1 += ' ' * (len(partstr) - 1) + power | |
| output += line1 + "\n" + line2 | |
| return output + astr[n:] | |
| class poly1d: | |
| """ | |
| A one-dimensional polynomial class. | |
| .. note:: | |
| This forms part of the old polynomial API. Since version 1.4, the | |
| new polynomial API defined in `numpy.polynomial` is preferred. | |
| A summary of the differences can be found in the | |
| :doc:`transition guide </reference/routines.polynomials>`. | |
| A convenience class, used to encapsulate "natural" operations on | |
| polynomials so that said operations may take on their customary | |
| form in code (see Examples). | |
| Parameters | |
| ---------- | |
| c_or_r : array_like | |
| The polynomial's coefficients, in decreasing powers, or if | |
| the value of the second parameter is True, the polynomial's | |
| roots (values where the polynomial evaluates to 0). For example, | |
| ``poly1d([1, 2, 3])`` returns an object that represents | |
| :math:`x^2 + 2x + 3`, whereas ``poly1d([1, 2, 3], True)`` returns | |
| one that represents :math:`(x-1)(x-2)(x-3) = x^3 - 6x^2 + 11x -6`. | |
| r : bool, optional | |
| If True, `c_or_r` specifies the polynomial's roots; the default | |
| is False. | |
| variable : str, optional | |
| Changes the variable used when printing `p` from `x` to `variable` | |
| (see Examples). | |
| Examples | |
| -------- | |
| >>> import numpy as np | |
| Construct the polynomial :math:`x^2 + 2x + 3`: | |
| >>> import numpy as np | |
| >>> p = np.poly1d([1, 2, 3]) | |
| >>> print(np.poly1d(p)) | |
| 2 | |
| 1 x + 2 x + 3 | |
| Evaluate the polynomial at :math:`x = 0.5`: | |
| >>> p(0.5) | |
| 4.25 | |
| Find the roots: | |
| >>> p.r | |
| array([-1.+1.41421356j, -1.-1.41421356j]) | |
| >>> p(p.r) | |
| array([ -4.44089210e-16+0.j, -4.44089210e-16+0.j]) # may vary | |
| These numbers in the previous line represent (0, 0) to machine precision | |
| Show the coefficients: | |
| >>> p.c | |
| array([1, 2, 3]) | |
| Display the order (the leading zero-coefficients are removed): | |
| >>> p.order | |
| 2 | |
| Show the coefficient of the k-th power in the polynomial | |
| (which is equivalent to ``p.c[-(i+1)]``): | |
| >>> p[1] | |
| 2 | |
| Polynomials can be added, subtracted, multiplied, and divided | |
| (returns quotient and remainder): | |
| >>> p * p | |
| poly1d([ 1, 4, 10, 12, 9]) | |
| >>> (p**3 + 4) / p | |
| (poly1d([ 1., 4., 10., 12., 9.]), poly1d([4.])) | |
| ``asarray(p)`` gives the coefficient array, so polynomials can be | |
| used in all functions that accept arrays: | |
| >>> p**2 # square of polynomial | |
| poly1d([ 1, 4, 10, 12, 9]) | |
| >>> np.square(p) # square of individual coefficients | |
| array([1, 4, 9]) | |
| The variable used in the string representation of `p` can be modified, | |
| using the `variable` parameter: | |
| >>> p = np.poly1d([1,2,3], variable='z') | |
| >>> print(p) | |
| 2 | |
| 1 z + 2 z + 3 | |
| Construct a polynomial from its roots: | |
| >>> np.poly1d([1, 2], True) | |
| poly1d([ 1., -3., 2.]) | |
| This is the same polynomial as obtained by: | |
| >>> np.poly1d([1, -1]) * np.poly1d([1, -2]) | |
| poly1d([ 1, -3, 2]) | |
| """ | |
| __hash__ = None | |
| def coeffs(self): | |
| """ The polynomial coefficients """ | |
| return self._coeffs | |
| def coeffs(self, value): | |
| # allowing this makes p.coeffs *= 2 legal | |
| if value is not self._coeffs: | |
| raise AttributeError("Cannot set attribute") | |
| def variable(self): | |
| """ The name of the polynomial variable """ | |
| return self._variable | |
| # calculated attributes | |
| def order(self): | |
| """ The order or degree of the polynomial """ | |
| return len(self._coeffs) - 1 | |
| def roots(self): | |
| """ The roots of the polynomial, where self(x) == 0 """ | |
| return roots(self._coeffs) | |
| # our internal _coeffs property need to be backed by __dict__['coeffs'] for | |
| # scipy to work correctly. | |
| def _coeffs(self): | |
| return self.__dict__['coeffs'] | |
| def _coeffs(self, coeffs): | |
| self.__dict__['coeffs'] = coeffs | |
| # alias attributes | |
| r = roots | |
| c = coef = coefficients = coeffs | |
| o = order | |
| def __init__(self, c_or_r, r=False, variable=None): | |
| if isinstance(c_or_r, poly1d): | |
| self._variable = c_or_r._variable | |
| self._coeffs = c_or_r._coeffs | |
| if set(c_or_r.__dict__) - set(self.__dict__): | |
| msg = ("In the future extra properties will not be copied " | |
| "across when constructing one poly1d from another") | |
| warnings.warn(msg, FutureWarning, stacklevel=2) | |
| self.__dict__.update(c_or_r.__dict__) | |
| if variable is not None: | |
| self._variable = variable | |
| return | |
| if r: | |
| c_or_r = poly(c_or_r) | |
| c_or_r = atleast_1d(c_or_r) | |
| if c_or_r.ndim > 1: | |
| raise ValueError("Polynomial must be 1d only.") | |
| c_or_r = trim_zeros(c_or_r, trim='f') | |
| if len(c_or_r) == 0: | |
| c_or_r = NX.array([0], dtype=c_or_r.dtype) | |
| self._coeffs = c_or_r | |
| if variable is None: | |
| variable = 'x' | |
| self._variable = variable | |
| def __array__(self, t=None, copy=None): | |
| if t: | |
| return NX.asarray(self.coeffs, t, copy=copy) | |
| else: | |
| return NX.asarray(self.coeffs, copy=copy) | |
| def __repr__(self): | |
| vals = repr(self.coeffs) | |
| vals = vals[6:-1] | |
| return f"poly1d({vals})" | |
| def __len__(self): | |
| return self.order | |
| def __str__(self): | |
| thestr = "0" | |
| var = self.variable | |
| # Remove leading zeros | |
| coeffs = self.coeffs[NX.logical_or.accumulate(self.coeffs != 0)] | |
| N = len(coeffs) - 1 | |
| def fmt_float(q): | |
| s = f'{q:.4g}' | |
| s = s.removesuffix('.0000') | |
| return s | |
| for k, coeff in enumerate(coeffs): | |
| if not iscomplex(coeff): | |
| coefstr = fmt_float(real(coeff)) | |
| elif real(coeff) == 0: | |
| coefstr = f'{fmt_float(imag(coeff))}j' | |
| else: | |
| coefstr = f'({fmt_float(real(coeff))} + {fmt_float(imag(coeff))}j)' | |
| power = (N - k) | |
| if power == 0: | |
| if coefstr != '0': | |
| newstr = f'{coefstr}' | |
| elif k == 0: | |
| newstr = '0' | |
| else: | |
| newstr = '' | |
| elif power == 1: | |
| if coefstr == '0': | |
| newstr = '' | |
| elif coefstr == 'b': | |
| newstr = var | |
| else: | |
| newstr = f'{coefstr} {var}' | |
| elif coefstr == '0': | |
| newstr = '' | |
| elif coefstr == 'b': | |
| newstr = '%s**%d' % (var, power,) | |
| else: | |
| newstr = '%s %s**%d' % (coefstr, var, power) | |
| if k > 0: | |
| if newstr != '': | |
| if newstr.startswith('-'): | |
| thestr = f"{thestr} - {newstr[1:]}" | |
| else: | |
| thestr = f"{thestr} + {newstr}" | |
| else: | |
| thestr = newstr | |
| return _raise_power(thestr) | |
| def __call__(self, val): | |
| return polyval(self.coeffs, val) | |
| def __neg__(self): | |
| return poly1d(-self.coeffs) | |
| def __pos__(self): | |
| return self | |
| def __mul__(self, other): | |
| if isscalar(other): | |
| return poly1d(self.coeffs * other) | |
| else: | |
| other = poly1d(other) | |
| return poly1d(polymul(self.coeffs, other.coeffs)) | |
| def __rmul__(self, other): | |
| if isscalar(other): | |
| return poly1d(other * self.coeffs) | |
| else: | |
| other = poly1d(other) | |
| return poly1d(polymul(self.coeffs, other.coeffs)) | |
| def __add__(self, other): | |
| other = poly1d(other) | |
| return poly1d(polyadd(self.coeffs, other.coeffs)) | |
| def __radd__(self, other): | |
| other = poly1d(other) | |
| return poly1d(polyadd(self.coeffs, other.coeffs)) | |
| def __pow__(self, val): | |
| if not isscalar(val) or int(val) != val or val < 0: | |
| raise ValueError("Power to non-negative integers only.") | |
| res = [1] | |
| for _ in range(val): | |
| res = polymul(self.coeffs, res) | |
| return poly1d(res) | |
| def __sub__(self, other): | |
| other = poly1d(other) | |
| return poly1d(polysub(self.coeffs, other.coeffs)) | |
| def __rsub__(self, other): | |
| other = poly1d(other) | |
| return poly1d(polysub(other.coeffs, self.coeffs)) | |
| def __truediv__(self, other): | |
| if isscalar(other): | |
| return poly1d(self.coeffs / other) | |
| else: | |
| other = poly1d(other) | |
| return polydiv(self, other) | |
| def __rtruediv__(self, other): | |
| if isscalar(other): | |
| return poly1d(other / self.coeffs) | |
| else: | |
| other = poly1d(other) | |
| return polydiv(other, self) | |
| def __eq__(self, other): | |
| if not isinstance(other, poly1d): | |
| return NotImplemented | |
| if self.coeffs.shape != other.coeffs.shape: | |
| return False | |
| return (self.coeffs == other.coeffs).all() | |
| def __ne__(self, other): | |
| if not isinstance(other, poly1d): | |
| return NotImplemented | |
| return not self.__eq__(other) | |
| def __getitem__(self, val): | |
| ind = self.order - val | |
| if val > self.order: | |
| return self.coeffs.dtype.type(0) | |
| if val < 0: | |
| return self.coeffs.dtype.type(0) | |
| return self.coeffs[ind] | |
| def __setitem__(self, key, val): | |
| ind = self.order - key | |
| if key < 0: | |
| raise ValueError("Does not support negative powers.") | |
| if key > self.order: | |
| zr = NX.zeros(key - self.order, self.coeffs.dtype) | |
| self._coeffs = NX.concatenate((zr, self.coeffs)) | |
| ind = 0 | |
| self._coeffs[ind] = val | |
| def __iter__(self): | |
| return iter(self.coeffs) | |
| def integ(self, m=1, k=0): | |
| """ | |
| Return an antiderivative (indefinite integral) of this polynomial. | |
| Refer to `polyint` for full documentation. | |
| See Also | |
| -------- | |
| polyint : equivalent function | |
| """ | |
| return poly1d(polyint(self.coeffs, m=m, k=k)) | |
| def deriv(self, m=1): | |
| """ | |
| Return a derivative of this polynomial. | |
| Refer to `polyder` for full documentation. | |
| See Also | |
| -------- | |
| polyder : equivalent function | |
| """ | |
| return poly1d(polyder(self.coeffs, m=m)) | |
| # Stuff to do on module import | |
| warnings.simplefilter('always', RankWarning) | |
Xet Storage Details
- Size:
- 44.1 kB
- Xet hash:
- b69689d895ec29bd46895b2d1fc059809264e60f67e563ee1331ee140e0b7980
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.