diff --git a/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Solvers.cs b/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Solvers.cs index de80ceff4..d31fc920d 100644 --- a/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Solvers.cs +++ b/Sources/AngouriMath/Functions/Continuous/Limits/Solvers/Limit.Solvers.cs @@ -331,9 +331,12 @@ private static bool LogarithmDiverges(Entity argumentLimit) if (upperDerivative.Nodes.Any(node => node is Derivativef) || lowerDerivative.Nodes.Any(node => node is Derivativef)) return null; - var p = (upperDerivative / upperLogArgument).InnerSimplified; - var q = (lowerDerivative / lowerLogArgument).InnerSimplified; - return LimitFunctional.ComputeLimit(p / q, x, Real.PositiveInfinity); + // (u'/u) / (v'/v) asked as the one quotient u' v / (u v'): asked as a quotient of + // quotients, the limit of ln(x - 1) / ln(ln(x)) at 1 from the left took twelve + // seconds over (1/(x - 1)) / ((1/x) / ln(x)), where x ln(x) / (x - 1) takes a + // hundredth of one. It took 14 ms before #2275 sent it to this rule. + var ratio = (upperDerivative * lowerLogArgument / (upperLogArgument * lowerDerivative)).InnerSimplified; + return LimitFunctional.ComputeLimit(ratio, x, Real.PositiveInfinity); } else diff --git a/Sources/Tests/UnitTests/Calculus/AQuotientOfLogarithmsIsAskedAsOneQuotientTest.cs b/Sources/Tests/UnitTests/Calculus/AQuotientOfLogarithmsIsAskedAsOneQuotientTest.cs new file mode 100644 index 000000000..54824897c --- /dev/null +++ b/Sources/Tests/UnitTests/Calculus/AQuotientOfLogarithmsIsAskedAsOneQuotientTest.cs @@ -0,0 +1,39 @@ +// +// 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.Threading.Tasks; +using AngouriMath.Core; +using Xunit; +using static AngouriMath.Entity; + +namespace AngouriMath.Tests.Calculus +{ + /// + /// A quotient of two logarithms that both diverge is the limit of the quotient of their logarithmic derivatives, + /// and that was asked as a quotient of quotients, (u'/u) / (v'/v). For ln(x - 1) / ln(ln(x)) at 1 that + /// is (1/(x - 1)) / ((1/x) / ln(x)), whose limit took twelve seconds from the left and six from the right, + /// where x ln(x) / (x - 1), the same function, takes a fraction of one. Found by limitcheck, which gave each + /// side five seconds; no issue was filed. The cap here is far from both: the fixed limit takes about 0.2 s. + /// + [Trait("Area", "Calculus")] + public sealed class AQuotientOfLogarithmsIsAskedAsOneQuotientTest + { + [Theory] + [InlineData("ln(x - 1) / ln(ln(x))", ApproachFrom.Left)] + [InlineData("ln(x - 1) / ln(ln(x))", ApproachFrom.Right)] + [InlineData("ln(x - 1) / ln(ln(x))", ApproachFrom.BothSides)] + [InlineData("log(ln(x), x - 1)", ApproachFrom.Left)] + [InlineData("ln(1 - x) / ln(-ln(x))", ApproachFrom.Left)] + public void IsOneAtOne(string input, ApproachFrom side) + { + var task = Task.Factory.StartNew(() => MathS.FromString(input).Limit("x", 1, side), TaskCreationOptions.LongRunning); + Assert.True(task.Wait(TimeSpan.FromSeconds(4)), $"the limit of {input} at 1, {side}, did not finish in four seconds"); + Assert.Equal(Number.Integer.One, task.Result); + } + } +}