From e2d60d831b03867033eeb3baf131242ab135b2b3 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Wed, 4 Nov 2026 02:26:33 +0000 Subject: [PATCH] Write a 1^oo limit's exponent as a quotient The second remarkable limit writes a 1^oo power f^g as e^(g (f - 1)), and the product in its exponent the descent read as 0 * oo, NaN, the claim that there is no limit. Only a base of 1 plus a polynomial was answered, by another route: (cos(x))^(1/x^2) at 0, which is e^(-1/2), was NaN, and from the right unevaluated. 2.6.0 answers the same. The exponent is (f - 1) / (1/g) now, a 0/0 that a function of an indeterminate quotient asks whole since #2358. Asking a product whole in the descent instead answered these too, and also answered x * ln(x) at 0 two-sided with 0, which the two-sided reading keeps NaN, its left side not being real; the quotient keeps that convention. limitcheck on SEED=14 and 16, and at DEPTH=3 on 19 and 23, is master's exactly; 4194 limit, integration and remarkable-limit tests pass. Co-Authored-By: Claude Opus 5.5 --- BREAKING-CHANGES.md | 15 ++++++ .../Continuous/Limits/Transformations.cs | 6 ++- ...oTheInfinityLimitThroughItsExponentTest.cs | 48 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 Sources/Tests/UnitTests/Calculus/AOneToTheInfinityLimitThroughItsExponentTest.cs diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index b421df3d7..b3378a053 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -292,6 +292,21 @@ carried it once combined: a second derivative of `1/sqrt(x^2 + 13)` stated `not | `"(a provided b > 0) + (c provided b > 0)".ToEntity().InnerSimplified` | `a + c provided b > 0 and b > 0` | `a + c provided b > 0` | | `MathS.Equations("sqrt(y) - x", "y - a").Solve("x", "y")` | `[[sqrt(a), (sqrt(a)) ^ 2], [-sqrt(a), (-sqrt(a)) ^ 2]]` | `[[sqrt(a) provided C(sqrt(a)), (sqrt(a)) ^ 2 provided C(sqrt(a))], [-sqrt(a) provided C(-sqrt(a)), (-sqrt(a)) ^ 2 provided C(-sqrt(a))]]`, `C(v)` being `v = 0 or -1/2 * pi < arg(v) and arg(v) <= 1/2 * pi` | +### A 1^oo limit has its value + +**Silent: a different answer.** The second remarkable limit writes a 1^oo power `f^g` as `e^(g (f - 1))`, and the +product in its exponent the descent read as 0 * oo, which is NaN, the claim that there is no limit. Only a base of 1 +plus a polynomial was answered, by another route. The exponent is the quotient `(f - 1) / (1/g)` now, which is asked +whole where the descent cannot settle it. No issue was filed. + +| Input | Was (2.6.0) | Now | +|---|---|---| +| `limit(cos(x)^(1/x^2), x, 0)` | `NaN` | `e ^ (-1/2)` | +| `limit((sin(x)/x)^(1/x^2), x, 0)` | `NaN` | `e ^ (-1/6)` | +| `limit(cos(2x)^(1/x^2), x, 0)` | `NaN` | `e ^ (-2)` | +| `limit((1 + sin(x))^(1/x), x, 0)` | `NaN` | `e` | +| `limitright(cos(x)^(1/x), x, 0)` | unevaluated | `1` | + ### A root in exact numbers is put back to the working precision **Silent: a number that is not a root, in exact numbers, is no longer answered as one.** Every root is put back into the diff --git a/Sources/AngouriMath/Functions/Continuous/Limits/Transformations.cs b/Sources/AngouriMath/Functions/Continuous/Limits/Transformations.cs index 99d206605..d84fdb3a6 100644 --- a/Sources/AngouriMath/Functions/Continuous/Limits/Transformations.cs +++ b/Sources/AngouriMath/Functions/Continuous/Limits/Transformations.cs @@ -186,7 +186,9 @@ private static Entity ApplySecondRemarkable(Entity expr, Variable x, Entity dest Powf(var xPlusOne, var xPower) when xPlusOne.ContainsNode(x) && xPower.ContainsNode(x) && EvalAssumingContinuous((xPlusOne - 1).Limit(x, dest)) == 0 && DivergesInMagnitude(xPower, x, dest) => - MathS.e.Pow(xPower * (xPlusOne - 1)), + // The exponent as the quotient (f - 1) / (1/g), not the product g (f - 1): a 0/0 the descent hands to the + // whole limit, where it read 0 * oo as NaN, and (cos(x))^(1/x^2) at 0, e^(-1/2), was NaN. + MathS.e.Pow((xPlusOne - 1) / (1 / xPower)), // a(x)^n / b(x)^n, the same limit written as a quotient. The simplifier used // to gather this into (a/b)^n for us, which is how the shape reached the rule @@ -206,7 +208,7 @@ private static Entity ApplySecondRemarkable(Entity expr, Variable x, Entity dest && IsEventuallyPositive(numeratorBase, x, dest) && IsEventuallyPositive(denominatorBase, x, dest) && EvalAssumingContinuous((numeratorBase / denominatorBase - 1).Limit(x, dest)) == 0 && DivergesInMagnitude(power, x, dest) => - MathS.e.Pow(power * (numeratorBase / denominatorBase - 1)), + MathS.e.Pow((numeratorBase / denominatorBase - 1) / (1 / power)), _ => expr }; diff --git a/Sources/Tests/UnitTests/Calculus/AOneToTheInfinityLimitThroughItsExponentTest.cs b/Sources/Tests/UnitTests/Calculus/AOneToTheInfinityLimitThroughItsExponentTest.cs new file mode 100644 index 000000000..d76494a2b --- /dev/null +++ b/Sources/Tests/UnitTests/Calculus/AOneToTheInfinityLimitThroughItsExponentTest.cs @@ -0,0 +1,48 @@ +// +// 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 AngouriMath.Core; +using Xunit; +using static AngouriMath.Entity; + +namespace AngouriMath.Tests.Calculus +{ + /// + /// The second remarkable limit writes a 1^oo power f^g as e^(g (f - 1)), and the product in its exponent + /// the descent reads as 0 * oo, NaN, where only a base of 1 plus a polynomial was answered by another route: + /// (cos(x))^(1/x^2) at 0, which is e^(-1/2), was NaN. The exponent is the quotient + /// (f - 1) / (1/g) now, which a function of an indeterminate quotient asks whole. No issue was filed. + /// + [Trait("Area", "Calculus")] + public sealed class AOneToTheInfinityLimitThroughItsExponentTest + { + [Theory] + [InlineData("(cos(x))^(1/x^2)", ApproachFrom.BothSides, "e^(-1/2)")] + [InlineData("(cos(x))^(1/x^2)", ApproachFrom.Right, "e^(-1/2)")] + [InlineData("(sin(x)/x)^(1/x^2)", ApproachFrom.BothSides, "e^(-1/6)")] + [InlineData("(cos(2x))^(1/x^2)", ApproachFrom.BothSides, "e^(-2)")] + [InlineData("(1 + sin(x))^(1/x)", ApproachFrom.BothSides, "e")] + [InlineData("(cos(x))^(1/x)", ApproachFrom.Right, "1")] + // As before. + [InlineData("(1 + x)^(1/x)", ApproachFrom.BothSides, "e")] + [InlineData("(1 - x^2)^(1/x^2)", ApproachFrom.BothSides, "1/e")] + public void HasItsValue(string input, ApproachFrom side, string expected) + { + var limit = MathS.FromString(input).Limit("x", 0, side); + Assert.IsAssignableFrom(limit.Evaled); + var difference = (limit - MathS.FromString(expected)).EvalNumerical(); + Assert.True(difference.Abs() < (Number.Real)1e-30, $"the limit of {input} at 0 is {limit}, where it is {expected}"); + } + + [Theory] + [InlineData("x * ln(x)")] + [InlineData("sin(x) * ln(x)")] + [InlineData("x^x")] + public void TheTwoSidedConventionIsKept(string input) + => Assert.Equal(MathS.NaN, MathS.FromString(input).Limit("x", 0).Evaled); + } +}