SigmaField
Mathematical Foundations for Quant Finance
0 of 256 lessons
      1. 6.5.1 The explicit scheme and stabilityConcept · 35 min
      2. 6.5.2 Implicit schemes and Crank–NicolsonConcept · 35 min
      3. 6.5.3 Practice set: finite differencesPractice set · 20 min
      4. 6.5.4 Case study: pricing a European option on a gridCase study · 35 min

Level 6, Differential equations 6.5 Finite differences for PDEs Lesson 1 of 4

ConceptLesson 6.5.1 in Level 6, Differential equations. About 35 minutes.

The explicit scheme and stability

A problem with a known answer

The heat equation of lesson 6.4.1 is ut=uxxu_t = u_{xx}. Here u(x,t)u(x, t) is the temperature at position xx and time tt. utu_t is its rate of change in time, and uxxu_{xx} its second partial derivative in xx.

Take a rod from x=0x = 0 to x=1x = 1 whose ends are held at temperature 0, and start it with the profile sin⁡(πx)\sin(\pi x). These are one initial condition and two boundary conditions, as in lesson 6.3.2. The solution is known:

u(x,t)=e−π2tsin⁡(πx)u(x, t) = e^{-\pi^2 t}\sin(\pi x)

It is lesson 6.4.1's decaying wave e−k2tsin⁡kxe^{-k^2t}\sin kx with k=πk = \pi. Check it by computing partials, as lesson 6.3.1 does: differentiating in tt gives ut=−π2e−π2tsin⁡(πx)u_t = -\pi^2 e^{-\pi^2 t}\sin(\pi x), and differentiating twice in xx gives the same. The profile keeps its shape and shrinks: at t=0.1t = 0.1 the middle value is e−0.1π2≈0.372708e^{-0.1\pi^2} \approx 0.372708.

Most problems have no formula like this. A finite-difference scheme finds the solution approximately, from numbers alone, and this exact answer lets you measure how well it does.

The grid

Split the rod into MM equal cells of width Δx=1M\Delta x = \frac{1}{M}, and time into steps of length Δt\Delta t. The grid points are xi=i Δxx_i = i\,\Delta x for i=0,1,…,Mi = 0, 1, \ldots, M, and the times are tn=n Δtt_n = n\,\Delta t for n=0,1,2,…n = 0, 1, 2, \ldots

Rule: A grid for u(x, t)

xi=i Δx,tn=n Δtuin≈u(xi,tn)\begin{gathered} x_i = i\,\Delta x, \quad t_n = n\,\Delta t \\[4pt] u_i^n \approx u(x_i, t_n) \end{gathered}

uinu_i^n is the scheme's value at point ii and time step nn. The upper index nn counts time steps; it is not a power. The bottom row ui0u_i^0 is the initial condition, and the two end columns u0nu_0^n and uMnu_M^n are the boundary values.

The grid for ut=uxxu_t = u_{xx} on a rod: the initial condition fills the bottom row and the boundary conditions fill the end columns. One step of the explicit scheme takes three neighbouring values at one time and gives the middle value one step later.

The explicit update

Replace each derivative in ut=uxxu_t = u_{xx} by a difference of grid values, both at time tnt_n.

  • Time: the forward difference of lesson 2.2.2, ut≈uin+1−uinΔtu_t \approx \frac{u_i^{n+1} - u_i^n}{\Delta t}. Lesson 2.8.1 gave its error: about 12utt Δt\frac{1}{2}u_{tt}\,\Delta t.
  • Space: the second difference of lesson 2.4.2, uxx≈ui+1n−2uin+ui−1nΔx2u_{xx} \approx \frac{u_{i+1}^n - 2u_i^n + u_{i-1}^n}{\Delta x^2}, with error about 112uxxxx Δx2\frac{1}{12}u_{xxxx}\,\Delta x^2 (lesson 2.8.1).

Set the two equal and solve for the one value at the new time:

Rule: The explicit scheme

uin+1=uin+r(ui+1n−2uin+ui−1n)r=ΔtΔx2\begin{gathered} u_i^{n+1} = u_i^n + r\left(u_{i+1}^n - 2u_i^n + u_{i-1}^n\right) \\[6pt] r = \frac{\Delta t}{\Delta x^2} \end{gathered}

