diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 5b3f0bb95..5051710b2 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -545,6 +545,20 @@ answered too ([#1852](https://github.com/asc-community/AngouriMath/issues/1852))
| `"x^m*sin(a + ln(k*x^n)*sqrt(-(1 + m)^2/n^2))".ToEntity().Integrate("x")` | `integral(...)` | 465 characters |
| `"x^2*sin(a + ln(k*x^n)*sqrt((-1)/n^2))^3".ToEntity().Integrate("x")` | `integral(...)` | 1,873 characters |
+### A power of a linear beside a quadratic's derivative over a power of the quadratic is integrated by parts
+
+**Answers where there were none.** `(b + 2 c x) sqrt(d + k x)/(a + b x + c x^2)^2` ran past any budget, the partial fractions
+taking the symbolic quadratic apart twice over. With `u` the power of the linear and `dv` the derivative over the power
+of the quadratic, parts leaves the quadratic one power lower, which is answered in under half a second
+([#718](https://github.com/asc-community/AngouriMath/issues/718)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"(b + 2*c*x)*(d + k*x)^4/(a + b*x + c*x^2)^2".ToEntity().Integrate("x")` | `integral(...)` | 2,215 characters |
+| `"(b + 2*c*x)*sqrt(d + k*x)/(a + b*x + c*x^2)^2".ToEntity().Integrate("x")` | `integral(...)` | 976 characters |
+| `"(b + 2*c*x)/((a + b*x + c*x^2)^2*sqrt(d + k*x))".ToEntity().Integrate("x")` | `integral(...)` | 1,075 characters |
+| `"(b + 2*c*x)*(d + k*x)^(3/2)/(a + b*x + c*x^2)^3".ToEntity().Integrate("x")` | `integral(...)` | 4,054 characters |
+
### An odd power of a quadratic's derivative over a power of the quadratic is integrated in the quadratic
**Shorter answers, and answers where there were none.** `(b + 2c x)^9/(a + b x + c x^2)^3` was answered through the
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index f6bb2f8db..3a7a8a3b4 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -19342,6 +19342,82 @@ Entity TakeOut(Entity node)
return inTermsOfU.Substitute(u, Number.Integer.One / x);
}
+ ///
+ /// A power of a linear beside the derivative of a quadratic, over a whole power of that
+ /// quadratic, by parts once: Q' L^m/Q^n with u = L^m and
+ /// dv = Q'/Q^n dx is -L^m/((n - 1) Q^(n - 1)) + m e/(n - 1) * integral L^(m - 1)/Q^(n - 1),
+ /// for L = d + e x, and the power of the quadratic is one lower in what is left.
+ ///
+ ///
+ /// Rubi's 1.2.1.3 (b + 2 c x) sqrt(d + e x)/(a + b x + c x^2)^2 and its kin took
+ /// thirty seconds or ran past the budget, the partial fractions taking the symbolic
+ /// quadratic apart twice over; what is left over its first power is answered in a third of
+ /// a second -- a whole power of the linear too, `(b + 2 c x) (d + e x)^4/(a + b x + c x^2)^2`
+ /// ran past the budget there. The numerator is read up to a constant multiple of Q'.
+ /// https://github.com/asc-community/AngouriMath/issues/718
+ ///
+ internal static Entity? SolveAPowerOfALinearBesideTheDerivativeOfAQuadraticOverItsPower(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ var (numerator, denominator) = Functions.SingleQuotient.Of(expr);
+ Entity? quadratic = null;
+ var power = 0;
+ Entity? linear = null;
+ Entity exponent = Number.Integer.Zero;
+ Entity? derivative = null;
+ Entity constant = Number.Integer.One;
+ foreach (var (side, below) in new[] { (numerator, false), (denominator, true) })
+ foreach (var factor in Mulf.LinearChildren(side))
+ {
+ if (!factor.ContainsNode(x))
+ {
+ constant = below ? constant / factor : constant * factor;
+ continue;
+ }
+ var (@base, raised) = factor is Powf(var b, var r) && !r.ContainsNode(x) ? (b, r) : (factor, (Entity)Number.Integer.One);
+ if (below && quadratic is null && raised is Number.Integer { EInteger: var whole } && whole.CompareTo(EInteger.FromInt32(2)) >= 0
+ && whole.CanFitInInt32() && TreeAnalyzer.TryGetPolyQuadratic(@base, x, out var leading, out _, out _) && !VanishesIdentically(leading))
+ {
+ quadratic = @base;
+ power = whole.ToInt32Unchecked();
+ continue;
+ }
+ if (!TreeAnalyzer.TryGetPolyLinear(@base, x, out var slope, out _) || VanishesIdentically(slope))
+ return null;
+ // The derivative once, above the bar; the linear any number of times, either side.
+ if (!below && derivative is null && raised == Number.Integer.One && (linear is null || linear != @base))
+ {
+ derivative = @base;
+ continue;
+ }
+ if (linear is not null && linear != @base)
+ return null;
+ linear = @base;
+ exponent = below ? exponent - raised : exponent + raised;
+ }
+ if (quadratic is null || derivative is null || linear is null
+ || !TreeAnalyzer.TryGetPolyQuadratic(quadratic, x, out var a, out var bq, out _)
+ || !TreeAnalyzer.TryGetPolyLinear(derivative, x, out var s, out var t)
+ || !TreeAnalyzer.TryGetPolyLinear(linear, x, out var e, out _))
+ return null;
+ // The derivative of Q is 2 a x + b; the numerator's linear is lambda times it.
+ var lambda = (s / (2 * a)).InnerSimplified;
+ if (!VanishesIdentically(t - lambda * bq))
+ return null;
+ exponent = exponent.InnerSimplified;
+ // A negative whole power of the linear is a rational function whose power of the
+ // linear parts would raise: `(b + 2 c x)/((d + e x) Q^3)` went from 6,220 characters
+ // to 14,351, the partial fractions answering it whole as before.
+ if (exponent == Number.Integer.Zero || exponent is Number.Integer { EInteger.Sign: < 0 })
+ return null;
+ var lower = power - 1;
+ var outside = -MathS.Pow(linear, exponent) / (lower * MathS.Pow(quadratic, Number.Integer.Create(lower)));
+ var left = exponent * e * MathS.Pow(linear, (exponent - 1).InnerSimplified) / (lower * MathS.Pow(quadratic, Number.Integer.Create(lower)));
+ if (Integration.ComputeAsAQuestionOfItsOwn(left.InnerSimplified, x, integrateByParts) is not { } rest)
+ return null;
+ var answer = (constant * lambda * (outside + rest)).InnerSimplified;
+ return Functions.PartialFractions.DerivativeHoldsAtSampledPoints(answer, expr, x) ? answer : null;
+ }
+
///
/// A root of a product beside a root of one of its factors, or a symbolic power of one
/// beside a symbolic power of a factor, the product split:
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 8c9302082..49f6fbd56 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -666,6 +666,9 @@ private static Entity WithItsPiecewiseSumsCombined(Entity expr)
// the question asked only, and the polynomial term below writes `1/u` as `u^(-1)` and
// asks that a level down: `1/(e^atanh(a x) (c - c/(a x))^(3/2))` reached it nowhere.
if ((answer = IndefiniteIntegralSolver.SolveByWritingEachLinearOnce(expr, x, integrateByParts)) is { }) return answer;
+ // A power of a linear beside the derivative of a quadratic over a whole power of it, by
+ // parts once, before anything takes the symbolic quadratic apart.
+ if ((answer = IndefiniteIntegralSolver.SolveAPowerOfALinearBesideTheDerivativeOfAQuadraticOverItsPower(expr, x, integrateByParts)) is { }) return answer;
// A root or a power of a product beside a power of one of its factors, the product
// split: `(a + b x^2)^(5/2)/sqrt(a^2 - b^2 x^4)` is `K (a + b x^2)^2/sqrt(a - b x^2)`.
// Early, since what reads the product whole is slower and longer: Rubi's 1.2.1.2:2218,
diff --git a/Sources/Tests/UnitTests/Calculus/TheDerivativeOfAQuadraticOverItsPowerIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/TheDerivativeOfAQuadraticOverItsPowerIntegralTest.cs
new file mode 100644
index 000000000..7691ba53f
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/TheDerivativeOfAQuadraticOverItsPowerIntegralTest.cs
@@ -0,0 +1,59 @@
+//
+// Copyright (c) 2019-2026 Angouri.
+// AngouriMath is licensed under MIT.
+// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
+// Website: https://am.angouri.org.
+//
+
+using System;
+using AngouriMath.Extensions;
+using Xunit;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// A power of a linear beside the derivative of a quadratic over a whole power of the
+ /// quadratic, by parts once. Rubi's 1.2.1.3 (b + 2 c x) sqrt(d + e x)/(a + b x + c x^2)^2,
+ /// written here with k for e, which is Euler's number.
+ /// #718
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class TheDerivativeOfAQuadraticOverItsPowerIntegralTest
+ {
+ private static void DifferentiatesBack(string integrand, params (string, double)[] pins)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ Assert.DoesNotContain("integral(", integral.Stringize());
+
+ // Pinned before it is differentiated, as the answers the rest of the integral writes
+ // carry signs and cases read where their arguments are numbers.
+ var pinned = integral.Substitute("C", 0);
+ Entity original = integrand.ToEntity();
+ foreach (var (name, value) in pins)
+ {
+ pinned = pinned.Substitute(name, value);
+ original = original.Substitute(name, value);
+ }
+ var derivative = pinned.Differentiate("x");
+ foreach (var at in new[] { -2.3, -0.7, 0.4, 1.9 })
+ {
+ var got = derivative.Substitute("x", at).EvalNumerical();
+ var want = original.Substitute("x", at).EvalNumerical();
+ var difference = Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart);
+ var scale = Math.Max(1.0, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart));
+ Assert.True(difference / scale < 1e-8,
+ $"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
+ }
+ }
+
+ [Theory]
+ [InlineData("(b+2*c*x)*sqrt(d+k*x)/(a+b*x+c*x^2)^2")]
+ [InlineData("(b+2*c*x)/((a+b*x+c*x^2)^2*sqrt(d+k*x))")]
+ [InlineData("(b+2*c*x)*(d+k*x)^4/(a+b*x+c*x^2)^2")]
+ public void IsAnsweredAndDifferentiatesBack(string integrand)
+ {
+ DifferentiatesBack(integrand, ("a", 2), ("b", 1.5), ("c", 1.25), ("d", 1.25), ("k", 2));
+ DifferentiatesBack(integrand, ("a", -1), ("b", 2), ("c", 2), ("d", -0.5), ("k", 1.5));
+ }
+ }
+}