8.2. Understanding Ordinary Differential Equations - Direction Fields#
For a first order ODE of the form:
we can actually interpret the ODE. We know that the derivative \(\dot{y}(t)\) is the slope of \(y(t)\) at a given point \((t, y)\). For a solution to the ODE, that passes through the point \((t, y)\), the slope of the solution at that point is given by \(f(t, y)\):
Using this fact we can use the ODE for a plot that shows directions of solution curves. This is called a direction field, which is a plot of the slope of the solution at different points in the \(t-y\) plane. We can just evaluate \(f(t, y)\) at different points in the \(t-y\) plane and plot the slope at each point using small arrows corresponding to the slope at each point.
Example 1#
Let’s look at the ODE we had in the previous section:
We actually know the General solution to this ODE, which is:
where \(c\) is an arbitrary constant. We also derive the particular solution by solving for \(c\) given the initial condition \(y(0) = 0\):
which is the solution:
Now let’s plot the direction field for this ODE:
import Pkg
Pkg.instantiate()
# load the neccessary packages
using Plots
deltat = 0.3
min = 0
max = 6
t = range(min, max, step=deltat)
y = range(min, max, step=deltat)
# rectangular grid with points
T = repeat(t', length(y), 1)
Y = repeat(y, 1, length(t))
# Define the differential equation dy/dt = cos(t)
dy = cos.(T)
dt = ones(size(dy))
# Plot the direction field
quiver(T, Y, quiver=(dt ./ 10, dy ./ 10), color=:blue, xlims=(min, max), ylims=(min, max), xlabel="t", ylabel="y", title="Direction field of dy/dt = t+y")
# Solution for y(0) = 0 -> y(t) = sin(t)
plot!(t, sin.(t), color=:red, label="y(t) = sin(t)")
# Solution for y(0) = 1 -> y(t) = sin(t) + 1
plot!(t, sin.(t) .+ 1, color=:green, label="y(t) = sin(t) + 1")
# Solution for y(0) = 2 -> y(t) = sin(t) + 2
plot!(t, sin.(t) .+ 2, color=:orange, label="y(t) = sin(t) + 2")
# Solution for y(0) = 3 -> y(t) = sin(t) + 3
plot!(t, sin.(t) .+ 3, color=:purple, label="y(t) = sin(t) + 3")
# Solution for y(0) = 4 -> y(t) = sin(t) + 4
plot!(t, sin.(t) .+ 4, color=:black, label="y(t) = sin(t) + 4")
# Solution for y(0) = 5 -> y(t) = sin(t) + 5
plot!(t, sin.(t) .+ 5, color=:brown, label="y(t) = sin(t) + 5")
Example 2#
Let’s plot the direction field and some solutions for another simple ODE:
# call this only once to install the package
using Pkg
Pkg.add("OrdinaryDiffEq")
Resolving package versions...
No Changes to `~/.julia/environments/v1.9/Project.toml`
No Changes to `~/.julia/environments/v1.9/Manifest.toml`
# This file implements a way to numerically solve the ODE problem using a method we will learn later.
include("./GiveODESolution.jl")
using .GiveODESolution
deltat = 0.3
t = range(-3, 3, step=deltat)
y = range(-3, 3, step=deltat)
# rectangular grid with points
T = repeat(t', length(y), 1)
Y = repeat(y, 1, length(t))
# Define the differential equation dy/dt = t+y
dy = T .+ Y
dt = ones(size(dy))
# Plot the direction field
quiver(T, Y, quiver=(dt ./ 10, dy ./ 10), color=:blue, xlims=(-3, 3), ylims=(-3, 3), xlabel="t", ylabel="y", title="Direction field of dy/dt = t+y")
# Get the solution for different initial conditions, we will understand this later
sol_1 = get_solution(1.0)
sol_2 = get_solution(1.8)
sol_3 = get_solution(2.0)
sol_4 = get_solution(2.2)
sol_5 = get_solution(2.5)
# Plot the solutions
plot!(sol_1, lw=2, label="Solution for y_0 = 1.0")
plot!(sol_2, lw=2, label="Solution for y_0 = 1.8")
plot!(sol_3, lw=2, label="Solution for y_0 = 2.0")
plot!(sol_4, lw=2, label="Solution for y_0 = 2.2")
plot!(sol_5, lw=2, label="Solution for y_0 = 2.5")
We can see that direction fields can help us understand the behavior of a given ODE and visualize different possible solutions for different initial conditions. In the next section wel will look at the Euler method for numerically solving ODEs and we will use the direction field to better understand the method.