diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index b0414ac96..942ebafc6 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -18148,6 +18148,66 @@ bool Read(Entity node, bool insideASum)
return back.Nodes.Any(node => node == MathS.NaN) ? null : back;
}
+ ///
+ /// An exponential of a polynomial of degree 3 to 12 written expanded where it is a multiple of a power of one shifted
+ /// linear and a constant, written so: a^3 + 3 a^2 b x + 3 a b^2 x^2 + b^3 x^3 is b^3 (x + a/b)^3. With
+ /// p the leading coefficient and s = p_(n - 1)/(n p), the polynomial less p (x + s)^n is a constant
+ /// exactly where each lower coefficient is p C(n, j) s^(n - j), and the integrand with the exponent written so
+ /// is the rule's below for a polynomial beside a function of a shifted linear. Rubi's 2.3.
+ /// https://github.com/asc-community/AngouriMath/issues/2075
+ ///
+ internal static Entity? SolveByWritingAnExponentAsAPowerOfAShiftedLinear(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ if (!Integration.AnsweringTheQuestionAskedOrOneBelow)
+ return null;
+ foreach (var node in expr.Nodes)
+ {
+ // Written expanded: a power of a sum in x is already written as one, and its expansion would be read again.
+ if (node is not Powf(var @base, var exponent) || @base.ContainsNode(x)
+ || !exponent.Nodes.Any(inner => inner is Sumf or Minusf && inner.ContainsNode(x))
+ || exponent.Nodes.Any(inner => inner is Powf(Sumf or Minusf, _) && inner.ContainsNode(x))
+ || !TreeAnalyzer.TryGetPolynomial(exponent, x, out var monomials) || monomials is null || monomials.Keys.Any(degree => degree.Sign < 0))
+ continue;
+ var n = monomials.Keys.Max()!;
+ if (n.CompareTo(EInteger.FromInt32(3)) < 0 || n.CompareTo(EInteger.FromInt32(12)) > 0
+ || !monomials.TryGetValue(n.Subtract(EInteger.One), out var next) || VanishesIdentically(next))
+ continue;
+ var degree = n.ToInt32Checked();
+ // Both small, and simplified so that the answer reads them: 3 a b^2/(3 b^3) is a/b. The condition that comes
+ // with it, that the leading coefficient is not 0, is the reading's own: the polynomial is of degree n.
+ var leading = monomials[n].InnerSimplified;
+ var shift = (next / (degree * leading)).Simplify();
+ while (shift is Providedf(var unconditional, _))
+ shift = unconditional;
+ var isAShiftedPower = true;
+ for (var j = 1; j <= degree - 2 && isAShiftedPower; j++)
+ {
+ var coefficient = monomials.TryGetValue(EInteger.FromInt32(j), out var written) ? written : Number.Integer.Zero;
+ isAShiftedPower = VanishesIdentically(coefficient - leading * Number.Integer.Create(Choose(degree, j)) * MathS.Pow(shift, degree - j));
+ }
+ if (!isAShiftedPower)
+ continue;
+ var constant = monomials.TryGetValue(EInteger.Zero, out var free) ? free : Number.Integer.Zero;
+ var left = (constant - leading * MathS.Pow(shift, degree)).Simplify();
+ while (left is Providedf(var unconditional, _))
+ left = unconditional;
+ var asAPower = VanishesIdentically(left) ? leading * MathS.Pow(x + shift, degree) : leading * MathS.Pow(x + shift, degree) + left;
+ // The same question, respelled: asked at this depth, so that the rules scoped to the question asked or one
+ // below still read it.
+ var rewritten = expr.Replace(inner => inner == node ? MathS.Pow(@base, asAPower) : inner);
+ return Integration.ComputeAsTheSameQuestion(rewritten, x, integrateByParts);
+ }
+ return null;
+
+ static EInteger Choose(int whole, int chosen)
+ {
+ var result = EInteger.One;
+ for (var i = 1; i <= chosen; i++)
+ result = result.Multiply(EInteger.FromInt32(whole - chosen + i)).Divide(EInteger.FromInt32(i));
+ return result;
+ }
+ }
+
///
/// A polynomial beside a function of one shifted linear a + b x that parts cannot reach, written in
/// u = a + b x: a power that is not whole of something holding a logarithm of it, x (a + b ln(c (d + e x)))^p,
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 2c66fcd5e..137b9d2b4 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -936,6 +936,7 @@ internal static bool ASumOverRootsWouldAnswer
// x leaves a Gaussian of the shifted linear beside a polynomial, which nothing reads.
if ((answer = IndefiniteIntegralSolver.SolveAPolynomialBesideErrorFunctionsOfAShiftedLinear(expr, x, integrateByParts)) is { }) return answer;
// And beside a symbolic power of a logarithm of one, or an exponential of a power of one, the same way.
+ if ((answer = IndefiniteIntegralSolver.SolveByWritingAnExponentAsAPowerOfAShiftedLinear(expr, x, integrateByParts)) is { }) return answer;
if ((answer = IndefiniteIntegralSolver.SolveAPolynomialBesideATranscendentalPowerOfAShiftedLinear(expr, x, integrateByParts)) is { }) return answer;
if ((answer = IndefiniteIntegralSolver.SolveAPowerOfXBesideATranscendentalPowerOfABinomial(expr, x, integrateByParts)) is { }) return answer;
// A half-odd power of a ± a sin(y) beside powers of other linears in the sine, by the half
diff --git a/Sources/Tests/UnitTests/Calculus/APowerBesideAnExponentialOfAPowerIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/APowerBesideAnExponentialOfAPowerIntegralTest.cs
index 3205bfdfe..fb101a74d 100644
--- a/Sources/Tests/UnitTests/Calculus/APowerBesideAnExponentialOfAPowerIntegralTest.cs
+++ b/Sources/Tests/UnitTests/Calculus/APowerBesideAnExponentialOfAPowerIntegralTest.cs
@@ -193,6 +193,16 @@ public void APositiveRateIsTakenOutOfThePower()
[InlineData("Chi(a + b*x)^2")]
public void AnExponentWrittenOtherwise(string integrand) => DifferentiatesBack(integrand);
+ ///
+ /// An exponent written expanded that is a power of one shifted linear and a constant, written so first:
+ /// a^3 + 3 a^2 b x + 3 a b^2 x^2 + b^3 x^3 is (a + b x)^3. Rubi's 2.3.
+ ///
+ [Theory]
+ [InlineData("e^(a^3 + 3*a^2*b*x + 3*a*b^2*x^2 + b^3*x^3)*x")]
+ [InlineData("f^(c + d^3 + 3*d^2*x + 3*d*x^2 + x^3)")]
+ [InlineData("x^2*e^(b*(1 + 4*x + 6*x^2 + 4*x^3 + x^4))")]
+ public void AnExponentThatIsAPowerOfAShiftedLinearWrittenExpanded(string integrand) => DifferentiatesBack(integrand);
+
///
/// Not where the integral is elementary, an exponential integral or an error function: those keep the form
/// they had.