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
14 changes: 14 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ divisor answers at once. A two-sided limit is not changed. Found by limitcheck;
| `"arcsin(-x * log(-1, x))".ToEntity().Limit("x", 0, ApproachFrom.Right)` | `limitright(arcsin(-x * log(-1, x)), x, 0)` | `0` |
| `"x * log(2 + x, x)".ToEntity().Limit("x", 0, ApproachFrom.Right)` | `0` after 27 s | `0` in 0.25 s |

### A product with a power for a factor is read by the power's exponent's limit in a one-sided limit

**Silent: a one-sided limit of a product whose factors tend to 0 and to an infinity, one of them a power `u^v` whose
exponent tends to a constant `c` other than 0, is read as `(other * u^c) * u^(v - c)`** wherever `u^(v - c)` tends to a
finite real other than 0. The principal power splits that way for any `u`. `(tan(x) + 1)^(x^(x - 1))` at 0 from the
right has the exponent `tan(x) * x^(x - 1)`, which is `tan(x) / x` times `x^x` and tends to 1, so the limit is `e`.
l'Hôpital's rule differentiated `x^(x - 1)` instead, and did not finish. A two-sided limit is not changed. Found by
limitcheck; no issue was filed.

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"(tan(x) + 1)^(x^(x - 1))".ToEntity().Limit("x", 0, ApproachFrom.Right)` | `limitright((tan(x) + 1) ^ x ^ (x - 1), x, 0)` | `e` |
| `"tan(x) * x^(x - 1)".ToEntity().Limit("x", 0, ApproachFrom.Right)` | `1` after 11 s | `1` in 0.21 s |

### A derivative keeps an exponent that is not rational exact

**Silent: the power rule writes a constant exponent that is not rational as it is, where it wrote its decimal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ partial record Mulf
&& AsTheWholeLimit(distributed, x, dist, side) is { } termByTerm
&& termByTerm.Evaled != MathS.NaN)
return termByTerm;
// So, with a power u^v for one factor whose exponent tends to a constant c other than 0, is the
// product read as (other * u^c) * u^(v - c), where u^(v - c) has a finite limit other than 0. That
// holds for the principal power, e^(v ln u) being e^(c ln u) e^((v - c) ln u). The exponent of
// (tan(x) + 1)^(x^(x - 1)) at 0 from the right is (tan(x) + 1 - 1) * x^(x - 1), and l'Hopital's rule
// differentiated x^(x - 1) for longer than any caller waits, where tan(x) / x tends to 1 and x^x to 1.
if (side is not ApproachFrom.BothSides && !IsComparingSides
&& multiplierLimit is { } zeroOrInfinity7 && multiplicandLimit is { } zeroOrInfinity8
&& IsZeroTimesAnInfinity(zeroOrInfinity7, zeroOrInfinity8)
&& (ByTheExponentsLimit(Multiplicand, Multiplier, x, dist, side) ?? ByTheExponentsLimit(Multiplier, Multiplicand, x, dist, side))
is { } byTheExponentsLimit)
return byTheExponentsLimit;
var (mp, md) =
(multiplierLimit, multiplicandLimit) switch
{
Expand Down Expand Up @@ -266,6 +277,21 @@ private static bool IsAnIndeterminateQuotient(Entity dividend, Entity divisor)
_ => false,
};

/// <summary>
/// The limit of <c>power * other</c> read as <c>(other * u^c) * u^(v - c)</c>, for a power <c>u^v</c> whose exponent
/// tends to a constant <c>c</c> other than 0 and where <c>u^(v - c)</c> tends to a finite real other than 0.
/// </summary>
private static Entity? ByTheExponentsLimit(Entity power, Entity other, Variable x, Entity dist, ApproachFrom side)
{
if (power is not Powf(var @base, var exponent) || !exponent.ContainsNode(x)
|| exponent.ComputeLimitDivideEtImpera(x, dist, side)?.Evaled is not Real { IsFinite: true, IsZero: false, IsNaN: false } constant
|| MathS.Pow(@base, (exponent - constant).InnerSimplified).ComputeLimitDivideEtImpera(x, dist, side)?.Evaled
is not Real { IsFinite: true, IsZero: false, IsNaN: false } rest
|| AsTheWholeLimit(other * MathS.Pow(@base, constant), x, dist, side)?.Evaled is not Number { IsNaN: false } head)
return null;
return (head * rest).Evaled;
}

/// <summary>Whether two factors' limits make a product 0 * oo.</summary>
private static bool IsZeroTimesAnInfinity(Entity first, Entity second)
=> (first.Evaled, second.Evaled) switch
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// 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 AngouriMath.Extensions;
using Xunit;

namespace AngouriMath.Tests.Calculus
{
/// <summary>
/// A product tending to 0 * oo with a power u^v for a factor, v tending to a constant c other than 0, is read as
/// (other * u^c) * u^(v - c). (tan(x) + 1)^(x^(x - 1)) at 0 from the right has the exponent tan(x) * x^(x - 1), which is
/// tan(x) / x times x^x, and l'Hopital's rule differentiated x^(x - 1) for longer than any caller waits.
/// Found by limitcheck; no issue was filed.
/// </summary>
[Trait("Area", "Calculus")]
public sealed class APowerIsSplitAtItsExponentsLimitTest
{
[Theory]
[InlineData("(tan(x) + 1)^(x^(x - 1))", "e")]
[InlineData("tan(x) * x^(x - 1)", "1")]
[InlineData("sin(x) * x^(x - 1)", "1")]
[InlineData("x^2 * x^(x - 3)", "+oo")]
[InlineData("ln(x) * x^(x + 1)", "0")]
public void TheLimitFromTheRightIsAnswered(string input, string expected)
{
var limit = Task.Run(() => input.ToEntity().Limit("x", 0, ApproachFrom.Right));
Assert.True(limit.Wait(TimeSpan.FromSeconds(30)), $"the limit of {input} did not finish");
Assert.Equal(expected.ToEntity().Evaled, limit.Result.Evaled);
}
}
}
Loading