diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 67f202fff..8bf45eebb 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -365,6 +365,24 @@ quotient of two such linears the sum is `(b - d t^2)^2 + (c t^2 - a)^2`. Rubi's
| `"(c + d*tan(x))^(3/2)/(a + b*tan(x))^3".ToEntity().Integrate("x")` | `integral(...)` | the same |
| `"1/((a + b*tan(x))^(3/2)*(c + d*tan(x))^(3/2))".ToEntity().Integrate("x")` | `integral(...)`; past a minute on the unreleased master | in the root of the quotient of the two, in a second |
+### A power of the secant beside a power of `a + i a tan` is integrated in the sum, whatever the powers
+
+**Answers where there were none.** `sec(x)^3 sqrt(a + i a tan(x))` was declined, with the rest of
+Rubi's 4.3.1.2 whose powers add up to no whole number. Under `u = a + i a tan(z)`,
+`du = i a sec(z)^2 dz` and `sec(z)^2 = (u/a) ((2 a - u)/a)`, so a power of the secant, or of the
+cosine, beside a power of the sum is a power of `u` beside a power of `2 a - u`. The antiderivative in
+`u` is found for a real `u`, and its conditions -- a radicand at least zero -- hold nowhere on the
+path, where `u` is not real; they are dropped, and the answer is kept only where its derivative is the
+integrand at sampled points. `cos(x)^9 (a + i a tan(x))^(7/2)` was answered on the unreleased master
+with the condition `1 + i tan(x) >= 0`, which no real `x` but the zeros of the tangent meets; it is
+answered without one now ([#718](https://github.com/asc-community/AngouriMath/issues/718)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"sec(x)^3*sqrt(a + i*a*tan(x))".ToEntity().Integrate("x")` | `integral(...)` | powers of `sqrt(a - i a tan(x))` times a factor constant wherever it is continuous, 495 characters |
+| `"sec(x)^5/(a + i*a*tan(x))^(3/2)".ToEntity().Integrate("x")` | `integral(...)` | the same, 399 characters |
+| `"cos(x)^9*(a + i*a*tan(x))^(7/2)".ToEntity().Integrate("x")` | `integral(...)`; on the unreleased master, an answer provided `1 + i tan(x) >= 0` | 1,067 characters, unconditional |
+
### A quotient in `x^2` over a power of a linear in `x^2` and a biquadratic is split in `x^2`
**Shorter answers, sooner.** `sqrt(c + d tan(x)) (A + B tan(x) + C tan(x)^2)/(a + b tan(x))^3` was
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index 729347128..fa6842798 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -27007,6 +27007,124 @@ static Entity SumOfThePowers(Entity first, Entity second)
=> (first + second).InnerSimplified is var sum && (sum is Number || sum.Complexity > 40) ? sum : sum.Simplify();
}
+ ///
+ /// A power of the secant, or of the cosine, of z beside a power of A + i A tan(z),
+ /// whatever the powers, integrated in that sum: under u = A + i A tan(z),
+ /// du = i A sec(z)^2 dz and sec(z)^2 = (u/A) ((2 A - u)/A), so
+ /// sec(z)^s u^n dz is u^n ((u/A) ((2 A - u)/A))^r du/(i A) with
+ /// r = (s - 2)/2, up to a factor constant wherever it is continuous; and
+ /// (u/A)^r ((2 A - u)/A)^r is (sec(z)^2)^r exactly, the two being
+ /// 1 + i tan(z) and 1 - i tan(z), whose arguments are opposite and less than a
+ /// right angle.
+ ///
+ ///
+ ///
+ /// sec(x)^3 sqrt(a + i a tan(x)) was declined, with the rest of Rubi's 4.3.1.2 whose
+ /// powers do not add up to a whole number, which
+ /// integrates as an
+ /// exponential and this does not: sec^5/(a + i a tan)^(3/2),
+ /// (e cos)^(3/2) sqrt(a + i a tan). In u each is a power of u beside a
+ /// power of 2 A - u.
+ ///
+ ///
+ /// The constant is not written, as there: the answer is the integrand times the
+ /// antiderivative in u over what that antiderivative differentiates back to, a
+ /// quotient constant wherever it is continuous.
+ /// https://github.com/asc-community/AngouriMath/issues/718
+ ///
+ ///
+ internal static Entity? SolveAPowerOfTheSecantBesideAPowerOfAnImaginaryTangentSumInTheSum(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ if (!expr.Nodes.Any(node => node is Tanf) || !expr.Nodes.Any(node => node is Secantf or Cosf))
+ return null;
+ Entity? argument = null, sum = null;
+ var plus = false;
+ Entity? sumPower = null;
+ Entity secantPower = Number.Integer.Zero;
+ var sawSecant = false;
+ foreach (var (factor, underneath) in FactorsOfTheIntegrand(expr))
+ {
+ if (!factor.ContainsNode(x))
+ continue;
+ var (@base, power) = factor is Powf(var b, var p) && !p.ContainsNode(x)
+ ? (b, p.Evaled is Number.Rational r ? r : p)
+ : (factor, (Entity)Number.Integer.One);
+ if (underneath)
+ power = power is Number.Rational numeric ? -numeric : (-power).InnerSimplified;
+ if (TryReadAnImaginaryTangent(@base, x, out var tangentOf, out var isPlus))
+ {
+ if (sumPower is not null || argument is not null && argument != tangentOf)
+ return null;
+ (sumPower, argument, plus, sum) = (power, tangentOf, isPlus, @base);
+ continue;
+ }
+ var (trigonometric, sign) = @base switch
+ {
+ Secantf => (@base, 1),
+ Cosf => (@base, -1),
+ Mulf(var left, var right) when !left.ContainsNode(x) && right is Secantf => (right, 1),
+ Mulf(var left, var right) when !left.ContainsNode(x) && right is Cosf => (right, -1),
+ Mulf(var left, var right) when !right.ContainsNode(x) && left is Secantf => (left, 1),
+ Mulf(var left, var right) when !right.ContainsNode(x) && left is Cosf => (left, -1),
+ _ => ((Entity?)null, 0)
+ };
+ var of = trigonometric switch { Secantf(var inner) => inner, Cosf(var inner) => inner, _ => null };
+ if (of is null || argument is not null && argument != of)
+ return null;
+ argument = of;
+ secantPower = sign == 1 ? secantPower + power : secantPower - power;
+ sawSecant = true;
+ }
+ if (sumPower is null || sum is null || argument is null || !sawSecant
+ || !TreeAnalyzer.TryGetPolyLinear(argument, x, out var slope, out _) || TreeAnalyzer.IsZero(slope))
+ return null;
+ secantPower = secantPower is Number ? secantPower : secantPower.InnerSimplified;
+ // Whole powers on both are a rational function of the sine and the cosine, which the
+ // rules for those answer in a fraction of a second, where in u they ran past five:
+ // `cos(x)^5/(a + i a tan(x))^3`.
+ if (sumPower is Number.Integer && secantPower is Number.Integer)
+ return null;
+ Entity constantTerm = Number.Integer.Zero;
+ foreach (var term in Sumf.LinearChildren(sum))
+ if (!term.ContainsNode(x))
+ constantTerm += term;
+ var a = constantTerm.InnerSimplified;
+ var u = Variable.CreateUnique(expr, "u_tan");
+ var half = ((secantPower - 2) / 2).InnerSimplified;
+ Entity squared = MathS.Pow(u / a, half) * MathS.Pow((2 * a - u) / a, half);
+ var inU = MathS.Pow(u, sumPower) * squared;
+ if (Integration.ComputeAsAQuestionOfItsOwn(inU, u, integrateByParts) is not { } inUAnswer
+ || inUAnswer.Nodes.Any(node => node == MathS.NaN))
+ return null;
+ // du/dx is +-i A z' sec(z)^2.
+ var derivativeOfU = (plus ? MathS.i : -MathS.i) * a * slope * MathS.Pow(MathS.Sec(argument), 2);
+ var differentiatesBackTo = inU.Substitute(u, sum) * derivativeOfU;
+ // The antiderivative in u was found for a real u, and its conditions say so -- a radicand
+ // at least zero -- where u = A + i A tan(z) is not real: kept, they hold nowhere on the
+ // path and the answer has no value at all. The formula is an antiderivative wherever it is
+ // analytic, so the conditions go, each piecewise taken arm by arm, and an answer is kept
+ // only where its derivative is the integrand at the sampled points.
+ foreach (var arm in new[] { 0, -1 })
+ {
+ var formula = WithoutConditions(inUAnswer, arm);
+ var answer = expr * formula.Substitute(u, sum) / differentiatesBackTo;
+ if (Functions.PartialFractions.DerivativeHoldsAtSampledPoints(answer, expr, x))
+ return answer;
+ if (!inUAnswer.Nodes.Any(node => node is Piecewise))
+ break;
+ }
+ return null;
+
+ // Every condition dropped, and of every piecewise the first arm, or with -1 the last.
+ static Entity WithoutConditions(Entity e, int arm)
+ => e.Replace(node => node switch
+ {
+ Providedf(var inner, _) => inner,
+ Piecewise piecewise when piecewise.Cases.Any() => arm == 0 ? piecewise.Cases.First().Expression : piecewise.Cases.Last().Expression,
+ _ => node
+ });
+ }
+
///
/// A + i A tan(z) or A - i A tan(z), with a constant A: the argument,
/// and whether the imaginary unit comes with a plus.
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 15073706b..cd915e3f9 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -683,6 +683,8 @@ private static Entity Normalized(Entity expr, Entity.Variable x) =>
// product and takes it apart, and so answers (c sec)^(5/2)/(a + i a tan)^(5/2) with the
// wrong constant wherever the cosine is negative.
if ((answer = IndefiniteIntegralSolver.SolveAPowerOfAnImaginaryTangentBesideAPowerOfTheSecant(expr, x, integrateByParts)) is { }) return answer;
+ // And whatever the powers, in the sum, where they do not add up to a whole number.
+ if ((answer = IndefiniteIntegralSolver.SolveAPowerOfTheSecantBesideAPowerOfAnImaginaryTangentSumInTheSum(expr, x, integrateByParts)) is { }) return answer;
// And powers of the two conjugate sums, both not whole, as the exponential they make.
if ((answer = IndefiniteIntegralSolver.SolveAConjugatePairOfImaginaryTangentSums(expr, x, integrateByParts)) is { }) return answer;
// A rational function of the tangent beside a power of a + i a tan(z), in that sum.
diff --git a/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.cs
new file mode 100644
index 000000000..2bd431a9b
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.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 the secant or the cosine beside a power of a + i a tan(x), the powers adding
+ /// up to no whole number, integrated in that sum: under u = a + i a tan(x),
+ /// sec(x)^2 = (u/a) ((2 a - u)/a). Rubi's 4.3.1.2. The integrands are complex for a real
+ /// x and are compared as complex numbers.
+ /// #718
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class SecantBesideAnImaginaryTangentSumIntegralTest
+ {
+ [Theory]
+ [InlineData("sec(x)^3*sqrt(a + i*a*tan(x))")]
+ [InlineData("sec(x)^5/(a + i*a*tan(x))^(3/2)")]
+ [InlineData("(k*cos(x))^(3/2)*sqrt(a + i*a*tan(x))")]
+ [InlineData("cos(x)^9*(a + i*a*tan(x))^(7/2)")]
+ [InlineData("(m*sec(x))^(2/3)*(a + i*a*tan(x))^(5/3)")]
+ public void InTheSum(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("k", 0.7).Substitute("m", 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}");
+ }
+ }
+}