diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 7a9dc5dfe..fd7d5df4d 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -177,6 +177,22 @@ the division's; with it on, the rounding is the setting's own and stays
| `"(-60.5)!"` at 30 digits, downcasting off | `5.86118478907722232671451280188E-81` | `2.93059239453861116335725639905E-81` |
| `"abs(75 + 316.22776601683796i)"`, downcasting off | `325` | `325.000000000000026076735749…` |
+### `a + i a tan` beside the tangent's differential is lowered over its conjugate
+
+**Answers where there were none.** `sqrt(a + i a tan(x))/(c + d tan(x))^(3/2)` ran past thirty seconds:
+under `u = tan(x)` it is `sqrt(a + i a u)/((c + d u)^(3/2) (1 + u^2))`, a search, where
+`(a + i a u)(a - i a u)` is `a^2 (1 + u^2)` and the sum's power is lowered by one over its conjugate, a root
+of a linear over a linear, which is answered in a second
+([#718](https://github.com/asc-community/AngouriMath/issues/718)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"sqrt(a + i*a*tan(x))/(c + d*tan(x))^(3/2)".ToEntity().Integrate("x")` | `integral(...)`; past thirty seconds on the unreleased master | 1,893 characters |
+| `"(a + i*a*tan(x))^(3/2)*(c + d*tan(x))^(5/2)".ToEntity().Integrate("x")` | `integral(...)`; past thirty seconds on the unreleased master | 670 characters |
+| `"sqrt(a + i*a*tan(x))/sqrt(c + d*tan(x))".ToEntity().Integrate("x")` | `integral(...)` | 169 characters |
+| `"1/(sqrt(a + i*a*tan(x))*(c + d*tan(x))^(3/2))".ToEntity().Integrate("x")` | `integral(...)`; past thirty seconds on the unreleased master | 2,217 characters |
+| `"1/((a + i*a*tan(x))^(3/2)*(c + d*tan(x))^(5/2))".ToEntity().Integrate("x")` | `integral(...)`; past thirty seconds on the unreleased master | 3,333 characters |
+
### One linear twice is not two linear powers
**Answers that had no value.** `(a c + b c x)^(-3 - 2 p) (f + g x) (a^2 + 2 a b x + b^2 x^2)^p` was answered
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index f632213fd..06b630a3a 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -10360,8 +10360,14 @@ static bool IsTwice(Entity argument, Entity.Variable x)
// none: `1/(u^2*(1 + u^2))` is integrated and `(1/u)^2/(1 + u^2)`, which is the same
// expression, is not. The half-angle and exponential substitutions comb their
// integrands for the same reason.
- var integrand = Functions.SingleQuotient
- .Combine(inU / (1 + MathS.Sqr(uSub))).Simplify();
+ // A power of A + i A u beside the differential: (A + i A u)(A - i A u) is A^2 (1 + u^2),
+ // so 1/(1 + u^2) is A^2/((A + i A u)(A - i A u)) and the sum's power is lowered by one,
+ // a root of a linear over a linear. `sqrt(a + i a tan(x))/(c + d tan(x))^(3/2)` was a
+ // search past thirty seconds as a quotient by 1 + u^2, and in the sum's conjugate it is
+ // answered in a second.
+ var integrand = ByTheSumsConjugate(inU, uSub) is { } overTheConjugate
+ ? overTheConjugate
+ : Functions.SingleQuotient.Combine(inU / (1 + MathS.Sqr(uSub))).Simplify();
if (integrand is Providedf(var withoutCondition, _))
integrand = withoutCondition;
// Asked as the same question: the rewrite renames the variable and adds no step of
@@ -10373,6 +10379,34 @@ static bool IsTwice(Entity argument, Entity.Variable x)
? result.Substitute(uSub, tangent)
: null;
}
+
+ ///
+ /// inU/(1 + u^2) written with the conjugate of a factor A +- i A u of
+ /// : inU/(A +- i A u) A^2/(A -+ i A u). Null where no factor is
+ /// such a sum.
+ ///
+ private static Entity? ByTheSumsConjugate(Entity inU, Entity.Variable u)
+ {
+ // A reciprocal of a product read as the quotient it is: a constant taken out of the
+ // sum's root leaves `(sqrt(1 + i u) (c + d u)^(3/2))^(-1)`, whose factors are below the bar.
+ if (inU is Powf(var reciprocal, Number.Integer { EInteger: var minusOne }) && minusOne.Equals(EInteger.FromInt32(-1)))
+ inU = 1 / reciprocal;
+ foreach (var (factor, _) in FactorsOfTheIntegrand(inU))
+ {
+ // A root of the sum, not a whole power: a polynomial in it beside the cosine is the
+ // rules' for the sine and the cosine, which answer `cos(x)^6 (a + i a tan(x))` sooner.
+ if (factor is not Powf(var sum, Number.Rational { ERational.Denominator: var denominator }) || denominator.Equals(EInteger.One))
+ continue;
+ if (sum is not Sumf and not Minusf || !TreeAnalyzer.TryGetPolyLinear(sum, u, out var slope, out var intercept)
+ || TreeAnalyzer.IsZero(intercept) || TreeAnalyzer.IsZero(slope))
+ continue;
+ if (!TreeAnalyzer.IsZero((slope - MathS.i * intercept).Simplify()) && !TreeAnalyzer.IsZero((slope + MathS.i * intercept).Simplify()))
+ continue;
+ var conjugate = intercept - slope * u;
+ return (inU / sum * MathS.Sqr(intercept) / conjugate).InnerSimplified;
+ }
+ return null;
+ }
///
/// (prod f_i^(k_i))^(p/q), q odd, as prod f_i^(k_i p/q) where every
/// f_i is a trigonometric function of itself or free of it,
diff --git a/Sources/Tests/UnitTests/Calculus/ImaginaryTangentSumBesideARootOfALinearInTheTangentIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/ImaginaryTangentSumBesideARootOfALinearInTheTangentIntegralTest.cs
new file mode 100644
index 000000000..b8012d1ae
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/ImaginaryTangentSumBesideARootOfALinearInTheTangentIntegralTest.cs
@@ -0,0 +1,54 @@
+//
+// 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 + i a tan(x) beside a root of c + d tan(x). Under u = tan(x),
+ /// dx = du/(1 + u^2) and (a + i a u)(a - i a u) = a^2 (1 + u^2), so the sum's power is
+ /// lowered by one over its conjugate: a root of a linear over a linear. Rubi's 4.3.2.1. The
+ /// integrands are complex for a real x and are compared as complex numbers.
+ /// #718
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class ImaginaryTangentSumBesideARootOfALinearInTheTangentIntegralTest
+ {
+ [Theory]
+ [InlineData("sqrt(a + i*a*tan(x))/(c + d*tan(x))^(3/2)")]
+ [InlineData("(a + i*a*tan(x))^(3/2)*(c + d*tan(x))^(5/2)")]
+ [InlineData("sqrt(a + i*a*tan(x))/sqrt(c + d*tan(x))")]
+ [InlineData("1/(sqrt(a + i*a*tan(x))*(c + d*tan(x))^(3/2))")]
+ [InlineData("1/((a + i*a*tan(x))^(3/2)*(c + d*tan(x))^(5/2))")]
+ public void OverTheSumsConjugate(string integrand)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ var text = integral.Stringize();
+ Assert.DoesNotContain("integral(", text);
+ Assert.True(text.Length < 5000, $"{text.Length} characters of answer for {integrand}");
+ Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("c", 0.7).Substitute("d", 1.1);
+ var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
+ var original = Pinned(integrand.ToEntity());
+ var compared = 0;
+ foreach (var at in new[] { -1.2, -0.7, 0.3, 0.8, 1.3, 2.9 })
+ {
+ var want = original.Substitute("x", at).EvalNumerical();
+ var got = derivative.Substitute("x", at).EvalNumerical();
+ if (want.IsNaN)
+ continue;
+ compared++;
+ Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
+ < 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
+ $"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
+ }
+ Assert.True(compared >= 5, $"only {compared} points could be compared for {integrand}");
+ }
+ }
+}