← Back to the main page

Any expression in AngouriMath is a tree. It may include numbers, variables, operators, functions, vectors, and more. The main class, representing the library, is called Entity. It is an abstract record, so every expression is a derived type of Entity.

The very basics of creating an expression

Include the main namespace of the library: using AngouriMath; Now, let us create a simple arithmetic expression.

To build a tree we use overriden operators, for example,
var x = MathS.Var("x");
var y = MathS.Var("y");
var expr = x + 4 * MathS.Sin(x / y);
expr has the type of Entity.Sumf, which is a derived type of Entity.

Now, let us see a shorter way of doing the same thing:
using static AngouriMath.MathS;
using static AngouriMath.Entity;

Variable x = "x"; // implicit conversation Variable y = "y"; var expr = x + 4 * Sin(x / y);
The first two usings are implied by default in all other code snippets provided in Wiki.

AngouriMath internally uses PeterO.Numbers, so here are how numbers in AM could be created:
using static AngouriMath.Entity.Number;
using PeterO.Numbers;

var a01 = Integer.Create(3); var a02 = Integer.Create(EInteger.FromInt32(3)); var a03 = Rational.Create(3.4); var a04 = Rational.Create(ERational.FromDouble(3.4)); var a05 = Real.Create(1.3234m); var a06 = Real.Create(EDecimal.FromDouble(3.4535)); var a07 = Complex.Create(32.4m, 434); var a08 = Complex.Create(EDecimal.FromDecimal(32.4m), EDecimal.FromInt32(434));

Easy way to create an expression

Now, let us shorten the creation of an expression and parse it from an expression. Here are two lines of the equivalent code:
Entity a = "x^2 + x + 4 / 5 + sqrt(5)";
var a = FromString("x^2 + x + 4 / 5 + sqrt(5)");
In some cases we can omit operators, for example, here are equivalent lines:
Entity a = "x2 + 4y";
Entity a = "x^2 + 4*y";

Most operators and functions have a fixed number of arguments, for instance, plus operator cannot have three or more arguments. Here are two lines of the equivalent code:
Entity a = "x + 2";
Entity b = "y";
var theirSum1 = new Sumf(a, b);
var theirSum2 = a + b;

In most code snippets in the rest of the wiki we will use implicit conversations in most cases.

Variable substitution

To substitute a particular value instead of a variable, use method Substitute:
Entity expr = "x + 2";
var newExpr = expr.Substitute("x", 3);
It is the same as
Entity newExpr = "3 + 2";

It does not change the initial expression. Moreover, all subtypes of Entity are immutable and cannot be changed by any method or function. This allows to safely pass any expression to any functions being sure that it will not change. As a result, any operation will create a new expression.

Nodes and pattern matching

Nodes is a property of every expression. This property contains all possible subnodes of a node including itself. Let us consider an example:
Entity expr = "a * x + 2";
foreach (var subExpr in expr.Nodes)
The output will be the following:
a * x + 2
a * x

We can also analyze a given expression through patterns. Let us implement a naive differentiating:
static Entity Diff(Entity expr, Variable var)
    => expr switch
        Variable sameVar when sameVar == var => 1,
        Variable otherVar => 0,
        Number => 0,
        Sumf(var left, var right) => Diff(left, var) + Diff(right, var),
        Mulf(var left, var right) => Diff(left, var) * right + Diff(right, var) * left,
        Sinf(var arg) => Cos(arg) * Diff(arg, var),
        _ => throw new Exception()
Thanks to C#9's pattern matching, now we can this easily switch over different types of an expression. Let us run the given function:
Console.WriteLine(Diff("a x + 3sin(x + c)", "x"));
The output will be the following:
0 * x + 1 * a + 0 * sin(x + c) + cos(x + c) * (1 + 0) * 3
When building an expression, no automatic simplification occurs.

2019-2021 Angouri · Project's repo · Site's repo · Octicons