Skip to content

Read a limit's value at a continuous point before simplifying - #2365

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
fix/read-the-value-before-simplifying
Nov 4, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
fix/read-the-value-before-simplifying

Conversation

@Rafael-SOWNet

@Rafael-SOWNet Rafael-SOWNet commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

x / (tanh(1/2) - tan(x)) at 1 took 10 s, and tanh(x) / (tanh(1/2) - tan(x)) at 1 took 18 s, at points where both are continuous. limitcheck at SEED=28 had thirteen limits that did not finish in 5 s, and twelve of them were these.

A limit at a finite point moves the variable out to infinity, x = a ± 1/x. It then simplified the whole expression before reading its value there. That value is what the substitution answers a continuous point with in any case, under the same guards for a jump, a cut and an indeterminate power, and simplifying was the expensive half.

The substitution is now also asked first, and it answers where its value is a finite real. It stays out of complex values, since a complex value can be the value on a cut, and the cut guards were written against the simplified form. One difference of form: a tangent can come back as the quotient of its sine and cosine.

One guard was owed. Reading the value first hands the descent an argument's limit already folded, -1 rather than -1 - 1/+oo. The factorial's descent put that straight into x! and wrote down the pole, so x! at -1 came back (-1)!. The factorial now declines at a negative integer.

limitcheck, DEPTH=3, seeds 14, 16, 19, 23, 26, 28 and 29, against master f3e514a:

master this branch
total time 667 s 437 s
the limit did not finish in 5 s 13 1
compared 36 275 36 294
the limit is another value 7 7
the limit is NaN where the values settle 84 85

Read the last row.

  • Two wrong NaNs are gone. abs(x + 1 - x^x) at 0 from each side is now unevaluated.
  • Three limits that were unevaluated are now NaN: sin(x)^(log(x, pi)^arcsin(x)) at 1, (2(x - pi))^ln(-x) at 0, and arctan((-1)^x)^(pi/x/cos(2)) at 1/2. Each has no real values on a side: (-oo)^(pi/2) from the left, ln(-x) for x > 0, and (-1)^x throughout. A side with no real values making no two-sided limit is the convention x^x at 0 is pinned to, by LimitTest.TestNoLimit, and limitcheck flags x^x the same way in every run.

I tried making the two-sided path claim NaN only where both sides are decided in full. That took these three back to unevaluated, but it also unpinned x^x, x ln x and sin(x) ln x. That is a decision about the convention and not a side effect to slip into a speed fix, so it is not here.

Every changed answer is recorded in BREAKING-CHANGES.md. Suite, AOT and the harnesses are green locally.

Found by limitcheck at SEED=28; no issue was filed.

🤖 Generated with Claude Code

A limit at a finite point moves the variable out to infinity, x = a +- 1/x,
and simplified that whole expression before reading its value there -- which
is what the substitution answers a continuous point with in any case, under
the same guards for a jump, a cut and an indeterminate power. Simplifying
was the expensive half: x / (tanh(1/2) - tan(x)) at 1 took 10 s and
tanh(x) / (tanh(1/2) - tan(x)) 18 s, for values read in milliseconds. The
substitution is now asked first as well, and answers where its value is a
finite real; a complex one can be the value on a cut, whose guards were
written against the simplified form. A tangent can come back as the quotient
of its sine and cosine.

Reading first hands the descent an argument's limit folded -- -1 rather than
-1 - 1/+oo -- and the factorial's descent put it straight into x!, writing
down the pole: x! at -1 was (-1)!. The factorial declines at a negative
integer now.

limitcheck, DEPTH=3, seeds 14, 16, 19, 23, 26, 28, 29 against master
f3e514a: 667 s -> 437 s, "did not finish in 5 s" 13 -> 1, compared 36275 ->
36294, the wrong values unchanged. "NaN where the values settle" 84 -> 85:
two wrong NaNs gone (abs(x + 1 - x^x) at 0 from each side, now
unevaluated), three limits NaN that were unevaluated, each an expression
with no real values on a side, which is the convention x^x at 0 is pinned
to. Found at SEED=28; no issue was filed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Rafael-SOWNet Rafael-SOWNet added this to the 2.7.0 milestone Nov 4, 2026
@Rafael-SOWNet Rafael-SOWNet moved this from Todo to In review in AngouriMath Nov 4, 2026
@codecov

codecov Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.78%. Comparing base (f3e514a) to head (8e30927).

Files with missing lines Patch % Lines
...nctions/Continuous/Limits/Solvers/Limit.Classes.cs 66.66% 0 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2365      +/-   ##
==========================================
+ Coverage   86.77%   86.78%   +0.01%     
==========================================
  Files         312      312              
  Lines       68855    68861       +6     
  Branches    20063    20066       +3     
==========================================
+ Hits        59746    59762      +16     
+ Misses       4923     4909      -14     
- Partials     4186     4190       +4     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 87.32% <81.81%> (+0.01%) ⬆️
fsharp 32.97% <ø> (ø)
interactive 40.72% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ns/Continuous/Limits/Solvers/Solvers.Definition.cs 89.86% <100.00%> (+0.19%) ⬆️
...nctions/Continuous/Limits/Solvers/Limit.Classes.cs 73.38% <66.66%> (-1.99%) ⬇️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Rafael-SOWNet
Rafael-SOWNet merged commit 984671d into master Nov 4, 2026
35 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the fix/read-the-value-before-simplifying branch November 4, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

1 participant