Skip to content

A geometric series is summed in closed form - #1218

Merged
Rafael-SOWNet merged 2 commits into
masterfrom
geometric-series
Sep 8, 2026
Merged

Rafael-SOWNet merged 2 commits into
masterfrom
geometric-series

Conversation

@Rafael-SOWNet

@Rafael-SOWNet Rafael-SOWNet commented Sep 8, 2026 •

Copy link
Copy Markdown
Member

Part of #1212 — the sum that question I.2's step integral leaves once #1215 splits it, and the last of the summation closed forms the plan there named (polynomial #1152, exponential #1213, binomial #1214).

What was left as written

Measured on 27ed5b53:

master
sum(2^(-k), k, 0, +oo), sum(1 / 2^k, k, 1, +oo), sum((-1/2)^k, k, 0, +oo) left as written
sum(x^k, k, 0, +oo), sum(x^k, k, 0, n), sum(2^k, k, a, n) left as written
sum(2^k, k, 0, 200) — past the hundred terms expanded one by one left as written
integral(2^(-floor(x)), x, 0, +oo) left as written (#1215 split it and declined the sum)

What changes

GeometricSeries.ClosedForm, last in the Summationf chain. The summand is read structurally as C * b^(m k + s): one power whose base is free of the index and whose exponent is the index times a whole number plus something free of it, every other factor free of the index. The ratio is r = b^m.

  • Between two bounds: C b^s (r^a - r^(b + 1)) / (1 - r) holds where the range is not empty and r ≠ 1; at r = 1 the sum is the number of terms times the constant; below b = a - 1 the range is empty and this library answers 0. A numeric ratio picks its branch; a symbolic one is offered all three as a piecewise, the way PolynomialSummation offers the empty range — sum(x^k, k, 0, n) is piecewise((n + 1) provided (x = 1 and n >= -1), ((1 - x^(n + 1)) / (1 - x)) provided (n >= -1), 0).
  • To +oo: converges exactly when |r| < 1. A numeric ratio outside that is left as written — the sum is infinite or has no value, and which of the two is not this reader's to say. A symbolic ratio carries the condition: sum(x^k, k, 0, +oo) is 1 / (1 - x) provided abs(x) < 1.
  • Not this family: a polynomial factor in the index (k x^k), an exponent that is not linear in the index, a base with the index in it, a bound that is a number and not whole. All stay as written.
  • r^0 is written as the number 1 rather than built, since a power carries provided not r = 0 and the sum at r = 0 is its first term — the first cut answered sum(x^k, k, 0, +oo) with and not x = 0 attached, which is false at a point where the sum is 1.

Three tests pinned sum(2^k, k, 1, n) as their example of a sum without a closed form; they use k^k now. The #1215 test that recorded integral(2^(-floor(x)), x, 0, +oo) staying as written for want of this sum now records 2.

Measured

Both columns on builds — 27ed5b53 against this branch:

was is
sum(2^(-k), k, 0, +oo), sum(1 / 2^k, k, 1, +oo), sum((-1/2)^k, k, 0, +oo) left as written 2, 1, 2/3
sum(x^k, k, 0, +oo); from 1 left as written 1 / (1 - x) provided abs(x) < 1; x / (1 - x) provided abs(x) < 1
sum(x^k, k, 0, n) left as written the three-case piecewise above
sum(2^k, k, a, n); sum(2^k, k, 0, 200) left as written piecewise((2^(n + 1) - 2^a) provided (n >= a - 1), 0); 2^201 - 1 as a number
integral(2^(-floor(x)), x, 0, +oo) left as written 2
sum(2^k, k, 0, +oo), sum((-1)^k, k, 0, +oo), sum(k * (1/2)^k, k, 0, +oo), sum(2^k, k, 0, 5) left as written; 63 the same

Checks

GeometricSeriesTest: seven numeric series, the symbolic ratio with its condition and its value at 0, outside the disc, three finite ranges past a hundred terms, six symbolic-bound substitutions, two symbolic lower bounds, six non-shapes. Full suite in two chunks: 8359 and 1412 pass.

One thing seen once and not reproduced, noted rather than hidden: in the first chunk run on this branch FractionFreeDeterminantTest.EliminationAgreesWithLaplaceWhereverBothApply reported one 4×4 whose Laplace determinant came back with two ninety-digit integers in it. It passes alone, passed on the rerun of the same chunk, and passes on master's build of the chunk; the test is seeded, so the input is fixed and the difference is scheduling. Nothing in this branch is on that path; filed as #1219.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

sum(x^k, k, 0, +oo) was left as written, and so was every other sum of
a power with the index in the exponent: sum(2^(-k), k, 0, +oo),
sum(x^k, k, 0, n), and sum(2^k, k, 0, 200), whose range is past the
hundred terms that are expanded one by one.

A summand that is C * b^(m k + s) -- a base free of the index, an
exponent that is the index times a whole number plus something free of
it, every other factor free of the index -- is summed as a geometric
series with the ratio b^m. Between two bounds the sum is
C b^s (r^a - r^(b + 1)) / (1 - r) where the range is not empty and the
ratio is not 1, the number of terms times the constant where the ratio
is 1, and 0 for an empty range; a numeric ratio picks its branch and a
symbolic one is offered all three as a piecewise, the way a polynomial
summand is offered the empty range. To +oo the series converges exactly
when |r| < 1: a numeric ratio outside that is left as written, and a
symbolic ratio carries provided abs(r) < 1. A polynomial factor in the
index is not this family and stays as written.

r^0 is written as 1 rather than built, since a power carries
`provided not r = 0` and the sum at r = 0 is its first term. Three
tests that pinned sum(2^k, k, 1, n) as an example of a sum without a
closed form now use k^k; the step integral of 2^(-floor(x)) over
[0, +oo), which #1215 left as written for want of this sum, is 2.

The sum question I.2 of #1212 leaves. BREAKING-CHANGES.md has the rows,
measured on both builds.

Part of #1212.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Happypig375

Happypig375 commented Sep 8, 2026 •

Copy link
Copy Markdown
Member

Can you really assume that integral(floor(x)^floor(x), x, 1, +oo) cannot be solved, or is it just missing a solver (add to TODO)?

@Rafael-SOWNet

Copy link
Copy Markdown
Member Author

No — and the example is worse than "missing a solver": it has a value. integral(floor(x)^floor(x), x, 1, +oo) splits into sum(n^n, n, 1, +oo), whose terms do not tend to zero, so the series diverges, and with positive terms it diverges to +oo. That is the answer, and a divergence test — terms not tending to 0, positive terms — is what is missing, not a closed form.

What the test pins is the fallback, which is right as far as it goes: when the split leaves a sum nothing here answers yet, the integral stays as written rather than becoming an unevaluated sum, and it never says NaN. But the comment said "cannot", and I have reworded it to say "not yet, and this one is +oo" so that the test reads as a TODO rather than a verdict. The divergence test goes on the list in #1212 under the summation closed forms; it is the same shape as the convergence condition this PR attaches for a symbolic ratio, applied to a numeric one.

…s to +oo

The test pinned integral(floor(x)^floor(x), x, 1, +oo) staying as written
with a comment that said the sum cannot be answered. It can: its terms
do not tend to zero, so the series diverges, and with positive terms
the answer is +oo. What is missing is a divergence test, and the
comment now says so. From the review of #1218.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Rafael-SOWNet
Rafael-SOWNet merged commit 2aeaa4c into master Sep 8, 2026
31 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the geometric-series branch September 8, 2026 15:28
Rafael-SOWNet added a commit that referenced this pull request Sep 9, 2026
sum(2^k, k, 0, +oo) and sum(k, k, 1, +oo) were left as written. They
have no finite value, and saying nothing was the only thing missing:
the nth-term test settles them. Terms that do not tend to zero mean
the series diverges, and the sign of the limit says which infinity --
where the terms tend to a positive L they are eventually all above
L / 2, so the partial sums pass every bound. A negative limit gives
-oo the same way, and the finitely many terms before that point are
finite and cannot change it.

A limit of zero is declined, and that is the point of the test rather
than a gap in it: sum(1/k) diverges and sum(1/k^2) converges and the
terms of both tend to 0. A limit that does not exist is declined too,
since telling "does not exist" apart from "was not computed" is not
something to infer from a failed computation.

And a summand that can fail to exist at some index is declined,
because one undefined term makes the sum undefined rather than
infinite -- sum(k / (k - 5), k, 0, +oo) has terms tending to 1 and no
term at k = 5. Rather than hunt for poles the index is allowed only
where none can arise, which also keeps this cheap: the structural
check runs first, so a summand it cannot speak about never reaches
the limit engine. A condition that holds over the whole range is
dropped, which is what lets the step split hand over
n ^ n provided not n = 0 or n > 0.

Last in the chain, so a series that converges is summed rather than
tested. Asked for on the review of #1218, where
integral(floor(x)^floor(x), x, 1, +oo) splits into sum(n^n, n, 1, +oo)
and was left as written for want of it -- that test carried a comment
saying it would move to the value the day this existed, and it has.
Three other pinned examples move with it, each having used an
infinite range as its illustration of a sum that stays.

BREAKING-CHANGES.md has the rows, measured on both builds.

Part of #1212.


Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Rafael-SOWNet

Copy link
Copy Markdown
Member Author

Delivered: #1224 merged, so integral(floor(x)^floor(x), x, 1, +oo) is now +oo rather than left as written, and the test line here that carried the "the day it is, this line moves to the value" comment moves with it.

To close the loop on the question you asked: it was missing a solver, and the nth-term test is it. The parts I deliberately kept it from answering are a vanishing limit (the case the test genuinely says nothing about — sum(1/k) diverges and sum(1/k^2) converges), a limit that does not exist, and a summand with a pole in the index — sum(k / (k - 5), k, 0, +oo) has terms tending to 1, so consulting only the limit would answer +oo and be wrong about the term at k = 5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants