diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 33458eb6e..dc450e579 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -1745,6 +1745,21 @@ quadratic alone, or beside a polynomial only, is left to the rules that answered
| `"x^2*sinh(a + b*x + c*x^2)^2".Integrate("x")` | `integral(x ^ 2 * ((e ^ (a + b * x + c * x ^ 2) - e ^ (-(a + b * x + c * x ^ 2))) / 2) ^ 2, x)` | the antiderivative |
| `"2^(x^2)*3^(x + 1)".Integrate("x")` | `integral(2 ^ x ^ 2 * 3 ^ (x + 1), x)` | the antiderivative, with `erfi` |
+### An exponential of a quadratic in a logarithm beside a power of `x` is integrated
+
+`e^(ln(x)^2)` was left unintegrated. `x^p G^(Q(L))`, where `L` is `ln(c x^r)` and `Q` a quadratic
+with a square term, is now integrated under `t = L`, where it is the Gaussian with a linear term. A
+polynomial beside it is summed a power at a time, and the logarithm of a power of a linear is the
+same question under `u = d + e x`
+([#1501](https://github.com/asc-community/AngouriMath/issues/1501)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"e^(ln(x)^2)".Integrate("x")` | `integral(e ^ ln(x) ^ 2, x)` | the antiderivative, with `erfi` |
+| `"x^2*F^(f*(a + b*ln(c*x^n))^2)".Integrate("x")` | `integral(x ^ 2 * F ^ (f * (a + b * ln(c * x ^ n)) ^ 2), x)` | the antiderivative |
+| `"(d*g + k*g*x)^m*F^(f*(a + b*ln(c*(d + k*x)^n))^2)".Integrate("x")` | `integral((d * g + k * g * x) ^ m * F ^ (f * (a + b * ln(c * (d + k * x) ^ n)) ^ 2), x)` | the antiderivative |
+| `"(g + h*x)^3*F^(f*(a + b*ln(c*(d + k*x)^n)^2))".Integrate("x")` | `integral((g + h * x) ^ 3 * F ^ (f * (a + b * ln(c * (d + k * x) ^ n) ^ 2)), x)` | the antiderivative |
+
### `binomial(n, k)` is a function
**Addition, not silent.** The binomial coefficient is a node, `Entity.Binomialf`, spelled
diff --git a/Sources/.editorconfig b/Sources/.editorconfig
index 47bf3f25e..af38df176 100644
--- a/Sources/.editorconfig
+++ b/Sources/.editorconfig
@@ -642,3 +642,6 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Calculus/ExponentialsOfQuadraticsTest.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/ExponentialOfAQuadraticInALogarithmTest.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 3ef20c341..e53e44037 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -9059,6 +9059,166 @@ private static Entity SquarefreePartAsWritten(Entity denominator, Entity.Variabl
return 2 / slopeOfF * theConstant * answerInT.Substitute(t, MathS.Sqrt(logarithm));
}
+ ///
+ /// A power of x times an exponential of a quadratic in a logarithm, x^p G^(Q(L)) with
+ /// L = ln(c x^r) and Q a quadratic with a square term, onto the
+ /// Gaussian. With t = L and L' = s/x, dx = x dt/s, and
+ /// x^(p + 1) e^(-(p + 1) L/s) is a constant, so the integral is that constant over
+ /// s times the integral of e^(Q(t) ln G + (p + 1) t/s): the Gaussian with a
+ /// linear term, which the table answers. A polynomial beside it is summed a power at a time,
+ /// and the logarithm of a power of a linear is the same question under u = d + e x.
+ /// Rubi's 2.3, F^(f (a + b ln(c (d + e x)^n))^2) (g + h x)^m and
+ /// F^(f (a + b ln(c (d + e x)^n)^2)) (g + h x)^m.
+ /// https://github.com/asc-community/AngouriMath/issues/1501
+ ///
+ ///
+ /// The constant is written x^(p + 1) e^(-(p + 1) L/s), as
+ /// writes it and as Rubi does,
+ /// rather than with ln(c x^r) split into ln c + r ln x, which holds only
+ /// where c is positive. A quadratic without its square term is a power of
+ /// c x^r, which the rules for powers answer.
+ ///
+ internal static Entity? SolveAPowerTimesAnExponentialOfAQuadraticInALogarithm(Entity expr, Entity.Variable x)
+ {
+ // The exponential and its logarithm first, which allocates nothing where there is
+ // none; and the logarithm of a linear before any factor is read, since beside it a
+ // constant multiple of that linear, (d g + e g x)^m, is a factor only in u.
+ if (expr is not (Mulf or Divf or Powf) || AnExponentialOfALogarithm(expr, x) is not { } theExponential)
+ return null;
+ if (TheLogarithmOfAPowerOfX(theExponential.Exponent, x) is not { } logarithm)
+ return LinearUnderALogarithm(theExponential.Exponent, x) is { } linear ? UnderTheLinearUnderTheLogarithm(expr, x, linear) : null;
+ Entity? p = null;
+ Entity constant = Number.Integer.One;
+ Entity? @base = null, exponent = null;
+ Dictionary? polynomial = null;
+ foreach (var (factor, underneath) in FactorsOfTheIntegrand(expr))
+ {
+ if (!factor.ContainsNode(x))
+ {
+ constant = underneath ? constant / factor : constant * factor;
+ continue;
+ }
+ if (factor == x && p is null)
+ p = underneath ? Number.Integer.MinusOne : Number.Integer.One;
+ else if (factor is Powf(var b, var e) && b == x && !e.ContainsNode(x) && p is null)
+ p = underneath ? -e : e;
+ else if (factor is Powf(Mulf(var left, var right), var scaledExponent) && (left == x) != (right == x)
+ && !(left == x ? right : left).ContainsNode(x) && !scaledExponent.ContainsNode(x) && p is null)
+ {
+ p = underneath ? -scaledExponent : scaledExponent;
+ var scalePower = MathS.Pow(left == x ? right : left, scaledExponent);
+ constant = underneath ? constant / scalePower : constant * scalePower;
+ }
+ else if (exponent is null && factor is Powf(var g, var power) && !g.ContainsNode(x) && power.ContainsNode(x))
+ (@base, exponent) = (g, underneath ? -power : power);
+ else if (polynomial is null && !underneath && TreeAnalyzer.TryGetPolynomial(factor, x, out var monomials)
+ && monomials.Count > 1 && monomials.Keys.All(degree => degree.Sign >= 0 && degree.CompareTo(EInteger.FromInt32(12)) <= 0))
+ polynomial = monomials;
+ else
+ return null;
+ }
+ if (@base is null || exponent is null || !exponent.ContainsNode(logarithm))
+ return null;
+ var t = Variable.CreateUnique(expr, "t");
+ var inT = exponent.Replace(node => node == logarithm ? t : node);
+ if (inT.ContainsNode(x) || !TreeAnalyzer.TryGetPolyQuadratic(inT, t, out var square, out _, out _) || TreeAnalyzer.IsZero(square))
+ return null;
+ var rate = Functions.PartialFractions.Bare((logarithm.Differentiate(x) * x).Simplify());
+ if (rate.ContainsNode(x) || rate.Evaled is Number.Complex { IsZero: true } || rate.Nodes.Any(node => node == MathS.NaN))
+ return null;
+ var exponentInT = @base == MathS.e ? inT : inT * MathS.Ln(@base);
+ p = (p ?? Number.Integer.Zero).InnerSimplified;
+ if (polynomial is null)
+ return ExponentialOfAQuadraticInALogarithmTerm(p, exponentInT, t, logarithm, rate, x) is { } single ? (constant * single).InnerSimplified : null;
+ Entity sum = Number.Integer.Zero;
+ foreach (var monomial in polynomial)
+ {
+ if (ExponentialOfAQuadraticInALogarithmTerm((p + Number.Integer.Create(monomial.Key)).InnerSimplified, exponentInT, t, logarithm, rate, x) is not { } term)
+ return null;
+ sum += monomial.Value * term;
+ }
+ return (constant * sum).InnerSimplified;
+ }
+
+ ///
+ /// The integral of x^q e^(E(L)), where is E in
+ /// standing for and L' = s/x: see
+ /// .
+ ///
+ private static Entity? ExponentialOfAQuadraticInALogarithmTerm(Entity q, Entity exponentInT, Entity.Variable t, Entity logarithm, Entity rate, Entity.Variable x)
+ {
+ var qPlusOne = (q + 1).InnerSimplified;
+ var atMinusOne = qPlusOne.Evaled is Number.Complex { IsZero: true };
+ var inT = MathS.Pow(MathS.e, atMinusOne ? exponentInT : exponentInT + qPlusOne / rate * t);
+ if (IntegralPatterns.TryStandardIntegrals(inT, t) is not { } answerInT)
+ return null;
+ // x^(q + 1) e^(-(q + 1) ln(x)) is 1 wherever ln(x) is real, so for ln(x) itself it is left out.
+ Entity theConstant = atMinusOne || logarithm == MathS.Ln(x)
+ ? Number.Integer.One
+ : MathS.Pow(x, qPlusOne) * MathS.Pow(MathS.e, -qPlusOne * logarithm / rate);
+ return theConstant / rate * answerInT.Substitute(t, logarithm);
+ }
+
+ ///
+ /// A factor of that is an exponential of with a
+ /// logarithm in its exponent, read through products and quotients, or .
+ ///
+ private static Powf? AnExponentialOfALogarithm(Entity expr, Entity.Variable x) => expr switch
+ {
+ Mulf(var left, var right) => AnExponentialOfALogarithm(left, x) ?? AnExponentialOfALogarithm(right, x),
+ Divf(var numerator, var denominator) => AnExponentialOfALogarithm(numerator, x) ?? AnExponentialOfALogarithm(denominator, x),
+ Powf(var @base, var exponent) power when !@base.ContainsNode(x) && exponent.ContainsNode(x)
+ && exponent.Nodes.Any(node => node is Logf) => power,
+ _ => null
+ };
+
+ ///
+ /// The one natural logarithm of in , where its
+ /// argument is a constant times a power of , or .
+ ///
+ private static Entity? TheLogarithmOfAPowerOfX(Entity expr, Entity.Variable x)
+ {
+ Entity? logarithm = null;
+ foreach (var node in expr.Nodes)
+ if (node is Logf(var @base, var argument) && @base == MathS.e && argument.ContainsNode(x))
+ {
+ if (logarithm is not null && logarithm != node)
+ return null;
+ logarithm = node;
+ }
+ return logarithm is Logf(_, var antilogarithm) && IsAProductOfPowersOfTheVariable(antilogarithm, x) ? logarithm : null;
+ }
+
+ ///
+ /// under u = d + e x, with the
+ /// d + e x under the logarithm, answered by
+ /// in u and
+ /// written back in x. A constant multiple of the linear, as (d g + e g x)^m
+ /// writes one, is read as g u, where substituting for x would leave a sum
+ /// that is a multiple of u only once simplified.
+ ///
+ private static Entity? UnderTheLinearUnderTheLogarithm(Entity expr, Entity.Variable x, Entity linear)
+ {
+ if (!TreeAnalyzer.TryGetPolyLinear(linear, x, out var slope, out var intercept) || slope is null || intercept is null)
+ return null;
+ var u = Variable.CreateUnique(expr, "u");
+ var inU = (expr.Replace(node =>
+ {
+ if (node == linear)
+ return u;
+ if (node is not (Sumf or Minusf) || !TreeAnalyzer.TryGetPolyLinear(node, x, out var nodeSlope, out var nodeIntercept)
+ || TreeAnalyzer.IsZero(nodeSlope) || TreeAnalyzer.IsZero(nodeIntercept))
+ return node;
+ // Bare: simplified, k g/k is g provided k is not 0, which k is, the linear being one.
+ return Functions.PartialFractions.Bare((nodeIntercept * slope - nodeSlope * intercept).Simplify()).Evaled is Number.Complex { IsZero: true }
+ ? Functions.PartialFractions.Bare((nodeSlope / slope).Simplify()) * u
+ : node;
+ }).Substitute(x, (u - intercept) / slope) / slope).InnerSimplified;
+ if (inU.ContainsNode(x) || LinearUnderALogarithm(inU, u) is not null)
+ return null;
+ return SolveAPowerTimesAnExponentialOfAQuadraticInALogarithm(inU, u)?.Substitute(u, linear).InnerSimplified;
+ }
+
///
/// Whether is A + B ln(c x^r) with A, B,
/// c and r free of and the logarithm present: one
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index a41f92922..abcd8827b 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -569,6 +569,8 @@ private static Entity Normalized(Entity expr, Entity.Variable x) =>
if ((answer = IndefiniteIntegralSolver.SolveAPowerTimesAPowerOfTheLogarithm(expr, x)) is { }) return answer;
// And a half-odd power of it, onto the Gaussian's moments by t = sqrt(F).
if ((answer = IndefiniteIntegralSolver.SolveAPowerTimesAHalfOddPowerOfTheLogarithm(expr, x)) is { }) return answer;
+ // And an exponential of a quadratic in it, onto the Gaussian by t = ln(c x^r).
+ if ((answer = IndefiniteIntegralSolver.SolveAPowerTimesAnExponentialOfAQuadraticInALogarithm(expr, x)) is { }) return answer;
// A power of an exponential with a positive base is the exponential of the product,
// exactly, and only that spelling is one the exponential rules read.
if ((answer = IndefiniteIntegralSolver.SolveByFlatteningAPowerOfAnExponential(expr, x, integrateByParts)) is { }) return answer;
diff --git a/Sources/Tests/UnitTests/Calculus/ExponentialOfAQuadraticInALogarithmTest.cs b/Sources/Tests/UnitTests/Calculus/ExponentialOfAQuadraticInALogarithmTest.cs
new file mode 100644
index 000000000..1a1a302cc
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/ExponentialOfAQuadraticInALogarithmTest.cs
@@ -0,0 +1,80 @@
+//
+// 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 System.Linq;
+using AngouriMath.Extensions;
+using Xunit;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// A power of x times an exponential of a quadratic in a logarithm, x^p G^(Q(ln(c x^r))),
+ /// onto the Gaussian by t = ln(c x^r): Rubi's 2.3,
+ /// F^(f (a + b ln(c (d + e x)^n))^2) (g + h x)^m, every one of which was left unevaluated.
+ /// https://github.com/asc-community/AngouriMath/issues/1501
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class ExponentialOfAQuadraticInALogarithmTest
+ {
+ /// Past 1, where every logarithm here is real for the pins below.
+ private static readonly double[] Points = { 1.3, 1.9, 2.6, 3.4 };
+ private static readonly (string Name, string Value)[] Pins =
+ { ("F", "2"), ("a", "1/2"), ("b", "2/3"), ("c", "5/4"), ("n", "3"), ("m", "1/2"), ("d", "1/2"), ("k", "2"), ("f", "3/4"), ("g", "2"), ("h", "1/3") };
+
+ private static Entity DifferentiatesBack(string integrand)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ Assert.DoesNotContain("integral(", integral.Stringize());
+ Entity Pinned(Entity e) => Pins.Aggregate(e, (current, pin) => current.Substitute(pin.Name, pin.Value.ToEntity()));
+ var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
+ var original = Pinned(integrand.ToEntity());
+ 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));
+ Assert.True(difference / scale < 1e-9, $"d/dx of {integral} is {got} at x = {at}, where {integrand} is {want}");
+ }
+ return integral;
+ }
+
+ [Theory]
+ [InlineData("e^(ln(x)^2)")]
+ [InlineData("x*e^(ln(x)^2)")]
+ [InlineData("e^(-ln(x)^2)/x^2")]
+ [InlineData("2^(ln(x)^2 + ln(x))")]
+ [InlineData("x^m*e^(ln(x)^2)")]
+ public void OfTheLogarithmItself(string integrand) => DifferentiatesBack(integrand);
+
+ [Theory]
+ [InlineData("F^(f*(a + b*ln(c*x^n))^2)")]
+ [InlineData("x^2*F^(f*(a + b*ln(c*x^n))^2)")]
+ [InlineData("F^(-f*(a + b*ln(c*x^n)^2))/x^3")]
+ [InlineData("x^m*F^(f*(a + b*ln(c*x^n))^2)")]
+ [InlineData("(1 + x)^2*F^(f*(a + b*ln(c*x^n))^2)")]
+ public void OfALogarithmOfAPower(string integrand) => DifferentiatesBack(integrand);
+
+ ///
+ /// The logarithm of a power of a linear, under u = d + e x, with a constant multiple
+ /// of the linear or a polynomial beside it, as Rubi's 2.3 writes them.
+ ///
+ [Theory]
+ [InlineData("F^(f*(a + b*ln(c*(d + k*x)^n))^2)")]
+ [InlineData("(d*g + k*g*x)^m*F^(f*(a + b*ln(c*(d + k*x)^n))^2)")]
+ [InlineData("F^(f*(a + b*ln(c*(d + k*x)^n)^2))/(d*g + k*g*x)^2")]
+ [InlineData("(g + h*x)^3*F^(f*(a + b*ln(c*(d + k*x)^n))^2)")]
+ [InlineData("e^(ln((d + k*x)^n)^2)*(d + k*x)^m")]
+ public void OfALogarithmOfAPowerOfALinear(string integrand) => DifferentiatesBack(integrand);
+
+ /// Beside 1/x it is the Gaussian in ln(x) alone.
+ [Fact]
+ public void BesideTheReciprocalItIsTheGaussianOfTheLogarithm()
+ => Assert.Contains(DifferentiatesBack("e^(ln(x)^2)/x").Nodes, node => node is Entity.Erfif);
+ }
+}