Skip to content

Say which infinity a quotient with a vanishing divisor tends to - #700

Merged
Happypig375 merged 1 commit into
ASC-Community:masterfrom
Rafael-SOWNet:fix/vanishing-denominator
Aug 4, 2026
Merged

Happypig375 merged 1 commit into
ASC-Community:masterfrom
Rafael-SOWNet:fix/vanishing-denominator

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

limitright(cos(x) / sin(x), x, 0) answers NaN. It is +oo. From the left it is -oo, and that is NaN too.

The descent puts each part's own limit in place of the part, so the quotient becomes 1 / 0 — which says nothing about which side the divisor vanishes from, and comes back NaN. NaN is not "I could not tell"; it is the claim that the limit does not exist.

1 / x escapes this, which is why the gap is easy to miss: once x is moved out to infinity that one is a quotient of polynomials and the solvers read it outright. Anything whose divisor is not a polynomial — sin(x), tan(x), e^x - 1, ln(x) at 1 — fell through.

How the side is read

Off the divisor's first derivative that does not vanish with it. Where g(a) = 0 and the first non-vanishing derivative there is the k-th, g(x) has the sign of g_k(a) * (x - a)^k near a — so the sign of g_k(a) on the right, and that times (-1)^k on the left.

That covers the first order (sin(x), e^x - 1, x - a) and the second (1 - cos(x), sin(x) - 1 at pi/2). An even order looks the same from both sides, so 1 / (1 - cos(x)) gains a two-sided limit of +oo as well.

Nothing is claimed unless a derivative comes out finite and non-zero at the point. An expression that is not differentiable there, or whose derivative diverges as sqrt(x)'s does, is left alone rather than guessed at — reading the sign wrongly would answer +oo where the truth is -oo, which is worse than not answering at all. Four derivatives is as far as it looks.

What it answers

before after (right / left)
1 / sin(x) at 0 NaN / NaN +oo / -oo
cos(x) / sin(x) at 0 NaN / NaN +oo / -oo
1 / tan(x) at 0 NaN / NaN +oo / -oo
-2 / (e^x - 1) at 0 NaN / NaN -oo / +oo
2 / ln(x) at 1 NaN / NaN +oo / -oo
1 / x^3 at 0 NaN / NaN +oo / -oo
cos(x) / (x - 1)^3 at 1 NaN / NaN +oo / -oo
1 / (1 - cos(x)) at 0 NaN / NaN +oo / +oo, and +oo two-sided
3 / (sin(x) - 1) at pi/2 NaN / NaN -oo / -oo

17 of the 35 new tests fail without the change.

The cases where the two sides genuinely disagree keep saying so: 1 / sin(x) and 1 / x^3 at 0 still have no two-sided limit, and there are tests pinning that, because turning a correct NaN into a wrong infinity is the failure mode this change could have had.

Cost

Reached only where the substitution above answered nothing or NaN, so it costs nothing on any path that already worked, and whatever that answered is kept if this finds nothing better.

Measurements

  • Suite: Failed: 0, Passed: 4044, Skipped: 14, Total: 4058.
  • A 117-problem corpus of simplifications, solves, integrals and limits: unchanged at 101/117 solved, 0 wrong / 0 error / 0 timeout, measured with and without the change on this branch.

Independent of my other open PRs; git merge-tree reports no conflict with any of them. It does compose with #697 — with both, sin(x) / (1 - cos(x)) at 0 answers +oo on the right and -oo on the left, since l'Hopital's rule turns it into cos(x) / sin(x) and this reads that. On this branch alone it is still NaN.

Fork CI to follow in a comment.

The descent puts each part's own limit in place of the part, and for this shape
that throws away the only thing that decides the answer: cos(x) / sin(x) at 0
becomes 1 / 0, which says nothing about which side the divisor vanishes from and
so comes back NaN -- the claim that the limit does not exist, where on the right
it is +oo and on the left -oo. Only 1 / x and the other quotients of polynomials
escaped it, because those the solvers read outright once x has been moved out to
infinity, and it is that accident which made the gap easy to miss.

The side the divisor vanishes from is read off its first derivative that does not
vanish with it. Where g(a) = 0 and the first non-vanishing derivative there is
the k-th, g(x) has the sign of g_k(a) * (x - a)^k near a, which is the sign of
g_k(a) on the right and that times (-1)^k on the left. That covers the first
order, where sin(x) and e^x - 1 and x - a live, and the second, where 1 - cos(x)
does -- and being even, that one looks the same from both sides, so
1 / (1 - cos(x)) now has a two-sided limit of +oo as well.

Nothing is claimed unless a derivative comes out finite and non-zero at the
point. An expression that is not differentiable there, or whose derivative
diverges as sqrt(x)'s does, is left alone rather than guessed at: reading the
sign wrongly would answer +oo where the truth is -oo, which is worse than not
answering. Four derivatives is as far as it looks.

Reached only where the substitution above answered nothing or NaN, so it costs
nothing on any path that already worked, and whatever that answered is kept if
this finds nothing better. 17 of the 35 new tests fail without it. Corpus
unchanged at 101/117 with 0 wrong; suite 4044 passed, 0 failed.
@Rafael-SOWNet

Copy link
Copy Markdown
Member Author

Fork CI, matrix run 30935777770 — success on windows-latest, ubuntu-latest and macos-latest, Failed: 0, Passed: 4044, Skipped: 14, Total: 4058 on each.

The branch ci-check/vanishing-denominator is this PR's head 6134b9a9 plus one commit that only adds a trigger to the workflow file, so Sources/ is byte-identical to what is under review.

For context on where this sits: I keep a corpus of 49 one-sided limits worked out by hand. Master answers 16 of them correctly, three of the misses being wrong answers rather than merely unanswered ones. #697 takes it to 42, #699 and this one together take it to 49. The three PRs are independent — git merge-tree reports no conflict between any pair — and each is measured on its own above.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 71.42857% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.41%. Comparing base (90c00a8) to head (6134b9a).
⚠️ Report is 58 commits behind head on master.

Files with missing lines Patch % Lines
...ath/Functions/Continuous/Limits/Transformations.cs 66.66% 3 Missing and 5 partials ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #700      +/-   ##
==========================================
- Coverage   80.99%   80.41%   -0.59%     
==========================================
  Files         155      156       +1     
  Lines       13687    12944     -743     
  Branches     1957     2132     +175     
==========================================
- Hits        11086    10409     -677     
+ Misses       1990     1923      -67     
- Partials      611      612       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@Happypig375
Happypig375 merged commit 6c1f6b4 into ASC-Community:master Aug 4, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the fix/vanishing-denominator branch August 4, 2026 20:49
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.

3 participants