Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
};
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// The second remarkable limit writes a 1^oo power <c>f^g</c> as <c>e^(g (f - 1))</c>, 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:
/// <c>(cos(x))^(1/x^2)</c> at 0, which is <c>e^(-1/2)</c>, was NaN. The exponent is the quotient
/// <c>(f - 1) / (1/g)</c> now, which a function of an indeterminate quotient asks whole. No issue was filed.
/// </summary>
[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<Number>(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);
}
}
Loading