SigmaField
Mathematical Foundations for Quant Finance
0 of 256 lessons
      1. 6.3.1 What a partial differential equation isConcept · 30 min
      2. 6.3.2 Initial, boundary and terminal conditionsConcept · 30 min
      3. 6.3.3 Practice set: partial differential equationsPractice set · 20 min
      4. 6.3.4 Case study: an option value fixed by its payoffCase study · 35 min

Level 6, Differential equations 6.3 PDE basics Lesson 3 of 4

Practice setLesson 6.3.3 in Level 6, Differential equations. About 20 minutes.

Practice set: partial differential equations

Partial differential equations

What a partial differential equation is (lesson 6.3.1)

0 of 10 correct

  1. 1.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
  9. 9.
  10. 10.
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.

Conditions

Initial, boundary and terminal conditions (lesson 6.3.2)

0 of 9 correct

  1. 1.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
  9. 9.
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.

Coding exercise

Exercise

Residuals by central differences

Write two functions that test a candidate solution u(x,t)u(x, t) at one point, as in lesson 6.3.1. Here u is a function of two arguments, u(x, t).

  1. heat_residual(u, x, t, h=1e-4) returns ut−uxxu_t - u_{xx} at (x,t)(x, t). Estimate utu_t by the central difference in tt and uxxu_{xx} by the second difference in xx, with step h.
  2. transport_residual(u, c, x, t, h=1e-5) returns ut+c uxu_t + c\,u_x at (x,t)(x, t), with central differences in tt and in xx.

Raise ValueError if h is not positive.

The tests use the solutions and failures of lesson 6.3.1. They need about six correct digits, which a one-sided difference cannot reach.

See the tests
import math


def test_heat_solution():
    """e⁻ᵗ sin x solves the heat equation: its residual at (1, 0.5) is about 0"""
    r = heat_residual(lambda x, t: math.exp(-t) * math.sin(x), 1.0, 0.5)
    expect_close(r, 0.0, what="heat_residual of e^-t sin x at (1, 0.5)", abs_tol=1e-6)


def test_heat_failure():
    """e⁻ᵗ sin 2x fails: its residual at (1, 0.5) is 3e^(−0.5) sin 2, about 1.654550"""
    r = heat_residual(lambda x, t: math.exp(-t) * math.sin(2 * x), 1.0, 0.5)
    expect_close(r, 3 * math.exp(-0.5) * math.sin(2), what="heat_residual of e^-t sin 2x at (1, 0.5)", rel=1e-6)


def test_heat_polynomial():
    """x² + 2t solves the heat equation: its residual at (3, 2) is about 0"""
    r = heat_residual(lambda x, t: x**2 + 2 * t, 3.0, 2.0)
    expect_close(r, 0.0, what="heat_residual of x^2 + 2t at (3, 2)", abs_tol=1e-5)


def test_heat_frozen():
    """x² does not solve the heat equation: its residual is −2 everywhere"""
    r = heat_residual(lambda x, t: x**2, 0.7, 0.3)
    expect_close(r, -2.0, what="heat_residual of x^2 at (0.7, 0.3)", rel=1e-6)


def test_transport_solution():
    """e^(−(x − 2t)²) solves u_t + 2u_x = 0: its residual at (2.5, 1) is about 0"""
    r = transport_residual(lambda x, t: math.exp(-(x - 2 * t) ** 2), 2, 2.5, 1.0)
    expect_close(r, 0.0, what="transport_residual of the bump with c = 2", abs_tol=1e-7)


def test_transport_wrong_speed():
    """The same bump with c = −2 leaves a residual of about 3.115203 at (2.5, 1)"""
    r = transport_residual(lambda x, t: math.exp(-(x - 2 * t) ** 2), -2, 2.5, 1.0)
    expect_close(r, 4 * math.exp(-0.25), what="transport_residual of the bump with c = -2", rel=1e-6)


def test_transport_wrong_direction():
    """(x + 2t)² moves left: with c = 2 its residual at (1, 1) is 8x + 16t = 24"""
    r = transport_residual(lambda x, t: (x + 2 * t) ** 2, 2, 1.0, 1.0)
    expect_close(r, 24.0, what="transport_residual of (x + 2t)^2 with c = 2", rel=1e-6)


def test_bad_step():
    """A step that is zero or negative raises ValueError in both functions"""
    for name, call in [("heat_residual", lambda: heat_residual(lambda x, t: x, 1.0, 1.0, h=0)),
                       ("transport_residual", lambda: transport_residual(lambda x, t: x, 1, 1.0, 1.0, h=-1e-5))]:
        try:
            call()
        except ValueError:
            continue
        raise AssertionError(f"{name} should raise ValueError for a step that is not positive")

Free further reading

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