Skip to content

A factor a numerator's terms hold to a power cancels - #2306

Merged
Rafael-SOWNet merged 2 commits into
masterfrom
a-factor-a-numerators-terms-hold-to-a-power-cancels
Oct 31, 2026
Merged

Rafael-SOWNet merged 2 commits into
masterfrom
a-factor-a-numerators-terms-hold-to-a-power-cancels

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

When one side of a quotient is a sum, and every term holds a polynomial factor of the other side, as it is or to a whole power, that factor now comes out of the sum before the factors are paired off.

Simplify master and 2.6.0 now
(x * (y + 1) + (y + 1)^2) / (y + 1)^4 left as it is (x + y + 1) / (y + 1) ^ 3
(x * (x^2 + 1) + (x^2 + 1)^2) / (x^2 + 1)^4 left as it is (x ^ 2 + 1 + x) / (x ^ 2 + 1) ^ 3
(a * (x^2 + 1) + b * (x^2 + 1)^2) / (x^2 + 1)^3 expanded, over x ^ 4 + 2 * x ^ 2 + 1 (a + b * (x ^ 2 + 1)) / (x ^ 2 + 1) ^ 2
  • The rules take k out of k*p + k*q, but not out of k*p + k^n. So only the first-power case cancelled.
  • The quotient rule squares the denominator at each derivative. So the derivatives of e^x / (1 + x^2), simplified step by step, went 21, 149, 629 and 5,117 nodes. They now go 21, 69, 109 and 149. A Taylor expansion to 9 terms took 8 s and takes 1 s, with the same coefficients.
  • Polynomial factors only. Taking a power of sin(t) out first left Simplify() does not handle complex trigonometrical statements well #557's second expression one Simplify short of 0. That case has its own route to cancellation, through the opened angles. DoubleAngleOverSineTest caught it.
  • Three of the new tests fail on master. The suite, the trio, F#, AOT and the eight harnesses pass.

Fixes #2301.

🤖 Generated with Claude Code

PairwiseGroupedQuotient pairs a quotient's factors off, and a sum is
one factor to it, so a factor of the denominator inside every term of
the numerator was met only after a rule had taken it out of the sum.
The rules take k out of k*p + k*q and k + k*q, not out of k*p + k^n, so
(x (y + 1) + (y + 1)^2) / (y + 1)^4 was left as written while
(x (y + 1) + (y + 1)) / (y + 1)^2 cancelled to (x + 1) / (y + 1).

Before pairing, a sum on either side now has a polynomial factor of
the other side taken out of it where every term holds that factor, as
it is or to a whole power, the lowest power of it that every term
holds. The pairing then meets it as it meets a factor written out: the
first is (x + y + 1) / (y + 1)^3. A power of a sine is left to the
cancellation it has through the opened angles and a common
denominator: taken out first, it left the second expression of #557
short of 0, at a form one more Simplify takes there.

The quotient rule squares the denominator at each derivative, and the
numerator it writes holds a factor of it, so the derivatives of
e^x / (1 + x^2), simplified at each step, went 21, 149, 629 and 5,117
nodes at the first, third, fifth and seventh; they go 21, 69, 109 and
149. A Taylor expansion to 9 terms took 8 s and takes 1 s, with the
same coefficients.

AFactorHeldToAPowerCancelsTest takes the issue's rows by value as well
as by what they print, and the seventh derivative's size. The suite,
the trio, F#, AOT and the eight harnesses pass.

Fixes #2301.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Rafael-SOWNet Rafael-SOWNet added this to the 2.7.0 milestone Oct 31, 2026
@Rafael-SOWNet Rafael-SOWNet moved this from Todo to In review in AngouriMath Oct 31, 2026
@codecov

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.77%. Comparing base (aef5535) to head (2e1ef0d).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #2306   +/-   ##
=======================================
  Coverage   86.77%   86.77%           
=======================================
  Files         311      311           
  Lines       67995    68025   +30     
  Branches    19745    19758   +13     
