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
13 changes: 13 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ Found by limitcheck; no issue was filed.
| `"floor(tanh(1 / x))".ToEntity().Limit("x", 0, ApproachFrom.Right)` | unevaluated | `0` |
| `"floor(tanh(1 / x))".ToEntity().Limit("x", 0)` | unevaluated | `NaN`: the left side is `-1` |

### A two-sided limit through a real function of a real argument is the sides' common value

**Silent: a tangent, an arccotangent, an error function and a step function of a real argument are read as real when
the two sides of a two-sided limit are compared**, as a sine, a cosine and an arctangent already were. Their sides were
not compared at all, and where the descent read a side as `0 * oo`, the limit was `NaN`, which says it does not exist.
Since 2.6.0, master answered `NaN` for these. Found by limitcheck; no issue was filed.

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"(pi^2 + (1/2) / x) * erf(x)".ToEntity().Limit("x", 0)` | `limit((pi * pi + 1/2 / x) * erf(x), x, 0)` | `1 / sqrt(pi)` |
| `"(1 + 1/x) * erf(x)".ToEntity().Limit("x", 0)` | `limit((1 + 1 / x) * erf(x), x, 0)` | `2 * 1 / sqrt(pi)` |
| `"(abs(x)^(x/pi))^sgn(x)".ToEntity().Limit("x", 0)` | `limit((abs(x) ^ (x / pi)) ^ sgn(x), x, 0)` | `1` |

### A logarithm of a part tending to 1 is read as the part less 1 in a limit

**Silent: a factor `ln(u)` whose antilogarithm tends to 1 is read as `u - 1`, as `sin(f)` is read as `f` where `f`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,17 @@ bool RealThere(Entity node)
Arctanf(var argument) => RealThere(argument),
Arcsinf(var argument) => RealThere(argument) && StrictlyInsideTheUnitInterval(argument),
Arccosf(var argument) => RealThere(argument) && StrictlyInsideTheUnitInterval(argument),
// So are a tangent and an arccotangent, the error functions, and the step functions, of a real
// argument. (pi^2 + 1/(2x)) erf(x) at 0 was NaN, where each side is 1/sqrt(pi).
Tanf(var argument) => RealThere(argument),
Arccotanf(var argument) => RealThere(argument),
Erff(var argument) => RealThere(argument),
Erfcf(var argument) => RealThere(argument),
Erfif(var argument) => RealThere(argument),
Floorf(var argument) => RealThere(argument),
Ceilf(var argument) => RealThere(argument),
Roundf(var argument) => RealThere(argument),
Signumf(var argument) => RealThere(argument),
_ => false
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// 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.Extensions;
using Xunit;

namespace AngouriMath.Tests.Calculus
{
/// <summary>
/// A two-sided limit compares its sides only where the expression is known to be real on both, and an error function
/// or a step function of a real argument was not known to be. (pi^2 + 1/(2x)) erf(x) at 0 was NaN, which says there
/// is no limit, where each side is 1/sqrt(pi). Found by limitcheck; no issue was filed.
/// </summary>
[Trait("Area", "Calculus")]
public sealed class ARealFunctionAgreesOnBothSidesTest
{
[Theory]
[InlineData("(pi^2 + (1/2) / x) * erf(x)", "1 / sqrt(pi)")]
[InlineData("(1 + 1/x) * erf(x)", "2 / sqrt(pi)")]
[InlineData("(abs(x)^(x/pi))^sgn(x)", "1")]
public void TheSidesAgree(string input, string expected)
{
var limit = input.ToEntity().Limit("x", 0);
Assert.False(limit.ContainsNode("x"), $"the limit of {input} was not taken: {limit}");
var difference = (limit - expected.ToEntity()).EvalNumerical();
Assert.True(difference is Entity.Number.Real { IsFinite: true } real && real.Abs() < 1e-20, $"the limit of {input} is {limit}, not {expected}");
}

// Where the sides differ there is still no limit.
[Theory]
[InlineData("floor(x)")]
[InlineData("sgn(x)")]
[InlineData("erfc(x) / x")]
public void TheSidesStillDiffer(string input)
=> Assert.Equal(MathS.NaN, input.ToEntity().Limit("x", 0));
}
}
Loading