Skip to content

A partial-fraction coefficient with symbols in it is in lowest terms, its rational content included, and a constant factor is not a symbolic coefficient - #1408

Merged
Rafael-SOWNet merged 2 commits into
masterfrom
partial-fraction-lowest-terms
Sep 18, 2026
Merged

Rafael-SOWNet merged 2 commits into
masterfrom
partial-fraction-lowest-terms

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Two rows of the Rubi hyperbolic sample that were answered in under two seconds became timeouts on today's master: csch(x)^5/(a + b cosh(x)) with #1389 (1.4 s → >60 s) and tanh(x)^6/(a + a sech(x)) with #1392 (0.66 s → >60 s). Bisected with a solo probe at each merge; both are the symbolic partial-fraction decomposition, and both are coefficients that were not in lowest terms.

The rational content. InLowestTermsOverTheSymbols put a coefficient in lowest terms by the polynomial gcd, which normalizes its divisor to whole coprime coefficients and so never cancels a number, and calls two sides without a variable in common coprime before it looks: -1024/(1024 a) stayed as it was. Newton's iteration for the inverse modulo (1 + u^2)^6 squares its iterate every round, so the second round carried 1024^2, the third integers of twelve hundred digits ([newton 2] maxchars=1190), and the minute went into EInteger.HalfGCD on them (dotnet-stack). The rational content of the denominator now goes up into the numerator — the denominator's coefficients whole and coprime with a positive leading one, by the Normalized the gcd already has, with the scale it used handed back — on every path out of the function.

The elimination's values. Where symbols are among them they are put in lowest terms before the terms are built. csch^5/(a + b cosh) under u = e^x, after the Hermite reduction, is a numerator with a page of a and b over (u^2 - 1)(b + 2 a u + b u^2); its values came out at 2233 nodes each as quotients of determinants, and each term went round the chain with that in front and did not return. In lowest terms they are 1/256 (3 a^3 - 7 a b^2)/(a^4 - 2 a^2 b^2 + b^4) and the like; the answer is 27 kB where it was 59, and the row is 1.3 s.

A constant factor is not a symbolic coefficient. The content of a written sum comes out before the symbolic split rather than after it, and the split's gate asks for a symbol among the coefficients of the factors in the variable rather than anywhere in the denominator: a (1 + u^2) + 2 a u is a (1 + u)^2, a repeated linear over the rationals, which the refactoring and the Hermite reduction read, where the split computed its digits with a in every coefficient for an answer twice the length. tanh^6/(a + a sech) is 6.7 kB and 2 s, from 7.8 kB before the regression.

row 2.5.0 master e780ce9a this branch
csch(x)^5/(a + b cosh(x)) unevaluated >60 s 1.3 s, 27 kB
tanh(x)^6/(a + a sech(x)) unevaluated after 115 s >60 s 2.1 s, 6.7 kB
1/(u (u^2 + 1)^6 (a (u^2 + 1) + 2 a u)) unevaluated 0.1 s, 1066 chars 50 ms, 499 chars
u^5/((u^2 - 1)^5 (2 a u + b (u^2 + 1))) unevaluated >60 s 0.4 s

Measured: the four rows under IntegrationDecline.Guard in SymbolicFactorsPartialFractionsTest, differentiated back and bounded in length; the suite green locally (11523 passed, 6 m 40 s); BREAKING-CHANGES entry with the 2.5.0 values from a build of the tag. The independent Rubi suite and the family-6 sample are running and will be posted here.

Part of #718.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

Rafael-SOWNet and others added 2 commits September 18, 2026 10:53
… its rational content included, and a constant factor is not a symbolic coefficient

Two rows of the Rubi hyperbolic sample that were answered in under two
seconds became timeouts: csch(x)^5/(a + b cosh(x)) with #1389 and
tanh(x)^6/(a + a sech(x)) with #1392. Both are the symbolic
partial-fraction decomposition, and both are coefficients that were not
in lowest terms.

