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 @@ -390,6 +390,19 @@ mentions answers it as a parameter, as a short system does, where it was `null`
| `MathS.Equations("x - 1", "x^2 - 1").Solve("x", "y")` | `null` | `[[1, t_1]]` |
| `MathS.Equations("a - 1", "b * 0").Solve("a", "b")` | `null` | `[[1, t_1]]` |

### A limit on an arctangent's cut is not read off the principal value

**Silent: a limit of `arctan` whose argument arrives on the arctangent's cut, the imaginary axis past `i` and `-i`, is
left unevaluated, where it was the principal value there.** That value is the limit from one side of the cut only, and
which side the argument comes from was not asked. `log(2, x)` comes to `i pi / ln(2)` from the left half-plane as x comes
up to -1, so `arctan(log(2, x))` tends to `-pi/2 + 0.224i` there, and the answer was `pi/2 + 0.224i`. A limit from the
side where the principal value is right is declined as well, as it is for the logarithm.

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"arctan(log(2, x))".ToEntity().Limit("x", -1, ApproachFrom.Right)` | `arctan(ln(-1) / ln(2))`, `pi/2 + 0.224i` | unevaluated |
| `"arctan(2i + x)".ToEntity().Limit("x", 0, ApproachFrom.Left)` | `arctan(2i)`, `pi/2 + 0.549i` | unevaluated |

### A limit on a logarithm's cut is not read off the principal value

**Silent: a limit of a logarithm, or of a power to an exponent that is not whole, whose argument arrives on the negative
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,13 @@ internal static bool TakesItsValueOnACut(Entity node, Variable x, Entity dest)
{
Logf(var @base, var antilogarithm) => OnTheCut(@base) || OnTheCut(antilogarithm),
Powf(var @base, var exponent) => exponent.Substitute(x, dest).Evaled is not Integer && OnTheCut(@base),
// The arctangent's cut is the imaginary axis past i and -i, which no argument real on
// the approach reaches, and its value there is the limit from one side only:
// arctan(log(2, x)) at -1+ has its argument arriving at i pi / ln(2) from the left
// half-plane, and tends to -pi/2 + 0.224i, where the value there is pi/2 + 0.224i.
Arctanf(var argument) => argument.ContainsNode(x)
&& argument.Substitute(x, dest).Evaled is Complex { RealPart.IsZero: true, ImaginaryPart: var imaginary }
&& imaginary.EDecimal.Abs().CompareTo(PeterO.Numbers.EDecimal.One) > 0,
_ => false
};
bool OnTheCut(Entity argument) => ArrivesOnTheCutOffTheRealLine(argument, argument.Substitute(x, dest), x, dest);
Expand Down
39 changes: 39 additions & 0 deletions Sources/Tests/UnitTests/Calculus/LimitOnAnArctangentsCutTest.cs
Original file line number Diff line number Diff line change
@@ -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.Linq;
using AngouriMath;
using AngouriMath.Core;
using AngouriMath.Extensions;
using Xunit;

namespace AngouriMath.Tests.Calculus
{
/// <summary>
/// The arctangent's cut is the imaginary axis past <c>i</c> and <c>-i</c>, and its principal value there is the limit
/// from one side only. <c>arctan(log(2, x))</c> at -1+ has its argument arriving at <c>i pi / ln(2)</c> from the left
/// half-plane and tends to <c>-pi/2 + 0.224i</c>, and it answered the principal value, <c>pi/2 + 0.224i</c>. Such a
/// limit is now left unevaluated. No issue was filed; found by work/limitcheck at seed 11.
/// </summary>
[Trait("Area", "Calculus")]
public sealed class LimitOnAnArctangentsCutTest
{
[Theory]
[InlineData("arctan(log(2, x))", "-1", ApproachFrom.Right)]
[InlineData("arctan(2i + x)", "0", ApproachFrom.Left)]
public void IsNotThePrincipalValue(string expression, string destination, ApproachFrom side)
{
var limit = expression.ToEntity().Limit("x", destination, side);
Assert.True(limit.Nodes.Any(node => node is Entity.Limitf), $"{expression} at {destination} from {side} was {limit}");
}

// Off the cut it is still read off.
[Fact]
public void OffTheCutIsTheValue()
=> Assert.Equal("arctan(1 + 2i)".ToEntity().Evaled, "arctan(x + 2i)".ToEntity().Limit("x", 1).Evaled);
}
}
Loading