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
6 changes: 4 additions & 2 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,9 @@ one where both sides are real, and `NaN` where either is not
- A constant is taken over `Complex` where the expression is compiled over it. As a `long`, a constant widened only
to `double`, so `sqrt(-1)`, `ln(-1)` and `arcsin(2)` were `NaN` and `1/0` was `+oo`
([#2235](https://github.com/asc-community/AngouriMath/issues/2235)).
- An Iverson bracket, an `int?`, and a `provided` integer, a `long?`, are widened to `double` before a function takes
them. They threw `KeyNotFoundException` or `AngouriBugException`
- A `provided` integer, a `long?`, and an Iverson bracket, an `int?`, are widened to `double` before a function or a
`piecewise` takes them. A `provided` integer threw `KeyNotFoundException` or `AngouriBugException` there, and an
Iverson bracket did not compile at all in 2.6.0
([#2237](https://github.com/asc-community/AngouriMath/issues/2237)).
- `sgn(0)` is `0`, where `z / |z|` made it `NaN` ([#2238](https://github.com/asc-community/AngouriMath/issues/2238)).

Expand All @@ -447,6 +448,7 @@ one where both sides are real, and `NaN` where either is not
| `"x + sqrt(-1)".ToEntity().Compile<Complex, Complex>("x")(0)` | `(NaN, 0)` | `(6.123233995736766E-17, 1)` |
| `"x + 1/0".ToEntity().Compile<Complex, Complex>("x")(0)` | `(Infinity, 0)` | `(NaN, NaN)` |
| `"x + sgn(-1 provided pi > 3)".ToEntity().Compile<Complex, Complex>("x")(1)` | throws `AngouriBugException` | `(0, 0)` |
| `"piecewise(piecewise(-1 provided x > 0, 3) provided x > 0, x) + x".ToEntity().Compile<double, double>("x")(1)` | throws `KeyNotFoundException` | `0` |
| `"sgn(x)".ToEntity().Compile<Complex, Complex>("x")(0)` | `(NaN, NaN)` | `(0, 0)` |

### A compiled product of real numbers is real at an infinity
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Common/LinqCompilationValueTest.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/Common/PiecewiseOfNullableCompilationTest.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/Common/CompileMatrixTest.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
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ private Expression HandlePiecewise(IEnumerable<Expression> en)
children[i] = ConvertType(children[i], typeof(bool?));
statements++;
}
// A case that is an Iverson bracket or a provided integer is widened to a double, as a function's
// operand is: MaxType has no int? or long?. https://github.com/asc-community/AngouriMath/issues/2237
else
children[i] = NumericOperand(children[i]);
if (statements > 0 && statements * 2 != children.Length)
throw new UncompilableNodeException("A piecewise whose cases are statements and numbers at once has no compiled form");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// 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.Common
{
/// <summary>
/// A piecewise whose case is an Iverson bracket or a provided integer compiles in the LINQ compiler, where it threw
/// <c>KeyNotFoundException</c>: its case types, an <c>int?</c> and a <c>long?</c>, were not in the widening table.
/// <a href="https://github.com/asc-community/AngouriMath/issues/2237">#2237</a>
/// </summary>
[Trait("Area", "Common")]
public sealed class PiecewiseOfNullableCompilationTest
{
[Theory]
[InlineData("sin(piecewise(iverson(x > 0) provided x > 0, sin(2)))", 2)]
[InlineData("sin(piecewise(iverson(x > 0) provided x > 0, sin(2)))", -2)]
[InlineData("exp(piecewise(2^x provided x > 0, iverson(x > 0)))", -1)]
[InlineData("abs(piecewise((-1)^2 provided x > 0, iverson(-1 > 0)))", 1)]
[InlineData("piecewise(iverson(sinh(3) > 0) provided x > 0, tan(-1))", 1)]
[InlineData("piecewise(piecewise(-1 provided x > 0, 3) provided x > 0, x) + x", 1)]
[InlineData("piecewise(piecewise(-1 provided x > 0, 3) provided x > 0, x) + x", -1)]
public void ItIsWhatEvaluationGives(string expression, double at)
{
var expected = ((Entity.Number.Complex)expression.ToEntity().Substitute("x", at).Evaled).ToNumerics();
var linq = expression.ToEntity().Compile<Complex, Complex>("x")(at);
var real = expression.ToEntity().Compile<double, double>("x")(at);
Assert.True(Complex.Abs(expected - linq) < 1e-12, $"{expression} at {at}: {expected} evaluated, {linq} by LINQ");
Assert.True(System.Math.Abs(expected.Real - real) < 1e-12, $"{expression} at {at}: {expected} evaluated, {real} over double");
}
}
}
Loading