SigmaField
Mathematical Foundations for Quant Finance
0 of 256 lessons
      1. 2.8.1 Finite differences and their errorsConcept · 35 min
      2. 2.8.2 Trapezoid and Simpson rulesConcept · 35 min
      3. 2.8.3 Practice set: numerical calculusPractice set · 20 min
      4. 2.8.4 Case study: bump-and-reprice GreeksCase study · 35 min

Level 2, Single-variable calculus 2.8 Numerical calculus Lesson 3 of 4

Practice setLesson 2.8.3 in Level 2, Single-variable calculus. About 20 minutes.

Practice set: numerical calculus

Finite differences and their errors

Finite differences and their errors (lesson 2.8.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.

Trapezoid and Simpson rules

Trapezoid and Simpson rules (lesson 2.8.2)

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.

Coding exercise

Exercise

A derivative that picks its step, and Simpson's rule

Write three functions, using lessons 2.8.1 and 2.8.2. EPS in the starter is the machine epsilon ε\varepsilon.

  1. central_diff(f, x, h=None) returns the central difference f(x+h)−f(x−h)2h\frac{f(x + h) - f(x - h)}{2h}. When h is None, use the default step ε1/3max⁡(∣x∣,1)\varepsilon^{1/3}\max(|x|, 1).
  2. second_diff(f, x, h=None) returns the second difference f(x+h)−2f(x)+f(x−h)h2\frac{f(x + h) - 2f(x) + f(x - h)}{h^2}. When h is None, use ε1/4max⁡(∣x∣,1)\varepsilon^{1/4}\max(|x|, 1).
  3. simpson(f, a, b, n) returns Simpson's rule with n strips. Raise ValueError unless n is even and at least 2.

The tests include x\sqrt{x} at 10610^6 and ln⁡x\ln x at 10410^4, where a fixed step such as 10−510^{-5} fails. They also check that Simpson's error shrinks about 16 times when the strips double, and that a reversed interval gives a negative answer.

See the tests
import math


def test_central_exp():
    """With the default step, the slope of eˣ at 1 is e to about 10 digits"""
    expect_close(central_diff(math.exp, 1.0), math.e, what="central_diff(math.exp, 1.0)", rel=1e-9)


def test_central_given_step():
    """A step you pass is used as it is: x² at 3 with h = 0.5 gives exactly 6"""
    expect_close(central_diff(lambda x: x**2, 3.0, h=0.5), 6.0, what="central_diff(x², 3, h=0.5)", rel=1e-12)


def test_central_scales_with_x():
    """The default step grows with x: the slope of √x at 10⁶ is 0.0005 to about 10 digits"""
    expect_close(central_diff(math.sqrt, 1e6), 0.0005, what="central_diff(math.sqrt, 1e6)", rel=1e-10)


def test_central_at_zero():
    """At x = 0 the default step is still sensible: the slope of sin x at 0 is 1"""
    expect_close(central_diff(math.sin, 0.0), 1.0, what="central_diff(math.sin, 0.0)", rel=1e-9)


def test_second_exp():
    """With the default step, the second derivative of eˣ at 1 is e to about 7 digits"""
    expect_close(second_diff(math.exp, 1.0), math.e, what="second_diff(math.exp, 1.0)", rel=1e-7)


def test_second_scales_with_x():
    """The default second-difference step grows with x: ln x at 10⁴ has f'' = −10⁻⁸"""
    expect_close(second_diff(math.log, 1e4), -1e-8, what="second_diff(math.log, 1e4)", rel=1e-5)


def test_simpson_cubic_exact():
    """Simpson's rule is exact for a cubic: x³ on [0, 2] with 2 strips gives 4"""
    expect_close(simpson(lambda x: x**3, 0.0, 2.0, 2), 4.0, what="simpson(x³, 0, 2, 2)", rel=1e-12)


def test_simpson_recip():
    """1/x on [1, 2] with 10 strips gives 0.6931502307, close to ln 2"""
    expect_close(simpson(lambda x: 1 / x, 1.0, 2.0, 10), 0.6931502306889303, what="simpson(1/x, 1, 2, 10)", rel=1e-12)


def test_simpson_order():
    """Doubling the strips cuts the error about 16 times: eˣ on [0, 1] with 8 and 16 strips"""
    exact = math.e - 1
    e8 = abs(simpson(math.exp, 0.0, 1.0, 8) - exact)
    e16 = abs(simpson(math.exp, 0.0, 1.0, 16) - exact)
    assert 14 < e8 / e16 < 18, f"expected the error to shrink about 16 times, but it shrank {e8 / e16:.2f} times"


def test_simpson_reversed():
    """A reversed interval gives the negative: sin x from π to 0 with 20 strips is about −2"""
    expect_close(simpson(math.sin, math.pi, 0.0, 20), -2.0, what="simpson(sin, π, 0, 20)", rel=1e-5)


def test_simpson_odd():
    """An odd number of strips raises ValueError"""
    try:
        simpson(lambda x: x**2, 0.0, 1.0, 3)
    except ValueError:
        return
    raise AssertionError("expected ValueError for 3 strips: Simpson's rule pairs the strips")


def test_simpson_zero_strips():
    """Zero strips raises ValueError"""
    try:
        simpson(lambda x: x**2, 0.0, 1.0, 0)
    except ValueError:
        return
    raise AssertionError("expected ValueError for 0 strips")

Free further reading

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