=======================================
+ Hits        59003    59030   +27     
- Misses       4871     4873    +2     
- Partials     4121     4122    +1     
Flag Coverage Δ
cpp 37.77% <ø> (ø)
csharp 87.32% <100.00%> (+<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 Δ
...tions/Simplification/Patterns/Patterns.Rational.cs 99.10% <100.00%> (+0.32%) ⬆️

... 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.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Rafael-SOWNet
Rafael-SOWNet merged commit 5d973db into master Oct 31, 2026
35 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in AngouriMath Oct 31, 2026
@Rafael-SOWNet

Copy link
Copy Markdown
Member Author

The squash commit, 5d973db, has the right subject, but its body is #2305's message, not this PR's. I took the body from the branch's latest commit that wasn't a merge, and after merging master in, that commit was #2305's squash. This is the message meant for it:

A factor a numerator's terms hold to a power cancels

PairwiseGroupedQuotient pairs a quotient's factors off, and a sum is
one factor to it, so a factor of the denominator inside every term of
the numerator was met only after a rule had taken it out of the sum.
The rules take k out of k*p + k*q and k + k*q, not out of k*p + k^n, so
(x (y + 1) + (y + 1)^2) / (y + 1)^4 was left as written while
(x (y + 1) + (y + 1)) / (y + 1)^2 cancelled to (x + 1) / (y + 1).

Before pairing, a sum on either side now has a polynomial factor of
the other side taken out of it where every term holds that factor, as
it is or to a whole power, the lowest power of it that every term
holds. The pairing then meets it as it meets a factor written out: the
first is (x + y + 1) / (y + 1)^3. A power of a sine is left to the
cancellation it has through the opened angles and a common
denominator: taken out first, it left the second expression of #557
short of 0, at a form one more Simplify takes there.

The quotient rule squares the denominator at each derivative, and the
numerator it writes holds a factor of it, so the derivatives of
e^x / (1 + x^2), simplified at each step, went 21, 149, 629 and 5,117
nodes at the first, third, fifth and seventh; they go 21, 69, 109 and
149. A Taylor expansion to 9 terms took 8 s and takes 1 s, with the
same coefficients.

AFactorHeldToAPowerCancelsTest takes the issue's rows by value as well
as by what they print, and the seventh derivative's size. The suite,
the trio, F#, AOT and the eight harnesses pass.

Fixes #2301.


🤖 Generated with Claude Code

@Rafael-SOWNet
Rafael-SOWNet deleted the a-factor-a-numerators-terms-hold-to-a-power-cancels branch October 31, 2026 22:54
Rafael-SOWNet added a commit that referenced this pull request Nov 4, 2026
GrewTooMuch turned the rule away where a quotient grew in nodes, and a
chain whose divisor is a reciprocal power, x^n / (1 / g^k), grows in its
exponents instead: the derivative of 1/g^k is over g^(2k), so k doubled
at each step with the node count flat, and the inner limits expanded the
powers. The limit of (-ln(2)/ln(x))^(e^x - 1) at 0 from the right went
6, 12, 24, ... and did not finish in ten minutes; it is 1, which 2.6.0
answered and #2306 stopped answering (bisected: #2306's factor taken out
of a sum changed the route into this chain). The spelling with log(x, 1/2)
and sgn(x) was 0 in 2.6.0 and hung on master.

The sum of the whole exponents is measured as the nodes are, with the
same room, the larger of eight more and three fifths again: a chain that
is getting somewhere lowers its degrees. Both limits are 1, in 6 s and
3.4 s. limitcheck at SEED=16, and at DEPTH=3 on SEED=19 and 23, changes
only the limit that did not finish; 752 limit tests pass.

Give the l'Hopital chain test five minutes, far from the runner and the hang

The 0^0 limit takes about 6 s here and past a minute on CI's Windows
runner, whose suite took 19 m 54 s against 7 m; a minute's cap measured
the runner. Before the fix it did not finish in ten minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Simplify does not cancel a factor when a numerator's term holds a power of it

1 participant