Skip to content

Add fractions over their least common denominator, and read a vanishing base's sign on the side approached - #2386

Merged
Rafael-SOWNet merged 3 commits into
masterfrom
feature/sum-of-fractions-cost
Nov 8, 2026
Merged

Rafael-SOWNet merged 3 commits into
masterfrom
feature/sum-of-fractions-cost

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Two commits.

Two fractions are added over their least common denominator. The simplifier added two fractions by cross-multiplying, so a factor both denominators share was squared, and each later sum multiplied the denominators again before anything cancelled. (1 - tanh(x)^2) / tanh(x) written through exponentials spent nearly all of its two seconds in two sums whose denominators had grown to (e^(2x) + 1)^6 (e^(2x) - 1)^3. Where the denominators share a factor, the sum now goes over their least common multiple. Denominators that share nothing are cross-multiplied as before.

A limit reads the sign of a vanishing base on the side approached, and at an infinity. The first commit writes (sqrt(x) x)^(x - 2 - x^2) at 0+, through x = 1/x, as (1/x)^(2 ((x - 1)/x^2 - 2)) at +oo, which the descent read as 0^(-4) and left. A base tending to 0, to an exponent tending to a negative number, tends to +oo where the base is positive on the way in; the descent knew it only for a base never negative anywhere. The sign near an infinity is now read from the vanishing order after putting 1/x for x, for a product or quotient from its parts, and for a positive base to a real power as positive. It is not read from a slope at an infinity: after the substitution, sinh(e^x) at -oo has a flat function's slope, and asking for it made sgn(sinh(e^x)) take 24 s to decline, against 0.13 s on master. It now takes 0.17 s.

master branch
Simplify of (1 - tanh(x)^2) / tanh(x) through exponentials 1.75 s 0.15 s, the same answer
1/(x+1) + 1/(x+1)^2, simplified left as the sum (2 + x) / (1 + x) ^ 2
(1/x)^(2 ((x - 1)/x^2 - 2)) at +oo unevaluated +oo
sin(x)^(x - 2) at 0+ unevaluated +oo
sgn(1/x) at +oo, at -oo unevaluated 1, -1
sgn(e^x) at -oo unevaluated 1
sinh(sgn(e^x)) at -oo unevaluated, 0.7 s (e - 1/e) / 2, 0.17 s

AVanishingBaseToANegativeWholePowerTest pinned sin(x)^(x - 2) at 0+ as left alone. It is +oo: the base is positive there, so the power is e^((x - 2) ln sin x). The test only pinned it because nothing answered it. What it was for, that an exponent merely tending to a whole number is not given that whole power's sign, is kept on the left, where the power is complex and the limit is still left alone.

limitcheck A/B against master (DEPTH=3, the usual seeds): 129 answers gained, none lost. 81 are at an infinity, mostly a sign. Seven rows the harness lists as another value are right:

  • sinh(sgn(e^x)), sgn(sgn(e^x)), sgn(e^x)^3 and 2 sgn(e^x) at -oo are functions of 1, where the harness's samples of e^x underflow to 0.
  • sgn(arctan(1/2)^(2/x)) at 0+ is 1, for the same reason.
  • sin(pi x)^(erf(pi) - (-1)^x) at 0+ and 2+ is +oo. Its exponent tends to erf(pi) - 1, about -8.9e-6, which is negative. mpmath gives 1.02 at x = 10^-1000 and 7.5e8 at 10^-1000000, where the harness's samples stop at 10^-8.

floor(tanh(x)/x) at 0 moved from a timeout to a decline. floor(sqrt(x^3)) at 0+ declines in 6–7 s on both builds; its one timeout in the first A/B was jitter.

Each changed answer is in BREAKING-CHANGES.md, measured on 2.6.0. The full suite (19,113), the wrapper suites, AOT and the ten harnesses pass.

Found by limitcheck at DEPTH=3, SEED=77, after the slow Simplify was found sampling a slow limit. No issue was filed.

