In this chapter, we will discuss various topics related to calculus. Calculus is the branch of mathematics that concerns the processes of differentiation and integration. Geometrically, the derivative of a function represents the gradient of the curve of the function, and the integral of a function represents the area below the curve of the function. Of course, these characterizations only hold in certain circumstances, but they provide a reasonable foundation for this chapter.
We start by looking at calculus for a simple class of functions: the polynomials. In the first recipe, we create a class that represents a polynomial and define methods that differentiate and integrate the polynomial. Polynomials are convenient because the derivative or integral of a polynomial is again a polynomial. Then, we use the SymPy package to perform symbolic differentiation and integration on more general functions. After that, we see methods for solving equations using the SciPy package. Next, we turn our attention to numerical integration (quadrature) and solving differential equations. We use the SciPy package to solve ordinary differential equations and systems of ordinary differential equations, and then use a finite difference scheme to solve a simple partial differential equation. Finally, we use the fast Fourier transform to process a noisy signal and filter out the noise.
In this chapter, we will cover the following recipes:
- Working with polynomials and calculus
- Differentiating and integrating symbolically using SymPy
- Solving equations
- Integrating functions numerically using SciPy
- Solving simple differential equations numerically
- Solving systems of differential equations
- Solving partial differential equations numerically
- Using discrete Fourier transforms for signal processing
Technical requirements
In addition to the scientific Python packages NumPy and SciPy, we also need the SymPy package. This can be installed using your favorite package manager, such as pip:
python3.8 -m pip install sympy
The code for this chapter can be found in theChapter 03 folder of the GitHub repository at https://github.com/PacktPublishing/Applying-Math-with-Python/tree/master/Chapter%2003.
Check out the following video to see the Code in Action: https://bit.ly/32HuH4X.
Working with polynomials and calculus
Polynomials are among the simplest functions in mathematics and are defined as a sum:
x represents a placeholder to be substituted, and ai is a number. Since polynomials are simple, they provide an excellent means for a brief introduction to calculus. Calculus concerns the differentiation and integration of functions. Integration is, roughly speaking, anti-differentiation, in the sense that first integrating and then differentiating yields the original function.
In this recipe, we will define a simple class that represents a polynomial and write methods for this class to perform differentiation and integration.
Getting ready
Geometrically, the derivative, obtained by differentiating, of a function is its gradient, and the integral, obtained by integrating, of a function is the area that lies between the curve of the function and the x axis, accounting for whether the curve lies above or below the axis. In practice, differentiating and integrating are done symbolically, using a set of rules and standard results that are particularly simple for polynomials.
There are no additional packages required for this recipe.
How to do it...
The following steps describe how to create a class representing a polynomial and implement differentiation and integration methods for this class:
- Let's start by defining a simple class to represent a polynomial:
class Polynomial:
"""Basic polynomial class"""
def __init__(self, coeffs):
self.coeffs = coeffs
def __repr__(self):
return f"Polynomial({repr(self.coeffs)})"
def __call__(self, x):
return sum(coeff*x**i for i, coeff
in enumerate(self.coeffs))
- Now that we have defined a basic class for a polynomial, we can move on to implement the differentiation and integration operations for this Polynomial class to illustrate how these operations change polynomials. We start with differentiation. We generate new coefficients by multiplying each element in the current list of coefficients without the first element. We use this new list of coefficients to create a new Polynomial instance that is returned:
def differentiate(self):
"""Differentiate the polynomial and return the derivative"""
coeffs = [i*c for i, c in enumerate(self.coeffs[1:], start=1)]
return Polynomial(coeffs)
- To implement the integration method, we need to create a new list of coefficients containing the new constant (converted to a float for consistency) given by the argument. We then add to this list of coefficients the old coefficients divided by their new position in the list:
def integrate(self, constant=0):
"""Integrate the polynomial, returning the integral"""
coeffs = [float(constant)]
coeffs += [c/i for i, c in enumerate(self.coeffs, start=1)]
return Polynomial(coeffs)
- Finally, to make sure these methods work as expected, we should test these two methods with a simple case. We can check this using a very simple polynomial, such as x2 - 2x + 1:
p = Polynomial([1, -2, 1])
p.differentiate()
# Polynomial([-2, 2])
p.integrate(constant=1)
# Polynomial([1.0, 1.0, -1.0, 0.3333333333])
How it works...
Polynomials offer an easy introduction to the basic operations of calculus, but it isn't so easy to construct Python classes for other general classes of functions. That being said, polynomials are extremely useful because they are well understood and, perhaps more importantly, calculus for polynomials is very easy. For powers of a variable x, the rule for differentiation is to multiply by the power and reduce the power by 1, so that xn becomes nxn-1.
Integration is more complex, since the integral of a function is not unique. We can add any constant to an integral and obtain a second integral. For powers of a variable x, the rule for integration is to increase the power by 1 and divide by the new power, so that xn becomes xn+1/(n+1), so to integrate a polynomial, we increase each power of x by 1 and divide the corresponding coefficient by the new power.
The Polynomial class that we defined in ...