Creating and Manipulating Polynomials with NumPy

Creating and Manipulating Polynomials with NumPy

Need a bit of background knowledge about polynomials and their uses before jumping into action? We’ve got you covered. Polynomials are mathematical functions with the following general form:

\[
P(x) = a_n x^n + a_{n-1} x^{n-1} + \cdots + a_1 x + a_0
\]

where ai are constant values or coefficients and x is our variable, which multiplies the existing coefficients in the function raised to different degrees from 1 to n.

This tutorial illustrates the process of creating and manipulating polynomial functions in Python, using NumPy.

The Degree of a Polynomial

The degree of a polynomial function is the maximum of degrees to which its variable is raised, and it determines to some degree the visual appearance of the function.

  • The simplest case is a degree 1 polynomial, corresponding to a linear function or straight line
  • A degree 2 polynomial is also called a quadratic function, visually represented as a parabola
  • Polynomials of degree 3 or higher are visually depicted as curves with more complexity and inflection points, depending on the degree of the function

Below are visual examples of degree 1, degree 2, and degree 3 polynomials:

Three examples of polynomial functions

As abstract and intangible as they might seem, polynomials are valuable tools in myriad real-world problems, and they are commonly used in industrial processes, analytics, signal processing, and optimization problems. They are also behind the scenes in some machine learning, AI, and engineering systems, due to their ability to model nonlinear relationships in data, reduce noise in complex data like images, and approximate complex telecommunication signals.

Creating a Polynomial

Creating a polynomial with NumPy is simple: just build a list containing the coefficients in decreasing degree, and use the numpy.poly1d() function to create the function, passing in the list of coefficients.

The code below creates the following polynomial and prints it.

\[
2x^3 – 4x^2 + 3x – 7
\]

import numpy as np

coefficients = [2, -4, 3, -7]
poly = np.poly1d(coefficients)

print(poly)

Output:

   3     2
2 x - 4 x + 3 x - 7

Evaluating a polynomial p(x), which boils down to determining the value of the function for a given input x, can be done with the NumPy function poly(3).

result = poly(3)
print(result)

The result for this polynomial function should be p(3) = 20.

Operations with Polynomials

Performing addition, subtraction, and multiplication of polynomial functions in NumPy is as easy as creating them, just by using Python arithmetic operators on them as if they were plain numbers.

p1 = np.poly1d([2, 0, 3])
p2 = np.poly1d([1, 2])

p_add = p1 + p2
p_sub = p1 - p2
p_mul = p1 * p2

print("Addition:\n", p_add)
print("Subtraction:\n", p_sub)
print("Multiplication:\n", p_mul)

Output:

Addition:
    2
2 x + 1 x + 5
Subtraction:
    2
2 x - 1 x + 1
Multiplication:
    3     2
2 x + 4 x + 3 x + 6

Other common operations with polynomials, particularly in optimization methods like those used in machine learning and deep learning models, are finding their roots, derivatives, and integrals.

The roots of a polynomial are the solutions (values of x) where the polynomial equals zero. NumPy provides a member function to calculate the roots of a polynomial:

roots = poly.roots
print("Roots:", roots)

Output:

Roots: [ 2.0854813 +0.j         -0.04274065+1.29477523j -0.04274065-1.29477523j]

This output may seem not very intuitive at first glance. NumPy has found three roots for this polynomial, but only the first one is real (x ≈ 2.08), the other two being complex conjugate solutions. Simply put, the curve associated with our polynomial touches the x-axis around the value of 2.08, but has two oscillations that do not intersect with the horizontal axis but are “imaginary roots”. For simplicity, let’s just consider there is one real solution for p(x) = 0, the one with x ≈ 2.08.

Of course, there are also methods to obtain the derivative and the integral of a polynomial, which return a polynomial one degree lower and one degree higher, respectively:

derivative = poly.deriv()
print("Derivative function:\n", derivative)
integral = poly.integ()
print("Integral function:\n", integral)

Output:

Derivative function:
    2
6 x - 8 x + 3
Integral function:
      4         3       2
0.5 x - 1.333 x + 1.5 x - 7 x

This is what the initial polynomial, its derivative, and its integral look like as curves when plotted together:

A polynomial, its derivative, and its integral

Fitting a Polynomial Function

Fitting a curve to a set of data is an extremely common aspect of data science processes, including descriptive and predictive analyses. Given a set of bi-dimensional data points (x,y), the numpy.polyfit() method is used to fit a polynomial to the set of points, finding the coefficients of the polynomial that best fit the data (yes, this is the essence of regression models!).

# Five data points: (1,1), (2,4), (3,9), (4,15), and (5, 26)
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 4, 9, 15, 26])

fitted_poly = np.polyfit(x, y, 2)

# The resulting list of coefficients is turned into a new polynomial
poly_fitted = np.poly1d(fitted_poly)
print(poly_fitted)

Output:

       2
1.214 x - 1.186 x + 1.2

We can plot the five points and the polynomial that best fits them with the following code:

import matplotlib.pyplot as plt

# Generate x values for the fitted polynomial curve
x_curve = np.linspace(min(x), max(x), 100)

# Calculate y values for the fitted polynomial curve
y_curve = poly_fitted(x_curve)

# Create the plot
plt.plot(x, y, 'o', label='Data Points')
plt.plot(x_curve, y_curve, label='Fitted Polynomial')

# Add labels and title
plt.xlabel('x')
plt.ylabel('y')
plt.title('Fitted Polynomial Curve and Data Points')

# Add legend
plt.legend()

# Display the plot
plt.show()

Fitting a polynomial curve to data

With this simple yet beautiful visualization of a polynomial fitting a small sample of data, we finalize this tutorial on learning to create and manipulate polynomials in NumPy. Thanks for reading, and thanks for “coding” along!

Leave a Reply

Your email address will not be published. Required fields are marked *