diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 06ad30b60..71c1b2b42 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -608,6 +608,19 @@ no numeric root finder applies, and its discriminant vanishes identically. Such
| `"1/(x^3-3*b*x+2*b^(3/2))".ToEntity().Integrate("x")` | `integral(...)` | 122 characters |
| `"1/(-9*b*x+9*x^3+2*b^(3/2)*sqrt(3))".ToEntity().Integrate("x")` | `integral(...)` | 176 characters |
+### An exponential of an arctangent beside a power of its quadratic is answered where it is an exact derivative
+
+**Answers where there were none.** `e^(i n arctan(a x)) x^2 (c + a^2 c x^2)^(-1 - n^2/2)` was left unevaluated: no rule
+reads a polynomial beside the exponential and a symbolic power of `c + a^2 c x^2`. Where the integrand is the
+derivative of `e^(N arctan(a x)) (α + β x) (c + a^2 c x^2)^(p + 1)` for a quadratic polynomial beside it, the two
+coefficients are solved for and that is the answer, checked by differentiating it back
+([#718](https://github.com/asc-community/AngouriMath/issues/718)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"e^(i*n*atan(a*x))*x^2*(c+a^2*c*x^2)^(-1-n^2/2)".ToEntity().Integrate("x")` | `integral(...)` | 148 characters |
+| `"e^(2*atan(x))*(3+8/3*x+5/3*x^2)*(1+x^2)^(-2/3)".ToEntity().Integrate("x")` | `integral(...)` | `e ^ (2 * arctan(x)) * (1 + x) * (1 + x ^ 2) ^ (1/3) + C` |
+
### An exponential of i arctan below the bar is read as a negative multiple
**Answers where there were none.** `x^2/(e^(i arctan(a x)) (c + a^2 c x^2)^(3/2))` was left unevaluated: the exponential
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index 8f143a53c..e41ab1075 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -9746,6 +9746,69 @@ node is Powf(var @base, Number.Rational power) && power is not Number.Integer &&
return ratio;
}
+ ///
+ /// An exponential of a multiple of arctan(a x) times a quadratic polynomial times a
+ /// power of c + a^2 c x^2, where it is an exact derivative:
+ /// (e^(N arctan(a x)) (alpha + beta x) Q^s)' is
+ /// c e^(N arctan(a x)) Q^(s - 1) (a N alpha + beta + (a N beta + 2 s a^2 alpha) x + a^2 beta (1 + 2 s) x^2)
+ /// for Q = c + a^2 c x^2, since Q^s/(1 + a^2 x^2) = c Q^(s - 1). The
+ /// constant and squared coefficients give alpha and beta; the linear one is
+ /// the condition. Rubi's 5.3.6:504, e^(i n arctan(a x)) x^2 (c + a^2 c x^2)^(-1 - n^2/2),
+ /// meets it exactly, and was left unevaluated: as powers of the two linears its exponents
+ /// do not sum to a whole number.
+ /// https://github.com/asc-community/AngouriMath/issues/718
+ ///
+ internal static Entity? SolveAnExactDerivativeOfAnExponentialOfAnArctangent(Entity expr, Entity.Variable x)
+ {
+ Entity? multiple = null, slope = null, quadratic = null, power = null;
+ Entity polynomial = Number.Integer.One;
+ foreach (var factor in Mulf.LinearChildren(expr))
+ {
+ if (factor is Powf(var e, var exponent) && e == MathS.e && exponent.ContainsNode(x))
+ {
+ if (multiple is not null)
+ return null;
+ var inverse = exponent.Nodes.OfType().FirstOrDefault();
+ if (inverse is null || !TreeAnalyzer.TryGetPolyLinear(inverse.Argument, x, out var a, out var b) || !TreeAnalyzer.IsZero(b))
+ return null;
+ var placeholder = Variable.CreateUnique(exponent, "u_atan");
+ var inThePlaceholder = exponent.Replace(node => node == inverse ? placeholder : node);
+ if (inThePlaceholder.ContainsNode(x) || !TreeAnalyzer.TryGetPolyLinear(inThePlaceholder, placeholder, out var n, out var constantPart)
+ || !TreeAnalyzer.IsZero(constantPart) || TreeAnalyzer.IsZero(n))
+ return null;
+ (multiple, slope) = (n, a);
+ }
+ else if (factor is Powf(var q, var p) && !p.ContainsNode(x) && p is not Number.Integer && q.ContainsNode(x))
+ {
+ if (quadratic is not null)
+ return null;
+ (quadratic, power) = (q, p);
+ }
+ else
+ polynomial *= factor;
+ }
+ if (multiple is null || slope is null || quadratic is null || power is null)
+ return null;
+ if (!TreeAnalyzer.TryGetPolyQuadratic(quadratic, x, out var c2, out var c1, out var c0) || !TreeAnalyzer.IsZero(c1) || TreeAnalyzer.IsZero(c0)
+ || !VanishesIdentically((c2 - MathS.Sqr(slope) * c0).Expand()))
+ return null;
+ if (!TreeAnalyzer.TryGetPolyQuadratic(polynomial, x, out var p2, out var p1, out var p0))
+ return null;
+ var s = (power + 1).Simplify();
+ var twice = (1 + 2 * s).Simplify();
+ if (TreeAnalyzer.IsZero(twice) || TreeAnalyzer.IsZero(p2))
+ return null;
+ var beta = (p2 / (c0 * MathS.Sqr(slope) * twice)).Simplify();
+ var alpha = ((p0 / c0 - beta) / (slope * multiple)).Simplify();
+ if (!VanishesIdentically((c0 * (slope * multiple * beta + 2 * s * MathS.Sqr(slope) * alpha) - p1).Simplify()))
+ return null;
+ var exponential = Mulf.LinearChildren(expr).First(factor => factor is Powf(var e, _) && e == MathS.e && factor.ContainsNode(x));
+ var candidate = exponential * (alpha + beta * x) * MathS.Pow(quadratic, s);
+ if (!AreProportionalAtSampledPoints(candidate.Differentiate(x), expr, x))
+ return null;
+ return candidate;
+ }
+
///
/// An exponential of a symbolic multiple of i arctan(L), L linear, beside
/// powers of multiples of 1 + L^2, written as powers of the two linears:
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 075450f19..7204719a2 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -670,6 +670,8 @@ private static Entity WithItsPiecewiseSumsCombined(Entity expr)
// An exponential of i times an inverse trigonometric function written algebraically, at the
// question asked, before the rules that spent the budget: `e^(3 i atan(a + b x))/x^2` ran out of
// time where, rewritten, it is answered in half a second. It is asked again in its place below.
+ // An exact derivative among them first, closed: `e^(i n arctan(a x)) x^2 (c + a^2 c x^2)^(-1 - n^2/2)`.
+ if ((answer = IndefiniteIntegralSolver.SolveAnExactDerivativeOfAnExponentialOfAnArctangent(expr, x)) is { }) return answer;
if (AnsweringTheQuestionAsked && (answer = IndefiniteIntegralSolver.SolveByWritingAnExponentialOfAnInverseAlgebraically(expr, x, integrateByParts)) is { }) return answer;
// The same for a symbolic multiple of the arctangent, beside powers of its quadratic.
if (AnsweringTheQuestionAsked && (answer = IndefiniteIntegralSolver.SolveAnExponentialOfASymbolicMultipleOfAnArctangentAsPowersOfTheLinears(expr, x, integrateByParts)) is { }) return answer;
diff --git a/Sources/Tests/UnitTests/Calculus/AnExactDerivativeOfAnExponentialOfAnArctangentIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/AnExactDerivativeOfAnExponentialOfAnArctangentIntegralTest.cs
new file mode 100644
index 000000000..f6c5e09d6
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/AnExactDerivativeOfAnExponentialOfAnArctangentIntegralTest.cs
@@ -0,0 +1,56 @@
+//
+// 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
+{
+ ///
+ /// An exponential of a multiple of arctan(a x) times a quadratic times a power of
+ /// c + a^2 c x^2, where it is an exact derivative: Rubi's 5.3.6
+ /// e^(i n arctan(a x)) x^2 (c + a^2 c x^2)^(-1 - n^2/2), which was left unevaluated.
+ /// #718
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class AnExactDerivativeOfAnExponentialOfAnArctangentIntegralTest
+ {
+ private static void DifferentiatesBack(string integrand, params (string, double)[] pins)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ Assert.DoesNotContain("integral(", integral.Stringize());
+
+ 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("e^(i*n*atan(a*x))*x^2*(c+a^2*c*x^2)^(-1-n^2/2)")]
+ [InlineData("e^(2*atan(x))*(3+8/3*x+5/3*x^2)*(1+x^2)^(-2/3)")]
+ public void IsAnsweredAndDifferentiatesBack(string integrand)
+ {
+ DifferentiatesBack(integrand, ("a", 1.3), ("c", 0.7), ("n", 0.4));
+ DifferentiatesBack(integrand, ("a", -0.5), ("c", -1.5), ("n", 2.3));
+ }
+ }
+}