🤖 Generated with Claude Code

Rafael-SOWNet and others added 3 commits November 8, 2026 00:51
The simplifier adds two fractions whose parts share a variable by
cross-multiplying, so a factor the two denominators share is squared,
and each sum after it multiplies the denominators again before anything
cancels. Every one of those sums simplifies both halves, on trees that
keep growing. (1 - tanh(x)^2) / tanh(x) written through exponentials
took two seconds to simplify, nearly all of it in two sums whose
denominators had grown to (e^(2x) + 1)^6 (e^(2x) - 1)^3.

Where the denominators share a factor, the sum now goes over their least
common multiple, each factor to the highest power either has it. A
factor is recognised under a power of a product, and with a negative
number added written as one subtracted. The multiple is 0 exactly where
the product is. Denominators that share nothing are cross-multiplied as
before.

Simplify of (1 - tanh(x)^2) / tanh(x) through exponentials: 1.9 s ->
0.36 s. Its limit times x * (1 + x^2) at 0 from the right: 9.6 s ->
0.45 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A base tending to 0, to an exponent tending to a negative number, tends
to +oo where the base is positive on the way in. The descent knew it
only for a base never negative anywhere, so (1/x)^(2 ((x - 1)/x^2 - 2))
at +oo was read as 0^(-4), which has no value, and left unevaluated.
Adding fractions over their least common denominator writes
(sqrt(x) x)^(x - 2 - x^2) at 0+ into that shape, through x = 1/x, so the
previous commit would otherwise have lost it.

The sign near the point is now read at an infinity from the vanishing
order at 0+ after putting 1/x (or -1/x) for x, where that reader is
stated; for a product or a quotient as the product of its parts' signs,
which sqrt(x) * x at 0+ needed, its slope tending to 0; and for a
positive base to a real power as positive, so e^x at -oo is positive and
sgn(e^x) there is 1. Not from a slope at an infinity: after the
substitution that of sinh(e^x) at -oo is a flat function's, and asking it
made sgn(sinh(e^x)) take 24 s to decline, against 0.13 s.

sin(x)^(x - 2) at 0+ is now +oo, which it is: its test pinned it as left
alone only because no rule answered it. Its intent, that an exponent
merely tending to a whole number is not given the whole power's sign,
is kept on the negative side, where the power is complex and the limit
is still left alone.

Found by limitcheck at DEPTH=3, SEED=77; no issue was filed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…BREAKING-CHANGES

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Rafael-SOWNet Rafael-SOWNet added this to the 2.7.0 milestone Nov 8, 2026
@codecov

codecov Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.36842% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 86.80%. Comparing base (a1c0034) to head (69f5bff).

Files with missing lines Patch % Lines
...ath/Functions/Continuous/Limits/Transformations.cs 93.75% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2386      +/-   ##
==========================================
+ Coverage   86.79%   86.80%   +0.01%     
==========================================
  Files         312      312              
  Lines       69156    69190      +34     
  Branches    20166    20177      +11     
==========================================
+ Hits        60022    60060      +38     
+ Misses       4918     4916       -2     
+ Partials     4216     4214       -2     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 87.34% <97.36%> (+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 Δ
...nctions/Continuous/Limits/Solvers/Limit.Classes.cs 74.93% <100.00%> (ø)
...tions/Simplification/Patterns/Patterns.Rational.cs 99.12% <100.00%> (+0.01%) ⬆️
Sources/AngouriMath/Functions/SingleQuotient.cs 92.92% <100.00%> (-4.64%) ⬇️
...ath/Functions/Continuous/Limits/Transformations.cs 88.78% <93.75%> (-0.05%) ⬇️

... and 8 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 7452b21 into master Nov 8, 2026
35 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in AngouriMath Nov 8, 2026
@Rafael-SOWNet
Rafael-SOWNet deleted the feature/sum-of-fractions-cost branch November 8, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant