Greetings. For the last 7 months I have been working on the biggest AngouriMath update . And there is something to tell about.
What is happening in a nutshell
In November 2019, I realized that this world, more precisely the world of the dotnet, lacks a symbolic algebra library for simplifying expressions, solving equations, for deriving latex, and so on. So I decided to create one.
But there is ...
Hearing what I am doing, different people come up with different solutions. Rewrite SymPy, make a wrapper over SageMath for dotnet, spiral Wolfram | Alpha, use primitive mathnet.symbolics (they themselves speak of primitiveness).
But all this has either limitations or difficulties. The same I am working on is a very lightweight library written and optimized for .NET. Open source, of course. (under MIT)
Update 1.2
In August, one of the main contributors @ HappyPig375 helped to rewrite a significant part of the library to the normal type hierarchy. Now there is a separate type for each operator or function. It was a tipping point, before which the library was slow, clumsy, and completely non-obvious. Now let's go over what has been done since then.
An expression is a record
For example, this is how the declaration of the sum operator looks like
public sealed partial record Sumf(Entity Augend, Entity Addend) : NumericNode
Thanks to this, we can easily apply the new pattern matching:
internal static Entity CommonRules(Entity x) => x switch
{
// (a * f(x)) * g(x) = a * (f(x) * g(x))
Mulf(Mulf(Number const1, Function func1), Function func2) => func1 * func2 * const1,
// (a/b) * (c/d) = (a*c)/(b*d)
Mulf(Divf(var any1, var any2), Divf(var any3, var any4)) => any1 * any3 / (any2 * any4),
// a / (b / c) = a * c / b
Divf(var any1, Divf(var any2, var any3)) => any1 * any3 / any2,
(this is an example of patterns that work when simplifying an expression)
Maths
, .
, , , .
12 , (sinh(x)
(e.Pow(x) - e.Pow(-x)) / 2
).
Abs Signum. abs : (|x|)
. , , ( | , ).
Phi ( ).
WriteLine(@"phi(8)".EvalNumerical());
WriteLine(@"(|-3 + 4i|)".EvalNumerical());
WriteLine(@"sinh(3)".Simplify());
WriteLine(@"sec(0.5)".Simplify());
4
5
(e ^ 3 - 1 / e ^ 3) / 2
sec(1/2)
. , NaN, . - SpecialSet, .
- . - , - , . : not
, or
, xor
, and
, implies
.
, Boolean
, EvaluableBoolean
. , EvaluableNumerical
, Number
.
WriteLine(@"(true or b) implies c".Simplify());
( c
)
Boolean
, . : =
, <
, >
, <=
, >=
.
. , a > b > c
, (a > b > c
, a > b and b > c
).
WriteLine(@"a < b >= c".Simplify());
( a < b and b >= c
)
. .
- FiniteSet, , . . : { 1, 2, 3 }
.
/ : [1; 2]
, (1; 2)
, [1; 2)
, (1; 2]
. .
SpecialSet
"" . CC
, RR
, QQ
, ZZ
, BB
, , , , .
ConditionalSet
set-builder notation, : { x : x > 0 and x^2 = y }
( x
, y
).
WriteLine(@"({ 1, 2 } \/ { 5 }) /\ { x : x in [2; 3] and x > 0 } ".Simplify());
( { 2 }
)
, . .
WriteLine("tan(a x) / (b x)".Limit("x", 0));
WriteLine("(sin(t) - t) / t3".Limit("t", 0));
( a / b
-1/6
)
"Provided"
, . , sqrt(x) provided x >= 0
. x, NaN.
, NaN, . , NaN NaN.
-
Piecewise
- Provided
. -, , Piecewise
, Provided
, .
, Piecewise
:
Entity abs = "piecewise(x provided x > 0, -x provided x <= 0)";
WriteLine(abs.Substitute("x", 3).EvalNumerical());
WriteLine(abs.Substitute("x", -3).EvalNumerical());
( 3 )
, / .
, , AngouriMathBaseException
. p/invoke
- - , , , AngouriMathBaseException
, . , , catch- ( ).
F#
API AngouriMath F#. , , F# . - , .
Interactive
, AngouriMath Jupyter. AngouriMath.Interactive ILatexiseable
LaTeX- MathJax ( ).
. , ? , . ([ThreadStatic]
), .
- , Solve
Simplify
, .
, . , , . ,
using var _ = MaxExpansionTermCount.Set(10);
// -
(, Set
, IDisposable
).
. , . , . , .
- , ( ).
Links
Github of the project.
Project site .
More detailed What's new .
Plans for the next updates.
My profile is on GitHub.
SymPy - inspire and give ideas.