From ef11af4b4d087827f1773347668076fd3f9b7fb8 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Thu, 1 Oct 2026 08:00:03 +0000 Subject: [PATCH 1/3] A special function of a logarithm of a monomial is integrated, through Ei of a complex argument (e x)^m Si(d (a + b ln(c x^n))) is by parts against (e x)^m, and what is left is a power of x times sin(d (a + b ln(c x^n)))/(a + b ln(c x^n)). Two rules were missing on the way, and both are here. A power of x times a function of one logarithm of a monomial, x^m G(ln(c x^n)), is integrated under t = ln(c x^n). dx is x dt/n, and x^(m + 1) is K e^((m + 1) t/n), where K = x^(m + 1) (c x^n)^(-(m + 1)/n) has derivative 0 wherever it is defined. So the answer is K/n times the integral of e^((m + 1) t/n) G(t) at t = ln(c x^n), an antiderivative wherever the integrand is real. For an even n that includes negative x, where ln(c x^n) is not ln(c) + n ln(x) and an answer through ln(x) would be off by a branch. A power of a monomial, (e x)^m, is x^m times a factor of the same kind. Rubi's answers to 8.3 to 8.5 are written in this K. And an exponential times sines and cosines of linears over linears: each sine and cosine is written as exponentials, the product multiplied out, and every term is an exponential with a complex rate over the linears, which the exponential rules answer with Ei of a complex argument. e^(2x) sin(x)/x is (Ei((2 + i) x) - Ei((2 - i) x))/(2i), two conjugate terms whose sum is real. Only with an exponential beside the sine or cosine: sin(x)/x alone stays Si(x). The evaluator reads Ei, Si and erf off the real line already, so these answers are checked like any other. Measured on the Rubi corpus, master at 9efc4864 and this change on it, run side by side: family 8 394 -> 409 of 420, all fifteen of F(d (a + b ln(c x^n))): Ei, Shi and Chi beside (e x)^m, and Si and Ci alone, beside x, x^2 and (e x)^m, and over x^2 and x^3. Family 4 at ten a file 611 -> 612, the one being cos(a + b ln(c x^n))^2. Family 2 is 544 of 650 on both, family 3 at twenty a file 173 of 180, the independent suites 1756 of 1814, and families 1, 5, 6 and 7 at five a file 439 of 499. 0 wrong everywhere. Run alone, the sixteen are 0 of 16 on master and 16 of 16 here. The unit tests pass, 14,272. The unit tests pass, 14,273, with the GC heap held to 4 GB, and the performance gate passes on 49f87185, which is this change on 9efc4864 but for K written as 1 where the logarithm is ln(x): allocation is what the baseline says on all 19 gated benchmarks. ExponentialIntegralIntegrationTest has three rows of an exponential beside a sine or cosine over a linear, and four of a function of a logarithm of a monomial, checked at negative x as well with n = 2. Part of #1501. Co-Authored-By: Claude Opus 5.5 --- BREAKING-CHANGES.md | 23 +++ .../Integration/IndefiniteIntegralSolver.cs | 177 ++++++++++++++++++ .../Integration/Integration.Definition.cs | 5 + .../ExponentialIntegralIntegrationTest.cs | 28 +++ 4 files changed, 233 insertions(+) diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index ccb8530f8..a4cfe4953 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -2381,6 +2381,29 @@ family 3 at twenty a file and a sample of the others are answered alone as they |---|---|---| | `"li(b*x)/x".Integrate("x")` | `li * b * x + C`, with `li` a variable | `li(b * x) * ln(b * x) - b * x + C` | +### A special function of a logarithm of a monomial is integrated, through `Ei` of a complex argument + +`(e x)^m Si(d (a + b ln(c x^n)))` is by parts against `(e x)^m`, and what is left is a power of `x` +times `sin(d (a + b ln(c x^n)))/(a + b ln(c x^n))`. Two rules were missing on the way +([#1501](https://github.com/asc-community/AngouriMath/issues/1501)): + +- **A function of one logarithm of a monomial.** A power of `x` times `G(ln(c x^n))` is integrated + under `t = ln(c x^n)`, with `x^(m + 1)` written as `K e^((m + 1) t/n)` and + `K = x^(m + 1) (c x^n)^(-(m + 1)/n)`, whose derivative is 0 wherever it is defined. That is an + antiderivative wherever the integrand is real. For an even `n` that includes negative `x`, where + `ln(c x^n)` is not `ln(c) + n ln(x)`. +- **An exponential beside a sine or cosine, over linears.** Each sine and cosine is written as + exponentials, and each term is the exponential integral of a complex argument. The two conjugate + terms add up to a real value. + +Both columns measured on a build, `v2.5.0` against this change. + +| Input | Was (2.5.0) | Now | +|---|---|---| +| `"e^(2*x)*sin(x)/x".Integrate("x")` | `integral(e ^ (2 * x) * sin(x) / x, x)` | `(-1/2 * i) * Ei((2 + i) * x) + 1/2 * i * Ei((2 - i) * x) + C` | +| `"x*sin(ln(x))/ln(x)".Integrate("x")` | `integral(x * sin(ln(x)) / ln(x), x)` | `(-1/2 * i) * Ei((2 + i) * ln(x)) + 1/2 * i * Ei((2 - i) * ln(x)) + C` | +| `"cos(a+b*ln(c*x^n))^2".Integrate("x")` | `integral(cos(a + b * ln(c * x ^ n)) ^ 2, x)` | an antiderivative in `sin` and `cos` of `2 (a + b ln(c x^n))`, beside `x (c x^n)^(-1/n)` | + ### An exponential or a hyperbolic function over several linears is split into partial fractions over them `e^x/(x (x + 1))` was left unevaluated, where `e^x/x` and `e^x/(x + 1)` were each answered with diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 46a7ea811..44a93629d 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -3978,6 +3978,99 @@ bool Read(Entity factor, int times) return Functions.PartialFractions.Bare((constant * sum).InnerSimplified); } + /// + /// An exponential of a linear times sines and cosines of linears, and a polynomial, over + /// linears: each sine and cosine is written as exponentials, sin(c x) = (e^(i c x) - e^(-i c x))/(2i), + /// the product multiplied out, and every term is an exponential of a linear with a + /// complex rate over the linears, which + /// and answer with the exponential + /// integral of a complex argument. e^(2x) sin(x)/x is + /// (Ei((2 + i) x) - Ei((2 - i) x))/(2i), real where x is: the two terms are + /// conjugates. What by parts leaves of Si(ln(x)), under t = ln(x), is + /// e^t sin(t)/t. Rubi's 8.4, (e x)^m Si(d (a + b ln(c x^n))), answers the same way. + /// https://github.com/asc-community/AngouriMath/issues/1501 + /// + /// + /// Only with an exponential of a real rate beside the sine or cosine: alone over a linear, + /// the sine and cosine integrals are their closed form, and the rule for them answers. + /// + internal static Entity? SolveAnExponentialTimesATrigonometricOverLinears(Entity expr, Entity.Variable x) + { + if (expr is not (Divf or Mulf)) + return null; + int exponentialsByShape = 0, trigonometricsByShape = 0; + var aPowerOfASumByShape = false; + CountFactorsByShape(expr, x, ref exponentialsByShape, ref trigonometricsByShape, ref aPowerOfASumByShape); + if (exponentialsByShape == 0 || trigonometricsByShape == 0) + return null; + Entity constant = Number.Integer.One; + Entity? polynomial = null; + var linears = new List<(Entity Linear, int Power)>(); + var exponents = new List(); + var terms = new List<(Entity Coefficient, int[] Multiples)> { (Number.Integer.One, new int[MostExponents]) }; + int exponentials = 0, trigonometrics = 0; + foreach (var (factor, underneath) in FactorsOfTheIntegrand(expr)) + { + if (!factor.ContainsNode(x)) + { + constant = underneath ? constant / factor : constant * factor; + continue; + } + var (@base, exponent) = factor is Powf(var raised, Number.Integer whole) && whole.EInteger.CanFitInInt32() && !whole.EInteger.IsZero + ? (raised, whole.EInteger.ToInt32Checked()) : (factor, 1); + if (underneath && TreeAnalyzer.TryGetPolyLinear(@base, x, out var slopeOfIt, out _) && !TreeAnalyzer.IsZero(slopeOfIt)) + { + var at = linears.FindIndex(pair => pair.Linear == @base); + if (at < 0) + linears.Add((@base, exponent)); + else + linears[at] = (@base, linears[at].Power + exponent); + continue; + } + if (underneath) + return null; + if (AsExponentialsOfQuadratics(factor, x, exponents) is { } read) + { + if (factor.Nodes.Any(node => node is Sinf or Cosf)) + trigonometrics++; + else + exponentials++; + if (Multiplied(terms, read) is not { } product) + return null; + terms = product; + continue; + } + if (TreeAnalyzer.TryGetPolynomial(factor, x, out var monomials) && monomials.Keys.All(degree => degree.Sign >= 0 && degree.CompareTo(EInteger.FromInt32(12)) <= 0)) + { + polynomial = polynomial is null ? factor : polynomial * factor; + continue; + } + return null; + } + if (exponentials == 0 || trigonometrics == 0 || linears.Count == 0 || linears.Count > 4 || linears.Sum(pair => pair.Power) > 12) + return null; + var below = linears.Aggregate((Entity)Number.Integer.One, (product, pair) => product * MathS.Pow(pair.Linear, pair.Power)); + var above = polynomial ?? Number.Integer.One; + Entity sum = Number.Integer.Zero; + foreach (var (coefficient, multiples) in terms) + { + var (a, b, c) = TheExponent(multiples, exponents); + // Linear exponents only: a quadratic left is the Gaussian's, and is another rule's. + if (!TreeAnalyzer.IsZero(a)) + return null; + var factorOfTheTerm = TreeAnalyzer.IsZero(c) ? coefficient : coefficient * MathS.Pow(MathS.e, c); + var question = TreeAnalyzer.IsZero(b) + ? above / below + : MathS.Pow(MathS.e, b * x) * above / below; + if (((TreeAnalyzer.IsZero(b) ? null + : linears.Count == 1 ? SolveAnExponentialOfALinearOverAPowerOfALinear(question, x) : SolveAnExponentialOverSeveralLinears(question, x)) + ?? Integration.ComputeIndefiniteIntegral(question, x, false)) is not { } integral) + return null; + sum += factorOfTheTerm * integral; + } + return Functions.PartialFractions.Bare((constant * sum).InnerSimplified); + } + /// Whether a factor of is a sum with an exponential of the variable in it. private static bool HasASumOfExponentials(Entity expr, Entity.Variable x) => expr switch { @@ -6614,6 +6707,90 @@ node is Logf(var @base, var argument) && !@base.ContainsNode(x) && @base != Math : null; } + /// + /// A power of x times a function of one logarithm of a monomial, x^m G(ln(c x^n)), + /// under t = ln(c x^n): dx = x dt/n, and x^(m + 1) is + /// K e^((m + 1) t/n) with K = x^(m + 1) (c x^n)^(-(m + 1)/n), whose derivative + /// is 0 wherever it is defined. So the answer is K/n times the integral of + /// e^((m + 1) t/n) G(t) at t = ln(c x^n), an antiderivative on the whole of + /// the real line where the integrand is real -- for an even n that includes negative + /// x, where ln(c x^n) is not ln(c) + n ln(x). A power of a monomial, + /// (e x)^p, is x^p times a factor of the same kind. What by parts leaves of + /// (e x)^m Si(d (a + b ln(c x^n))) is this, with G(t) a sine over a linear in + /// t. Rubi's answers to 8.3 to 8.5 are written in exactly this K. + /// https://github.com/asc-community/AngouriMath/issues/1501 + /// + /// + /// After , which answers ln(x) alone. + /// + internal static Entity? SolveByAPowerAndALogarithmOfAMonomial(Entity expr, Entity.Variable x, bool integrateByParts) + { + if (!expr.Nodes.Any(node => node is Logf)) + return null; + Entity constant = Number.Integer.One; + Entity m = Number.Integer.Zero; + Entity locallyConstant = Number.Integer.One; + Entity rest = Number.Integer.One; + foreach (var (factor, underneath) in FactorsOfTheIntegrand(expr)) + { + if (!factor.ContainsNode(x)) + { + constant = underneath ? constant / factor : constant * factor; + continue; + } + // x, a power of x, or a power of a monomial (k x)^p, p free of x. + var (@base, power) = factor is Powf(var raised, var exponent) && !exponent.ContainsNode(x) ? (raised, exponent) : (factor, (Entity)Number.Integer.One); + if (TheMonomial(@base, x) is var (coefficientOfIt, degreeOfIt) && degreeOfIt == Number.Integer.One) + { + var p = underneath ? -power : power; + m = m + p; + if (coefficientOfIt != Number.Integer.One) + locallyConstant = locallyConstant * MathS.Pow(@base, p) * MathS.Pow(x, -p); + continue; + } + rest = underneath ? rest / factor : rest * factor; + } + // One logarithm of a monomial in what is left. + var logarithms = rest.Nodes.OfType().Where(node => node.Base == MathS.e && node.ContainsNode(x)).Distinct().ToList(); + if (logarithms.Count != 1 || TheMonomial(logarithms[0].Antilogarithm, x) is not var (c, n) || TreeAnalyzer.IsZero(n)) + return null; + var t = Variable.CreateUnique(expr, "t_log"); + var inT = rest.Substitute(logarithms[0], t); + if (inT.ContainsNode(x)) + return null; + var mPlusOne = (m + Number.Integer.One).InnerSimplified; + var integrand = (MathS.Pow(MathS.e, (mPlusOne / n).InnerSimplified * t) * inT).InnerSimplified; + if (integrand is Providedf(var bare, _)) + integrand = bare; + if (Integration.ComputeIndefiniteIntegral(integrand, t, integrateByParts) is not { } inTIntegral) + return null; + // Of ln(x) itself, K is 1, and written as x^(m + 1) x^(-(m + 1)) it is not seen to be. + var k = logarithms[0].Antilogarithm == x ? Number.Integer.One + : MathS.Pow(x, mPlusOne) * MathS.Pow(logarithms[0].Antilogarithm, (-mPlusOne / n).InnerSimplified); + var back = constant * locallyConstant * k / n * inTIntegral.Substitute(t, logarithms[0]); + return back.Nodes.Any(node => node == MathS.NaN) ? null : back; + } + + /// + /// as c x^n, c and n free of , + /// or . + /// + private static (Entity Coefficient, Entity Degree)? TheMonomial(Entity expr, Entity.Variable x) + { + if (expr == x) + return (Number.Integer.One, Number.Integer.One); + if (expr is Powf(var @base, var power) && @base == x && !power.ContainsNode(x)) + return (Number.Integer.One, power); + if (expr is Mulf(var left, var right)) + { + if (!left.ContainsNode(x) && TheMonomial(right, x) is var (c, n)) + return (left * c, n); + if (!right.ContainsNode(x) && TheMonomial(left, x) is var (c2, n2)) + return (right * c2, n2); + } + return null; + } + /// /// A quotient of two homogeneous polynomials in sin(u) and cos(u), /// integrated by t = tan(u) — which turns it into a rational function of t diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs index 5be10b342..5889a488e 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs @@ -646,6 +646,9 @@ private static Entity Normalized(Entity expr, Entity.Variable x) => // And either over several linears, split into partial fractions over them first, as the // trigonometric rule below splits. if ((answer = IndefiniteIntegralSolver.SolveAnExponentialOverSeveralLinears(expr, x)) is { }) return answer; + // And with sines and cosines beside the exponential, written as exponentials: each term + // is then the exponential's, with a complex rate. + if ((answer = IndefiniteIntegralSolver.SolveAnExponentialTimesATrigonometricOverLinears(expr, x)) is { }) return answer; // Sines and cosines of a linear over a power of a linear, onto Si and Ci under u = the // linear, where the search would take the quotient by parts without end. if ((answer = IndefiniteIntegralSolver.SolveATrigonometricOfALinearOverAPowerOfALinear(expr, x)) is { }) return answer; @@ -838,6 +841,8 @@ private static Entity Normalized(Entity expr, Entity.Variable x) => // is why the general substitution does not find it and why it pays: the integrator // answers an exponential times almost anything. if ((answer = IndefiniteIntegralSolver.SolveByLogarithmSubstitution(expr, x, integrateByParts)) is { }) return answer; + // And a power of x times a function of one logarithm of a monomial, under t = that logarithm. + if ((answer = IndefiniteIntegralSolver.SolveByAPowerAndALogarithmOfAMonomial(expr, x, integrateByParts)) is { }) return answer; // And the inverse trigonometric functions' own, beside the logarithm's and for the // same reason: `x = sin(u)` removes the `x` that substituting for `arcsin(x)` leaves. if ((answer = IndefiniteIntegralSolver.SolveByInverseTrigonometricSubstitution(expr, x, integrateByParts)) is { }) return answer; diff --git a/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs b/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs index 18fff93ee..b40f3c336 100644 --- a/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs +++ b/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs @@ -62,6 +62,34 @@ private static readonly (string, string)[] Pins = public void AnExponentialOfALinearOverAPowerOfALinear(string integrand) => DifferentiatesBack(integrand, AroundZero, Pins); + /// + /// Beside a sine or a cosine of a linear, the sine and cosine are written as exponentials, + /// and each term is the exponential's above with a complex rate: e^(2x) sin(x)/x is + /// (Ei((2 + i) x) - Ei((2 - i) x))/(2i), two conjugate terms whose sum is real. + /// + [Theory] + [InlineData("e^(2*x)*sin(x)/x")] + [InlineData("e^x*cos(x)/(1 + x)")] + [InlineData("x*e^x*sin(2*x)/(x - 1)")] + public void AnExponentialTimesASineOrCosineOverALinear(string integrand) + => DifferentiatesBack(integrand, AroundZero, Pins); + + /// + /// A power of x times a function of a logarithm of a monomial, under + /// t = ln(c x^n), with x^(m + 1) written as K e^((m + 1) t/n) and + /// K = x^(m + 1) (c x^n)^(-(m + 1)/n) locally constant. With an even n the + /// integrand is real at negative x as well, and the answer is checked there too, + /// where ln(c x^n) is not ln(c) + n ln(x). + /// + [Theory] + [InlineData("x*sin(ln(x))/ln(x)")] + [InlineData("Si(d*(a + b*ln(c*x^n)))")] + [InlineData("x*Ci(d*(a + b*ln(c*x^n)))")] + [InlineData("(k*x)^m*Ei(d*(a + b*ln(c*x^n)))")] + public void APowerTimesAFunctionOfALogarithmOfAMonomial(string integrand) + => DifferentiatesBack(integrand, new[] { -2.1, -0.7, 0.6, 1.7 }, + ("a", "2/5"), ("b", "13/10"), ("c", "7/10"), ("d", "19/10"), ("k", "11/10"), ("m", "1/2"), ("n", "2")); + /// /// Over several linears, the quotient is split into partial fractions over them first, and /// each term is the question above: e^x/(x (x + 1)) is Ei(x) - Ei(x + 1)/e. The From b6f0d9912041fa035762c72a91539e75e0daf7ee Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Thu, 1 Oct 2026 10:09:20 +0000 Subject: [PATCH 2/3] The power and logarithm rule hands the integrator one quotient SolveByAPowerAndALogarithmOfAMonomial built its integrand in t as a product: for (d x)^m x/ln(b x) that is e^((m + 2) t) t^(-1), which the exponential integral rules do not read, and which runs away in integration by parts on master (#1646). Built with SingleQuotient.Combine, as the logarithm substitution builds its own, (d x)^m x/ln(b x) is K Ei((m + 2) ln(b x)) in 0.3 s, and (d x)^m li(b x), Rubi's 8.3 row 269, is answered in 0.8 s. Co-Authored-By: Claude Opus 5.5 --- .../Continuous/Integration/IndefiniteIntegralSolver.cs | 5 ++++- .../Calculus/ExponentialIntegralIntegrationTest.cs | 1 + .../UnitTests/Calculus/SpecialFunctionsByPartsTest.cs | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 44a93629d..e04cdb285 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -6759,7 +6759,10 @@ node is Logf(var @base, var argument) && !@base.ContainsNode(x) && @base != Math if (inT.ContainsNode(x)) return null; var mPlusOne = (m + Number.Integer.One).InnerSimplified; - var integrand = (MathS.Pow(MathS.e, (mPlusOne / n).InnerSimplified * t) * inT).InnerSimplified; + // One quotient, as the logarithm substitution writes its own: `e^((m + 2) t)/t` is the + // exponential integral, and as a product with `t^(-1)` it went to integration by parts. + // https://github.com/asc-community/AngouriMath/issues/1646 + var integrand = Functions.SingleQuotient.Combine(inT * MathS.Pow(MathS.e, (mPlusOne / n).InnerSimplified * t)).InnerSimplified; if (integrand is Providedf(var bare, _)) integrand = bare; if (Integration.ComputeIndefiniteIntegral(integrand, t, integrateByParts) is not { } inTIntegral) diff --git a/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs b/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs index b40f3c336..7190702a9 100644 --- a/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs +++ b/Sources/Tests/UnitTests/Calculus/ExponentialIntegralIntegrationTest.cs @@ -131,6 +131,7 @@ public void AnOddNegativeMomentOfTheGaussian(string integrand) [InlineData("(1 + x)/ln(x)")] [InlineData("x^2/ln(c*(d + k*x^3)^n)")] [InlineData("x^8/ln(c*(d + k*x^3)^n)^2")] + [InlineData("(k*x)^m*x/ln(b*x)")] public void APowerOverAPowerOfALogarithm(string integrand) => DifferentiatesBack(integrand, PastOne, Pins); diff --git a/Sources/Tests/UnitTests/Calculus/SpecialFunctionsByPartsTest.cs b/Sources/Tests/UnitTests/Calculus/SpecialFunctionsByPartsTest.cs index 4139e5635..0ba2167aa 100644 --- a/Sources/Tests/UnitTests/Calculus/SpecialFunctionsByPartsTest.cs +++ b/Sources/Tests/UnitTests/Calculus/SpecialFunctionsByPartsTest.cs @@ -87,6 +87,15 @@ public void TheLogarithmicIntegralIsByParts(string integrand) public void TheLogarithmicIntegralOverXIsOneRoundOfParts() => DifferentiatesBackAt(new[] { 0.35, 1.45, 2.3 }, "li(b*x)/x", ("b", "13/10")); + /// + /// Beside a power of a monomial, the remainder is b (d x)^m x/((m + 1) ln(b x)), a power + /// of x over a logarithm of a monomial, which is Ei((m + 2) ln(b x)) times a + /// locally constant factor. Rubi's 8.3 row 269. + /// + [Fact] + public void TheLogarithmicIntegralBesideAPowerOfAMonomial() + => DifferentiatesBackAt(new[] { 0.35, 1.45, 2.3 }, "(d*x)^m*li(b*x)", ("b", "13/10"), ("d", "19/10"), ("m", "1/2")); + /// /// Against a power of x, the special function is the factor differentiated: what is /// left is the power times e^(-u^2), e^u/u, sin(u)/u and the like. From 77172178bedce3f52f29bf3a938af19907e464e7 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Thu, 1 Oct 2026 11:14:32 +0000 Subject: [PATCH 3/3] The changelog entry says how (d x)^m li(b x) is answered Co-Authored-By: Claude Opus 5.5 --- BREAKING-CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index a4cfe4953..d286091ff 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -2391,7 +2391,8 @@ times `sin(d (a + b ln(c x^n)))/(a + b ln(c x^n))`. Two rules were missing on th under `t = ln(c x^n)`, with `x^(m + 1)` written as `K e^((m + 1) t/n)` and `K = x^(m + 1) (c x^n)^(-(m + 1)/n)`, whose derivative is 0 wherever it is defined. That is an antiderivative wherever the integrand is real. For an even `n` that includes negative `x`, where - `ln(c x^n)` is not `ln(c) + n ln(x)`. + `ln(c x^n)` is not `ln(c) + n ln(x)`. By parts leaves `(d x)^m x/ln(b x)` of `(d x)^m li(b x)`, + and this rule answers it with `Ei((m + 2) ln(b x))`. - **An exponential beside a sine or cosine, over linears.** Each sine and cosine is written as exponentials, and each term is the exponential integral of a complex argument. The two conjugate terms add up to a real value.