def chebmul(c1, c2): """Multiply one Chebyshev series by another. Returns the product of two Chebyshev series `c1` * `c2`. The arguments are sequences of coefficients ordered from low to high, i.e., [1,2,3] is the series ``T_0 + 2*T_1 + 3*T_2.`` Parameters ---------- c1, c2 : array_like 1d arrays of chebyshev series coefficients ordered from low to high. Returns ------- out : ndarray Chebyshev series of the product. See Also -------- chebadd, chebsub, chebdiv, chebpow """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) z1 = _cseries_to_zseries(c1) z2 = _cseries_to_zseries(c2) prd = _zseries_mul(z1, z2) ret = _zseries_to_cseries(prd) return pu.trimseq(ret)
def polyadd(c1, c2): """Add one polynomial to another. Returns the sum of two polynomials `c1` + `c2`. The arguments are sequences of coefficients ordered from low to high, i.e., [1,2,3] is the polynomial ``1 + 2*x + 3*x**2"``. Parameters ---------- c1, c2 : array_like 1d arrays of polynomial coefficients ordered from low to high. Returns ------- out : ndarray polynomial of the sum. See Also -------- polysub, polymul, polydiv, polypow """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if len(c1) > len(c2): c1[:c2.size] += c2 ret = c1 else: c2[:c1.size] += c1 ret = c2 return pu.trimseq(ret)
def polymul(c1, c2): """Multiply one polynomial by another. Returns the product of two polynomials `c1` * `c2`. The arguments are sequences of coefficients ordered from low to high, i.e., [1,2,3] is the polynomial ``1 + 2*x + 3*x**2.`` Parameters ---------- c1, c2 : array_like 1d arrays of polyyshev series coefficients ordered from low to high. Returns ------- out : ndarray polynomial of the product. See Also -------- polyadd, polysub, polydiv, polypow """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) ret = np.convolve(c1, c2) return pu.trimseq(ret)
def chebadd(c1, c2): """Add one Chebyshev series to another. Returns the sum of two Chebyshev series `c1` + `c2`. The arguments are sequences of coefficients ordered from low to high, i.e., [1,2,3] is the series "T_0 + 2*T_1 + 3*T_2". Parameters ---------- c1, c2 : array_like 1d arrays of Chebyshev series coefficients ordered from low to high. Returns ------- out : ndarray Chebyshev series of the sum. See Also -------- chebsub, chebmul, chebdiv, chebpow """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if len(c1) > len(c2) : c1[:c2.size] += c2 ret = c1 else : c2[:c1.size] += c1 ret = c2 return pu.trimseq(ret)
def polyfromroots(roots): """Generate a polynomial with given roots. Generate a polynomial whose roots are given by `roots`. The resulting series is the produet `(x - roots[0])*(x - roots[1])*...` Inputs ------ roots : array_like 1-d array containing the roots in sorted order. Returns ------- series : ndarray 1-d array containing the coefficients of the Chebeshev series ordered from low to high. See Also -------- polyroots """ if len(roots) == 0: return np.ones(1) else: [roots] = pu.as_series([roots], trim=False) prd = np.zeros(len(roots) + 1, dtype=roots.dtype) prd[-1] = 1 for i in range(len(roots)): prd[-(i + 2):-1] -= roots[i] * prd[-(i + 1):] return prd
def cheb2poly(cs) : """Convert a Chebyshev series to a polynomial. Covert a series containing Chebyshev series coefficients orderd from low to high to an equivalent polynomial ordered from low to high by degree. Inputs ------ cs : array_like 1-d array containing the Chebyshev series coeffients ordered from low to high. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial ordered from low to high by degree. See Also -------- poly2cheb """ [cs] = pu.as_series([cs]) pol = np.zeros(len(cs), dtype=cs.dtype) quo = _cseries_to_zseries(cs) x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(0, len(cs) - 1) : quo, rem = _zseries_div(quo, x) pol[i] = rem[0] pol[-1] = quo[0] return pol
def polycompanion(cs): """Return the companion matrix of cs. Parameters ---------- cs : array_like 1-d array of series coefficients ordered from low to high degree. Returns ------- mat : ndarray Scaled companion matrix of dimensions (deg, deg). """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: raise ValueError("Series must have maximum degree of at least 1.") if len(cs) == 2: return np.array(-cs[0] / cs[1]) n = len(cs) - 1 mat = np.zeros((n, n), dtype=cs.dtype) bot = mat.reshape(-1)[n :: n + 1] bot[...] = 1 mat[:, -1] -= cs[:-1] / cs[-1] return mat
def polyroots(cs): """Roots of a polynomial. Compute the roots of the Chebyshev series `cs`. The argument `cs` is a sequence of coefficients ordered from low to high. i.e., [1,2,3] is the polynomial ``1 + 2*x + 3*x**2``. Parameters ---------- cs : array_like of shape(M,) 1D array of polynomial coefficients ordered from low to high. Returns ------- out : ndarray An array containing the complex roots of the polynomial series. Examples -------- """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1 : return np.array([], dtype=cs.dtype) if len(cs) == 2 : return np.array([-cs[0]/cs[1]]) n = len(cs) - 1 cmat = np.zeros((n,n), dtype=cs.dtype) cmat.flat[n::n+1] = 1 cmat[:,-1] -= cs[:-1]/cs[-1] roots = la.eigvals(cmat) roots.sort() return roots
def polyfromroots(roots) : """Generate a polynomial with given roots. Generate a polynomial whose roots are given by `roots`. The resulting series is the produet `(x - roots[0])*(x - roots[1])*...` Inputs ------ roots : array_like 1-d array containing the roots in sorted order. Returns ------- series : ndarray 1-d array containing the coefficients of the Chebeshev series ordered from low to high. See Also -------- polyroots """ if len(roots) == 0 : return np.ones(1) else : [roots] = pu.as_series([roots], trim=False) prd = np.zeros(len(roots) + 1, dtype=roots.dtype) prd[-1] = 1 for i in range(len(roots)) : prd[-(i+2):-1] -= roots[i]*prd[-(i+1):] return prd
def polyadd(c1, c2): """Add one polynomial to another. Returns the sum of two polynomials `c1` + `c2`. The arguments are sequences of coefficients ordered from low to high, i.e., [1,2,3] is the polynomial ``1 + 2*x + 3*x**2"``. Parameters ---------- c1, c2 : array_like 1d arrays of polynomial coefficients ordered from low to high. Returns ------- out : ndarray polynomial of the sum. See Also -------- polysub, polymul, polydiv, polypow """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if len(c1) > len(c2) : c1[:c2.size] += c2 ret = c1 else : c2[:c1.size] += c1 ret = c2 return pu.trimseq(ret)
def chebadd(c1, c2): """Add one Chebyshev series to another. Returns the sum of two Chebyshev series `c1` + `c2`. The arguments are sequences of coefficients ordered from low to high, i.e., [1,2,3] is the series "T_0 + 2*T_1 + 3*T_2". Parameters ---------- c1, c2 : array_like 1d arrays of Chebyshev series coefficients ordered from low to high. Returns ------- out : ndarray Chebyshev series of the sum. See Also -------- chebsub, chebmul, chebdiv, chebpow """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if len(c1) > len(c2): c1[:c2.size] += c2 ret = c1 else: c2[:c1.size] += c1 ret = c2 return pu.trimseq(ret)
def polycompanion(cs): """Return the companion matrix of cs. Parameters ---------- cs : array_like 1-d array of series coefficients ordered from low to high degree. Returns ------- mat : ndarray Scaled companion matrix of dimensions (deg, deg). """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2 : raise ValueError('Series must have maximum degree of at least 1.') if len(cs) == 2: return np.array(-cs[0]/cs[1]) n = len(cs) - 1 mat = np.zeros((n, n), dtype=cs.dtype) bot = mat.reshape(-1)[n::n+1] bot[...] = 1 mat[:,-1] -= cs[:-1]/cs[-1] return mat
def poly2cheb(pol): """Convert a polynomial to a Chebyshev series. Convert a series containing polynomial coefficients ordered by degree from low to high to an equivalent Chebyshev series ordered from low to high. Inputs ------ pol : array_like 1-d array containing the polynomial coeffients Returns ------- cseries : ndarray 1-d array containing the coefficients of the equivalent Chebyshev series. See Also -------- cheb2poly """ [pol] = pu.as_series([pol]) pol = pol[::-1] zs = pol[:1].copy() x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(1, len(pol)): zs = _zseries_mul(zs, x) zs[i] += pol[i] return _zseries_to_cseries(zs)
def chebfromroots(roots) : """Generate a Chebyschev series with given roots. Generate a Chebyshev series whose roots are given by `roots`. The resulting series is the produet `(x - roots[0])*(x - roots[1])*...` Inputs ------ roots : array_like 1-d array containing the roots in sorted order. Returns ------- series : ndarray 1-d array containing the coefficients of the Chebeshev series ordered from low to high. See Also -------- chebroots """ if len(roots) == 0 : return np.ones(1) else : [roots] = pu.as_series([roots], trim=False) prd = np.array([1], dtype=roots.dtype) for r in roots : fac = np.array([.5, -r, .5], dtype=roots.dtype) prd = _zseries_mul(fac, prd) return _zseries_to_cseries(prd)
def legfromroots(roots) : """ Generate a Legendre series with the given roots. Return the array of coefficients for the P-series whose roots (a.k.a. "zeros") are given by *roots*. The returned array of coefficients is ordered from lowest order "term" to highest, and zeros of multiplicity greater than one must be included in *roots* a number of times equal to their multiplicity (e.g., if `2` is a root of multiplicity three, then [2,2,2] must be in *roots*). Parameters ---------- roots : array_like Sequence containing the roots. Returns ------- out : ndarray 1-d array of the Legendre series coefficients, ordered from low to high. If all roots are real, ``out.dtype`` is a float type; otherwise, ``out.dtype`` is a complex type, even if all the coefficients in the result are real (see Examples below). See Also -------- polyfromroots, chebfromroots Notes ----- What is returned are the :math:`c_i` such that: .. math:: \\sum_{i=0}^{n} c_i*P_i(x) = \\prod_{i=0}^{n} (x - roots[i]) where ``n == len(roots)`` and :math:`P_i(x)` is the `i`-th Legendre (basis) polynomial over the domain `[-1,1]`. Note that, unlike `polyfromroots`, due to the nature of the Legendre basis set, the above identity *does not* imply :math:`c_n = 1` identically (see Examples). Examples -------- >>> import numpy.polynomial.legendre as L >>> L.legfromroots((-1,0,1)) # x^3 - x relative to the standard basis array([ 0. , -0.4, 0. , 0.4]) >>> j = complex(0,1) >>> L.legfromroots((-j,j)) # x^2 + 1 relative to the standard basis array([ 1.33333333+0.j, 0.00000000+0.j, 0.66666667+0.j]) """ if len(roots) == 0 : return np.ones(1) else : [roots] = pu.as_series([roots], trim=False) prd = np.array([1], dtype=roots.dtype) for r in roots: prd = legsub(legmulx(prd), r*prd) return prd
def polyroots(cs): """Roots of a polynomial. Compute the roots of the Chebyshev series `cs`. The argument `cs` is a sequence of coefficients ordered from low to high. i.e., [1,2,3] is the polynomial ``1 + 2*x + 3*x**2``. Parameters ---------- cs : array_like of shape(M,) 1D array of polynomial coefficients ordered from low to high. Returns ------- out : ndarray An array containing the complex roots of the polynomial series. Examples -------- """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0] / cs[1]]) n = len(cs) - 1 cmat = np.zeros((n, n), dtype=cs.dtype) cmat.flat[n::n + 1] = 1 cmat[:, -1] -= cs[:-1] / cs[-1] roots = la.eigvals(cmat) roots.sort() return roots
def cheb2poly(cs): """Convert a Chebyshev series to a polynomial. Covert a series containing Chebyshev series coefficients orderd from low to high to an equivalent polynomial ordered from low to high by degree. Inputs ------ cs : array_like 1-d array containing the Chebyshev series coeffients ordered from low to high. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial ordered from low to high by degree. See Also -------- poly2cheb """ [cs] = pu.as_series([cs]) pol = np.zeros(len(cs), dtype=cs.dtype) quo = _cseries_to_zseries(cs) x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(0, len(cs) - 1): quo, rem = _zseries_div(quo, x) pol[i] = rem[0] pol[-1] = quo[0] return pol
def legval(x, cs): """Evaluate a Legendre series. If `cs` is of length `n`, this function returns : ``p(x) = cs[0]*P_0(x) + cs[1]*P_1(x) + ... + cs[n-1]*P_{n-1}(x)`` If x is a sequence or array then p(x) will have the same shape as x. If r is a ring_like object that supports multiplication and addition by the values in `cs`, then an object of the same type is returned. Parameters ---------- x : array_like, ring_like Array of numbers or objects that support multiplication and addition with themselves and with the elements of `cs`. cs : array_like 1-d array of Legendre coefficients ordered from low to high. Returns ------- values : ndarray, ring_like If the return is an ndarray then it has the same shape as `x`. See Also -------- legfit Examples -------- Notes ----- The evaluation uses Clenshaw recursion, aka synthetic division. Examples -------- """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if isinstance(x, tuple) or isinstance(x, list) : x = np.asarray(x) if len(cs) == 1 : c0 = cs[0] c1 = 0 elif len(cs) == 2 : c0 = cs[0] c1 = cs[1] else : nd = len(cs) c0 = cs[-2] c1 = cs[-1] for i in range(3, len(cs) + 1) : tmp = c0 nd = nd - 1 c0 = cs[-i] - (c1*(nd - 1))/nd c1 = tmp + (c1*x*(2*nd - 1))/nd return c0 + c1*x
def legval(x, cs): """Evaluate a Legendre series. If `cs` is of length `n`, this function returns : ``p(x) = cs[0]*P_0(x) + cs[1]*P_1(x) + ... + cs[n-1]*P_{n-1}(x)`` If x is a sequence or array then p(x) will have the same shape as x. If r is a ring_like object that supports multiplication and addition by the values in `cs`, then an object of the same type is returned. Parameters ---------- x : array_like, ring_like Array of numbers or objects that support multiplication and addition with themselves and with the elements of `cs`. cs : array_like 1-d array of Legendre coefficients ordered from low to high. Returns ------- values : ndarray, ring_like If the return is an ndarray then it has the same shape as `x`. See Also -------- legfit Examples -------- Notes ----- The evaluation uses Clenshaw recursion, aka synthetic division. Examples -------- """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if isinstance(x, tuple) or isinstance(x, list): x = np.asarray(x) if len(cs) == 1: c0 = cs[0] c1 = 0 elif len(cs) == 2: c0 = cs[0] c1 = cs[1] else: nd = len(cs) c0 = cs[-2] c1 = cs[-1] for i in range(3, len(cs) + 1): tmp = c0 nd = nd - 1 c0 = cs[-i] - (c1 * (nd - 1)) / nd c1 = tmp + (c1 * x * (2 * nd - 1)) / nd return c0 + c1 * x
def polymulx(cs): """Multiply a polynomial by x. Multiply the polynomial `cs` by x, where x is the independent variable. Parameters ---------- cs : array_like 1-d array of polynomial coefficients ordered from low to high. Returns ------- out : ndarray Array representing the result of the multiplication. Notes ----- .. versionadded:: 1.5.0 """ # cs is a trimmed copy [cs] = pu.as_series([cs]) # The zero series needs special treatment if len(cs) == 1 and cs[0] == 0: return cs prd = np.empty(len(cs) + 1, dtype=cs.dtype) prd[0] = cs[0]*0 prd[1:] = cs return prd
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. 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 poly2cheb(pol) : """Convert a polynomial to a Chebyshev series. Convert a series containing polynomial coefficients ordered by degree from low to high to an equivalent Chebyshev series ordered from low to high. Inputs ------ pol : array_like 1-d array containing the polynomial coeffients Returns ------- cseries : ndarray 1-d array containing the coefficients of the equivalent Chebyshev series. See Also -------- cheb2poly """ [pol] = pu.as_series([pol]) pol = pol[::-1] zs = pol[:1].copy() x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(1, len(pol)) : zs = _zseries_mul(zs, x) zs[i] += pol[i] return _zseries_to_cseries(zs)
def chebfromroots(roots): """Generate a Chebyschev series with given roots. Generate a Chebyshev series whose roots are given by `roots`. The resulting series is the produet `(x - roots[0])*(x - roots[1])*...` Inputs ------ roots : array_like 1-d array containing the roots in sorted order. Returns ------- series : ndarray 1-d array containing the coefficients of the Chebeshev series ordered from low to high. See Also -------- chebroots """ if len(roots) == 0: return np.ones(1) else: [roots] = pu.as_series([roots], trim=False) prd = np.array([1], dtype=roots.dtype) for r in roots: fac = np.array([.5, -r, .5], dtype=roots.dtype) prd = _zseries_mul(fac, prd) return _zseries_to_cseries(prd)
def leg2poly(cs) : """ Convert a Legendre series to a polynomial. Convert an array representing the coefficients of a Legendre series, ordered from lowest degree to highest, to an array of the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest to highest degree. Parameters ---------- cs : array_like 1-d array containing the Legendre series coefficients, ordered from lowest order term to highest. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest order term to highest. See Also -------- poly2leg Notes ----- The easy way to do conversions between polynomial basis sets is to use the convert method of a class instance. Examples -------- >>> c = P.Legendre(range(4)) >>> c Legendre([ 0., 1., 2., 3.], [-1., 1.]) >>> p = c.convert(kind=P.Polynomial) >>> p Polynomial([-1. , -3.5, 3. , 7.5], [-1., 1.]) >>> P.leg2poly(range(4)) array([-1. , -3.5, 3. , 7.5]) """ from polynomial import polyadd, polysub, polymulx [cs] = pu.as_series([cs]) n = len(cs) if n < 3: return cs else: c0 = cs[-2] c1 = cs[-1] # i is the current degree of c1 for i in range(n - 1, 1, -1) : tmp = c0 c0 = polysub(cs[i - 2], (c1*(i - 1))/i) c1 = polyadd(tmp, (polymulx(c1)*(2*i - 1))/i) return polyadd(c0, polymulx(c1))
def polyfromroots(roots): """ Generate a polynomial with the given roots. Return the array of coefficients for the polynomial whose leading coefficient (i.e., that of the highest order term) is `1` and whose roots (a.k.a. "zeros") are given by *roots*. The returned array of coefficients is ordered from lowest order term to highest, and zeros of multiplicity greater than one must be included in *roots* a number of times equal to their multiplicity (e.g., if `2` is a root of multiplicity three, then [2,2,2] must be in *roots*). Parameters ---------- roots : array_like Sequence containing the roots. Returns ------- out : ndarray 1-d array of the polynomial's coefficients, ordered from low to high. If all roots are real, ``out.dtype`` is a float type; otherwise, ``out.dtype`` is a complex type, even if all the coefficients in the result are real (see Examples below). See Also -------- chebfromroots Notes ----- What is returned are the :math:`a_i` such that: .. math:: \\sum_{i=0}^{n} a_ix^i = \\prod_{i=0}^{n} (x - roots[i]) where ``n == len(roots)``; note that this implies that `1` is always returned for :math:`a_n`. Examples -------- >>> import numpy.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]) """ if len(roots) == 0: return np.ones(1) else: [roots] = pu.as_series([roots], trim=False) prd = np.zeros(len(roots) + 1, dtype=roots.dtype) prd[-1] = 1 for i in range(len(roots)): prd[-(i + 2):-1] -= roots[i] * prd[-(i + 1):] return prd
def polyfromroots(roots) : """ Generate a polynomial with the given roots. Return the array of coefficients for the polynomial whose leading coefficient (i.e., that of the highest order term) is `1` and whose roots (a.k.a. "zeros") are given by *roots*. The returned array of coefficients is ordered from lowest order term to highest, and zeros of multiplicity greater than one must be included in *roots* a number of times equal to their multiplicity (e.g., if `2` is a root of multiplicity three, then [2,2,2] must be in *roots*). Parameters ---------- roots : array_like Sequence containing the roots. Returns ------- out : ndarray 1-d array of the polynomial's coefficients, ordered from low to high. If all roots are real, ``out.dtype`` is a float type; otherwise, ``out.dtype`` is a complex type, even if all the coefficients in the result are real (see Examples below). See Also -------- chebfromroots Notes ----- What is returned are the :math:`a_i` such that: .. math:: \\sum_{i=0}^{n} a_ix^i = \\prod_{i=0}^{n} (x - roots[i]) where ``n == len(roots)``; note that this implies that `1` is always returned for :math:`a_n`. Examples -------- >>> import numpy.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]) """ if len(roots) == 0 : return np.ones(1) else : [roots] = pu.as_series([roots], trim=False) prd = np.zeros(len(roots) + 1, dtype=roots.dtype) prd[-1] = 1 for i in range(len(roots)) : prd[-(i+2):-1] -= roots[i]*prd[-(i+1):] return prd
def legroots(cs): """ Compute the roots of a Legendre series. Returns the roots (a.k.a "zeros") of the Legendre series represented by `cs`, which is the sequence of coefficients from lowest order "term" to highest, e.g., [1,2,3] is the series ``L_0 + 2*L_1 + 3*L_2``. Parameters ---------- cs : array_like 1-d array of Legendre series coefficients ordered from low to high. maxiter : int, optional Maximum number of iterations of Newton to use in refining the roots. Returns ------- out : ndarray Sorted array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots chebroots Notes ----- The root estimates are obtained as the eigenvalues of the companion matrix, Roots far from the real interval [-1, 1] in the complex plane may have large errors due to the numerical instability of the Lengendre 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 interval [-1, 1] can be improved by a few iterations of Newton's method. The Legendre series basis polynomials aren't powers of ``x`` so the results of this function may seem unintuitive. Examples -------- >>> import numpy.polynomial.legendre as leg >>> leg.legroots((1, 2, 3, 4)) # 4L_3 + 3L_2 + 2L_1 + 1L_0 has only real roots array([-0.85099543, -0.11407192, 0.51506735]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0]/cs[1]]) m = legcompanion(cs) r = la.eigvals(m) r.sort() return r
def legroots(cs): """ Compute the roots of a Legendre series. Returns the roots (a.k.a "zeros") of the Legendre series represented by `cs`, which is the sequence of coefficients from lowest order "term" to highest, e.g., [1,2,3] is the series ``L_0 + 2*L_1 + 3*L_2``. Parameters ---------- cs : array_like 1-d array of Legendre series coefficients ordered from low to high. maxiter : int, optional Maximum number of iterations of Newton to use in refining the roots. Returns ------- out : ndarray Sorted array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots chebroots Notes ----- The root estimates are obtained as the eigenvalues of the companion matrix, Roots far from the real interval [-1, 1] in the complex plane may have large errors due to the numerical instability of the Lengendre 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 interval [-1, 1] can be improved by a few iterations of Newton's method. The Legendre series basis polynomials aren't powers of ``x`` so the results of this function may seem unintuitive. Examples -------- >>> import numpy.polynomial.legendre as leg >>> leg.legroots((1, 2, 3, 4)) # 4L_3 + 3L_2 + 2L_1 + 1L_0 has only real roots array([-0.85099543, -0.11407192, 0.51506735]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0] / cs[1]]) m = legcompanion(cs) r = la.eigvals(m) r.sort() return r
def cheb2poly(cs) : """ Convert a Chebyshev series to a polynomial. Convert an array representing the coefficients of a Chebyshev series, ordered from lowest degree to highest, to an array of the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest to highest degree. Parameters ---------- cs : array_like 1-d array containing the Chebyshev series coefficients, ordered from lowest order term to highest. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest order term to highest. See Also -------- poly2cheb Notes ----- The easy way to do conversions between polynomial basis sets is to use the convert method of a class instance. Examples -------- >>> from numpy import polynomial as P >>> c = P.Chebyshev(range(4)) >>> c Chebyshev([ 0., 1., 2., 3.], [-1., 1.]) >>> p = c.convert(kind=P.Polynomial) >>> p Polynomial([ -2., -8., 4., 12.], [-1., 1.]) >>> P.cheb2poly(range(4)) array([ -2., -8., 4., 12.]) """ from polynomial import polyadd, polysub, polymulx [cs] = pu.as_series([cs]) n = len(cs) if n < 3: return cs else: c0 = cs[-2] c1 = cs[-1] for i in range(n - 3, -1, -1) : tmp = c0 c0 = polysub(cs[i], c1) c1 = polyadd(tmp, polymulx(c1)*2) return polyadd(c0, polymulx(c1))
def cheb2poly(cs): """ Convert a Chebyshev series to a polynomial. Convert an array representing the coefficients of a Chebyshev series, ordered from lowest degree to highest, to an array of the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest to highest degree. Parameters ---------- cs : array_like 1-d array containing the Chebyshev series coefficients, ordered from lowest order term to highest. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest order term to highest. See Also -------- poly2cheb Notes ----- The easy way to do conversions between polynomial basis sets is to use the convert method of a class instance. Examples -------- >>> from numpy import polynomial as P >>> c = P.Chebyshev(range(4)) >>> c Chebyshev([ 0., 1., 2., 3.], [-1., 1.]) >>> p = c.convert(kind=P.Polynomial) >>> p Polynomial([ -2., -8., 4., 12.], [-1., 1.]) >>> P.cheb2poly(range(4)) array([ -2., -8., 4., 12.]) """ from polynomial import polyadd, polysub, polymulx [cs] = pu.as_series([cs]) n = len(cs) if n < 3: return cs else: c0 = cs[-2] c1 = cs[-1] for i in range(n - 3, -1, -1): tmp = c0 c0 = polysub(cs[i], c1) c1 = polyadd(tmp, polymulx(c1) * 2) return polyadd(c0, polymulx(c1))
def polyroots(cs): """ Compute the roots of a polynomial. Return the roots (a.k.a. "zeros") of the "polynomial" `cs`, the polynomial's coefficients from lowest order term to highest (e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``). Parameters ---------- cs : array_like of shape (M,) 1-d array of polynomial coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots of the polynomial. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- chebroots 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]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0]/cs[1]]) m = polycompanion(cs) r = la.eigvals(m) r.sort() return r
def chebroots(cs): """ Compute the roots of a Chebyshev series. Return the roots (a.k.a "zeros") of the C-series represented by `cs`, which is the sequence of the C-series' coefficients from lowest order "term" to highest, e.g., [1,2,3] represents the C-series ``T_0 + 2*T_1 + 3*T_2``. Parameters ---------- cs : array_like 1-d array of C-series coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots Notes ----- Algorithm(s) used: Remember: because the C-series basis set is different from the "standard" basis set, the results of this function *may* not be what one is expecting. Examples -------- >>> import numpy.polynomial as P >>> import numpy.polynomial.chebyshev as C >>> P.polyroots((-1,1,-1,1)) # x^3 - x^2 + x - 1 has two complex roots array([ -4.99600361e-16-1.j, -4.99600361e-16+1.j, 1.00000e+00+0.j]) >>> C.chebroots((-1,1,-1,1)) # T3 - T2 + T1 - T0 has only real roots array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0] / cs[1]]) n = len(cs) - 1 cmat = np.zeros((n, n), dtype=cs.dtype) cmat.flat[1::n + 1] = .5 cmat.flat[n::n + 1] = .5 cmat[1, 0] = 1 cmat[:, -1] -= cs[:-1] * (.5 / cs[-1]) roots = la.eigvals(cmat) roots.sort() return roots
def polyroots(cs): """ Compute the roots of a polynomial. Return the roots (a.k.a. "zeros") of the "polynomial" `cs`, the polynomial's coefficients from lowest order term to highest (e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``). Parameters ---------- cs : array_like of shape (M,) 1-d array of polynomial coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots of the polynomial. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- chebroots 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]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0] / cs[1]]) m = polycompanion(cs) r = la.eigvals(m) r.sort() return r
def chebroots(cs): """ Compute the roots of a Chebyshev series. Return the roots (a.k.a "zeros") of the C-series represented by `cs`, which is the sequence of the C-series' coefficients from lowest order "term" to highest, e.g., [1,2,3] represents the C-series ``T_0 + 2*T_1 + 3*T_2``. Parameters ---------- cs : array_like 1-d array of C-series coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots Notes ----- Algorithm(s) used: Remember: because the C-series basis set is different from the "standard" basis set, the results of this function *may* not be what one is expecting. Examples -------- >>> import numpy.polynomial as P >>> import numpy.polynomial.chebyshev as C >>> P.polyroots((-1,1,-1,1)) # x^3 - x^2 + x - 1 has two complex roots array([ -4.99600361e-16-1.j, -4.99600361e-16+1.j, 1.00000e+00+0.j]) >>> C.chebroots((-1,1,-1,1)) # T3 - T2 + T1 - T0 has only real roots array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1 : return np.array([], dtype=cs.dtype) if len(cs) == 2 : return np.array([-cs[0]/cs[1]]) n = len(cs) - 1 cmat = np.zeros((n,n), dtype=cs.dtype) cmat.flat[1::n+1] = .5 cmat.flat[n::n+1] = .5 cmat[1, 0] = 1 cmat[:,-1] -= cs[:-1]*(.5/cs[-1]) roots = la.eigvals(cmat) roots.sort() return roots
def herm2poly(cs) : """ Convert a Hermite series to a polynomial. Convert an array representing the coefficients of a Hermite series, ordered from lowest degree to highest, to an array of the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest to highest degree. Parameters ---------- cs : array_like 1-d array containing the Hermite series coefficients, ordered from lowest order term to highest. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest order term to highest. See Also -------- poly2herm Notes ----- The easy way to do conversions between polynomial basis sets is to use the convert method of a class instance. Examples -------- >>> from numpy.polynomial.hermite import herm2poly >>> herm2poly([ 1. , 2.75 , 0.5 , 0.375]) array([ 0., 1., 2., 3.]) """ from polynomial import polyadd, polysub, polymulx [cs] = pu.as_series([cs]) n = len(cs) if n == 1: return cs if n == 2: cs[1] *= 2 return cs else: c0 = cs[-2] c1 = cs[-1] # i is the current degree of c1 for i in range(n - 1, 1, -1) : tmp = c0 c0 = polysub(cs[i - 2], c1*(2*(i - 1))) c1 = polyadd(tmp, polymulx(c1)*2) return polyadd(c0, polymulx(c1)*2)
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 -------- chebroots 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]) """ # 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]]) m = polycompanion(c) r = la.eigvals(m) r.sort() return r
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 -------- chebroots 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]) """ # 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]]) m = polycompanion(c) r = la.eigvals(m) r.sort() return r
def cheb2poly(cs) : """ cheb2poly(cs) Convert a Chebyshev series to a polynomial. Convert an array representing the coefficients of a Chebyshev series, ordered from lowest degree to highest, to an array of the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest to highest degree. Parameters ---------- cs : array_like 1-d array containing the Chebyshev series coefficients, ordered from lowest order term to highest. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest order term to highest. See Also -------- poly2cheb Notes ----- Note that a consequence of the input needing to be array_like and that the output is an ndarray, is that if one is going to use this function to convert a Chebyshev instance, T, to a Polynomial instance, P, the usage is ``P = Polynomial(cheb2poly(T.coef))``; see Examples below. Examples -------- >>> from numpy import polynomial as P >>> c = P.Chebyshev(np.arange(4)) >>> c Chebyshev([ 0., 1., 2., 3.], [-1., 1.]) >>> p = P.Polynomial(P.cheb2poly(c.coef)) >>> p Polynomial([ -2., -8., 4., 12.], [-1., 1.]) """ [cs] = pu.as_series([cs]) pol = np.zeros(len(cs), dtype=cs.dtype) quo = _cseries_to_zseries(cs) x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(0, len(cs) - 1) : quo, rem = _zseries_div(quo, x) pol[i] = rem[0] pol[-1] = quo[0] return pol
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, polymul, polypow Examples -------- >>> import numpy.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])) """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if c2[-1] == 0 : raise ZeroDivisionError() len1 = len(c1) len2 = len(c2) if len2 == 1 : return c1/c2[-1], c1[:1]*0 elif len1 < len2 : return c1[:1]*0, c1 else : dlen = len1 - len2 scl = c2[-1] c2 = c2[:-1]/scl i = dlen j = len1 - 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 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, polymul, polypow Examples -------- >>> import numpy.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])) """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if c2[-1] == 0: raise ZeroDivisionError() len1 = len(c1) len2 = len(c2) if len2 == 1: return c1 / c2[-1], c1[:1] * 0 elif len1 < len2: return c1[:1] * 0, c1 else: dlen = len1 - len2 scl = c2[-1] c2 = c2[:-1] / scl i = dlen j = len1 - 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 cheb2poly(cs): """ cheb2poly(cs) Convert a Chebyshev series to a polynomial. Convert an array representing the coefficients of a Chebyshev series, ordered from lowest degree to highest, to an array of the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest to highest degree. Parameters ---------- cs : array_like 1-d array containing the Chebyshev series coefficients, ordered from lowest order term to highest. Returns ------- pol : ndarray 1-d array containing the coefficients of the equivalent polynomial (relative to the "standard" basis) ordered from lowest order term to highest. See Also -------- poly2cheb Notes ----- Note that a consequence of the input needing to be array_like and that the output is an ndarray, is that if one is going to use this function to convert a Chebyshev instance, T, to a Polynomial instance, P, the usage is ``P = Polynomial(cheb2poly(T.coef))``; see Examples below. Examples -------- >>> from numpy import polynomial as P >>> c = P.Chebyshev(np.arange(4)) >>> c Chebyshev([ 0., 1., 2., 3.], [-1., 1.]) >>> p = P.Polynomial(P.cheb2poly(c.coef)) >>> p Polynomial([ -2., -8., 4., 12.], [-1., 1.]) """ [cs] = pu.as_series([cs]) pol = np.zeros(len(cs), dtype=cs.dtype) quo = _cseries_to_zseries(cs) x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(0, len(cs) - 1): quo, rem = _zseries_div(quo, x) pol[i] = rem[0] pol[-1] = quo[0] return pol
def lagroots(cs): """ Compute the roots of a Laguerre series. Return the roots (a.k.a "zeros") of the Laguerre series represented by `cs`, which is the sequence of coefficients from lowest order "term" to highest, e.g., [1,2,3] is the series ``L_0 + 2*L_1 + 3*L_2``. Parameters ---------- cs : array_like 1-d array of Laguerre series coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots chebroots Notes ----- Algorithm(s) used: Remember: because the Laguerre series basis set is different from the "standard" basis set, the results of this function *may* not be what one is expecting. Examples -------- >>> from numpy.polynomial.laguerre import lagroots, lagfromroots >>> coef = lagfromroots([0, 1, 2]) >>> coef array([ 2., -8., 12., -6.]) >>> lagroots(coef) array([ -4.44089210e-16, 1.00000000e+00, 2.00000000e+00]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1 : return np.array([], dtype=cs.dtype) if len(cs) == 2 : return np.array([1 + cs[0]/cs[1]]) m = lagcompanion(cs) r = la.eigvals(m) r.sort() return r
def hermroots(cs): """ Compute the roots of a Hermite series. Return the roots (a.k.a "zeros") of the Hermite series represented by `cs`, which is the sequence of coefficients from lowest order "term" to highest, e.g., [1,2,3] is the series ``L_0 + 2*L_1 + 3*L_2``. Parameters ---------- cs : array_like 1-d array of Hermite series coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots chebroots Notes ----- Algorithm(s) used: Remember: because the Hermite series basis set is different from the "standard" basis set, the results of this function *may* not be what one is expecting. Examples -------- >>> from numpy.polynomial.hermite import hermroots, hermfromroots >>> coef = hermfromroots([-1, 0, 1]) >>> coef array([ 0. , 0.25 , 0. , 0.125]) >>> hermroots(coef) array([ -1.00000000e+00, -1.38777878e-17, 1.00000000e+00]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-.5 * cs[0] / cs[1]]) m = hermcompanion(cs) r = la.eigvals(m) r.sort() return r
def poly2cheb(pol): """ poly2cheb(pol) Convert a polynomial to a Chebyshev series. Convert an array representing the coefficients of a polynomial (relative to the "standard" basis) ordered from lowest degree to highest, to an array of the coefficients of the equivalent Chebyshev series, ordered from lowest to highest degree. Parameters ---------- pol : array_like 1-d array containing the polynomial coefficients Returns ------- cs : ndarray 1-d array containing the coefficients of the equivalent Chebyshev series. See Also -------- cheb2poly Notes ----- Note that a consequence of the input needing to be array_like and that the output is an ndarray, is that if one is going to use this function to convert a Polynomial instance, P, to a Chebyshev instance, T, the usage is ``T = Chebyshev(poly2cheb(P.coef))``; see Examples below. Examples -------- >>> from numpy import polynomial as P >>> p = P.Polynomial(np.arange(4)) >>> p Polynomial([ 0., 1., 2., 3.], [-1., 1.]) >>> c = P.Chebyshev(P.poly2cheb(p.coef)) >>> c Chebyshev([ 1. , 3.25, 1. , 0.75], [-1., 1.]) """ [pol] = pu.as_series([pol]) pol = pol[::-1] zs = pol[:1].copy() x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(1, len(pol)): zs = _zseries_mul(zs, x) zs[i] += pol[i] return _zseries_to_cseries(zs)
def poly2cheb(pol) : """ poly2cheb(pol) Convert a polynomial to a Chebyshev series. Convert an array representing the coefficients of a polynomial (relative to the "standard" basis) ordered from lowest degree to highest, to an array of the coefficients of the equivalent Chebyshev series, ordered from lowest to highest degree. Parameters ---------- pol : array_like 1-d array containing the polynomial coefficients Returns ------- cs : ndarray 1-d array containing the coefficients of the equivalent Chebyshev series. See Also -------- cheb2poly Notes ----- Note that a consequence of the input needing to be array_like and that the output is an ndarray, is that if one is going to use this function to convert a Polynomial instance, P, to a Chebyshev instance, T, the usage is ``T = Chebyshev(poly2cheb(P.coef))``; see Examples below. Examples -------- >>> from numpy import polynomial as P >>> p = P.Polynomial(np.arange(4)) >>> p Polynomial([ 0., 1., 2., 3.], [-1., 1.]) >>> c = P.Chebyshev(P.poly2cheb(p.coef)) >>> c Chebyshev([ 1. , 3.25, 1. , 0.75], [-1., 1.]) """ [pol] = pu.as_series([pol]) pol = pol[::-1] zs = pol[:1].copy() x = np.array([.5, 0, .5], dtype=pol.dtype) for i in range(1, len(pol)) : zs = _zseries_mul(zs, x) zs[i] += pol[i] return _zseries_to_cseries(zs)
def hermpow(cs, pow, maxpower=16) : """Raise a Hermite series to a power. Returns the Hermite series `cs` raised to the power `pow`. The arguement `cs` is a sequence of coefficients ordered from low to high. i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.`` Parameters ---------- cs : array_like 1d array of Hermite series coefficients ordered from low to high. 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 umanageable size. Default is 16 Returns ------- coef : ndarray Hermite series of power. See Also -------- hermadd, hermsub, hermmul, hermdiv Examples -------- >>> from numpy.polynomial.hermite import hermpow >>> hermpow([1, 2, 3], 2) array([ 81., 52., 82., 12., 9.]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) power = int(pow) if power != pow or power < 0 : raise ValueError("Power must be a non-negative integer.") elif maxpower is not None and power > maxpower : raise ValueError("Power is too large") elif power == 0 : return np.array([1], dtype=cs.dtype) elif power == 1 : return cs else : # This can be made more efficient by using powers of two # in the usual way. prd = cs for i in range(2, power + 1) : prd = hermmul(prd, cs) return prd
def chebsub(c1, c2): """ Subtract one Chebyshev series from another. Returns the difference of two Chebyshev series `c1` - `c2`. The sequences of coefficients are from lowest order term to highest, i.e., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. Parameters ---------- c1, c2 : array_like 1-d arrays of Chebyshev series coefficients ordered from low to high. Returns ------- out : ndarray Of Chebyshev series coefficients representing their difference. See Also -------- chebadd, chebmul, chebdiv, chebpow Notes ----- Unlike multiplication, division, etc., the difference of two Chebyshev series is a Chebyshev series (without having to "reproject" the result onto the basis set) so subtraction, just like that of "standard" polynomials, is simply "component-wise." Examples -------- >>> from numpy.polynomial import chebyshev as C >>> c1 = (1,2,3) >>> c2 = (3,2,1) >>> C.chebsub(c1,c2) array([-2., 0., 2.]) >>> C.chebsub(c2,c1) # -C.chebsub(c1,c2) array([ 2., 0., -2.]) """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if len(c1) > len(c2): c1[:c2.size] -= c2 ret = c1 else: c2 = -c2 c2[:c1.size] += c1 ret = c2 return pu.trimseq(ret)
def legsub(c1, c2): """ Subtract one Legendre series from another. Returns the difference of two Legendre series `c1` - `c2`. The sequences of coefficients are from lowest order term to highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. Parameters ---------- c1, c2 : array_like 1-d arrays of Legendre series coefficients ordered from low to high. Returns ------- out : ndarray Of Legendre series coefficients representing their difference. See Also -------- legadd, legmul, legdiv, legpow Notes ----- Unlike multiplication, division, etc., the difference of two Legendre series is a Legendre series (without having to "reproject" the result onto the basis set) so subtraction, just like that of "standard" polynomials, is simply "component-wise." Examples -------- >>> from numpy.polynomial import legendre as L >>> c1 = (1,2,3) >>> c2 = (3,2,1) >>> L.legsub(c1,c2) array([-2., 0., 2.]) >>> L.legsub(c2,c1) # -C.legsub(c1,c2) array([ 2., 0., -2.]) """ # c1, c2 are trimmed copies [c1, c2] = pu.as_series([c1, c2]) if len(c1) > len(c2) : c1[:c2.size] -= c2 ret = c1 else : c2 = -c2 c2[:c1.size] += c1 ret = c2 return pu.trimseq(ret)
def chebpow(cs, pow, maxpower=16): """Raise a Chebyshev series to a power. Returns the Chebyshev series `cs` raised to the power `pow`. The arguement `cs` is a sequence of coefficients ordered from low to high. i.e., [1,2,3] is the series ``T_0 + 2*T_1 + 3*T_2.`` Parameters ---------- cs : array_like 1d array of chebyshev series coefficients ordered from low to high. 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 umanageable size. Default is 16 Returns ------- coef : ndarray Chebyshev series of power. See Also -------- chebadd, chebsub, chebmul, chebdiv Examples -------- """ # cs is a trimmed copy [cs] = pu.as_series([cs]) power = int(pow) if power != pow or power < 0: raise ValueError("Power must be a non-negative integer.") elif maxpower is not None and power > maxpower: raise ValueError("Power is too large") elif power == 0: return np.array([1], dtype=cs.dtype) elif power == 1: return cs else: # This can be made more efficient by using powers of two # in the usual way. zs = _cseries_to_zseries(cs) prd = zs for i in range(2, power + 1): prd = np.convolve(prd, zs) return _zseries_to_cseries(prd)
def polyroots(cs): """ Compute the roots of a polynomial. Return the roots (a.k.a. "zeros") of the "polynomial" `cs`, the polynomial's coefficients from lowest order term to highest (e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``). Parameters ---------- cs : array_like of shape (M,) 1-d array of polynomial coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots of the polynomial. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- chebroots Examples -------- >>> import numpy.polynomial as P >>> P.polyroots(P.polyfromroots((-1,0,1))) array([-1., 0., 1.]) >>> P.polyroots(P.polyfromroots((-1,0,1))).dtype dtype('float64') >>> j = complex(0,1) >>> P.polyroots(P.polyfromroots((-j,0,j))) array([ 0.00000000e+00+0.j, 0.00000000e+00+1.j, 2.77555756e-17-1.j]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) <= 1 : return np.array([], dtype=cs.dtype) if len(cs) == 2 : return np.array([-cs[0]/cs[1]]) n = len(cs) - 1 cmat = np.zeros((n,n), dtype=cs.dtype) cmat.flat[n::n+1] = 1 cmat[:,-1] -= cs[:-1]/cs[-1] roots = la.eigvals(cmat) roots.sort() return roots
def chebroots(cs): """ Compute the roots of a Chebyshev series. Return the roots (a.k.a "zeros") of the C-series represented by `cs`, which is the sequence of the C-series' coefficients from lowest order "term" to highest, e.g., [1,2,3] represents the C-series ``T_0 + 2*T_1 + 3*T_2``. Parameters ---------- cs : array_like 1-d array of C-series coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots Notes ----- Algorithm(s) used: Remember: because the C-series basis set is different from the "standard" basis set, the results of this function *may* not be what one is expecting. Examples -------- >>> import numpy.polynomial.chebyshev as cheb >>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0]/cs[1]]) m = chebcompanion(cs) r = la.eigvals(m) r.sort() return r
def chebroots(cs): """ Compute the roots of a Chebyshev series. Return the roots (a.k.a "zeros") of the C-series represented by `cs`, which is the sequence of the C-series' coefficients from lowest order "term" to highest, e.g., [1,2,3] represents the C-series ``T_0 + 2*T_1 + 3*T_2``. Parameters ---------- cs : array_like 1-d array of C-series coefficients ordered from low to high. Returns ------- out : ndarray Array of the roots. If all the roots are real, then so is the dtype of ``out``; otherwise, ``out``'s dtype is complex. See Also -------- polyroots Notes ----- Algorithm(s) used: Remember: because the C-series basis set is different from the "standard" basis set, the results of this function *may* not be what one is expecting. Examples -------- >>> import numpy.polynomial.chebyshev as cheb >>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) """ # cs is a trimmed copy [cs] = pu.as_series([cs]) if len(cs) < 2: return np.array([], dtype=cs.dtype) if len(cs) == 2: return np.array([-cs[0] / cs[1]]) m = chebcompanion(cs) r = la.eigvals(m) r.sort() return r
def chebpow(cs, pow, maxpower=16) : """Raise a Chebyshev series to a power. Returns the Chebyshev series `cs` raised to the power `pow`. The arguement `cs` is a sequence of coefficients ordered from low to high. i.e., [1,2,3] is the series ``T_0 + 2*T_1 + 3*T_2.`` Parameters ---------- cs : array_like 1d array of chebyshev series coefficients ordered from low to high. 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 umanageable size. Default is 16 Returns ------- coef : ndarray Chebyshev series of power. See Also -------- chebadd, chebsub, chebmul, chebdiv Examples -------- """ # cs is a trimmed copy [cs] = pu.as_series([cs]) power = int(pow) if power != pow or power < 0 : raise ValueError("Power must be a non-negative integer.") elif maxpower is not None and power > maxpower : raise ValueError("Power is too large") elif power == 0 : return np.array([1], dtype=cs.dtype) elif power == 1 : return cs else : # This can be made more efficient by using powers of two # in the usual way. zs = _cseries_to_zseries(cs) prd = zs for i in range(2, power + 1) : prd = np.convolve(prd, zs) return _zseries_to_cseries(prd)