Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullables #147

Merged
merged 4 commits into from
Jul 15, 2020
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
16 changes: 16 additions & 0 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Build

on: [push, pull_request]
jobs:
Build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.201'
- name: Build
run: dotnet build
8 changes: 2 additions & 6 deletions .github/workflows/Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Test

on: [push, pull_request]
jobs:
Unit_test:
UnitTests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -15,12 +15,8 @@ jobs:
uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.201'
- name: Setup JDK # Needed to run ANTLR
uses: actions/setup-java@v1
with:
java-version: '8'
- name: Test
run: |
dotnet add "Tests/UnitTests" package Microsoft.NET.Test.Sdk # Update is required for GitHubActionsTestLogger to print anything
dotnet add "Tests/UnitTests" package GitHubActionsTestLogger
dotnet test "Tests/UnitTests" -c Release -l GitHubActions
dotnet test "Tests/UnitTests" -c Release -l GitHubActions
9 changes: 3 additions & 6 deletions AngouriMath.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotnetBenchmark", "Tests\Do
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AngouriMathPlot", "AngouriMathPlot\AngouriMathPlot.csproj", "{B7D28355-A342-4E6E-AD45-3D47F4A054A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "testprj", "fieldtest\testprj\testprj.csproj", "{82DC716A-2FC7-49DC-9C62-CCE4CB29885E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9C4C2000-D0E3-45FE-A9D3-1B489ACA4594}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.github\workflows\Build.yml = .github\workflows\Build.yml
Directory.Build.props = Directory.Build.props
.github\workflows\Test.yml = .github\workflows\Test.yml
EndProjectSection
EndProject
Global
Expand Down Expand Up @@ -62,10 +63,6 @@ Global
{B7D28355-A342-4E6E-AD45-3D47F4A054A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7D28355-A342-4E6E-AD45-3D47F4A054A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7D28355-A342-4E6E-AD45-3D47F4A054A5}.Release|Any CPU.Build.0 = Release|Any CPU
{82DC716A-2FC7-49DC-9C62-CCE4CB29885E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82DC716A-2FC7-49DC-9C62-CCE4CB29885E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82DC716A-2FC7-49DC-9C62-CCE4CB29885E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82DC716A-2FC7-49DC-9C62-CCE4CB29885E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 1 addition & 0 deletions AngouriMath/AngouriMath.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
</None>
<PackageReference Include="Antlr4.Runtime.Standard" Version="4.8.0" />
<PackageReference Include="PeterO.Numbers" Version="1.6.0" />
<PackageReference Include="Nullable" Version="1.2.1" />
<EmbeddedResource Include="Core/FromString/Antlr/Angourimath.tokens" />
</ItemGroup>
</Project>
84 changes: 38 additions & 46 deletions AngouriMath/Convenience/MathS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static Set SolveInequalityNumerically(Entity inequality, VariableEntity v
/// a ^ 0.5
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Entity Sqrt(Entity a) => Powf.Hang(a, Number.CreateRational(1, 2));
public static Entity Sqrt(Entity a) => Powf.Hang(a, RationalNumber.Create(1, 2));

/// <summary>
/// Special case of power function
Expand Down Expand Up @@ -281,7 +281,7 @@ public static Set SolveInequalityNumerically(Entity inequality, VariableEntity v
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Obsolete("Use Number.Create or implicit construction instead")]
public static Number Num(EDecimal a, EDecimal b) => Number.Create(a, b);
public static Number Num(EDecimal a, EDecimal b) => ComplexNumber.Create(a, b);

/// <summary>
/// Creates a real instance of Number (not NumberEntity!)
Expand All @@ -290,13 +290,13 @@ public static Set SolveInequalityNumerically(Entity inequality, VariableEntity v
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Obsolete("Use Number.Create or implicit construction instead")]
public static ComplexNumber Num(EDecimal a) => Number.Create(a);
public static ComplexNumber Num(EDecimal a) => RealNumber.Create(a);

/// <summary>
/// List of public constants
/// </summary>
public static readonly VariableEntity e = "e";
public static readonly ComplexNumber i = Number.Create(0, 1.0);
public static readonly ComplexNumber i = ComplexNumber.ImaginaryOne;
public static readonly VariableEntity pi = "pi";

/// <summary>
Expand All @@ -318,7 +318,7 @@ public static Entity FromString(string expr)
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string ToBaseN(RealNumber num, int N)
=> NumberSystem.ToBaseN(num, N);
=> NumberSystem.ToBaseN(num.Value, N);

/// <summary>
/// Translates num into 10 number system
Expand All @@ -343,15 +343,26 @@ public static string Latex(ILatexiseable latexiseable)
/// </summary>
public static class Numbers
{
/*
*
* This list represents the only possible way to explicitly create numeric instances
* It will automatically downcast the result for you, so that 1.0 is an IntegerNumber
* To avoid it, you may temporarily disable it
*
* MathS.Settings.DowncastingEnabled.Set(false);
* var yourNum = Number.Create(1.0);
* MathS.Settings.DowncastingEnabled.Unset();
*
*/
/// <summary>
/// Creates an instance of ComplexNumber from System.Numerics.Complex
/// </summary>
/// <param name="value"></param>
/// <returns>
/// ComplexNumber
/// </returns>
public static ComplexNumber Create(Complex value)
=> Number.Functional.Downcast(new ComplexNumber(value)) as ComplexNumber;
public static ComplexNumber Create(Complex value) =>
Create(EDecimal.FromDouble(value.Real), EDecimal.FromDouble(value.Imaginary));

/// <summary>
/// Creates an instance of IntegerNumber from long
Expand All @@ -360,8 +371,7 @@ public static ComplexNumber Create(Complex value)
/// <returns>
/// IntegerNumber
/// </returns>
public static IntegerNumber Create(long value)
=> Number.Functional.Downcast(new IntegerNumber((EInteger)value)) as IntegerNumber;
public static IntegerNumber Create(long value) => IntegerNumber.Create(value);

/// <summary>
/// Creates an instance of IntegerNumber from System.Numerics.EInteger
Expand All @@ -370,8 +380,7 @@ public static IntegerNumber Create(long value)
/// <returns>
/// IntegerNumber
/// </returns>
public static IntegerNumber Create(EInteger value)
=> Number.Functional.Downcast(new IntegerNumber(value)) as IntegerNumber;
public static IntegerNumber Create(EInteger value) => IntegerNumber.Create(value);

/// <summary>
/// Creates an instance of IntegerNumber from int
Expand All @@ -380,19 +389,23 @@ public static IntegerNumber Create(EInteger value)
/// <returns>
/// IntegerNumber
/// </returns>
public static IntegerNumber Create(int value)
=> Number.Functional.Downcast(new IntegerNumber((EInteger)value)) as IntegerNumber;
public static IntegerNumber Create(int value) => IntegerNumber.Create(value);

/// <summary>
/// Creates an instance of RationalNumber of two IntegerNumbers
/// </summary>
/// <param name="numerator"></param>
/// <param name="denominator"></param>
/// <returns>
/// RationalNumber
/// </returns>
public static RationalNumber CreateRational(IntegerNumber numerator, IntegerNumber denominator)
=> Number.Functional.Downcast(new RationalNumber(numerator, denominator)) as RationalNumber;
public static RationalNumber CreateRational(EInteger numerator, EInteger denominator)
=> RationalNumber.Create(numerator, denominator);
/// <summary>
/// Creates an instance of RationalNumber of two IntegerNumbers
/// </summary>
/// <returns>
/// RationalNumber
/// </returns>
public static RationalNumber Create(ERational rational) => RationalNumber.Create(rational);

/// <summary>
/// Creates an instance of RealNumber from EDecimal
Expand All @@ -401,8 +414,7 @@ public static RationalNumber CreateRational(IntegerNumber numerator, IntegerNumb
/// <returns>
/// RealNumber
/// </returns>
public static RealNumber Create(EDecimal value)
=> Number.Functional.Downcast(new RealNumber(value)) as RealNumber;
public static RealNumber Create(EDecimal value) => RealNumber.Create(value);

/// <summary>
/// Creates an instance of RealNumber from double
Expand All @@ -411,8 +423,7 @@ public static RealNumber Create(EDecimal value)
/// <returns>
/// RealNumber
/// </returns>
public static RealNumber Create(double value)
=> Number.Functional.Downcast(new RealNumber(value)) as RealNumber;
public static RealNumber Create(double value) => RealNumber.Create(EDecimal.FromDouble(value));

/// <summary>
/// Creates an instance of ComplexNumber from two RealNumbers
Expand All @@ -426,28 +437,7 @@ public static RealNumber Create(double value)
/// <returns>
/// ComplexNumber
/// </returns>
public static ComplexNumber Create(RealNumber re, RealNumber im)
=> Number.Functional.Downcast(new ComplexNumber(re, im)) as ComplexNumber;

/// <summary>
/// If you need an indefinite value of a real number, use this
/// Number.Create(RealNumber.UndefinedState.POSITIVE_INFINITY)
/// Number.Create(RealNumber.UndefinedState.NEGATIVE_INFINITY)
/// Number.Create(RealNumber.UndefinedState.NAN)
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
public static RealNumber Create(RealNumber.UndefinedState state)
=> new RealNumber(state);

/// <summary>
/// If you need an indefinite value of a complex number, e. g.
/// Number.Create(RealNumber.UndefinedState.POSITIVE_INFINITY, RealNumber.UndefinedState.NEGATIVE_INFINITY)
/// -> +oo + -ooi
/// </summary>
/// <returns></returns>
public static ComplexNumber Create(RealNumber.UndefinedState realState, RealNumber.UndefinedState imaginaryState)
=> Number.Create(Number.Create(realState), Number.Create(imaginaryState));
public static ComplexNumber Create(EDecimal re, EDecimal im) => ComplexNumber.Create(re, im);
}

/// <summary>
Expand Down Expand Up @@ -524,7 +514,7 @@ public static class Settings
/// <summary>
/// If a numerator or denominator is too large, it's suspended to better keep the real number instead of casting
/// </summary>
public static Setting<long> MaxAbsNumeratorOrDenominatorValue { get; } = 100000000;
public static Setting<EInteger> MaxAbsNumeratorOrDenominatorValue { get; } = (EInteger)100000000;

/// <summary>
/// Sets threshold for comparison
Expand All @@ -536,7 +526,7 @@ public static class Settings
/// <summary>
/// Numbers whose absolute value is less than PrecisionErrorZeroRange are considered zeros
/// </summary>
public static Setting<EDecimal> PrecisionErrorZeroRange { get; } = EDecimal.FromDecimal(1.0e-16m);
public static Setting<EDecimal> PrecisionErrorZeroRange { get; } = EDecimal.FromDecimal(1e-16m);

/// <summary>
/// If you only need analytical solutions and an empty set if no analytical solutions were found, disable Newton's method
Expand Down Expand Up @@ -601,7 +591,9 @@ public static class Utils
/// true if success
/// false otherwise (do not access dst in this case, it's undefined)
/// </returns>
public static bool TryPolynomial(Entity expr, VariableEntity variable, out Entity dst)
public static bool TryPolynomial(Entity expr, VariableEntity variable,
[System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
out Entity? dst)
=> Functions.Utils.TryPolynomial(expr, variable, out dst);


Expand Down
64 changes: 18 additions & 46 deletions AngouriMath/Convenience/SynonymFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,54 +68,26 @@ namespace AngouriMath.Extensions
public static class AMExtensions
{
public static ComplexNumber ToComplexNumber(this Complex complex)
=> Number.Create(complex);

public static Entity ToEntity(this String expr)
=> MathS.FromString(expr);

public static Entity Simplify(this String expr)
=> expr.ToEntity().Simplify();

public static ComplexNumber Eval(this String expr)
=> expr.ToEntity().Eval();

public static Entity Expand(this String expr)
=> expr.ToEntity().Expand();

public static Entity Collapse(this String expr)
=> expr.ToEntity().Collapse();

public static Entity Substitute(this String expr, VariableEntity var, Entity value)
=> ComplexNumber.Create(EDecimal.FromDouble(complex.Real), EDecimal.FromDouble(complex.Imaginary));

public static Entity ToEntity(this string expr) => MathS.FromString(expr);
public static Entity Simplify(this string expr) => expr.ToEntity().Simplify();
public static ComplexNumber Eval(this string expr) => expr.ToEntity().Eval();
public static Entity Expand(this string expr) => expr.ToEntity().Expand();
public static Entity Collapse(this string expr) => expr.ToEntity().Collapse();
public static Entity Substitute(this string expr, VariableEntity var, Entity value)
=> expr.ToEntity().Substitute(var, value);

public static Set SolveEquation(this String expr, VariableEntity x)
public static Set SolveEquation(this string expr, VariableEntity x)
=> expr.ToEntity().SolveEquation(x);

public static RealNumber ToNumber(this EDecimal value)
=> Number.Create(value);

public static RealNumber ToNumber(this decimal value)
=> Number.Create(value);

public static RealNumber ToNumber(this double value)
=> Number.Create(value);

public static RealNumber ToNumber(this float value)
=> Number.Create(value);

public static IntegerNumber ToNumber(this EInteger value)
=> Number.Create(value);

public static IntegerNumber ToNumber(this int value)
=> Number.Create(value);

public static IntegerNumber ToNumber(this long value)
=> Number.Create(value);

public static string Latexise(this String str)
=> str.ToEntity().Latexise();

public static FastExpression Compile(this String str, params VariableEntity[] variables)
public static RealNumber ToNumber(this EDecimal value) => RealNumber.Create(value);
public static RealNumber ToNumber(this decimal value) => RealNumber.Create(EDecimal.FromDecimal(value));
public static RealNumber ToNumber(this double value) => RealNumber.Create(EDecimal.FromDouble(value));
public static RealNumber ToNumber(this float value) => RealNumber.Create(EDecimal.FromSingle(value));
public static IntegerNumber ToNumber(this EInteger value) => IntegerNumber.Create(value);
public static IntegerNumber ToNumber(this int value) => IntegerNumber.Create(value);
public static IntegerNumber ToNumber(this long value) => IntegerNumber.Create(value);
public static string Latexise(this string str) => str.ToEntity().Latexise();
public static FastExpression Compile(this string str, params VariableEntity[] variables)
=> str.ToEntity().Compile(variables);

// C# can't into templates :(
Expand Down
12 changes: 5 additions & 7 deletions AngouriMath/Core/Sys/Const.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,22 +198,20 @@ internal static Entity EvalIfCan(Entity a)
res += expr.Complexity();

// Number of variables
res += TreeAnalyzer.Count(expr, entity => entity.entType == Entity.EntType.VARIABLE);
res += TreeAnalyzer.Count(expr, entity => entity is VariableEntity);

// Number of variables
res += TreeAnalyzer.Count(expr, entity => entity.entType == Entity.EntType.OPERATOR && entity.Name == "divf") / 2;
res += TreeAnalyzer.Count(expr, entity => entity is OperatorEntity && entity.Name == "divf") / 2;

// Number of negative powers
res += TreeAnalyzer.Count(expr, (entity) =>
{
if (!(entity.entType == Entity.EntType.OPERATOR &&
if (!(entity is OperatorEntity &&
entity.Name == "powf" &&
entity.Children[1].entType == Entity.EntType.NUMBER))
entity.Children[1] is NumberEntity numEntity))
return false;
var numEntity = entity.Children[1] as NumberEntity;
if (numEntity.Value.IsImaginary())
if (!(numEntity.Value is RealNumber realNumber))
return false;
var realNumber = numEntity.Value as RealNumber;
return realNumber < 0;
});
return res;
Expand Down
Loading