Thinking about orthogonal polynomials over the past couple days made me curious about creating a class definition in Python that would allow one to do simple polynomial calculations (e.g. addition, multiplication, evaluation). I struggled a little bit with creating an elegant solution for polynomial multiplication. I settled on a double loop, but I am wondering if anyone has a nicer solution, please share!
from operator import add class Polynomial(object): def __init__(self, coeffs): self.degree = len(coeffs) - 1 self.rep = self.__str(coeffs) self.coefficients = coeffs def __repr__(self): return self.rep def __str(self, coeffs): #Create list of nonzero terms terms = [' + ' + str(coeffs[k]) + 'x**' \ + str(k) \ for k in range(0, self.degree + 1) \ if coeffs[k] <> 0] #If zero polynomial, return 0 if len(terms) == 0: return str(0) #Otherwise concatenate terms p = reduce(add, terms) #Strip out leading + return p.lstrip(' + ') def __add(self, other): """Adds two polynomials.""" #Max length of polynomials' coeff lists d = max(self.degree, other.degree) + 1 #Pad coeffs lists with 0s until equal length self_temp = self.coefficients + *(d-self.degree-1) other_temp = other.coefficients + *(d-other.degree-1) #Sum coeffs lists elementwise return Polynomial(map(add, self_temp, other_temp)) def __mul(self, other): """Multiplies two polynomials.""" n = self.degree + other.degree #Degree of product prod_coeffs = *(n+1) #Initalize coefficient list of product #Compute Cauchy product for i in range(0, self.degree + 1): for j in range(0, other.degree + 1): prod_coeffs[i+j] += self.coefficients[i] * other.coefficients[j] return Polynomial(prod_coeffs) def __add__(self, other): """Overloads the + operator.""" return self.__add(other) def __mul__(self, other): """Overloads the * operator.""" return self.__mul(other) def __call__(self, val): """Evaluates the polynomial at x = val.""" sum = 0 return reduce(add, [self.coefficients[i]*(val**i) \ for i in range(self.degree + 1)])