diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index c78613901..4772039dc 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -1710,6 +1710,18 @@ since they are these exponentials
| `"(p + q*x)^2*f^(a + b*x + c*x^2)".Integrate("x")` | `integral((p + q * x) ^ 2 * f ^ (a + b * x + c * x ^ 2), x)` | the antiderivative |
| `"x^2*sinh(a + b*x + c*x^2)".Integrate("x")` | `integral(x ^ 2 * (e ^ (a + b * x + c * x ^ 2) - e ^ (-(a + b * x + c * x ^ 2))) / 2, x)` | the antiderivative |
+### An exponential of a polynomial beside the polynomial's derivative is integrated
+
+`e^(a + b x + c x^2) (b + 2 c x) sqrt(a + b x + c x^2)` was left unintegrated. `G^P k P' f(P)`, with
+`P` a polynomial of degree two or more and `P'` a factor of its own up to a constant, is now
+integrated under `u = P`, as `k G^u f(u)`
+([#1501](https://github.com/asc-community/AngouriMath/issues/1501)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"e^(a + b*x + c*x^2)*(b + 2*c*x)*(a + b*x + c*x^2)^(1/2)".Integrate("x")` | `integral(e ^ (a + b * x + c * x ^ 2) * (b + 2 * c * x) * sqrt(a + b * x + c * x ^ 2), x)` | the antiderivative, with `erfi` |
+| `"e^(a + b*x + c*x^2)*(b + 2*c*x)/(a + b*x + c*x^2)^(3/2)".Integrate("x")` | `integral(e ^ (a + b * x + c * x ^ 2) * (b + 2 * c * x) / (a + b * x + c * x ^ 2) ^ (3/2), x)` | the antiderivative, with `erfi` |
+
### An exponential of a quadratic in `1/x` or `1/(c + d x)` is integrated
`e^(-1/x^2)` was left unintegrated. `L^m F^(A/L^2 + B/L + C)`, with `L = c + d x` and a whole `m`,
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index 6a3e13657..b79c1e89f 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -17193,6 +17193,63 @@ private static bool IsARationalFunctionOfExponentials(Entity expr, Entity.Variab
}
}
+ ///
+ /// An exponential of a polynomial beside the polynomial's derivative, with the rest a
+ /// function of the polynomial: G^P k P' f(P) is k G^u f(u) under u = P.
+ /// Rubi's 2.3, e^(a + b x + c x^2) (b + 2 c x) (a + b x + c x^2)^(n/2).
+ /// https://github.com/asc-community/AngouriMath/issues/1501
+ ///
+ ///
+ /// reads this u and does not reach it: for its
+ /// own search it writes an exponential of a sum as a product of exponentials, so that
+ /// e^(e^x) e^x is e^u du, and e^(a + b x + c x^2) is then
+ /// e^a e^(b x) e^(c x^2), with no P left in it to replace. Declining took
+ /// it 24 s. Only a polynomial of degree two or more, whose derivative is a factor of its
+ /// own: an exponential of a linear is the table's.
+ ///
+ internal static Entity? SolveByTheExponentAsTheVariable(Entity expr, Entity.Variable x, bool integrateByParts)
+ {
+ if (expr is not (Mulf or Divf) || AnExponentialOfAPolynomial(expr, x) is not { } exponential)
+ return null;
+ var polynomial = exponential.Exponent;
+ var derivative = polynomial.Differentiate(x);
+ Entity? scale = null;
+ Entity rest = Number.Integer.One;
+ foreach (var (factor, underneath) in FactorsOfTheIntegrand(expr))
+ {
+ // The derivative, up to a constant, above the bar: a sum, as it is written.
+ if (scale is null && !underneath && factor is Sumf or Minusf && factor.ContainsNode(x)
+ && Functions.PartialFractions.Bare((factor / derivative).Simplify()) is var ratio && !ratio.ContainsNode(x)
+ && ratio.Evaled is not Number.Complex { IsZero: true })
+ {
+ scale = ratio;
+ continue;
+ }
+ rest = underneath ? rest / factor : rest * factor;
+ }
+ if (scale is null)
+ return null;
+ var u = Variable.CreateUnique(expr, "u");
+ var inU = (scale * rest.Replace(node => node == polynomial ? u : node)).InnerSimplified;
+ if (inU.ContainsNode(x))
+ return null;
+ return Integration.ComputeAsAQuestionOfItsOwn(inU, u, integrateByParts)?.Substitute(u, polynomial);
+ }
+
+ ///
+ /// A factor of , read through products and quotients, that is a
+ /// constant to a polynomial in of degree two or more, or .
+ ///
+ private static Powf? AnExponentialOfAPolynomial(Entity expr, Entity.Variable x) => expr switch
+ {
+ Mulf(var left, var right) => AnExponentialOfAPolynomial(left, x) ?? AnExponentialOfAPolynomial(right, x),
+ Divf(var numerator, var denominator) => AnExponentialOfAPolynomial(numerator, x) ?? AnExponentialOfAPolynomial(denominator, x),
+ Powf(var @base, Sumf or Minusf) power when !@base.ContainsNode(x) && power.Exponent.ContainsNode(x)
+ && TreeAnalyzer.TryGetPolynomial(power.Exponent, x, out var monomials)
+ && monomials.Keys.All(degree => degree.Sign >= 0) && monomials.Keys.Any(degree => degree.CompareTo(EInteger.One) > 0) => power,
+ _ => null
+ };
+
///
/// Attempts to solve an integral using u-substitution.
/// Looks for patterns where f(g(x)) * g'(x) can be integrated as F(g(x)).
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index abcd8827b..a72bfc477 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -579,6 +579,9 @@ private static Entity Normalized(Entity expr, Entity.Variable x) =>
// An exponential of a multiple of a logarithm is a power of the argument, which is
// how every inverse hyperbolic function under an exponential arrives.
if ((answer = IndefiniteIntegralSolver.SolveByFoldingAnExponentialOfALogarithm(expr, x, integrateByParts)) is { }) return answer;
+ // An exponential of a polynomial beside the polynomial's derivative, under u = P,
+ // which the substitution search does not reach: it writes the exponential apart.
+ if ((answer = IndefiniteIntegralSolver.SolveByTheExponentAsTheVariable(expr, x, integrateByParts)) is { }) return answer;
// `A + i A tan(z)` is `A e^(i z)/cos(z)`, which beside a polynomial is a shape the
// closed rules answer, where the imaginary unit in the coefficient is read by none.
if ((answer = IndefiniteIntegralSolver.SolveByWritingAnImaginaryTangentAsAnExponential(expr, x, integrateByParts)) is { }) return answer;
diff --git a/Sources/Tests/UnitTests/Calculus/GaussianIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/GaussianIntegralTest.cs
index 2ecd98370..52ba97dd1 100644
--- a/Sources/Tests/UnitTests/Calculus/GaussianIntegralTest.cs
+++ b/Sources/Tests/UnitTests/Calculus/GaussianIntegralTest.cs
@@ -146,6 +146,19 @@ public void ASymbolicGaussianWithALinearTermBesideAPolynomial(string integrand)
public void ASymbolicGaussianInAReciprocal(string integrand)
=> DifferentiatesBack(integrand, ("f", "2"), ("a", "1/3"), ("b", "-2/3"), ("c", "5"), ("d", "3/2"));
+ ///
+ /// An exponential of a quadratic beside the quadratic's derivative and a half-odd power of
+ /// the quadratic, under u = a + b x + c x^2: e^u u^(n/2). Rubi's 2.3. The
+ /// quadratic is positive at every point for these pins.
+ ///
+ [Theory]
+ [InlineData("e^(a + b*x + c*x^2)*(b + 2*c*x)*(a + b*x + c*x^2)^(1/2)")]
+ [InlineData("e^(a + b*x + c*x^2)*(b + 2*c*x)*(a + b*x + c*x^2)^(5/2)")]
+ [InlineData("e^(a + b*x + c*x^2)*(b + 2*c*x)/(a + b*x + c*x^2)^(3/2)")]
+ [InlineData("3*e^(a + b*x + c*x^2)*(2*b + 4*c*x)/sqrt(a + b*x + c*x^2)")]
+ public void TheExponentAsTheVariable(string integrand)
+ => DifferentiatesBack(integrand, ("a", "1/3"), ("b", "-2/3"), ("c", "5/4"));
+
///
/// An odd negative power ends at int e^(A x^2)/x, which is the exponential
/// integral, so it is not taken.