# Math.NET Symbolics

Math.NET Symbolics is a basic open source computer algebra library for .Net and Mono written in F#.

This project does not aim to become a full computer algebra system. If you need such a system, have a look at Axiom or Maxima instead, or for commercial solutions Maple, Mathematica or Wolfram Alpha.

## NuGet Packages

The recommended way to get Math.NET Symbolics is to use NuGet. The following packages are provided and maintained in the public NuGet Gallery:

Core Package:

## Platform Support and Dependencies

• .Net 4.0 and Mono: Windows, Linux and Mac.

Package Dependencies:

• FParsec (isolated usage only for infix parsing)

## Math.NET Symbolics with F# and F# Interactive

With NuGet you can start quickly by installing the MathNet.Symbolics package, which automatically loads its dependencies MathNet.Numerics and MathNet.Numerics.FSharp. In F# interactive you can reference them by loading two scripts, along the lines of

 1: 2:  #load @"..\..\packages\MathNet.Numerics.FSharp.3.8.0\MathNet.Numerics.fsx" #load @"..\..\packages\MathNet.Symbolics.0.9.0\MathNet.Symbolics.fsx" 

To get started, open the namespaces and the Operators module and declare the variables and constants you intend to use as symbols:

  1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:  open System.Numerics open MathNet.Numerics open MathNet.Symbolics open Operators let x = symbol "x" let y = symbol "y" let z = symbol "z" let a = symbol "a" let b = symbol "b" let c = symbol "c" let d = symbol "d" let e = symbol "e" let f = symbol "f" 

Then we're all set to start writing expressions:

 1: 2: 3: 4:  a + a // returns 2*a a * a // returns a^2 2 + 1/x - 1 // returns 1 + 1/x (a/b/(c*a))*(c*d/a)/d // returns 1/(a*b) 

Math.NET Symbolics expressions are always in a simplified form according to a set of rules. Expressions are tree structures, but F# interactive shows them in a readable infix form thanks to a display printer added in the script loaded above. You can also use these printers manually to format any expression as infix string, LaTeX expression or in strict mode to see the actual internal representation:

 1: 2: 3:  Infix.format (1/(a*b)) // returns string "1/(a*b)" Infix.formatStrict (1/(a*b)) // returns string "a^(-1)*b^(-1)" LaTeX.format (1/(a*b)) // returns string "\frac{1}{ab}" 

Strings in infix notation can be parsed back into expressions:

 1: 2: 3: 4: 5:  Infix.parse "1/(a*b)" // Returns ParsedExpression 1/(a*b) Infix.parse "1/(a*b" // Returns ParseFailure, 7: Expecting infix operator or ')' Infix.tryParse "1/(a*b)" // Returns Some (1/(a*b)) Infix.parseOrUndefined "1/(a*b)" // Returns 1/(a*b) Infix.parseOrThrow "1/(a*b)" // Returns 1/(a*b) 

### Number Literals

Numbers can be forced to become expressions using the Q suffix, e.g. 3Q is an expression representing an integer with value 3. This is usually not needed if at least one of the operands is an expression, e.g. a symbol. But if all operands are standard .Net numbers, they will be treated as such. For example (3 + 2)*4/6 is a standard F# integer expression and will result in 3 due to .Net integer arithmetics. However, if we force it to become an expression by writing (3Q + 2)*4/6, it will result in the fraction expression 10/3 as expected.

Since Math.NET Symbolics is about algebra, all number literals are arbitrarily big rational numbers, i.e. integers or fractions. If you need floating point numbers, use a symbol for them instead and provide their value at evaluation time.

### Evaluating Expressions

Often you need to evaluate the resulting number value of an expression given the values for all its symbols. To do so, prepare the value set as map or dictionary and pass it to the evaluate function. Values need to be of type FloatingPoint which is a discriminated union that can represent not only float and complex but also vectors and matrices of the same.

 1: 2:  let symbols = Map.ofList [ "a", Real 2.0; "b", Real 3.0 ] Evaluate.evaluate symbols (1/(a*b)) // Returns Real 0.1666666667 (as float) 