InLowestTermsOverTheSymbols put a coefficient in lowest terms by the
polynomial gcd, which normalizes its divisor to whole coprime
coefficients and so never cancels a number, and calls two sides without
a variable in common coprime before it looks: -1024/(1024 a) stayed as
it was. Newton's iteration for the inverse modulo (1 + u^2)^6 squares
its iterate every round, so the second round had 1024^2 and the third
integers of twelve hundred digits, and the minute went into their gcd.
The rational content of the denominator now goes up into the numerator
-- the denominator's coefficients whole and coprime with a positive
leading one, by the normalization the gcd already has, with the scale
it used handed back -- on every path out of the function.

The values the elimination solves for, where symbols are among them,
are put in lowest terms before the terms are built. csch^5/(a + b cosh)
under u = e^x, after the Hermite reduction, is a numerator with a page
of a and b over (u^2 - 1)(b + 2 a u + b u^2), and its values came out
at two thousand nodes each as quotients of determinants; each term
went round the chain with that in front and did not return. In lowest
terms they are 1/256 (3 a^3 - 7 a b^2)/(a^4 - 2 a^2 b^2 + b^4) and the
like, the answer is 27 kilobytes where it was 59, and the row is 1.3 s.

And the content of a written sum comes out before the symbolic split
rather than after it, and a constant factor in front of the denominator
does not make the split's gate read it as symbolic: a (1 + u^2) + 2 a u
is a (1 + u)^2, a repeated linear over the rationals, which the
refactoring and the Hermite reduction read, where the split computed
its digits with a in every coefficient for an answer twice the length.
tanh^6/(a + a sech) is 6.7 kilobytes and 2 s, from 7.8 kilobytes before
the regression.

Measured: the two rows and their rational cores under the wall-clock
guard in SymbolicFactorsPartialFractionsTest, differentiated back; the
suite green; the independent Rubi suite and the family-6 sample are in
the pull request.

Part of #718.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
The family-6 sample lost two rows to the first commit:
cosh(c + d x)^6/(a + b sinh(c + d x)^2)^2 and 1/(a + b csch(c + d x)^2)^3,
6.4 s and 3.4 s on master and past the budget on the branch. Their
elimination hands back values of twelve to twenty-eight thousand nodes,
and the lowest terms of one -- an expansion and a gcd -- did not return
in three seconds, where the answer with them as they come is six.
A value past 4096 in complexity is left as the elimination gave it;
the ones that needed the lowest terms were two thousand nodes.

Part of #718.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Rafael-SOWNet

Copy link
Copy Markdown
Member Author

Corpus on d5ce8276, both runs detached and alone on the machine:

  • Independent Rubi suite: 1706/1774, 0 wrong, 0 timeouts — identical verdicts to master e780ce9a (0 changed; 89.6 → 86.0 s).
  • Family 6 (hyperbolic, 417 problems): 315/417 from 312, 0 wrong, 0 error. Three rows changed, all Timeout → Solved: csch(x)^5/(a+b cosh(x)) 1.1 s, tanh(x)^6/(a+a sech(x)) 0.7 s, and coth(x)^4/(a+b csch(x)) (14.8 s in the run, answered from a warm memo — over the budget solo). Nothing lost.

The second commit is what the first run of family 6 asked for: it lost cosh(c+d x)^6/(a+b sinh(c+d x)^2)^2 (6.4 s on master) and 1/(a+b csch(c+d x)^2)^3 (3.4 s), confirmed solo, because their elimination hands back values of 12–28 thousand nodes and putting one in lowest terms did not return in three seconds where the answer with them as they come is six. A value past complexity 4096 is now left as the elimination gave it (the ones that needed the lowest terms were ~2 thousand nodes); both rows are back at master's timings.

@Rafael-SOWNet
Rafael-SOWNet marked this pull request as ready for review September 18, 2026 11:56
@Rafael-SOWNet
Rafael-SOWNet merged commit 84b0a9c into master Sep 18, 2026
31 checks passed
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.

1 participant