Each new value is the old one plus rr times its second difference. So it rises where the profile bends up and falls where it bends down, as heat does (lesson 6.4.1). The scheme is explicit: each new value comes straight from old ones.

This is the step lesson 6.4.1's cell took, with Δx=0.05\Delta x = 0.05 and Δt=0.0005\Delta t = 0.0005, so r=0.2r = 0.2. This lesson asks how large rr may be, and how the error depends on the grid.

rr is a pure number here, because ut=uxxu_t = u_{xx} measures time in units of distance squared. For an equation ut=a uxxu_t = a\,u_{xx} with a constant a>0a > 0, the same steps give r=a ΔtΔx2r = \frac{a\,\Delta t}{\Delta x^2}.

One step by hand

Take M=4M = 4 cells, so Δx=0.25\Delta x = 0.25, and r=0.25r = 0.25, so Δt=r Δx2=0.015625\Delta t = r\,\Delta x^2 = 0.015625. Start from sin⁡(πx)\sin(\pi x) on the grid and apply the update at the three inside points:

xix_i00.250.50.751
start, ui0u_i^000.707110.70710
second difference−0.4142-0.4142−0.5858-0.5858−0.4142-0.4142
one step, ui1u_i^100.60360.85360.60360
exact at t=0.015625t = 0.01562500.60610.85710.60610

At the middle, u21=1+0.25×(−0.5858)=0.8536u_2^1 = 1 + 0.25 \times (-0.5858) = 0.8536. The ends stay at 0: they are boundary values, not updated.

Every inside value shrank by the same factor, 0.8536, so the scheme keeps the sine's shape. The exact solution shrinks by e−π2Δt≈0.8571e^{-\pi^2\Delta t} \approx 0.8571 in the same time, so the scheme cools the rod slightly too fast.

That common factor is no accident. The second difference of a sine on the grid is a fixed multiple of the sine, so each step multiplies it by g=1−4rsin⁡2(πΔx/2)g = 1 - 4r\sin^2(\pi\Delta x/2). Here that is 1−sin⁡2(π/8)≈0.85361 - \sin^2(\pi/8) \approx 0.8536.

Try it

The grid is np.linspace(0, 1, M + 1), which includes both ends. One line does the update for every inside point at once: u[2:] are the right neighbours, u[:-2] the left ones.

The cell prints the start, the second differences, the step, the exact values and the factor gg.

⌘/Ctrl + Enter runs the cell

Boundary values

The update needs a neighbour on each side, so it runs only at the inside points i=1,…,M−1i = 1, \ldots, M - 1. At every step the two ends are set by the boundary conditions instead. In code, updating u[1:-1] leaves u[0] and u[-1] alone.

Hold the left end at 0 and the right end at 1, and start with 0 everywhere inside. Take M=10M = 10 and r=0.4r = 0.4, so Δt=0.004\Delta t = 0.004.

  • After one step only the point next to the hot end has changed: u9=0+0.4×(1−0+0)=0.4u_9 = 0 + 0.4 \times (1 - 0 + 0) = 0.4.
  • After two steps, u9=0.48u_9 = 0.48 and u8=0.16u_8 = 0.16. Heat enters one cell per step.
  • After 25 steps (t=0.1t = 0.1) the middle value is 0.2674; after 125 steps (t=0.5t = 0.5) it is 0.4957.

The profile settles on the straight line u=xu = x between the two end values. There uxx=0u_{xx} = 0, so nothing changes any more: a steady state. At t=1t = 1 the scheme is within 2.91×10−52.91 \times 10^{-5} of the line everywhere.

Try it

explicit runs the update for a number of steps. The ends of u are never touched, so they keep the boundary values they start with.

The loop prints the steps, the profile and its largest distance from the line u=xu = x, at four times.

⌘/Ctrl + Enter runs the cell

Stability: r at most one half

A larger rr means a longer time step and fewer steps to reach a given time. But rr cannot be as large as you like. Gather the terms of the update by grid value:

uin+1=r ui−1n+(1−2r) uin+r ui+1nu_i^{n+1} = r\,u_{i-1}^n + (1 - 2r)\,u_i^n + r\,u_{i+1}^n

The three weights add up to 1. When r≤12r \le \frac{1}{2}, none is negative, so each new value is an average of old ones and lies between them: nothing can grow. When r>12r > \frac{1}{2}, the middle weight is negative.

The zig-zag

