Unit 6: Meet the Bernoulli numbers

The worked case

44 min: video 10, reading 14, activity 20 page v0.1.0, video v0.1.0
Release candidate. The unit videos are added in the first release.

Video

Unit video

The narrated video for Unit 6, about 10 minutes, is published with the first release.

Learning purpose: Enough mathematics to know what correct output looks like — including the two convention traps that make correct programs disagree.

Accessible text alternative: the transcript linked below, and this page, which covers the same material.

Transcript of the Unit 6 video

The narration is spoken by synthetic voices made for this course, each shown on screen as a drawn robot. No person is speaking.

Watch what changes

Nine bars rise one after another, for 1 squared up to 9 squared, each as tall as its square. A bracket under them marks the question asked: 1 squared plus 2 squared and so on up to 9 squared, which is 285. Below, the formula for squares appears: 0 squared plus 1 squared and so on up to m minus 1 squared equals m cubed plus 3 times B1 times m squared plus 3 times B2 times m, all over 3. Under it the right-hand side is written again and filled in: B1 becomes minus one half, then B2 becomes one sixth, then each m becomes 9. It works out as 729 minus 243 over 2 plus 9 over 2, all over 3, which is 204. The bars are then re-marked with a second bracket: the formula summed 0 squared up to 8 squared, which is 204, not the 1 squared up to 9 squared that was asked. The closing line reads: every step correct, a different question answered. Open diagram at full size (opens in a new tab)

Reading time: about 14 minutes. Activity: about 20 minutes.

1. What you should be able to do afterwards

  1. Say, in plain terms, what a Bernoulli number is and where the sequence comes from.
  2. Derive B4 from the recurrence, by hand, and show your working.
  3. Explain why two correct-looking programs can disagree about B1, and say which convention this course uses.
  4. Translate between Lovelace's Note G labels and modern indices.

2. Why this unit comes before the AI unit

In Unit 7 you will ask an AI system to produce a routine that returns Bernoulli numbers. It will produce something, and what it produces can look competent whether or not it is right.

The question that decides whether that output is useful to you is not "does this look right" but "what should the answer be". If you have nothing independent of the output to answer the second question with — a value you derived, a published table, a separate method — you have no way of answering the first. So this unit gives you the independent answer first, deliberately, before anything is generated.

This ordering is the whole point of the course's approach to critical thinking: build enough understanding to judge, then use the tool.

3. What a Bernoulli number is

The Bernoulli numbers are a fixed sequence of exact rational numbers — ordinary fractions — with one value for each whole-number index from 0 upwards. They are written B0, B1, B2, and so on.

They are not approximations, not estimates, and not a matter of taste. Given the index and the convention (a fixed choice, explained under Trap 1 below), the value is completely determined. That property is what makes them a good subject for this course: there is a right answer, it can be written down exactly, and disagreement can always be resolved.

Here is the sequence this course works with.

n B_n n B_n
0 1 10 5/66
1 -1/2 12 -691/2730
2 1/6 14 7/6
3 0 16 -3617/510
4 derive in the activity 18 43867/798
6 1/42 20 -174611/330
8 shown after your derivation 30 8615841276005/14322

All odd B_n for n > 1 are exactly zero. That is not a rounding artefact or a convenient approximation; those values are zero, precisely.

Two things are worth noticing before you read on. First, the values do not shrink tidily — B14 is larger than B12, and B30 is enormous. Second, the denominators are already awkward by B12. Both facts matter later: a routine that returns decimals can look right at every index and be exact at almost none of them, so only an exact comparison catches it.

4. Where the sequence comes from

You do not need this section to complete the unit. It is here so the numbers do not feel as though they were invented for the exercise.

Ask a simple question: what is 1² + 2² + … + 9²? The answer is 285, and you can get it by adding nine numbers. But there is also a closed formula that gives the answer for any upper limit, without adding anything up. There is another for cubes, another for fourth powers, and so on.

Write those formulas in a single general form covering every power at once, and the same sequence of fractions appears in the coefficients each time. That sequence is the Bernoulli numbers. They were established mathematics well before Note G took them as its example: they appear in Jacob Bernoulli's Ars Conjectandi, published in 1713 [S9], and Note G already calls them "the Numbers of Bernoulli" [P2a]. For sources on Note G itself, see References and source policy.

One detail of that general formula is a preview of Trap 1 below. The reference form writes it through Bernoulli polynomials [M6, sec. 24.4(iii)]; expanded into coefficients with this course's B1 = -1/2, it sums up to one less than the limit you give it. For squares and the limit m it reads

0^2 + 1^2 + ... + (m-1)^2 = (m^3 + 3*B1*m^2 + 3*B2*m) / 3

and with B1 = -1/2, B2 = 1/6 and the limit 9 it gives (729 - 243/2 + 9/2) / 3 = 204, which is 0^2 + 1^2 + ... + 8^2; it returns 285 only for the limit 10. (The form that sums from 1 to the limit needs B1 = +1/2.) Every step of that calculation is correct, and it still answers a different question from the one asked: checking that a procedure was carried out correctly is not checking that it was the right procedure for your question.

5. The rule that generates them

Every Bernoulli number is fixed by the ones before it, through one identity, which holds for every n from 1 on (B0 = 1 is where it starts):

sum_{j=0}^{n} C(n+1, j) * B_j = 0      for n >= 1

Read sum_{j=0}^{n} as "add up one term for each j from 0 to n": the expression after it is written out once with j = 0, once with j = 1, and so on up to j = n, and the terms are added. B_j is the Bernoulli number with index j.

C(n+1, j) is the binomial coefficient — "n plus one choose j" — the numbers from row n+1 of Pascal's triangle. Each row of the triangle begins and ends with 1, and every other number is the sum of the two above it. Its rows are counted from 0, and so are the positions within a row, so C(n+1, j) is the number at position j in row n+1:

row 0:       1
row 1:      1 1
row 2:     1 2 1
row 3:    1 3 3 1

What you need before you start works through this notation more slowly. Row n+1 has n+2 numbers and j stops at n, so its last number is not used: it would multiply B_{n+1}, which the identity for n+1 fixes. For a given n, the identity gives you a sum of terms, all of them known except the last, which contains B_n. Substitute what you know, and solve.

The smallest case is n = 1. Row 2 of Pascal's triangle is 1, 2, 1, and j runs from 0 to 1, so the identity has two terms: 1*B0 + 2*B1 = 0. With B0 = 1, that gives 2*B1 = -1, so B1 = -1/2, the value in the table.

The identity sum over j from 0 to n of n plus 1 choose j, times B_j, equals zero is shown, then taken for n equals 1. Row 2 of Pascal's triangle, 1 2 1, appears, and its first two numbers are marked as the coefficients used, because j runs from 0 to n. Two terms appear: 2 choose 0 times B0, plus 2 choose 1 times B1, equals zero. B0 is replaced by 1, leaving B1 as the one unknown. The working reads 1 plus 2 times B1 equals 0, then 2 times B1 equals minus 1, then B1 equals minus one half, which is boxed. Every term was known except the last; substitute, and solve for it. Open diagram at full size (opens in a new tab)

Starting from B0 = 1, this generates the whole sequence, one value at a time, in a fixed order, with no judgement required at any step. It is an ordered procedure in exactly the sense of Unit 2.

The same identity also works as a check, and checking is the cheaper direction: given a list of claimed values, substitute them all and see whether each row sums to exactly zero. Nothing has to be solved. Unit 8 uses this.

Worked example: B2

Take n = 2. The identity gives three terms:

C(3,0)·B0 + C(3,1)·B1 + C(3,2)·B2 = 0

Row n + 1 = 3 of Pascal's triangle is 1, 3, 3, 1; j runs from 0 to 2, so the coefficients are 1, 3, 3. Substituting B0 = 1 and B1 = -1/2:

