Scalar ordinary differential equations
Examples on right-hand-side functions
The Forward Euler scheme
Function implementation
Verifying the implementation
From discrete to continuous solution
Switching numerical method
Class implementation
Logistic growth via a function-based approach
Logistic growth via a class-based approach
Systems of ordinary differential equations
Mathematical problem
Example of a system of ODEs
Function implementation
Class implementation
The ODESolver class hierarchy
Numerical methods
Construction of a solver hierarchy
The Backward Euler method
Verification
Example: Exponential decay
Example: The logistic equation with problem and solver classes
Example: An oscillating system
Application 4: the trajectory of a ball
Further developments of ODESolver
Exercises
Exercise 1: Solve a simple ODE with function-based code
Exercise 2: Solve a simple ODE with class-based code
Exercise 3: Solve a simple ODE with the ODEsolver hierarchy
Exercise 4: Solve an ODE specified on the command line
Exercise 5: Implement a numerical method for ODEs
Exercise 6: Solve an ODE for emptying a tank
Exercise 7: Solve an ODE for the arc length
Exercise 8: Simulate a falling or rising body in a fluid
Exercise 9: Verify the limit of a solution as time grows
Exercise 10: Scale the logistic equation
Exercise 11: Compute logistic growth with time-varying carrying capacity
Exercise 12: Solve an ODE until constant solution
Exercise 13: Use a problem class to hold data about an ODE
Exercise 14: Derive and solve a scaled ODE problem
Exercise 15: Clean up a file to make it a module
Exercise 16: Simulate radioactive decay
Exercise 17: Compute inverse functions by solving an ODE
Exercise 18: Make a class for computing inverse functions
Exercise 19: Add functionality to a class
Exercise 20: Compute inverse functions by interpolation
Exercise 21: Code the 4th-order Runge-Kutta method; function
Exercise 22: Code the 4th-order Runge-Kutta method; class
Exercise 23: Compare ODE methods
Exercise 24: Code a test function for systems of ODEs
Exercise 25: Code Heun's method for ODE systems; function
Exercise 26: Code Heun's method for ODE systems; class
Exercise 27: Implement and test the Leapfrog method
Exercise 28: Implement and test an Adams-Bashforth method
Exercise 29: Solve two coupled ODEs for radioactive decay
Exercise 30: Implement a 2nd-order Runge-Kutta method; function
Exercise 31: Implement a 2nd-order Runge-Kutta method; class
Exercise 32: Code the iterated midpoint method; function
Exercise 33: Code the iterated midpoint method; class
Exercise 34: Make a subclass for the iterated midpoint method
Exercise 35: Compare the accuracy of various methods for ODEs
Exercise 36: Animate how various methods for ODEs converge
Exercise 37: Study convergence of numerical methods for ODEs
Exercise 38: Find a body's position along with its velocity
Exercise 39: Add the effect of air resistance on a ball
Exercise 40: Solve an ODE system for an electric circuit
Exercise 41: Simulate the spreading of a disease by a SIR model
Exercise 42: Introduce problem and solver classes in the SIR model
Exercise 43: Introduce vaccination in a SIR model
Exercise 44: Introduce a vaccination campaign in a SIR model
Exercise 45: Find an optimal vaccination period
Exercise 46: Simulate human-zombie interaction
Exercise 47: Simulate a zombie movie
Exercise 48: Simulate a war on zombies
Exercise 49: Explore predator-prey population interactions
Exercise 50: Formulate a 2nd-order ODE as a system
Exercise 51: Solve \( \ddot u + u =0 \)
Exercise 52: Make a tool for analyzing oscillatory solutions
Exercise 53: Implement problem, solver, and visualizer classes
Exercise 54: Use classes for flexible choices of models
Exercise 55: Apply software for oscillating systems
Exercise 56: Model the economy of fishing
References
We shall in the present document view differential equations from an abstract point of view, which allows us to formulate numerical methods and create general software that are applicable to a large family of widely different differential equation problems from mathematics, physics, biology, and finance. More specifically, the abstract view is motivated by the slogan implement once, apply anywhere. This principle is the dominating strategy for implementing differentiation (\( f'(x) \) and \( f''(x) \)), integration (\( \int_a^b f(x)dx \)), and root finding (\( f(x)=0 \)). In the mentioned applications, we work with a general function \( f(x) \) so that any problem can be solved by the same piece of code as long as we can define the problem in terms of a function \( f(x) \). This is an excellent demonstration of the power of mathematics, and this abstract view of problems in terms of some \( f(x) \) is especially powerful in numerical methods and programming. Now we shall formulate differential equations on the abstract form \( u^{\prime}=f(u,t) \) and create software that can solve any equation for which the \( f(u,t) \) is given.
Before studying the present document, the reader should have some
familiarity with differential equations
and basic numerical methods for their solution.
Only fundamental programming skills regarding loops, lists, arrays, functions,
if
tests, command-line arguments, and curve plotting
are required for the basic function-based
material in this document. However, the sections Class implementation and
Class implementation,
as well as many exercises, use classes to a large
extent and hence demand familiarity with the class
concept.
The material on object-oriented programming in
the section The ODESolver class hierarchy requires good knowledge of class
hierarchies and
inheritance.
All computer codes associated with this document is found in src/ode2.
This chapter is taken from the book A Primer on Scientific Programming with Python by H. P. Langtangen, 5th edition, Springer, 2016.