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.
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:
Measured on a clean build of
masterat 51194ce.The denominator is
(x^2 + 1)(x^2 + 2), and the answer isarctan(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, becausex^4 - 1has rational roots at±1and the existing step can get a foothold.Why
IndefiniteIntegralSolver.SolveByPartialFractionssplitsN/Dat a rational root ofD, viaPolynomialFactoring.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:
Dinto irreducibles, and group them into two coprime partsAandB;U,VwithU·A + V·B = 1by the extended Euclidean algorithm in ℚ[x];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.Gcdover ℤ without the Bézout cofactors.Repeated factors need the usual ladder over
(x - r)^k/(f)^k;TrySplitOffRationalRootalready handles the rational-root case of that and is worth reading first.Worth checking before starting
Providedconditions the existing step attaches survive the split correctly — cancelling a factor is where a domain silently widens.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.