(1)(1) + (3)(-1/2) + (3)(B2) = 0

Work the known part first:

1 - 3/2 = -1/2

So:

-1/2 + 3·B2 = 0
        3·B2 = 1/2
          B2 = 1/6

Which is what the table says. Notice what you did not need: a calculator, a computer, or anyone's assurance. You needed the rule, the earlier values, and care with fractions.

In the activity you will do the same for B4, where n = 4 gives five terms instead of three. That is the derivation checkpoint cp06-b4-by-hand, and it is worth doing before you read further into this page. Stop here and attempt Task 1 from your own working. On the course site, the rest of this reading is hidden in a labelled section you open yourself, because it contains the result.

Continue after attempting Task 1 in the activity

6. Trap 1 — there are two conventions

Here is a scenario you will meet in Unit 8. Two programs both claim to compute Bernoulli numbers. They agree on every value except one. One says B1 = -1/2, the other says B1 = +1/2. Everything else — B2 = 1/6, B4 = -1/30, all of it — is identical.

Neither program need have a bug.

There are two established conventions for this sequence:

B0 B1 B2 B4 B6
First Bernoulli numbers 1 -1/2 1/6 -1/30 1/42
Second Bernoulli numbers 1 +1/2 1/6 -1/30 1/42
Headed 'Comparing index by index', two rows of Bernoulli values, the first convention and the second convention, are compared from n=0 to n=6. At n=0 both read 1 and the column is marked same. At n=1 the first convention reads minus one half and the second reads plus one half; the column is outlined in amber and labelled diverges. The later indices agree again and each is marked same: 1/6 at n=2, 0 at n=3, withheld in both rows at n=4, 0 at n=5 and 1/42 at n=6. An amber line reads: the two conventions part at n=1: -1/2 and +1/2. Below it: every other value is identical; they differ in exactly one place. Open diagram at full size (opens in a new tab)

Both are standard, both are published, and they differ in exactly one value. They come from two standard definitions of the sequence. You do not need to follow them; each is a generating function (a function whose power series has the sequence in its coefficients): t/(e^t - 1) gives the first [M6, eq. 24.2.1], and t/(1 - e^(-t)), which equals t/(e^t - 1) + t, gives the second; adding t changes only B1. Which one you want depends on the formula you feed it into: the sums-of-powers formula earlier needs B1 = -1/2 to sum up to one less than the limit, and B1 = +1/2 to sum from 1 to the limit. Neither is more correct than the other in the abstract.

This course fixes the first convention: B1 = -1/2. That is what the reference implementation in course/lab/reference_bernoulli.py returns, it is what the checker enforces, and it is a clause you will write into a prompt in Unit 10.

The lesson generalises well beyond Bernoulli numbers. When two competent sources disagree, the first thing to check is not who made a mistake but whether they were answering the same question. A specification that omits a convention has not made the convention go away; it has only made the disagreement harder to diagnose. In Unit 8 this failure mode has a name: b1-sign.

7. Trap 2 — Ada's indexing is not ours

The second trap is historical, and it is easier to walk into.

Since every odd Bernoulli number above B1 is zero, Lovelace does not give those zeros a label. Her labels start at the modern B2, and from there she numbers only the values that are actually present, using the odd numbers 1, 3, 5, 7 for the modern B2, B4, B6, B8. So each of her labels is one smaller than the modern index: her Bk is the modern B(k+1) (Lovelace 1843, Note G):

Ada's label modern index value
B1 B2 1/6
B3 B4 -1/30
B5 B6 1/42
B7 B8 -1/30

Note G's worked example computes Ada's B7, which in modern notation is B8 = -1/30 (Lovelace 1843, Note G).

