diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index b82a9959c..e317ff4bb 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -22156,17 +22156,35 @@ private static (Entity Constant, Entity Base, Entity ExponentInU, Variable U, En
/// exponential of the product: (e^x)^(1/3) is e^(x/3) and (3^(3x))^(1/4)
/// is 3^(3x/4), exactly, since the base is positive; and it is only in that
/// spelling that the exponential rules read them. Timofeev's
- /// (cos(x/2) + sin(x/2))/(e^x)^(1/3) and cos(3x/2)/(3^(3x))^(1/4).
+ /// (cos(x/2) + sin(x/2))/(e^x)^(1/3) and cos(3x/2)/(3^(3x))^(1/4). And a whole
+ /// power of a constant times one, (-e^(-b x))^2, as the constant's power times the
+ /// exponential of the multiple, whatever the constant is.
///
internal static Entity? SolveByFlatteningAPowerOfAnExponential(Entity expr, Entity.Variable x, bool integrateByParts)
{
- var flattened = expr.Replace(node =>
- node is Powf(Powf(var @base, var inner), var outer)
- && !@base.ContainsNode(x) && inner.ContainsNode(x) && !outer.ContainsNode(x)
- && (@base == MathS.e || @base.Evaled is Number.Real { IsPositive: true })
- && outer.Evaled is Number.Real
- ? MathS.Pow(@base, (outer * inner).InnerSimplified)
- : node);
+ bool IsAnExponential(Entity @base, Entity inner) =>
+ !@base.ContainsNode(x) && inner.ContainsNode(x)
+ && (@base == MathS.e || @base.Evaled is Number.Real { IsPositive: true });
+ // A whole power of a constant times an exponential: (k E)^n is k^n E^n for every k and
+ // E when n is whole, so (-e^(-b x))^2 is e^(-2 b x). The product of two of them, which
+ // sinh(b x)^3 sinh(d x)^3 expands into, is read by nothing else.
+ Entity? Distributed(Entity left, Entity right, Number.Integer whole) =>
+ (left, right) switch
+ {
+ (Powf(var b, var p), var k) when !k.ContainsNode(x) && IsAnExponential(b, p) =>
+ MathS.Pow(k, whole) * MathS.Pow(b, (whole * p).InnerSimplified),
+ (var k, Powf(var b, var p)) when !k.ContainsNode(x) && IsAnExponential(b, p) =>
+ MathS.Pow(k, whole) * MathS.Pow(b, (whole * p).InnerSimplified),
+ _ => null
+ };
+ var flattened = expr.Replace(node => node switch
+ {
+ Powf(Powf(var @base, var inner), var outer)
+ when IsAnExponential(@base, inner) && !outer.ContainsNode(x) && outer.Evaled is Number.Real =>
+ MathS.Pow(@base, (outer * inner).InnerSimplified),
+ Powf(Mulf(var left, var right), Number.Integer whole) => Distributed(left, right, whole) ?? node,
+ _ => node
+ });
// The same question in another spelling, asked as one of its own, so that the
// closed rules that answer only at the top -- the exponential times a
// trigonometric -- are consulted for it.
diff --git a/Sources/Tests/UnitTests/Calculus/AWholePowerOfAMultipleOfAnExponentialIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/AWholePowerOfAMultipleOfAnExponentialIntegralTest.cs
new file mode 100644
index 000000000..f8b4d8a70
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/AWholePowerOfAMultipleOfAnExponentialIntegralTest.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 whole power of a constant times an exponential, (k e^u)^n = k^n e^(n u). The terms of
+ /// sinh(a + b x)^3 sinh(c + d x)^3, written in exponentials, are products of two of them,
+ /// (-e^(-b x))^2 (-e^(-d x))^2, which nothing else read: 2.5.0 answered the product, and
+ /// 2.6.0's development had stopped. Rubi's 6.7.1.
+ /// #718
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class AWholePowerOfAMultipleOfAnExponentialIntegralTest
+ {
+ [Theory]
+ [InlineData("(-e^(-b*x))^2*(-e^(-d*x))^2")]
+ [InlineData("(-e^(-b*x))^2")]
+ [InlineData("(2*e^x)^3")]
+ [InlineData("sinh(b*x)^3*sinh(d*x)^3")]
+ [InlineData("sinh(a + b*x)^3*sinh(c + d*x)^3")]
+ public void AsAnExponentialOfTheMultiple(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("b", 0.7).Substitute("c", 0.4).Substitute("d", 0.3);
+ 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}");
+ }
+ }
+}