diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index f2e47d4f4..8b5bbb404 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -307,6 +307,28 @@ either now; and the secant quotient was simplified to `cos/(b^(5/2) d)` through
`(1/cos)^(3/2) = cos^(-3/2)`, which is wrong for every negative cosine and cancelled against the
same wrong step on the denominator. On the 1774-problem independent suites this is 1707 to 1705, the two `asin` rows, with the sign error gone.
+### A function comes out of a fractional power of its even power with its sign
+
+**Improvement, not silent.** The entry two above made `(sin(x)^2)^(3/2)` the modulus `|sin(x)|^3`
+and left three of Rubi's integrands unevaluated for it, and answered two more in powers of the
+modulus through the substitutions. The modulus is the function times its sign, and the sign is a
+constant between the function's zeros: `(a sin(x)^2)^(5/2)` is `a^(5/2) sgn(sin(x)) sin(x)^5`, the
+sign comes out in front of the integral, and what is left is a whole power any rule reads. An even
+power of a real function is not negative, so `(c q)^p = c^p q^p` holds for the principal powers
+whatever `c` is, and nothing is assumed about the constant — checked at `a = -3` as well as
+`a = 2`. Whole products of the exponents only, at the top of the integration only, and after the
+rule that does the same for a polynomial under a square root, whose answers are as they were.
+[#1387](https://github.com/asc-community/AngouriMath/issues/1387)
+
+| | Was | Is |
+|---|---|---|
+| `"x*sqrt(sin(x)^2)".Integrate("x")` | unevaluated | `sgn(sin(x)) (sin(x) - x cos(x))` |
+| `"(csc(x)^2)^(3/2)".Integrate("x")`, `"1/(csc(x)^2)^(7/2)".Integrate("x")` | unevaluated | `sgn(csc(x))` times the integral of `csc^3`, of `sin^7` |
+| `"(sin(x)^2)^(3/2)".Integrate("x")` | `(2/3 tan(x/2)^5 + 2 tan(x/2)^3) ((2 tan(x/2))^2)^(1/2)/((tan(x/2)^2 + 1)^3)` | `sgn(sin(x)) (cos(x)^3/3 - cos(x))` |
+| `"(a*sin(x)^2)^(5/2)".Integrate("x")` | `sgn(sin(x)) a^(5/2) (...)` in `(1 - abs(sin(x))^2)^(1/2)` over `sgn(cos(x))` | `sgn(sin(x)) a^(5/2) (2 cos(x)^3/3 - cos(x) - cos(x)^5/5)` |
+| `"1/sqrt(a*cot(x)^2)".Integrate("x")` | `-sgn(tan(x)) ln(1/sqrt(1 + abs(tan(x))^2))/sqrt(a)` | `sgn(cot(x)) ln(1 + tan(x)^2)/(2 sqrt(a))` |
+| `"(b*tan(x)^2)^(5/2)".Integrate("x")` | `sgn(tan(x)) b^(5/2) ((abs(tan(x))^2)^2/2 - abs(tan(x))^2 + ln(abs(tan(x))^2 + 1))/2` | the same with `tan(x)` for `abs(tan(x))` |
+
### A condition the answer states on its own is no longer repeated beside it
**Improvement, not silent.** `Simplify` returned `(1 - ln(x))/x^2 provided not x = 0` for the
diff --git a/Sources/.editorconfig b/Sources/.editorconfig
index 786bdbae9..6e3890d8a 100644
--- a/Sources/.editorconfig
+++ b/Sources/.editorconfig
@@ -442,6 +442,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Calculus/CombinedRadicalsTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n
+[Tests/UnitTests/Calculus/EvenPowerSignTest.cs]
+file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n
+
[Tests/UnitTests/Calculus/RothsteinTragerTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index 89eda82a9..e98517cb2 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -11371,6 +11371,82 @@ bool IsAConstantTimesAPowerOfOneMinusUSquared(Entity polynomial, out Entity cons
return answer.Nodes.Any(node => node == MathS.NaN) ? null : answer;
}
+ ///
+ /// A fractional power of a constant times an even power of a function of x, the
+ /// function taken out of the power with its sign: (a sin(x)^2)^(5/2) is
+ /// a^(5/2) |sin(x)|^5, which is a^(5/2) sgn(sin(x)) sin(x)^5 -- the sign
+ /// a constant between the sine's zeros, carried through the integration as a symbol
+ /// and written back. Rubi's x sqrt(sin(x)^2) is sgn(sin(x)) (sin(x) - x cos(x))
+ /// that way, and 1/(csc(x)^2)^(7/2) is sgn(csc(x)) times the seventh power
+ /// of the sine, where the substitutions read the root of the square as a modulus and
+ /// answered in powers of it.
+ ///
+ ///
+ /// An even power of a real function is not negative, so (c q)^p = c^p q^p holds
+ /// for the principal powers whatever c is, and (f^(2k))^p is |f|^(2kp).
+ /// Whole products of the exponents only, so that what is handed on is a whole power of
+ /// the function; a polynomial radicand is the rule above's, which comes first. At the
+ /// top only, as there: a substitution's variable is one it knows the sign of, and a
+ /// sign written for it is one nothing differentiates.
+ /// https://github.com/asc-community/AngouriMath/issues/718
+ ///
+ internal static Entity? SolveByTakingAFunctionOutOfAPowerOfItsEvenPower(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ if (!Integration.AnsweringTheQuestionAsked)
+ return null;
+ Entity signs = Number.Integer.One;
+ var rewritten = expr.Replace(node =>
+ {
+ if (node is not Powf(var radicand, Number.Rational exponent) || exponent is Number.Integer || !radicand.ContainsNode(x))
+ return node;
+ // The radicand read as a constant times even whole powers of functions of x,
+ // each power whole once multiplied by the exponent; anything else is not this
+ // rule's.
+ Entity constant = Number.Integer.One;
+ var functions = new List<(Entity function, EInteger power)>();
+ var top = radicand;
+ if (radicand is Divf(var above, var below) && !below.ContainsNode(x))
+ {
+ constant = Number.Integer.One / below;
+ top = above;
+ }
+ foreach (var factor in Mulf.LinearChildren(top))
+ {
+ if (!factor.ContainsNode(x))
+ {
+ constant = constant * factor;
+ continue;
+ }
+ // A real function: a fractional power of one is not, where its base is
+ // negative, and its even power is then not the square of a modulus.
+ if (factor is not Powf(var function, Number.Integer degree) || !degree.EInteger.IsEven || degree.EInteger.Sign <= 0
+ || TreeAnalyzer.TryGetPolynomial(function, x, out _) || function is Powf(_, not Number.Integer))
+ return node;
+ var product = exponent.ERational.Multiply(ERational.FromEInteger(degree.EInteger)).ToLowestTerms();
+ if (!product.Denominator.Equals(EInteger.One))
+ return node;
+ functions.Add((function, product.Numerator));
+ }
+ if (functions.Count == 0)
+ return node;
+ Entity outside = constant == Number.Integer.One ? Number.Integer.One : MathS.Pow(constant, exponent);
+ foreach (var (function, power) in functions)
+ {
+ // |f|^n is f^n for an even n and sgn(f) f^n for an odd one.
+ if (!power.IsEven)
+ signs = signs * MathS.Signum(function);
+ outside = outside * MathS.Pow(function, Number.Integer.Create(power));
+ }
+ return outside;
+ });
+ if (rewritten == expr)
+ return null;
+ if (Integration.ComputeAsAQuestionOfItsOwn(rewritten, x, integrateByParts) is not { } result)
+ return null;
+ var answer = signs == Number.Integer.One ? result : signs * result;
+ return answer.Nodes.Any(node => node == MathS.NaN) ? null : answer;
+ }
+
///
/// A denominator factor that is a sum or difference of two square roots of
/// polynomials, multiplied above and below by its conjugate:
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 49fad0937..da2ce7c44 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -513,6 +513,9 @@ private static Entity Normalized(Entity expr, Entity.Variable x) =>
// A square root of a polynomial with a repeated factor, the factor taken out of
// the root with its sign: `sqrt((x - 3)^2 (x + 1))` is `sgn(x - 3) (x - 3) sqrt(x + 1)`.
if ((answer = IndefiniteIntegralSolver.SolveByTakingASquareFactorOutOfARoot(expr, x, integrateByParts)) is { }) return answer;
+ // A fractional power of a constant times an even power of a function, the function
+ // taken out with its sign: `(a sin(x)^2)^(5/2)` is `a^(5/2) sgn(sin(x)) sin(x)^5`.
+ if ((answer = IndefiniteIntegralSolver.SolveByTakingAFunctionOutOfAPowerOfItsEvenPower(expr, x, integrateByParts)) is { }) return answer;
// A sum of two roots below the bar, multiplied above and below by its conjugate:
// `1/(sqrt(A) - sqrt(B))` is `(sqrt(A) + sqrt(B))/(A - B)`.
if ((answer = IndefiniteIntegralSolver.SolveByRationalisingASumOfRoots(expr, x, integrateByParts)) is { }) return answer;
diff --git a/Sources/Tests/UnitTests/Calculus/EvenPowerSignTest.cs b/Sources/Tests/UnitTests/Calculus/EvenPowerSignTest.cs
new file mode 100644
index 000000000..cc4ae2913
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/EvenPowerSignTest.cs
@@ -0,0 +1,83 @@
+//
+// 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 fractional power of a constant times an even power of a function, the function
+ /// taken out of the power with its sign: (a sin(x)^2)^(5/2) is
+ /// a^(5/2) sgn(sin(x)) sin(x)^5, and the sign is a constant between the zeros of
+ /// the sine that comes out in front of the integral.
+ /// #718
+ ///
+ ///
+ /// Rubi's x sqrt(sin(x)^2), (csc(x)^2)^(3/2) and 1/(csc(x)^2)^(7/2)
+ /// had no antiderivative, and (a sin(x)^2)^(5/2) one in powers of the modulus of the
+ /// sine. Every answer is differentiated back on both sides of a zero of the function, and
+ /// the constant is given a negative value as well as a positive one: an even power is not
+ /// negative, so (c q)^p = c^p q^p for the principal powers whatever c is.
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class EvenPowerSignTest
+ {
+ /// On both sides of the sine's zero at pi, and of the cosine's at pi/2 and 3pi/2.
+ private static readonly double[] AroundTheZeros = { 0.5, 1.2, 2.0, 3.5, 5.0, 6.5 };
+
+ private static void DifferentiatesBack(string integrand, double[] points, double constant)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ Assert.DoesNotContain("integral(", integral.Stringize());
+ Assert.DoesNotContain("NaN", integral.Stringize());
+ Assert.DoesNotContain("abs(", integral.Stringize());
+
+ var derivative = integral.Substitute("C", 0).Substitute("a", constant).Differentiate("x");
+ var original = integrand.ToEntity().Substitute("a", constant);
+ foreach (var at in points)
+ {
+ 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} at a = {constant} is {got} at x = {at}, "
+ + $"where the integrand is {want}");
+ }
+ }
+
+ [Theory]
+ [InlineData("(a*sin(x)^2)^(5/2)")]
+ [InlineData("(a*sin(x)^2)^(3/2)/a")]
+ [InlineData("x*sqrt(a*sin(x)^2)")]
+ [InlineData("(a*csc(x)^2)^(3/2)")]
+ [InlineData("1/(a*csc(x)^2)^(7/2)")]
+ [InlineData("1/sqrt(a*cot(x)^2)")]
+ [InlineData("(a*cos(x)^4)^(3/4)")]
+ public void TheFunctionComesOutOfThePowerWithItsSign(string integrand)
+ {
+ DifferentiatesBack(integrand, AroundTheZeros, 2);
+ DifferentiatesBack(integrand, AroundTheZeros, -3);
+ Assert.Contains("sgn(", integrand.ToEntity().Integrate("x").Stringize());
+ }
+
+ /// An even product of the exponents has no sign to keep.
+ [Theory]
+ [InlineData("(a*sin(x)^4)^(1/2)")]
+ [InlineData("1/(a*cos(x)^4)^(1/2)")]
+ [InlineData("(a*cos(x)^4)^(3/2)")]
+ public void AnEvenWholePowerNeedsNoSign(string integrand)
+ {
+ DifferentiatesBack(integrand, AroundTheZeros, 2);
+ DifferentiatesBack(integrand, AroundTheZeros, -3);
+ Assert.DoesNotContain("sgn(", integrand.ToEntity().Integrate("x").Stringize());
+ }
+ }
+}