A zig-zag is a profile whose grid values alternate: +1,−1,+1,−1+1, -1, +1, -1, and so on. At a point with value −1-1, the second difference is 1−2(−1)+1=41 - 2(-1) + 1 = 4; at a point with value +1+1 it is −4-4. So it is −4-4 times the value everywhere, and one step multiplies the whole zig-zag by 1−4r1 - 4r.

rr0.250.40.50.550.6
factor 1−4r1 - 4r0−0.6-0.6−1-1−1.2-1.2−1.4-1.4

For r<12r < \frac{1}{2} the factor lies between −1-1 and 1, so the zig-zag dies away. At r=12r = \frac{1}{2} it flips sign each step but keeps its size. Above 12\frac{1}{2} it flips sign and grows, by 1.4 times per step at r=0.6r = 0.6.

A corner in the profile contains a little of every wave the grid can hold, the zig-zag included, and so does rounding error. So above 12\frac{1}{2} there is always a zig-zag to grow.

Rule: Stability of the explicit scheme

r=ΔtΔx2≤12that is, Δt≤12Δx2\begin{gathered} r = \frac{\Delta t}{\Delta x^2} \le \frac{1}{2} \\[6pt] \text{that is, } \Delta t \le \tfrac{1}{2}\Delta x^2 \end{gathered}

A scheme is stable if errors do not grow from step to step. The zig-zag is the fastest wave a grid can hold and the first to grow, so this limit on rr is the whole condition. It is stated here, not proved.

Start from a tent with a corner at the middle, min⁡(x,1−x)\min(x, 1 - x), on M=20M = 20 cells. Here is the largest value ∣ui∣|u_i| after each number of steps:

steps1020304050
r=0.4r = 0.40.38750.34070.30480.27450.2481
r=0.5r = 0.50.3770.32380.28330.24940.2201
r=0.55r = 0.550.38790.40220.72232.64113.31
r=0.6r = 0.60.46052.32547.93118930,370

The tent starts at 0.5 and should only cool. For r≤12r \le \frac{1}{2} it does; above, the values explode. After 20 steps at r=0.6r = 0.6, the seven values around the corner are −1.2909-1.2909, 2.0903, −1.6636-1.6636, 2.3253, −1.6636-1.6636, 2.0903 and −1.2909-1.2909: a zig-zag.

Try it

The first lines check the zig-zag: its second difference, and one step at r=0.6r = 0.6, which turns ±1\pm 1 into ∓1.4\mp 1.4 away from the ends.

The loop builds the tent table. The last line prints the values around the corner after 20 steps at r=0.6r = 0.6.

⌘/Ctrl + Enter runs the cell

The explorer runs the scheme on a kink, max⁡(x,0)\max(x, 0), with its ends held, beside the exact solution. Set the time to 0.5 and pick the rr presets in turn. At 0.25 and 0.5 the dots sit on the curve; at 0.55 a zig-zag appears at the corner.

At 0.6 the zig-zag swamps everything. Finally, at r=0.55r = 0.55, move the cells from 30 to 60 and watch it blow up sooner.

Explore

The scheme updates each grid value from its two neighbours, with r = Δt/Δx². Keep r at or below 1/2 and it follows the exact curve; push r past 1/2 and the error grows from step to step until it swamps the answer.

−2020123

Dashed: the profile at time 0. Dark: the exact solution. Dots: the scheme on its grid.

Grid
Δx = 0.2, Δt = r Δx² = 0.016, 6 steps to t = 0.096
Largest error
0.002

The price of stability

The limit ties the time step to the square of the space step. Halve Δx\Delta x and the largest stable Δt\Delta t falls 4 times. Reaching the same time then takes 4 times as many steps, each with twice as many points.

cells MM101001,000
largest Δt\Delta t0.0055×10−55 \times 10^{-5}5×10−75 \times 10^{-7}
steps to t=0.1t = 0.1202,000200,000

Lesson 6.5.2 removes this limit with schemes that are stable for every rr.

The error as the grid gets finer

Back to the sine, whose exact solution is known. Keep r=0.4r = 0.4, run to t=0.1t = 0.1, and measure the largest error over the grid:

cells MMΔx\Delta xΔt\Delta tstepslargest errorerror ratio
100.10.004254.294×10−34.294 \times 10^{-3}
200.050.0011001.063×10−31.063 \times 10^{-3}4.04
400.0250.000254002.649×10−42.649 \times 10^{-4}4.01
800.01250.00006251,6006.620×10−56.620 \times 10^{-5}4.00

