<<

Outline

• How to represent a ? • Evaluation of a polynomial.

• Basic operations: sum, product and .

Jordi Cortadella • Greatest common . Department of Computer Science

Introduction to Programming © Dept. CS, UPC 2 Representation of polynomials Polynomial evaluation (Horner’s scheme) • Design a that evaluates the value of a 푛 푛−1 푃 푥 = 푎푛푥 + 푎푛−1푥 + ⋯ + 푎1푥 + 푎0 polynomial.

푛 푛 − 1 ⋯ 1 0 • A polynomial of degree 푛 can be efficiently 푎푛 푎푛−1 ⋯ 푎1 푎0 evaluated using Horner’s algorithm:

A list of coefficients 푛 푛−1 푃 푥 = 푎푛푥 + 푎푛−1푥 + ⋯ + 푎1푥 + 푎0 =

(⋯ ((푎푛푥 + 푎푛−1)푥 + 푎푛−2)푥 + ⋯ )푥 + 푎0 Properties of the representation: • 푎푛 ≠ 0 (the topmost element is not zero). • Example: • 푃 푥 = 0 is represented with an empty vector. 3푥3 − 2푥2 + 푥 − 4 = 3푥 − 2 푥 + 1 푥 − 4

Introduction to Programming © Dept. CS, UPC 3 Introduction to Programming © Dept. CS, UPC 4 Polynomial evaluation (Horner’s scheme) Polynomial evaluation (Horner’s scheme)

3 2 def poly_eval(P, x): 3푥 − 2푥 + 푥 − 4 """Returns the evaluation of P(x)"""

r = 0 # Evaluates the polynomial using Horner's scheme # The coefficients are visited from highest to lowest for i in range(len(P)-1, -1, -1): 3 푥 − 2 푥 + 1 푥 − 4 r = r*x + P[i] return r

Introduction to Programming © Dept. CS, UPC 5 Introduction to Programming © Dept. CS, UPC 6 Product of polynomials Product of polynomials • Key point: def poly_mul(P, Q): Given 푃 푥 = 푎 푥푛 + 푎 푥푛−1 + ⋯ + 푎 푥 + 푎 """Returns P*Q""" 푛 푛−1 1 0 푚 푚−1 and 푄 푥 = 푏푚푥 + 푏푚−1푥 + ⋯ + 푏1푥 + 푏0,

푖 Example: what is the coefficient 푐푖 of 푥 in (푃 ⋅ 푄)(푥)? 푃 푥 = 2푥3 + 푥2 − 4 푖 푗 푄 푥 = 푥2 − 2푥 + 3 • The product 푎푖푥 ⋅ 푏푗푥 must be added to the term with 푥푖+푗. 푃 ⋅ 푄 푥 = 2푥5 + −4 + 1 푥4 + 6 − 2 푥3 + −4 + 3 푥2 + 8푥 − 12 • Idea: for every 푖 and 푗, add 푎 ⋅ 푏 to the (푖 + 푗)-th 푃 ⋅ 푄 푥 = 2푥5 − 3푥4 + 4푥3 − 푥2 + 8푥 − 12 푖 푗 coefficient of the product.

Introduction to Programming © Dept. CS, UPC 7 Introduction to Programming © Dept. CS, UPC 8 Product of polynomials Product of polynomials

푥3 푥2 푥1 푥0 def poly_mul(P, Q): """Returns P*Q""" 1 0 3 -1 × 2 -1 3 # Special case for a polynomial of size 0 if len(P) == 0 or len(Q) == 0: return [] 3 0 9 -3 R = [0]*(len(P)+len(Q)-1) # list of zeros -1 0 -3 1 for i in range(len(P)): for j in range(len(Q)): + 2 0 6 -2 R[i+j] += P[i]*Q[j] return R 2 -1 9 -5 10 -3

푥5 푥4 푥3 푥2 푥1 푥0

Introduction to Programming © Dept. CS, UPC 9 Introduction to Programming © Dept. CS, UPC 10 Sum of polynomials Sum of polynomials • Note that over the real , A function to normalize a polynomial might be useful in degree 푃 ⋅ 푄 = degree 푃 + degree(푄) some algorithms, i.e., remove the leading zeros to guarantee the most significant coefficient is not zero. (except if 푃 = 0 or 푄 = 0).

So we know the size of the result vector a priori. def poly_normalize(P): """Resizes the polynomial to guarantee that the leading coefficient is not zero.""" while len(P) > 0 and P[-1] == 0: • This is not true for the polynomial sum, e.g., P.pop(-1) degree 푥 + 5 + −푥 − 1 = 0

