Skip to content

Split a rational function at a rational root of its denominator (#233) - #690

Merged
Happypig375 merged 2 commits into
ASC-Community:masterfrom
Rafael-SOWNet:feat/partial-fractions
Aug 4, 2026
Merged

Happypig375 merged 2 commits into
ASC-Community:masterfrom
Rafael-SOWNet:feat/partial-fractions

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Builds on #681 — the first of the two commits is that PR, and the diff will shrink to the second once it lands.

Named in #233's own list of what is missing.

"1 / (x ^ 3 + 1)".Integrate("x")   // master: integral(1 / (x ^ 3 + 1), x)

A linear or quadratic denominator was answered in one piece, but nothing read anything above that.

A step at a time, not the whole decomposition

A step is all that is needed: what is left over is a smaller problem of the same kind, and by the time its denominator is a quadratic there is already a rule for it.

1/(x³ + 1)  splits at the root −1 into  (1/3)/(x + 1)  +  (2 − x)/(3(x² − x + 1))

and the second of those is a linear numerator over a quadratic, which #681 reads as it stands. Each step takes a degree off the denominator, so it ends.

The coefficient is Heaviside's — at the root every other term of the decomposition is finite, so A = N(r)/Q(r) — and what is left, N − A·Q, then has that root by construction and divides exactly. All of it on exact ratios, reusing the rational-root search already here for factoring.

What it gains

Ten integrals, each checked by differentiating the answer back and comparing at points:

1/(x³+1), x/(x³+1)
1/(x³−x), 1/(x³+x) root at zero
1/(x⁴−1), x/(x⁴−1) two steps
(x²+1)/(x³−x) non-constant numerator
1/((x−1)(x−2)(x−3)) factored or multiplied out
(x+1)/(x³−x²−2x)

What it declines

Rational roots only, and simple ones:

  • No rational root — x²/(x⁴+1) is left unevaluated. x⁴+1 factors only over the irrationals.
  • A repeated root — that needs a term over (x − r)² as well, which this does not produce.
  • Degree below three — left to the rules that answer those in one piece, so nothing that already worked goes through this at all.
  • An improper fraction — a polynomial plus a proper one, and the division is not done here.

All four are left unevaluated rather than answered wrongly, and the first two are pinned as such.

Verification

21 tests, 10 of which fail without the change. 4038 unit tests and 127 F# tests on both target frameworks, none failing. 117-problem self-verifying corpus at 105/117 — int:partial-fractions goes from 60% to 80% — with nothing wrong, in error or timing out. 1320 property checks over 151 expressions, none failing.

The table matched k/(ax^2 + bx + c) only when k did not mention x, so anything with
a variable on top had no antiderivative at all:

  int x / (x^2 + 2x + 5)        int (x + 3) / (x^2 + 3x + 2)        int x / (x + 1)

A linear numerator is a multiple of the denominator's derivative plus a constant:
px + q = (p/2a)(2ax + b) + (q - pb/2a). The first part integrates to a logarithm and
the second is the constant-numerator case that was already there, so this only needs
the rewrite. The same rewrite one degree down turns (px + q)/(bx + c) into the
constant p/b plus a remainder over the divisor.

Both are guarded on the leading coefficient being a non-zero number, since the
rewrite divides by it. A quadratic denominator with a vanishing quadratic term falls
through to the linear arm rather than being divided by zero.

Also 1/cos(u)^2 and 1/sin(u)^2, which are written that way at least as often as
sec(u)^2 and csc(u)^2, and none of the four shapes was recognised.

Corpus 88/117 -> 91/117: int:table and int:rational-quadratic reach 100%, and
int:partial-fractions goes from 2 out of 5 to 3. 3901 unit tests and 127 F# tests
pass, no wrong answers in the corpus, and the property checker's 1320 checks are
clean.

x^2/(x^4 + 1) and 1/(x^3 + 1) are still out of reach: both need the denominator
factored first, which is a different piece of work.
A linear or quadratic denominator was answered in one piece, but nothing read
anything above that, so 1/(x^3 + 1) had no antiderivative at all. It is on the
list of what is missing in
#233.

The decomposition is done a step at a time rather than in full, because a step
is all that is needed: what is left over is a smaller problem of the same kind,
and by the time its denominator is a quadratic there is already a rule for it.
1/(x^3 + 1) splits at the root -1 into (1/3)/(x + 1) and
(2 - x)/(3(x^2 - x + 1)), and the second is a linear numerator over a quadratic,
which the previous commit reads as it stands. Each step takes a degree off the
denominator, so it ends.

The coefficient is Heaviside's -- at the root every other term of the
decomposition is finite, so A = N(r)/Q(r) -- and what is left, N - A*Q, then has
that root by construction and divides exactly. All of it on the exact ratios,
reusing the rational root search already here for factoring.

Rational roots only, and simple ones. A denominator with no rational root, such
as x^4 + 1, and one whose root repeats, which would need a term over the square
as well, are both left unevaluated rather than answered wrongly. A denominator
below degree three is left to the rules that answer it in one piece.

Ten integrals gained, each checked by differentiating back:
1/(x^3 + 1), x/(x^3 + 1), 1/(x^3 - x), 1/(x^3 + x), 1/(x^4 - 1), x/(x^4 - 1),
(x^2 + 1)/(x^3 - x), 1/((x - 1)(x - 2)(x - 3)) whether written factored or
multiplied out, and (x + 1)/(x^3 - x^2 - 2x).

21 tests, 10 of which fail without the change. 4038 in all, 127 F#, corpus
105/117 with the partial fraction category at 80% from 60% and nothing wrong,
in error or timing out. 1320 property checks.
@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 93.47826% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.57%. Comparing base (90c00a8) to head (35edae0).
⚠️ Report is 58 commits behind head on master.

Files with missing lines Patch % Lines
...th/Functions/Simplification/PolynomialFactoring.cs 88.09% 3 Missing and 2 partials ⚠️
...Continuous/Integration/IndefiniteIntegralSolver.cs 90.00% 0 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #690      +/-   ##
==========================================
- Coverage   80.99%   80.57%   -0.42%     
==========================================
  Files         155      156       +1     
  Lines       13687    13006     -681     
  Branches     1957     2141     +184     
==========================================
- Hits        11086    10480     -606     
+ Misses       1990     1920      -70     
+ Partials      611      606       -5     

☔ 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 a2c29b2 into ASC-Community:master Aug 4, 2026
24 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the feat/partial-fractions branch August 4, 2026 20:48
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