Each halving of Δx\Delta x divides the error by 4, so the error shrinks like Δx2\Delta x^2. The two parts of lesson 2.8.1's error explain it. The time error, about 12utt Δt\frac{1}{2}u_{tt}\,\Delta t, equals r2utt Δx2\frac{r}{2}u_{tt}\,\Delta x^2 once Δt=r Δx2\Delta t = r\,\Delta x^2; the space error is about 112uxxxx Δx2\frac{1}{12}u_{xxxx}\,\Delta x^2.

Rule: Error of the explicit scheme

error≈C1 Δt+C2 Δx2with r fixed: ∝Δx2\begin{gathered} \text{error} \approx C_1\,\Delta t + C_2\,\Delta x^2 \\[4pt] \text{with } r \text{ fixed: } \propto \Delta x^2 \end{gathered}

C1C_1 and C2C_2 depend on the solution, not on the grid. The scheme is first order in time and second order in space. With rr fixed, halving Δx\Delta x cuts the error about 4 times and costs about 8 times the work.

Stability and accuracy are different questions. Stability says the errors do not grow; the step sizes say how large they are to begin with.

Try it

For each grid the cell runs the sine to t=0.1t = 0.1 with r=0.4r = 0.4. It prints the steps, the largest error and its ratio to the previous one.

round(0.1 / dt) makes the number of steps a whole number; here each one is exact.

⌘/Ctrl + Enter runs the cell

Case study 6.5.4 uses these ideas on the Black–Scholes equation, with the improved schemes of lesson 6.5.2.

Common mistakes

  1. Halving Δx\Delta x but keeping Δt\Delta t. That multiplies rr by 4: a stable r=0.4r = 0.4 becomes 1.61.6, and the answer explodes. Cut Δt\Delta t by 4 too.
  2. Using Δx\Delta x instead of Δx2\Delta x^2 in rr. With Δx=0.1\Delta x = 0.1 and Δt=0.004\Delta t = 0.004, rr is 0.4, not 0.04.
  3. Updating in place in a loop. Computing u[i] from a u[i - 1] already changed this step gives a different scheme. Keep the old values until every new one is made; the slice line does this.
  4. Updating the ends. The end values come from the boundary conditions, not from the update.
  5. Reading uinu_i^n as a power. The upper index nn counts time steps.
  6. Taking stable for accurate. At r≤12r \le \frac{1}{2} errors do not grow, but a coarse grid still has large ones.

The explicit scheme

0 of 12 correct

  1. 1.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
  9. 9.
  10. 10.
  11. 11.
  12. 12.
How to type answers
  • Powers with ^: x^7, 2^(1/3), a^-2.
  • Multiply with * or by writing side by side: 3x^2, 2(x+1).
  • ln(x) is the natural log, log(x, 2) is log base 2, e is Euler's number, sqrt(x) is a square root.
  • sin(x), cos(x) and tan(x) take radians; write pi for π and sin(x)^2 for sin²x.
  • Your first answer to each question is saved: it counts towards your score and brings the question back for review.
  • Exact answers like ln(20)/ln(3) are best. Decimals need about 4 significant figures.

Summary card

  • A grid has points xi=i Δxx_i = i\,\Delta x and times tn=n Δtt_n = n\,\Delta t; uinu_i^n approximates u(xi,tn)u(x_i, t_n). The bottom row is the initial condition, the end columns the boundary values.
  • The explicit scheme for ut=uxxu_t = u_{xx}: uin+1=uin+r(ui+1n−2uin+ui−1n)u_i^{n+1} = u_i^n + r(u_{i+1}^n - 2u_i^n + u_{i-1}^n) with r=ΔtΔx2r = \frac{\Delta t}{\Delta x^2}, at the inside points only.
  • It is stable for r≤12r \le \frac{1}{2}: then each new value is an average of old ones. Above, a zig-zag grows by ∣1−4r∣|1 - 4r| per step until it swamps the answer.
  • Its error is about C1 Δt+C2 Δx2C_1\,\Delta t + C_2\,\Delta x^2: with rr fixed, halving Δx\Delta x cuts it 4 times, but the stability limit makes fine grids expensive.

Free further reading

Optional. This lesson covers what you need; these add more examples and practice. All are free to read.