Introduction to Programming © Dept. CS, UPC 11 Introduction to Programming © Dept. CS, UPC 12 Sum of polynomials Euclidean division of polynomials def poly_add(P, Q): • For every pair of polynomials 퐴 and 퐵, such that """Returns P+Q""" 퐵 ≠ 0, find 푄 and 푅 such that if len(Q) > len(P): # guarantees len(P) >= len(Q) P, Q = Q, P 퐴 = 퐵 ∙ 푄 + 푅

# Adds the coefficients up to len(Q) and degree 푅 < degree(퐵). R = [] for i in range(len(Q)): P 푄 and 푅 are the only polynomials satisfying this R.append(P[i]+Q[i]) Q property. R += P[i+1:] # appends the remaining coefficients of P poly_normalize(R) • Classical algorithm: Polynomial . return R

Introduction to Programming © Dept. CS, UPC 13 Introduction to Programming © Dept. CS, UPC 14 Polynomial long division Polynomial long division

def poly_div(A, B): def poly_div(A, B): """Returns the (Q) and the (R) """Returns the quotient (Q) and the remainder (R) of the Euclidean division A/B. They are returned of the Euclidean division A/B. They are returned as a tuple (Q, R)""" as a tuple (Q, R)"""

A B Q R A B Q R

Introduction to Programming © Dept. CS, UPC 15 Introduction to Programming © Dept. CS, UPC 16 Polynomial long division Polynomial long division def poly_div(A, B): def poly_div(A, B): """Returns the quotient (Q) and the remainder (R) """Returns the quotient (Q) and the remainder (R) of the Euclidean division A/B. They are returned of the Euclidean division A/B. They are returned as a tuple (Q, R)""" as a tuple (Q, R)"""

A B Q R A B Q R

Introduction to Programming © Dept. CS, UPC 17 Introduction to Programming © Dept. CS, UPC 18 Polynomial long division Polynomial long division def poly_div(A, B): def poly_div(A, B): """Returns the quotient (Q) and the remainder (R) """Returns the quotient (Q) and the remainder (R) of the Euclidean division A/B. They are returned of the Euclidean division A/B. They are returned as a tuple (Q, R)""" as a tuple (Q, R)"""

A B Q R A B Q R

Introduction to Programming © Dept. CS, UPC 19 Introduction to Programming © Dept. CS, UPC 20 Polynomial long division Polynomial long division

def poly_div(A, B): def poly_div(A, B): """Returns the quotient (Q) and the remainder (R) """Returns the quotient (Q) and the remainder (R) of the Euclidean division A/B. They are returned of the Euclidean division A/B. They are returned as a tuple (Q, R)""" as a tuple (Q, R)"""

A B Q R A B Q R

Introduction to Programming © Dept. CS, UPC 21 Introduction to Programming © Dept. CS, UPC 22 Polynomial long division Polynomial long division

def poly_div(A, B): Invariant: A = BQ+R """Returns the quotient (Q) and the remainder (R) of the A Euclidean division A/B. They are returned as a tuple (Q, R)""" 5 4 3 2 1 0 3 2 1 0 R = A[:] # copy of A k if len(A) < len(B): R: 2 6 -3 1 0 -1 B: 2 0 1 -1 return [], R

6 -4 2 0 -1 2 1 0 Q = [0]*(len(A)-len(B)+1) k+iQ Q: 1 3 -2 # For each digit of Q iQ -4 -1 3 -1 for iQ in range(len(Q)-1, -1, -1): Q[iQ] = R[-1]/B[-1] -1 5 -3 R.pop(-1) for k in range(len(B)-1): R[k+iQ] -= Q[iQ]*B[k]

poly_normalize(R) return Q, R

Introduction to Programming © Dept. CS, UPC 23 Introduction to Programming © Dept. CS, UPC 24 GCD of two polynomials Re-visiting for gcd Example: # gcd(a, 0) = a # gcd(a, b) = gcd(b, a%b) For polynomials:

def gcd(a, b): • a and b are polynomials. """Returns gcd(a, b)""" while b > 0: • a%b is the remainder of a, b = b, a%b the Euclidean division. return a

Introduction to Programming © Dept. CS, UPC 25 Introduction to Programming © Dept. CS, UPC 26 Euclidean algorithm for gcd Euclidean algorithm for gcd

def poly_gcd(A, B): """Returns gcd(A, B)""" while len(B) > 0: Q, R = poly_div(A, B) A, B = B, R

# Converts to monic polynomial (e.g., 3x-6  x-2) c = A[–1] for i in range(len(A)): monic polynomial A[i] /= c

return A

Introduction to Programming © Dept. CS, UPC 27 Introduction to Programming © Dept. CS, UPC 28 Conclusions • Polynomials are used very often in numerical analysis.

• Polynomial functions have nice properties: continuous and simple derivatives and antiderivatives.

• There are simple root-finding algorithms to find approximations of the roots.

Introduction to Programming © Dept. CS, UPC 29