#----------A polynomial class which supports addition, # multiplication, and evaluation-------------- class poly: def __init__(self,coefs): self.coefs = coefs # #Call method, to evaluate the value of the polynomial def __call__(self,x): a = self.coefs #Just a convenient local synonym for the coefs value = a[-1] for i in range(2,len(a)+1): value = value*x + a[-i] return value # #Methods to handle addition def __add__(self,other): #Check what type other is and act accordingly if isinstance(other,poly): #Find out which polynomial is higher order and #act accordingly. In essence, pad out the coefficient #list of the lower order polynomial with zeros. if len(self.coefs)>= len(other.coefs): P = self.coefs Q = other.coefs else: P = other.coefs Q = self.coefs Q = Q + [0. for i in range(len(P)-len(Q))] #Pad with zeros return poly([P[i]+Q[i] for i in range(len(P))]) # #Handle case where the other operand is a number T = type(other) if (T == type(1))or(T==type(1L))or(T ==type(1.))or(T== type(1.+2.j)): return poly([a+other for a in self.coefs]) #If p and q are polynomials, the above method will handle #p+q and q+p, and it will also handle p+2., etc. However, #it won't handle 2.+p, because the float object (2.) does #not know how to add itself to a polynomial. This is why we need #to define an __radd__method, which will be called in cases #like this def __radd__(self,other): return self.__add__(other) #Note we don't include the "self" #argument when calling a method! # #---------------------------------------------------------------- # #Methods to handle multiplication def __mul__(self,other): #Check for type of "other" operand and act accordingly if isinstance(other,poly): n = len(self.coefs) m = len(other.coefs) coefs = [self.convolve(i,self.coefs,other.coefs) for i in range(n+m -1)] return poly(coefs) # #Handle case where the other operand is a number T = type(other) if (T == type(1))or(T==type(1L))or(T ==type(1.))or(T== type(1.+2.j)): return poly([a*other for a in self.coefs]) # #Handle cases like 2*p, as for addition def __rmul__(self,other): return self.__mul__(other) # #--------------------------------------------------------------- # #Method to build a string that prints out the polynomial in #a nice algebraic format. Note that we use #the %r format code instead of %f, since %r automatically #prints out the coeff in the way its own __repr__ method #would. This allows us to handle complex, integer, etc. #without trouble. def __repr__(self): str = '' for i in range(len(self.coefs)): if i == 0: str += ' %r'%self.coefs[i] elif i==1: str += ' %rx'%self.coefs[i] else: str += ' %rx**%d'%(self.coefs[i],i) if i < len(self.coefs)-1: str += '+' return str # #A utility routine to compute the convolution of the #two lists of coefficients. This is used in polynomial #multiplication. This could be made more efficient using #Numeric arrays, since the Numeric.convolve(...) function #is much faster than the Python loop used below. def convolve(self,i,c1,c2): sum = 0 lim1 = max(0,i-(len(c2)-1)) lim2 = min(len(c1),i+1) for j in range(lim1,lim2): sum += c1[j]*c2[i-j] return sum