SigmaField
Mathematical Foundations for Quant Finance
0 of 256 lessons
      1. 6.2.1 Constant coefficients and the characteristic equationConcept · 35 min
      2. 6.2.2 General solutions and boundary conditionsConcept · 35 min
      3. 6.2.3 Practice set: second-order equationsPractice set · 20 min
      4. 6.2.4 Case study: the perpetual American putCase study · 35 min

Level 6, Differential equations 6.2 Second-order linear ODEs Lesson 3 of 4

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

Practice set: second-order equations

The characteristic equation

Constant coefficients and the characteristic equation (lesson 6.2.1)

0 of 8 correct

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

General solutions and boundary conditions

General solutions and boundary conditions (lesson 6.2.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

Solving any constant-coefficient equation

Write ivp_solution(a, b, c, y0, v0, t). It returns y(t)y(t) for the solution of ay′′+by′+cy=0ay'' + by' + cy = 0 with y(0)=y0y(0) = y_0 and y′(0)=v0y'(0) = v_0, by the formulas of lessons 6.2.1 and 6.2.2. t may be a number or a NumPy array.

  • Decide the case from the discriminant b2−4acb^2 - 4ac, then write the general solution of that case.
  • Fix c1c_1 and c2c_2 from y0y_0 and v0v_0 (lesson 6.2.2). In the complex case, remember that eαte^{\alpha t} adds to the slope.
  • Raise ValueError if a is 0: the equation is then first order.

The tests use the examples of both lessons, an equation with a≠1a \neq 1 in each real case, and a growing solution. They compare your answer with solve_ivp for other coefficients, and check that it starts at y0y_0 with slope v0v_0.

See the tests
import math

import numpy as np
from scipy.integrate import solve_ivp


def _numerical(a, b, c, y0, v0, T):
    sol = solve_ivp(lambda t, s: [s[1], -(b * s[1] + c * s[0]) / a], (0, T), [y0, v0], rtol=1e-12, atol=1e-12)
    return sol.y[0, -1]


def test_two_real_roots():
    """y'' + 5y' + 4y = 0 from y(0) = 1, y'(0) = 0 is 0.484401 at t = 1"""
    expect_close(ivp_solution(1, 5, 4, 1, 0, 1), 0.4844007085990117, what="ivp_solution(1, 5, 4, 1, 0, 1)", rel=1e-9)


def test_repeated_root():
    """y'' + 4y' + 4y = 0 from y(0) = 1, y'(0) = 0 is 3e⁻² at t = 1"""
    expect_close(ivp_solution(1, 4, 4, 1, 0, 1), 3 * math.exp(-2), what="ivp_solution(1, 4, 4, 1, 0, 1)", rel=1e-9)


def test_complex_roots():
    """y'' + 2y' + 5y = 0 from y(0) = 1, y'(0) = 0 is 0.014164 at t = 1"""
    expect_close(ivp_solution(1, 2, 5, 1, 0, 1), 0.01416404894540483, what="ivp_solution(1, 2, 5, 1, 0, 1)", rel=1e-9)


def test_waves():
    """y'' + y = 0 from y(0) = 0, y'(0) = 1 is sin t: sin 2 at t = 2"""
    expect_close(ivp_solution(1, 0, 1, 0, 1, 2), math.sin(2), what="ivp_solution(1, 0, 1, 0, 1, 2)", rel=1e-9)


def test_growth():
    """y'' − y = 0 from y(0) = 1, y'(0) = 0 is (e + 1/e)/2 at t = 1"""
    expect_close(ivp_solution(1, 0, -1, 1, 0, 1), (math.e + 1 / math.e) / 2, what="ivp_solution(1, 0, -1, 1, 0, 1)", rel=1e-9)


def test_leading_coefficient():
    """2y'' + 3y' + y = 0 from y(0) = 1, y'(0) = 1 is −3e⁻² + 4e⁻¹ at t = 2"""
    expect_close(ivp_solution(2, 3, 1, 1, 1, 2), -3 * math.exp(-2) + 4 * math.exp(-1), what="ivp_solution(2, 3, 1, 1, 1, 2)", rel=1e-9)


def test_repeated_with_a():
    """0.5y'' + 2y' + 2y = 0 has a repeated root −2: from y(0) = 1, y'(0) = −1 it is 4e⁻⁶ at t = 3"""
    expect_close(ivp_solution(0.5, 2, 2, 1, -1, 3), 4 * math.exp(-6), what="ivp_solution(0.5, 2, 2, 1, -1, 3)", rel=1e-9)


def test_against_solve_ivp():
    """It agrees with solve_ivp for y'' + 0.3y' + 2.5y = 0 and 3y'' − y' − 2y = 0"""
    for args, T in [((1, 0.3, 2.5, -1, 2), 4), ((3, -1, -2, 0.5, 0.5), 2)]:
        expect_close(ivp_solution(*args, T), _numerical(*args, T), what=f"ivp_solution{args + (T,)}", rel=1e-7)


def test_starts_right():
    """The solution of y'' + y' + 3y = 0 starts at y(0) = 2 with slope −1"""
    h = 1e-6
    expect_close(ivp_solution(1, 1, 3, 2, -1, 0), 2.0, what="y(0)", rel=1e-12)
    slope = (ivp_solution(1, 1, 3, 2, -1, h) - ivp_solution(1, 1, 3, 2, -1, -h)) / (2 * h)
    expect_close(slope, -1.0, what="slope at 0", rel=1e-6)


def test_array():
    """An array of times gives an array of values"""
    t = np.linspace(0, 3, 7)
    got = ivp_solution(1, 2, 5, 1, 0, t)
    assert isinstance(got, np.ndarray) and got.shape == t.shape, f"expected an array of shape {t.shape}, got {got!r}"
    expect_close(got, np.exp(-t) * (np.cos(2 * t) + 0.5 * np.sin(2 * t)), what="values at 0, 0.5, ..., 3", rel=1e-9)


def test_first_order():
    """a = 0 raises ValueError: there is no second derivative"""
    try:
        ivp_solution(0, 1, 2, 1, 0, 1)
    except ValueError:
        return
    raise AssertionError("expected ValueError for a = 0")

Free further reading

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