### Manipulating Expressions

• Operators: standard operators, recommended to open always.
• Structure: structural analysis, operand access, substitution, map
• Algebraic: algebraic expansion, separate factors
• Polynomial: properties, degrees, coefficients, terms, divide, gcd, expansion, partial fraction
• Rational: numerator/denominator, properties, rationalize, expand, simplify
• Exponential: expand, contract, simplify
• Trigonometric: expand, separate, contract, substitute, simplify
• Calculus: differentiate

For example, let's try to contract the trigonometric expression $$(\cos{x})^4$$ into $$\frac{3}{8} + \frac{1}{2}\cos{2x} + \frac{1}{8}\cos{4x}$$:

 1:  Trigonometric.contract (cos(x)**4) // Returns 3/8 + (1/2)*cos(2*x) + (1/8)*cos(4*x) 

### Algebraic Algorithms

These modules can also be combined to build more interesting manipulations. For example, let's implement a taylor expansion routine to approximate the shape of a differentiable function $$x(\zeta)$$ at some point $$\zeta = a$$ by its $$k-1$$ first derivatives at that point (order $$k$$). We can leverage the existing structural substitute routine to substitute $$\zeta$$ with $$a$$ to get the resulting expression at $$a$$, and the differentiate routine to evaluate the partial derivative $$\frac{\partial{x}}{\partial\zeta}$$.

 1: 2: 3: 4: 5: 6: 7:  let taylor (k:int) symbol a x = let rec impl n nf acc dxn = if n = k then acc else let dxn_a = dxn |> Structure.substitute symbol a let dxn' = dxn |> Calculus.differentiate symbol impl (n+1) (nf*(n+1)) (acc + dxn_a/nf*(symbol-a)**n) dxn' impl 0 1 zero x |> Algebraic.expand 

Let's use this routine to approximate $$\sin{x}+\cos{x}$$ at $$x = 0$$ using the first 4 derivatives:

 1:  taylor 4 x 0Q (sin(x)+cos(x)) // Returns 1 + x - (1/2)*x^2 - (1/6)*x^3 

## Math.NET Symbolics with C#

Even though Math.NET Symbolics is written entirely in F#, it can be used in C# almost exactly the same way. The equivalent C# code to the F# code above could look as follows:

  1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:  using MathNet.Symbolics; using Expr = MathNet.Symbolics.Expression; var x = Expr.Symbol("x"); var y = Expr.Symbol("y"); var z = Expr.Symbol("z"); var a = Expr.Symbol("a"); var b = Expr.Symbol("b"); var c = Expr.Symbol("c"); var d = Expr.Symbol("d"); var e = Expr.Symbol("e"); var f = Expr.Symbol("f"); Infix.Format(a + a); // returns 2*a Infix.Format(a * a); // returns a^2 Infix.Format(2 + 1 / x - 1); // returns 1 + 1/x Infix.Format((a / b / (c * a)) * (c * d / a) / d); // returns 1/(a*b) Infix.Format(1 / (a * b)); // returns string "1/(a*b)" Infix.FormatStrict(1 / (a * b)); // returns string "a^(-1)*b^(-1)" LaTeX.Format(1 / (a * b)); // returns string "\frac{1}{ab}" Infix.Format(Infix.ParseOrUndefined("1/(a*b)")); // Returns 1/(a*b) Infix.Format(Infix.ParseOrUndefined("1/(a*b")); // Returns Undefined Infix.Format(Infix.ParseOrThrow("1/(a*b)")); // Returns 1/(a*b) var symbols = new Dictionary {{ "a", 2.0 }, { "b", 3.0 }}; // Returns 0.166666666666667 Evaluate.Evaluate(symbols, 1/(a*b)).RealValue; // Returns 3/8 + (1/2)*cos(2*x) + (1/8)*cos(4*x) Infix.Format(Trigonometric.Contract(Expr.Pow(Expr.Cos(x), 4))); // Taylor Expansion Expr Taylor(int k, Expr symbol, Expr a, Expr x) { int factorial = 1; Expr accumulator = Expr.Zero; Expr derivative = x; for(int i=0; i