Headed 'Same symbol, two different numbers', two number lines run across the frame, one above the other. The upper line is modern Bernoulli indexing: B0 = 1, B1 = -1/2, B2 = 1/6, B3 = 0, B4 has a value to derive, B5 = 0, B6 = 1/42, B7 = 0, and B8 is withheld. The lower line begins as an exact copy, aligned index for index. Then the lower line changes. The first two terms, 1 and -1/2, fall away, marked 'not numbered in Note G', because Note G's numbering begins at 1/6. Then the three zero terms at B3, B5 and B7 fall away, each marked with the word 'zero', because Note G numbers only the non-zero terms. Four terms remain. They are renumbered as Ada's B1, B3, B5 and B7, and the labels visibly slide one place to the right as they arrive, so the two lines are no longer in step. The animation ends with Ada's B7 highlighted directly beneath the modern B8, and the statement that Note G computes Ada's B7, which is the modern B8: the same symbol, two different terms, because the modern B7 is 0. A last line warns: ask for B7 without saying which indexing, and the answer you get back may be the wrong term. Open diagram at full size (opens in a new tab)

Two rows of this mapping carry the same value as B4, and the conventions table above prints it too: the value is no secret. The checkpoint tests whether you can produce it from the recurrence, not whether you can find it in a table, which is why the activity asks you to work it out before you look.

Nothing here is an error on Lovelace's part. It is a different notation that happens to use identical symbols, which is exactly what makes it hazardous. A generated routine can be a faithful reading of Note G and a broken modern component at the same time. Historical fidelity and specification compliance are not the same requirement: a routine can fail by following Note G's numbering when the modern one was asked for. In Unit 8 this failure mode is named ada-indexing.

The mapping is also available in code, in the oracle (the course's trusted reference, described under "Terms used here"): ada_to_modern_index and modern_to_ada_index.

8. Two routes to verification

The activity offers two routes. They carry equal weight, cover the same checkpoints, and are marked the same way, which is to say not at all.

Table-based verification. Derive B4 on paper from the recurrence, then compare a claimed set of values against the table above, index by index. This is what a reviewer does when they have a document rather than a program: line up the claim against the reference and look for the first place they differ. Reading a specification against a known-good table is a professional technique in its own right, not a reduced version of running the code.

Python with exact rationals. Derive B4 on paper too, then check your arithmetic in code, using fractions.Fraction from the standard library. Nothing to install.

from fractions import Fraction

b0 = Fraction(1)
b1 = Fraction(-1, 2)
b2 = Fraction(1, 6)

print(b0 + 3 * b1)        # the known part of the n = 2 identity

Use Fraction, not float. float would give you 0.16666666666666666 for B2, which is not 1/6 and will not compare equal to it. To the eye the difference is invisible at every index; an exact comparison sees it at once. Exact arithmetic is a requirement of this course's interface contract, not a stylistic preference.

Terms used here

  • Convention — a choice that is fixed by agreement rather than derived, such as B1 = -1/2. Two people following different conventions can both be right and still disagree.
  • Exact rational arithmetic — computing with fractions as numerator and denominator, so no rounding occurs. Python's fractions.Fraction does this.
  • Oracle — a trusted reference you compare an answer against. Here, course/lab/reference_bernoulli.py.

These also appear in Glossary.

Check yourself

This unit has three checkpoints:

  • cp06-b4-by-hand — derive B4 from the recurrence
  • cp06-convention — identify which convention a program's output is consistent with
  • cp06-ada-index — translate a Note G label into a modern index

Run them in either route:

python3 selfcheck.py run cp06-b4-by-hand  # or in the browser

For cp06-b4-by-hand, a wrong answer will not show you the right one. It will name the specific slip your answer looks like and give you the next step. That is deliberate: deriving the value is the objective, so handing it over would remove the exercise.

Timings: video 10 min, reading 14 min, activity 20 min.

Check yourself

This unit has 3 checkpoints, answered here. A wrong answer says which misunderstanding it matches. Nothing is uploaded.

Local progress is available in a supported browser.

Manage or delete this record

Prefer a terminal?

The same questions, from The verification lab and self-check:

python3 selfcheck.py run --unit 6

Your progress, and every checkpoint in the course