#------------------------------------------------------------ # Copyright (C) 2017-2019 Dr. William T. Verts #------------------------------------------------------------ # See pages 272-275 in the Companion for a variation of # these functions #------------------------------------------------------------ #------------------------------------------------------------ # Clean up a polynomial by enforcing the following rules: # # (1) The polynomial is never empty. # (2) Any floats with fractions really close to zero # get converted to integers. # (3) Any high-order coefficients of zero get deleted, # except that if the polynomial is entirely zeroes # the result returned is [0]. # Examples: # polyNormalize([2,0,3,4,0,5]) returns [2,0,3,4,0,5] # polyNormalize([2,0,3,0,0,0]) returns [2,0,3] # polyNormalize([2.0, 3.5, 4]) returns [2, 3.5, 4] # polyNormalize([0,0,0,0,0,0]) returns [0] # polyNormalize([]) returns [0] #------------------------------------------------------------ def polyNormalize (P): # P is a list of coefficients Q = [0 for I in range(max(1,len(P)))] # Create a zero polynomial Q the same size as P (or [0] if P==[]) for I in range(len(P)): # For every entry in P Value = P[I] # Grab the coefficient if (abs(Value - float(int(Value))) < 1.0E-14): # Close enough to integer to call it one Q[I] = int(Value) # Convert (possible) float to int else: # Q[I] = Value # Have to keep it as a float while (len(Q) > 1) and (Q[-1] == 0): del Q[-1] # Delete any high-order zero entries (but leave one if all were 0) return Q # Return the cleaned-up polynomial equivalent to P #------------------------------------------------------------ # Add/Subtract two or three polynomials. #------------------------------------------------------------ def polyAdd(P0,P1,P2=[]): # P0, P1, and P2 are lists of coefficients P = [0 for I in range(max(len(P0),len(P1),len(P2)))] # P will be my answer, length assumed to be same as longest polynomial for I in range(len(P0)): P[I] = P[I] + P0[I] # Add P0 to result for I in range(len(P1)): P[I] = P[I] + P1[I] # Add P1 to result for I in range(len(P2)): P[I] = P[I] + P2[I] # Add P2 to result return polyNormalize(P) # Return cleaned-up result def polySubtract(P0,P1,P2=[]): # P0, P1, and P2 are lists of coefficients P = [0 for I in range(max(len(P0),len(P1),len(P2)))] # P will be my answer, length assumed to be same as longest polynomial for I in range(len(P0)): P[I] = P[I] + P0[I] # Add P0 to result for I in range(len(P1)): P[I] = P[I] - P1[I] # Subtract P1 from result for I in range(len(P2)): P[I] = P[I] - P2[I] # Subtract P2 from result return polyNormalize(P) # Return cleaned-up result #------------------------------------------------------------ # Multiply two polynomials. This is like multiplying two # large numbers by hand where there are partial products # that must be added to the correct digit position. In this # case, the position of a partial product is determined by # the new exponent. For example, if P0 = [1,4,2] = 2X^2+4X+1 # and P1 = [7,3,8] = 8X^2+3X+7, then the partial product of # P0[1] and P1[2] represents the 4X term times the 8X^2 term, # which is 32X^3, so result of multiplying P0[1] and P1[2] # (the 32) adds into slot 1+2 of the result, or P[3]. That # is, if I=1 and J=2, then P[I+J] = P[I+J] + P0[I] * P1[J] # is the same as P[3] = P[3] + P0[1] * P1[2]. #------------------------------------------------------------ def polyMultiply(P0,P1): # P0 and P1 are lists of coefficients P = [0 for I in range(len(P0)+len(P1))] # P will be my answer, length assumed to be total of terms in both polynomials for I in range(len(P0)): # Step through all coefficients in P0, for J in range(len(P1)): # For each coefficient in P0 step through all coefficients in P1, P[I+J] = P[I+J] + P0[I] * P1[J] # Add partial product to correct slot in the answer return polyNormalize(P) # Return cleaned-up result #------------------------------------------------------------ # Differentiate P(X) with respect to X. In this code the # P[0] term is the constant, which is ignored, and the result # will have one fewer terms than the source. All other terms # multiply the exponent (I) times the coefficient (P[I]) to # get the coefficient of the next lower term. Notice that # the code to differentiate a polynomial is significantly # smaller and simpler than multiplication! #------------------------------------------------------------ def polyDifferentiate(P): Q = [0 for I in range(len(P)-1)] for I in range(1,len(P)): Q[I-1] = I * P[I] return polyNormalize(Q) #------------------------------------------------------------ # Convert a polynomial from its internal representation into # a string that has the appearance of a standard mathematical # polynomial. That is, a polynomial such as [-1, 2, 0, 5] # returns the string 5X^3 + 2X - 1 (notice that the X^1 term # suppresses the exponent, the X^0 term uses just the # coefficient, and the X^2 term has a zero coefficient and # is therefore ignored). #------------------------------------------------------------ def polyStr(P): S = "" for Exponent in range(len(P)-1,-1,-1): # Step through coefficients from highest exponent to lowest Coefficient = P[Exponent] if Coefficient != 0: # We only care about non-zero coefficients if Coefficient < 0: if S != "": S = S + " - " # String not empty and coefficient was negative (internal term) else: S = S + "-" # String was empty but coefficient was negative (first term) else: if S != "": S = S + " + " # String not empty and coefficient was positive (internal term) # The + is suppressed if first term was positive. if (Exponent == 0) or (abs(Coefficient) != 1): # No need to include coefficient if it is 1 (unless it's the X^0 term) S = S + str(abs(Coefficient)) # Include the coefficient without a sign (handled earlier) if (Exponent >= 1): # Include X for all but the X^0 term S = S + "X" if (Exponent > 1): # Include the exponent for all terms X^2, X^3, X^4, etc., but not X^0 or X^1 S = S + "^" + str(Exponent) if S == "": S = "0" # If the string comes up empty, it's zero. return S #------------------------------------------------------------ # Tests #------------------------------------------------------------ Frog = [-1,7,0.5,0,-3] Toad = [5,-3,2.5,2,-3] print ("Frog = " + polyStr(Frog)) print ("Toad = " + polyStr(Toad)) print ("Frog + Toad = " + polyStr(polyAdd(Frog,Toad))) print ("Frog - Toad = " + polyStr(polySubtract(Frog,Toad))) print ("Frog * Toad = " + polyStr(polyMultiply(Frog,Toad))) print ("d/dx(Frog) = " + polyStr(polyDifferentiate(Frog)))