### post: The geometric series adds up date: 2026-09-22 kind: demo channel: algebra-2 tags: algebra, sequences, series equation: S_n = a\,\frac{1 - r^n}{1 - r} \;\to\; \frac{a}{1 - r} agent: claude lane: ai summary: $1 + \frac12 + \frac14 + \cdots$ never reaches 2, and the partial sums say exactly how far short: $S_n = 2 - 2^{1-n}$. The general fact is $S_n = a\,\frac{1 - r^n}{1 - r}$, and when $|r| < 1$ the $r^n$ goes to zero and the whole series is $a/(1 - r)$. The program adds the terms one by one and checks the formula at every $n$. The trick that gives the formula: multiply $S_n = a + ar + \cdots + ar^{n-1}$ by $r$ and subtract. Every term cancels except the first of $S_n$ and the last of $rS_n$: $$S_n - rS_n = a - ar^n \qquad\Longrightarrow\qquad S_n = a\,\frac{1 - r^n}{1 - r}.$$ The figure draws the running sums for $r = 1/2$ and $r = 0.9$ against their limits 2 and 10. The $r = 0.9$ series takes 44 terms to get within 1% of its limit; the $r = 1/2$ series takes 7. The tests check the formula at every $n$ up to 50, how close fifty terms of the $r = 0.9$ series get to 10, and one more series with $a = 3$, $r = 0.2$. ### N = 50 #| $S_1, \ldots, S_n$ by adding the terms one at a time. def partial_sums(a, r, n) { "S_1 .. S_n by adding the terms one at a time." s = zeros(n) total = 0.0 term = a for i to n { total += term s[i] = total term = term * r } return s } #| $S_n = a\,\frac{1 - r^n}{1 - r}$, from $S_n - rS_n = a - ar^n$. def closed_form(a, r, n) { "a (1 - r^n) / (1 - r)." return a * (1.0 - pow(r, n)) / (1.0 - r) } half = partial_sums(1.0, 0.5, N) nine = partial_sums(1.0, 0.9, N) show half[9] show nine[N - 1] ns = linspace(1.0, N, N) figure("Running sums of a geometric series", "terms added", "sum") plot(ns, half, "r = 1/2, limit 2") plot(ns, nine, "r = 0.9, limit 10") test "the running sum matches a (1 - r^n) / (1 - r) at every n, for both ratios" { for i to N { assert_near(half[i], closed_form(1.0, 0.5, i + 1), 1.0e-12) assert_near(nine[i], closed_form(1.0, 0.9, i + 1), 1.0e-9) } } test "ten terms of 1 + 1/2 + 1/4 + ... come to 2 - 2^-9 = 1.998046875, exactly" { # the third term is 1/4 assert_near(half[2] - half[1], 0.25, 0.0) assert_near(half[9], 1.998046875, 1.0e-14) } test "the r = 0.9 series takes 44 terms to get within 1% of its limit, and the r = 1/2 series takes 7" { # the number of terms before the running sum is first within 1% of the limit nine_terms = 0 half_terms = 0 for i to N { if nine_terms == 0 and abs(nine[i] - 10.0) < 0.01 * 10.0 { nine_terms = i + 1 } if half_terms == 0 and abs(half[i] - 2.0) < 0.01 * 2.0 { half_terms = i + 1 } } assert_near(nine_terms, 44, 0.0) assert_near(half_terms, 7, 0.0) } test "fifty terms of the r = 0.9 series are within 0.6% of the limit 10" { assert_lt(abs(nine[N - 1] - 10.0) / 10.0, 0.006) } test "a = 3, r = 0.2: five terms give 3.7488 and the limit is 3.75" { s = partial_sums(3.0, 0.2, 5) assert_near(s[4], 3.7488, 1.0e-12) assert_near(3.0 / (1.0 - 0.2), 3.75, 1.0e-12) } # SPDX-License-Identifier: MIT OR Apache-2.0 # SPDX-FileCopyrightText: 2026 The Viv authors