Skip to content

Partial fractions over irreducible factors, not only rational roots #919

Description

@Rafael-SOWNet

What happens

A rational function whose denominator factors over ℚ but has no rational root has no antiderivative today, even when every factor is one the integrator already handles:

"1/(x^4 + 3x^2 + 2)".Integrate("x")   ->  integral(1 / (x ^ 4 + 3 * x ^ 2 + 2), x)
"x/(x^4 + 3x^2 + 2)".Integrate("x")   ->  integral(x / (x ^ 4 + 3 * x ^ 2 + 2), x)

Measured on a clean build of master at 51194ce.

The denominator is (x^2 + 1)(x^2 + 2), and the answer is arctan(x) - arctan(x/sqrt(2))/sqrt(2). Both factors are quadratics the rule for a linear numerator over a quadratic already integrates. Nothing is missing but the split.

For contrast, 1/(x^4 - 1) is integrated, because x^4 - 1 has rational roots at ±1 and the existing step can get a foothold.

Why

IndefiniteIntegralSolver.SolveByPartialFractions splits N/D at a rational root of D, via PolynomialFactoring.TrySplitOffRationalRoot. That is all the decomposition there is, so a denominator with no rational root is left whole and the integral is returned unevaluated. This is honest — it is not a wrong answer — but it is a gap with a known cure.

What would fix it

#918 adds univariate factorisation over ℚ (PolynomialFactorization), so the irreducible factorisation of the denominator is now available. What is still missing is the decomposition itself.

The smallest step that fits the existing design — which deliberately does one step and recurses, each step taking a degree off the denominator — is a coprime split rather than a full decomposition:

  • factor D into irreducibles, and group them into two coprime parts A and B;
  • find U, V with U·A + V·B = 1 by the extended Euclidean algorithm in ℚ[x];
  • then N/(A·B) = N·V/A + N·U/B, and each side is a strictly smaller problem of the same kind.

That needs an extended Euclid over ℚ[x], which does not exist yet — there is one over 𝔽ₚ inside the factoriser, and IntegerPolynomial.Gcd over ℤ without the Bézout cofactors.

Repeated factors need the usual ladder over (x - r)^k / (f)^k; TrySplitOffRationalRoot already handles the rational-root case of that and is worth reading first.

Worth checking before starting

  • That the recursion still terminates on every path, and that a factor the quadratic rules cannot integrate is left unevaluated rather than half-transformed.
  • Whether the Provided conditions the existing step attaches survive the split correctly — cancelling a factor is where a domain silently widens.
  • What it does to the integration corpus, not just to these two inputs.

Part of #746 item 43's follow-on: the polynomial layer exists now, and this is one of the things that was waiting behind it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    <medium> up-for-grabsThat task is between <easy> and <hard>. Maybe not five minutes of work, but also not too huge.ProposalContribute to the project by proposing some improvements

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions