#------------------------------------------------------------------------------- # Name: polynomial # Purpose: Functions to operate on polynomials. # # Author: pab # polyXXX functions are based on functions found in the matlab toolbox polyutil written by # Author: Peter J. Acklam # E-mail: pjacklam@online.no # WWW URL: http://home.online.no/~pjacklam # # Created: 30.12.2008 # Copyright: (c) pab 2008 # Licence: LGPL #------------------------------------------------------------------------------- #!/usr/bin/env python """ Extended functions to operate on polynomials """ import warnings import numpy as np from numpy.lib.polynomial import * __all__ = np.lib.polynomial.__all__ __all__ = __all__ + ['polyreloc', 'polyrescl', 'polytrim', 'poly2hstr', 'poly2str', 'polyshift', 'polyishift', 'map_from_intervall', 'map_to_intervall', 'cheb2poly', 'chebextr', 'chebroot', 'chebpoly', 'chebfit', 'chebval', 'chebder', 'chebint', 'Cheb1d', 'dct', 'idct'] def polyreloc(p,x,y=0.0): """ Relocate polynomial The polynomial `p` is relocated by "moving" it `x` units along the x-axis and `y` units along the y-axis. So the polynomial `r` is relative to the point (x,y) as the polynomial `p` is relative to the point (0,0). Parameters ---------- p : array-like, poly1d vector or matrix of column vectors of polynomial coefficients to relocate. (Polynomial coefficients are in decreasing order.) x : scalar distance to relocate P along x-axis y : scalar distance to relocate P along y-axis (default 0) Returns ------- r : ndarray, poly1d vector/matrix/poly1d of relocated polynomial coefficients. See also -------- polyrescl Example ------- >>> import numpy as np >>> p = np.arange(6); p.shape = (2,-1) >>> np.polyval(p,0) array([3, 4, 5]) >>> np.polyval(p,1) array([3, 5, 7]) >>> r = polyreloc(p,-1) # move to the left along x-axis >>> np.polyval(r,-1) # = polyval(p,0) array([3, 4, 5]) >>> np.polyval(r,0) # = polyval(p,1) array([3, 5, 7]) """ truepoly = isinstance(p, poly1d) r = np.atleast_1d(p).copy() n = r.shape[0] # Relocate polynomial using Horner's algorithm for ii in range(n,1,-1): for i in range(1,ii): r[i] = r[i] - x*r[i-1] r[-1] = r[-1] + y if r.ndim>1 and r.shape[-1]==1: r.shape = (r.size,) if truepoly: r = poly1d(r) return r def polyrescl(p, x, y=1.0): """ Rescale polynomial. Parameters ---------- p : array-like, poly1d vector or matrix of column vectors of polynomial coefficients to rescale. (Polynomial coefficients are in decreasing order.) x,y : scalars defining the factors to rescale the polynomial `p` in x-direction and y-direction, respectively. Returns ------- r : ndarray, poly1d vector/matrix/poly1d of rescaled polynomial coefficients. See also -------- polyreloc Example ------- >>> import numpy as np >>> p = np.arange(6); p.shape = (2,-1) >>> np.polyval(p,0) array([3, 4, 5]) >>> np.polyval(p,1) array([3, 5, 7]) >>> r = polyrescl(p,2) # scale by 2 along x-axis >>> np.polyval(r,0) # = polyval(p,0) array([ 3., 4., 5.]) >>> np.polyval(r,2) # = polyval(p,1) array([ 3., 5., 7.]) """ truepoly = isinstance(p, poly1d) r = np.atleast_1d(p).copy() n = r.shape[0] xscale =(float(x)**np.arange(1-n , 1)) if r.ndim==1: q = y*r*xscale else: q = y*r*xscale[:,np.newaxis] if truepoly: q = poly1d(q) return q def polytrim(p): """ Trim polynomial by stripping off leading zeros. Parameters ---------- p : array-like, poly1d vector of polynomial coefficients in decreasing order. Returns ------- r : ndarray, poly1d vector/matrix/poly1d of trimmed polynomial coefficients. Example ------- >>> p = [0,1,2] >>> polytrim(p) array([1, 2]) """ truepoly = isinstance(p, poly1d) if truepoly: return p else: r = np.atleast_1d(p).copy() # Remove leading zeros is_not_lead_zeros =np.logical_or.accumulate(r != 0,axis=0) if r.ndim==1: r = r[is_not_lead_zeros] else: is_not_lead_zeros = np.any(is_not_lead_zeros,axis=1) r = r[is_not_lead_zeros,:] return r def poly2hstr(p, variable='x' ): """ Return polynomial as a Horner represented string. Parameters ---------- p : array-like poly1d vector of polynomial coefficients in decreasing order. variable : string display character for variable Returns ------- p_str : string consisting of the polynomial coefficients in the vector P multiplied by powers of the given `variable`. Examples -------- >>> poly2hstr([1, 1, 2], 's' ) '(s + 1)*s + 2' See also -------- poly2str """ var = variable coefs = polytrim(np.atleast_1d(p)) order = len(coefs)-1 # Order of polynomial. s = '' # Initialize output string. ix = 1; for expon in range(order,-1,-1): coef = coefs[order-expon] #% There is no point in adding a zero term (except if it's the only #% term, but we'll take care of that later). if coef == 0: ix = ix+1 else: #% Append exponent if necessary. if ix>1: exponstr = '%.0f' % ix s = '%s**%s' % (s,exponstr); ix = 1 #% Is it the first term? isfirst = s == '' # We need the coefficient only if it is different from 1 or -1 or # when it is the constant term. needcoef = (( abs(coef) != 1 ) | ( expon == 0 ) & isfirst) | 1-isfirst # We need the variable except in the constant term. needvar = ( expon != 0 ) #% Add sign, but we don't need a leading plus-sign. if isfirst: if coef < 0: s = '-' # % Unary minus. else: if coef < 0: s = '%s - ' % s # % Binary minus (subtraction). else: s = '%s + ' % s # % Binary plus (addition). #% Append the coefficient if it is different from one or when it is #% the constant term. if needcoef: coefstr = '%.20g' % abs(coef) s = '%s%s' % (s,coefstr) #% Append variable if necessary. if needvar: #% Append a multiplication sign if necessary. if needcoef: if 1-isfirst: s = '(%s)' % s s = '%s*' % s s = '%s%s' % ( s, var ) #% Now treat the special case where the polynomial is zero. if s=='': s = '0' return s def poly2str(p,variable='x'): """ Return polynomial as a string. Parameters ---------- p : array-like poly1d vector of polynomial coefficients in decreasing order. variable : string display character for variable Returns ------- p_str : string consisting of the polynomial coefficients in the vector P multiplied by powers of the given `variable`. See also -------- poly2hstr Examples -------- >>> poly2str([1, 1, 2], 's' ) 's**2 + s + 2' """ thestr = "0" var = variable # Remove leading zeros coeffs = polytrim(np.atleast_1d(p)) N = len(coeffs)-1 for k in range(len(coeffs)): coefstr = '%.4g' % abs(coeffs[k]) if coefstr[-4:] == '0000': coefstr = coefstr[:-5] power = (N-k) if power == 0: if coefstr != '0': newstr = '%s' % (coefstr,) else: if k == 0: newstr = '0' else: newstr = '' elif power == 1: if coefstr == '0': newstr = '' elif coefstr == 'b' or coefstr == '1': newstr = var else: newstr = '%s*%s' % (coefstr, var) else: if coefstr == '0': newstr = '' elif coefstr == 'b' or coefstr == '1': newstr = '%s**%d' % (var, power,) else: newstr = '%s*%s**%d' % (coefstr, var, power) if k > 0: if newstr != '': if coeffs[k] < 0: thestr = "%s - %s" % (thestr, newstr) else: thestr = "%s + %s" % (thestr, newstr) elif (k == 0) and (newstr != '') and (coeffs[k] < 0): thestr = "-%s" % (newstr,) else: thestr = newstr return thestr def polyshift(py,a=-1,b=1): """ Polynomial coefficient shift Polyshift shift the polynomial coefficients by a variable shift: Y = 2*(X-.5*(b+a))/(b-a) i.e., the interval -1 <= Y <= 1 is mapped to the interval a <= X <= b Parameters ---------- py : array-like polynomial coefficients for the variable y. a,b : scalars lower and upper limit. Returns ------- px : ndarray polynomial coefficients for the variable x. See also -------- polyishift Example ------- >>> py = [1, 0] >>> px = polyshift(py,0,5) >>> polyval(px,[0, 2.5, 5]) #% This is the same as the line below array([-1., 0., 1.]) >>> polyval(py,[-1, 0, 1 ]) array([-1, 0, 1]) """ if (a==-1) & (b ==1): return py L = b-a return polyishift(py,-(2.+b+a)/L,(2.-b-a)/L) def polyishift(px,a=-1,b=1): """ Inverse polynomial coefficient shift Polyishift does the inverse of Polyshift, shift the polynomial coefficients by a variable shift: Y = 2*(X-.5*(b+a)/(b-a) i.e., the interval a <= X <= b is mapped to the interval -1 <= Y <= 1 Parameters ---------- px : array-like polynomial coefficients for the variable x. a,b : scalars lower and upper limit. Returns ------- py : ndarray polynomial coefficients for the variable y. See also -------- polyishift Example ------- >>> px = [1, 0] >>> py = polyishift(px,0,5); >>> polyval(px,[0, 2.5, 5]) #% This is the same as the line below array([ 0. , 2.5, 5. ]) >>> polyval(py,[-1, 0, 1]) array([ 0. , 2.5, 5. ]) """ if (a==-1) & (b ==1): return px L = b-a xscale = 2./L xloc = -float(a+b)/L return polyreloc( polyrescl(px,xscale),xloc) def map_from_interval(x,a,b) : """F(x), where F: [a,b] -> [-1,1].""" return (x - (b + a)/2.0)*(2.0/(b - a)) def map_to_interval(x,a,b) : """F(x), where F: [-1,1] -> [a,b].""" return (x*(b - a) + (b + a))/2.0 def poly2cheb(p,a=-1,b=1): """ Convert polynomial coefficients into Chebyshev coefficients Parameters ---------- p : array-like polynomial coefficients a,b : real scalars lower and upper limits (Default -1,1) Returns ------- ck : ndarray Chebychef coefficients POLY2CHEB do the inverse of CHEB2POLY: given a vector of polynomial coefficients AK, returns an equivalent vector of Chebyshev coefficients CK. This is useful for economization of power series. The steps for doing so: 1. Convert polynomial coefficients to Chebychev coefficients, CK. 2. Truncate the CK series to a smaller number of terms, using the coefficient of the first neglected Chebychev polynomial as an error estimate. 3 Convert back to a polynomial by CHEB2POLY See also -------- cheb2poly chebval chebfit Examples -------- >>> import numpy as np >>> p = np.arange(5) >>> ck = poly2cheb(p) >>> cheb2poly(ck) array([ 1., 2., 3., 4.]) Reference --------- William H. Press, Saul Teukolsky, William T. Wetterling and Brian P. Flannery (1997) "Numerical recipes in Fortran 77", Vol. 1, pp 184-194 """ f = poly1d(p) n = len(f.coeffs) return chebfit(f,n,a,b) def cheb2poly(ck,a=-1,b=1): """ Converts Chebyshev coefficients to polynomial coefficients Parameters ---------- ck : array-like Chebychef coefficients a,b : real, scalars lower and upper limits (Default -1,1) Returns ------- p : ndarray polynomial coefficients It is not advised to do this for len(ck)>10 due to numerical cancellations. See also -------- chebval chebfit Examples -------- >>> import numpy as np >>> p = np.arange(5) >>> ck = poly2cheb(p) >>> cheb2poly(ck) array([ 1., 2., 3., 4.]) References ---------- http://en.wikipedia.org/wiki/Chebyshev_polynomials http://en.wikipedia.org/wiki/Chebyshev_form http://en.wikipedia.org/wiki/Clenshaw_algorithm """ n = len(ck) b_Nmi = np.zeros(1) b_Nmip1 = np.zeros(1) y = np.r_[2/(b-a), -(a+b)/(b-a)] y2 = 2.*y # Clenshaw recurence for ix in range(n-1,0,-1): tmp = b_Nmi b_Nmi = polymul(y2,b_Nmi) # polynomial multiplication nb = len(b_Nmip1) b_Nmip1[-1] = b_Nmip1[-1]-ck[ix] b_Nmi[-nb::] = b_Nmi[-nb::]-b_Nmip1 b_Nmip1 = tmp p = polymul(y,b_Nmi) # polynomial multiplication nb = len(b_Nmip1) b_Nmip1[-1] = b_Nmip1[-1]-ck[0] p[-nb::] = p[-nb::]-b_Nmip1 return polytrim(p) def chebextr(n): """ Return roots of derivative of Chebychev polynomial of the first kind. All local extreme values of the polynomial are either -1 or 1. So, CHEBPOLY( N, CHEBEXTR(N) ) ) return the same as (-1).^(N:-1:0) except for the numerical noise in the former. Because the extreme values of Chebychev polynomials of the first kind are either -1 or 1, their roots are often used as starting values for the nodes in minimax approximations. Parameters ---------- n : scalar, integer degree of Chebychev polynomial. Examples -------- >>> x = chebextr(4) >>> chebpoly(4,x) array([ 1., -1., 1., -1., 1.]) Reference --------- http://en.wikipedia.org/wiki/Chebyshev_nodes http://en.wikipedia.org/wiki/Chebyshev_polynomials """ return -np.cos((np.pi*np.arange(n+1))/n); def chebroot(n,kind=1): """ Return roots of Chebychev polynomial of the first or second kind. The roots of the Chebychev polynomial of the first kind form a particularly good set of nodes for polynomial interpolation because the resulting interpolation polynomial minimizes the problem of Runge's phenomenon. Parameters ---------- n : scalar, integer degree of Chebychev polynomial. kind: 1 or 2, optional kind of Chebychev polynomial (default 1) Examples -------- >>> import numpy as np >>> x = chebroot(3) >>> np.abs(chebpoly(3,x))<1e-15 array([ True, True, True], dtype=bool) >>> chebpoly(3) array([ 4., 0., -3., 0.]) >>> x2 = chebroot(4,kind=2) >>> np.abs(chebpoly(4,x2,kind=2))<1e-15 array([ True, True, True, True], dtype=bool) >>> chebpoly(4,kind=2) array([ 16., 0., -12., 0., 1.]) Reference --------- http://en.wikipedia.org/wiki/Chebyshev_nodes http://en.wikipedia.org/wiki/Chebyshev_polynomials """ if kind not in (1,2): raise ValueError('kind must be 1 or 2') return -np.cos(np.pi*(np.arange(n)+0.5*kind)/(n+kind-1)); def chebpoly(n, x=None, kind=1): """ Return Chebyshev polynomial of the first or second kind. These polynomials are orthogonal on the interval [-1,1], with respect to the weight function w(x) = (1-x^2)^(-1/2+kind-1). chebpoly(n) returns the coefficients of the Chebychev polynomial of degree N. chebpoly(n,x) returns the Chebychev polynomial of degree N evaluated in X. Parameters ---------- n : integer, scalar degree of Chebychev polynomial. x : array-like, optional evaluation points kind: 1 or 2, optional kind of Chebychev polynomial (default 1) Returns ------- p : ndarray polynomial coefficients if x is None. Chebyshev polynomial evaluated at x otherwise Examples -------- >>> import numpy as np >>> x = chebroot(3) >>> np.abs(chebpoly(3,x))<1e-15 array([ True, True, True], dtype=bool) >>> chebpoly(3) array([ 4., 0., -3., 0.]) >>> x2 = chebroot(4,kind=2) >>> np.abs(chebpoly(4,x2,kind=2))<1e-15 array([ True, True, True, True], dtype=bool) >>> chebpoly(4,kind=2) array([ 16., 0., -12., 0., 1.]) Reference --------- http://en.wikipedia.org/wiki/Chebyshev_polynomials """ if x is None: # Calculate coefficients. if n == 0: p = np.ones(1) else: p = np.round( pow(2,n-2+kind) * np.poly( chebroot(n,kind=kind) ) ) p[1::2] = 0; return p else: # Evaluate polynomial in chebychev form ck = np.zeros(n+1) ck[n] = 1. return _chebval(np.atleast_1d(x),ck,kind=kind) def chebfit(fun,n=10,a=-1,b=1,trace=False): """ Computes the Chebyshevs coefficients so that f(x) can be approximated by: n-1 f(x) = sum ck*Tk(x) k=0 where Tk is the k'th Chebyshev polynomial of the first kind. Parameters ---------- fun : callable function to approximate n : integer, scalar, optional number of base points (abscissas). Default n=10 (maximum 50) a,b : real, scalars, optional integration limits Returns ------- ck : ndarray polynomial coefficients in Chebychev form. Examples -------- Fit exp(x) >>> import pylab as pb >>> a = 0; b = 2 >>> ck = chebfit(pb.exp,7,a,b); >>> x = pb.linspace(0,4); >>> h=pb.plot(x,pb.exp(x),'r',x,chebval(x,ck,a,b),'g.') >>> x1 = chebroot(9)*(b-a)/2+(b+a)/2 >>> ck1 = chebfit(pb.exp(x1)) >>> h=pb.plot(x,pb.exp(x),'r',x,chebval(x,ck1,a,b),'g.') >>> pb.close() See also -------- chebval Reference --------- http://en.wikipedia.org/wiki/Chebyshev_nodes http://mathworld.wolfram.com/ChebyshevApproximationFormula.html W. Fraser (1965) "A Survey of Methods of Computing Minimax and Near-Minimax Polynomial Approximations for Functions of a Single Independent Variable" Journal of the ACM (JACM), Vol. 12 , Issue 3, pp 295 - 314 William H. Press, Saul Teukolsky, William T. Wetterling and Brian P. Flannery (1997) "Numerical recipes in Fortran 77", Vol. 1, pp 184-194 """ if (n>50): warnings.warn('CHEBFIT should only be used for n<50') if hasattr(fun,'__call__'): x = map_to_interval(chebroot(n),a,b) f = fun(x); if trace: import pylab as plb plb.plot(x,f,'+') else: f = fun n = len(f) #raise ValueError('Function must be callable!') # N-1 # c(k) = (2/N) sum w(n) f(n)*cos(pi*k*(2n+1)/(2N)), 0 <= k < N. # n=0 # # w(0) = 0.5, w(n)=1 for n>0 ck = dct(f[::-1])/n ck[0] = ck[0]/2. return ck def dct(x,n=None): """ Discrete Cosine Transform N-1 y[k] = 2* sum x[n]*cos(pi*k*(2n+1)/(2*N)), 0 <= k < N. n=0 Examples -------- >>> import numpy as np >>> x = np.arange(5) >>> np.abs(x-idct(dct(x)))<1e-14 array([ True, True, True, True, True], dtype=bool) >>> np.abs(x-dct(idct(x)))<1e-14 array([ True, True, True, True, True], dtype=bool) Reference --------- http://en.wikipedia.org/wiki/Discrete_cosine_transform http://users.ece.utexas.edu/~bevans/courses/ee381k/lectures/ """ fft = np.fft.fft x = np.atleast_1d(x) if n is None: n = x.shape[-1] if x.shape[-1]0 Examples -------- >>> import numpy as np >>> x = np.arange(5) >>> np.abs(x-idct(dct(x)))<1e-14 array([ True, True, True, True, True], dtype=bool) >>> np.abs(x-dct(idct(x)))<1e-14 array([ True, True, True, True, True], dtype=bool) Reference --------- http://en.wikipedia.org/wiki/Discrete_cosine_transform http://users.ece.utexas.edu/~bevans/courses/ee381k/lectures/ """ ifft = np.fft.ifft x = np.atleast_1d(x) if n is None: n = x.shape[-1] w = np.exp(1j * np.arange(n) * np.pi/(2*n)) if x.shape[-1]>> import pylab as pb >>> x = pb.linspace(-1,1) >>> ck = pb.zeros(5); ck[-1]=1 >>> h = pb.plot(x,chebval(x,ck),x,chebpoly(4,x),'.') >>> pb.close() Fit exponential function: >>> import pylab as pb >>> ck = chebfit(pb.exp,7,0,2) >>> x = pb.linspace(0,4); >>> h=pb.plot(x,chebval(x,ck,0,2),'g',x,pb.exp(x)) >>> pb.close() See also -------- chebfit References ---------- http://en.wikipedia.org/wiki/Clenshaw_algorithm http://mathworld.wolfram.com/ClenshawRecurrenceFormula.html """ y = map_from_interval(np.atleast_1d(x),a,b) if fill is None: f = _chebval(y,ck,kind=kind) else: cond = (np.abs(y)<=1) f = np.where(cond,0,fill) if np.any(cond): yk = np.extract(cond,y) f[cond] = _chebval(yk,ck,kind=kind) return f def chebder(ck,a=-1,b=1): """ Differentiate Chebyshev polynomial Parameters ---------- ck : array-like polynomial coefficients in Chebyshev form of function to differentiate a,b : real, scalars limits for polynomial(Default -1,1) Return ------ cder : ndarray polynomial coefficients in Chebyshev form of the derivative Examples -------- Fit exponential function: >>> import pylab as pb >>> ck = chebfit(pb.exp,7,0,2) >>> x = pb.linspace(0,4) >>> ck2 = chebder(ck,0,2); >>> h=pb.plot(x,chebval(x,ck,0,2),'g',x,pb.exp(x),'r') >>> pb.close() See also -------- chebint chebfit """ n = len(ck) cder = np.zeros(n) # n and n-1 are special cases. # cder(n-1)=0; cder[-2] = 2*(n-1)*ck[-1] for j in range(n-3,-1,-1): cder[j] = cder[j+2]+2*j*ck[j+1] return cder*2./(b-a) # Normalize to the interval b-a. def chebint(ck,a=-1,b=1): """ Integrate Chebyshef polynomial Parameters ---------- ck : array-like polynomial coefficients in Chebyshev form of function to integrate. a,b : real, scalars limits for polynomial(Default -1,1) Return ------ cint : ndarray polynomial coefficients in Chebyshev form of the integrated function Examples -------- Fit exponential function: >>> import pylab as pb >>> ck = chebfit(pb.exp,7,0,2) >>> x = pb.linspace(0,4) >>> ck2 = chebint(ck,0,2); >>> h=pb.plot(x,chebval(x,ck,0,2),'g',x,pb.exp(x),'r.') >>> pb.close() See also -------- chebder chebfit """ n = len(ck) cint = np.zeros(n); con = 0.25*(b-a); dif1 = np.diff(ck[::2]) ix1= np.r_[1:n-1:2] cint[ix1] = -(con*dif1)/(ix1-1) if n>3: dif2 = np.diff(ck[1::2]) ix2=np.r_[2:n-1:2] cint[ix2] = -(con*dif2)/(ix2-1) #% cint(n) is a special case cint[-1] = (con*ck[n-2])/(n-1) cint[0] = np.sum((-1)**np.r_[1:n]*cint[1::]) # Set constant of integration return cint class Cheb1d(object): coeffs = None order = None a = None b = None def __init__(self,ck,a=-1,b=1): if isinstance(ck, poly1d): for key in ck.__dict__.keys(): self.__dict__[key] = ck.__dict__[key] return cki = np.trim_zeros(np.atleast_1d(ck),'b') if len(cki.shape) > 1: raise ValueError, "Polynomial must be 1d only." self.__dict__['coeffs'] = cki self.__dict__['order'] = len(cki) - 1 self.__dict__['a'] = a self.__dict__['b'] = b def __call__(self,x): return chebval(x,self.coeffs,self.a,self.b) def __array__(self, t=None): if t: return np.asarray(self.coeffs, t) else: return np.asarray(self.coeffs) def __repr__(self): vals = repr(self.coeffs) vals = vals[6:-1] return "Cheb1d(%s)" % vals def __len__(self): return self.order def __str__(self): pass def __neg__(self): return Cheb1d(-self.coeffs,self.a,self.b) def __pos__(self): return self 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 __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 __eq__(self, other): return np.alltrue(self.coeffs == other.coeffs) def __ne__(self, other): return np.any(self.coeffs != other.coeffs) or (self.a!=other.a) or (self.b !=other.b) def __setattr__(self, key, val): raise ValueError, "Attributes cannot be changed this way." def __getattr__(self, key): if key in ['c','coef','coefficients']: return self.coeffs elif key in ['o']: return self.order elif key in ['a']: return self.a elif key in ['b']: return self.b else: try: return self.__dict__[key] except KeyError: raise AttributeError("'%s' has no attribute '%s'" % (self.__class__, key)) def __getitem__(self, val): if val > self.order: return 0 if val < 0: return 0 return self.coeffs[val] 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.__dict__['coeffs'] = NX.concatenate((self.coeffs,zr)) self.__dict__['order'] = key self.__dict__['coeffs'][key] = val return def __iter__(self): return iter(self.coeffs) def integ(self, m=1): """ Return an antiderivative (indefinite integral) of this polynomial. Refer to `chebint` for full documentation. See Also -------- chebint : equivalent function """ return Cheb1d(chebint(self.coeffs, self.a,self.b)) def deriv(self, m=1): """ Return a derivative of this polynomial. Refer to `chebder` for full documentation. See Also -------- chebder : equivalent function """ return Cheb1d(chebder(self.coeffs,self.a,self.b)) def test_doctstrings(): if False: #True: # x = np.arange(4) dx = dct(x) idx = idct(dx) import pylab as plb a = 0; b = 2; ck = chebfit(np.exp,6,a,b); t = chebval(0,ck,a,b) x=np.linspace(0,2,6); plb.plot(x,np.exp(x),'r', x,chebval(x,ck,a,b),'g.') #x1 = chebroot(9).'*(b-a)/2+(b+a)/2 ; #ck1 =chebfit([x1 exp(x1)],9,a,b); #plot(x,exp(x),'r'), hold on #plot(x,chebval(x,ck1,a,b),'g'), hold off t = poly2hstr([1,1,2]) py = [1, 0] px = polyshift(py,0,5); t1=polyval(px,[0, 2.5, 5]) #% This is the same as the line below t2=polyval(py,[-1, 0, 1 ]) px = [1, 0] py = polyishift(px,0,5); t1 = polyval(px,[0, 2.5, 5]) #% This is the same as the line below t2 = polyval(py,[-1, 0, 1 ]) print(t1,t2) else: import doctest doctest.testmod() if __name__== '__main__': test_doctstrings()