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 @@ -139,6 +139,19 @@ and a number that passes every round is left open, since passing is not a proof
| `"(10^30 + 1) in PP".ToEntity().Evaled` | `1000000000000000000000000000001 in PP` | `False` |
| `"(10^30 + 57) in PP".ToEntity().Evaled` | `1000000000000000000000000000057 in PP` | `1000000000000000000000000000057 in PP` |

### `arcsin` and `arccos` of a real number past 1 have their value

**Silent: `arcsin(x)` and `arccos(x)` of a real `x` past 1 are `sign(x) pi/2 - i arccosh|x|` and `pi/2 - arcsin(x)`,
where for about one argument in ten they were `NaN`.** The two share `(|w + 1| - |w - 1|) / 2`, which is in `[-1, 1]` by
the triangle inequality and exactly 1 for such an `x`. Rounded, it came out a little past 1 for some `x`, and the decimal
arcsine of that is `NaN`. Of `arcsin(k + c)` for `k` from 1 to 40 and `c` in `pi`, `e`, `sqrt(2)`, `sqrt(3)` and `ln(3)`,
20 were `NaN` ([#2244](https://github.com/asc-community/AngouriMath/issues/2244)).

| Input | Was (2.6.0) | Now |
|---|---|---|
| `"arcsin(6 + pi)".ToEntity().Evaled` | `NaN` | `1.5707963267948966 - 2.902976737696685i`, to 15 digits |
| `"arccos(6 + pi)".ToEntity().Evaled` | `NaN` | `2.902976737696685i`, to 15 digits |

### A system with a product equation is solved branch by branch

**Silent: solutions that were missing are answered.** `EquationSystem.Solve` eliminated `x * y = 0` for `y` as `0`,
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Convenience/SignumOfNaNTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Convenience/ArcsineOfARealPastOneTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[AngouriMath/Functions/Compilation/RealProducts.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

Expand Down
10 changes: 9 additions & 1 deletion Sources/AngouriMath/Core/Entity/Continuous/Number/Operators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,15 @@ public static Complex Cotan(Complex num)
var rho = xp1.MultiplyAndAdd(xp1, y.Multiply(y, context), context).SqrtByIntegerRoot(context);
var sigma = xm1.MultiplyAndAdd(xm1, y.Multiply(y, context), context).SqrtByIntegerRoot(context);
var alpha = rho.Add(sigma, context).Divide(2, context);
return (rho.Subtract(sigma, context).Divide(2, context),
// beta is (|w + 1| - |w - 1|) / 2, in [-1, 1] by the triangle inequality and exactly 1 for a real w past
// 1; the two roots are rounded, and a beta of 1 + ε made arcsin(beta) NaN, as arcsin(6 + pi) was.
// https://github.com/asc-community/AngouriMath/issues/2244
var beta = rho.Subtract(sigma, context).Divide(2, context);
if (beta.GreaterThan(EDecimal.One))
beta = EDecimal.One;
else if (beta.LessThan(-EDecimal.One))
beta = -EDecimal.One;
return (beta,
alpha.MultiplyAndSubtract(alpha, EDecimal.One, context).SqrtByIntegerRoot(context).Add(alpha, context).NaturalLogarithm(context).Multiply((y.IsNegative || y.IsZero) ? -1 : 1, context));
}

Expand Down
52 changes: 52 additions & 0 deletions Sources/Tests/UnitTests/Convenience/ArcsineOfARealPastOneTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// 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.Numerics;
using AngouriMath;
using AngouriMath.Extensions;
using Xunit;

namespace AngouriMath.Tests.Convenience
{
/// <summary>
/// <c>arcsin</c> and <c>arccos</c> of a real number past 1 have their value, <c>sign(x) pi/2 - i arccosh|x|</c> and
/// <c>pi/2 - arcsin(x)</c>, where for one argument in ten they were NaN: the rounded <c>(|w + 1| - |w - 1|) / 2</c>
/// came out a little past 1, whose decimal arcsine is NaN. <c>arcsin(6 + pi)</c> was one.
/// <a href="https://github.com/asc-community/AngouriMath/issues/2244">#2244</a>
/// </summary>
[Trait("Area", "Convenience")]
public sealed class ArcsineOfARealPastOneTest
{
private static double Arccosh(double x) => System.Math.Log(x + System.Math.Sqrt(x * x - 1));

private static bool Agree(Complex expected, Complex actual) => Complex.Abs(expected - actual) <= 1e-12 * System.Math.Max(1, Complex.Abs(expected));

[Theory]
[InlineData("pi")]
[InlineData("e")]
[InlineData("sqrt(2)")]
[InlineData("sqrt(3)")]
[InlineData("ln(3)")]
public void BothHaveTheirValue(string constant)
{
for (var k = 1; k <= 40; k++)
foreach (var sign in new[] { "", "-" })
{
var argument = $"{sign}({k} + {constant})";
var x = ((Entity.Number.Complex)argument.ToEntity().Evaled).ToNumerics().Real;
if (System.Math.Abs(x) <= 1)
continue;
var arcsin = ((Entity.Number.Complex)$"arcsin({argument})".ToEntity().Evaled).ToNumerics();
var arccos = ((Entity.Number.Complex)$"arccos({argument})".ToEntity().Evaled).ToNumerics();
var expectedArcsin = new Complex(System.Math.Sign(x) * System.Math.PI / 2, -Arccosh(System.Math.Abs(x)));
var expectedArccos = new Complex(x > 0 ? 0 : System.Math.PI, Arccosh(System.Math.Abs(x)));
Assert.True(Agree(expectedArcsin, arcsin), $"arcsin({argument}): {arcsin}, where {expectedArcsin}");
Assert.True(Agree(expectedArccos, arccos), $"arccos({argument}): {arccos}, where {expectedArccos}");
}
}
}
}
Loading