namespace System
namespace System.Numerics
namespace MathNet
namespace MathNet.Numerics
namespace MathNet.Symbolics
Multiple items
module Operators

from MathNet.Symbolics

--------------------
module Operators

from Microsoft.FSharp.Core
val x : Expression

Full name: index.x
val symbol : name:string -> Expression

Full name: MathNet.Symbolics.Operators.symbol
val y : Expression

Full name: index.y
val z : Expression

Full name: index.z
val a : Expression

Full name: index.a
val b : Expression

Full name: index.b
val c : Expression

Full name: index.c
val d : Expression

Full name: index.d
val e : Expression

Full name: index.e
val f : Expression

Full name: index.f
module Infix

from MathNet.Symbolics
val format : expression:Expression -> string

Full name: MathNet.Symbolics.Infix.format
val formatStrict : expression:Expression -> string

Full name: MathNet.Symbolics.Infix.formatStrict
module LaTeX

from MathNet.Symbolics
val format : expression:Expression -> string

Full name: MathNet.Symbolics.LaTeX.format
val parse : infix:string -> ParseResult

Full name: MathNet.Symbolics.Infix.parse
val tryParse : infix:string -> Expression option

Full name: MathNet.Symbolics.Infix.tryParse
val parseOrUndefined : infix:string -> Expression

Full name: MathNet.Symbolics.Infix.parseOrUndefined
val parseOrThrow : infix:string -> Expression

Full name: MathNet.Symbolics.Infix.parseOrThrow
val symbols : Map<string,Approximation>

Full name: index.symbols
Multiple items
module Map

from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...

Full name: Microsoft.FSharp.Collections.Map<_,_>

--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
val ofList : elements:('Key * 'T) list -> Map<'Key,'T> (requires comparison)

Full name: Microsoft.FSharp.Collections.Map.ofList
union case Approximation.Real: float -> Approximation
type Evaluate =
static member Polynomial : z:float * [<ParamArray>] coefficients:float[] -> float + 2 overloads

Full name: MathNet.Numerics.Evaluate
val evaluate : symbols:System.Collections.Generic.IDictionary<string,FloatingPoint> -> _arg1:Expression -> FloatingPoint

Full name: MathNet.Symbolics.Evaluate.evaluate
module Trigonometric

from MathNet.Symbolics
val contract : x:Expression -> Expression

Full name: MathNet.Symbolics.Trigonometric.contract
val cos : _arg1:Expression -> Expression

Full name: MathNet.Symbolics.Operators.cos
val taylor : k:int -> symbol:Expression -> a:Expression -> x:Expression -> Expression

Full name: index.taylor
val k : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val symbol : Expression
val a : Expression
val x : Expression
val impl : (int -> int -> Expression -> Expression -> Expression)
val n : int
val nf : int
val acc : Expression
val dxn : Expression
val dxn_a : Expression
module Structure

from MathNet.Symbolics
val substitute : y:Expression -> r:Expression -> x:Expression -> Expression

Full name: MathNet.Symbolics.Structure.substitute
val dxn' : Expression
module Calculus

from MathNet.Symbolics
val differentiate : symbol:Expression -> _arg1:Expression -> Expression

Full name: MathNet.Symbolics.Calculus.differentiate
val zero : Expression

Full name: MathNet.Symbolics.Operators.zero
module Algebraic

from MathNet.Symbolics
val expand : _arg1:Expression -> Expression

Full name: MathNet.Symbolics.Algebraic.expand
val sin : _arg1:Expression -> Expression

Full name: MathNet.Symbolics.Operators.sin