# F# Math (I.) - Numeric types in PowerPack

In this article, we'll briefly look at two numeric types that are available in F# PowerPack.
The type `complex`

represents complex numbers consisting of real and imaginary parts.
Both parts are stored as a floating point numbers. The type `BigRational`

represents
rational numbers consisting of numerator and denominator of arbitrary sizes. Integers of arbitrary
size are represented using `BigInteger`

type that is available in .NET 4.0
(in the `System.Numerics.dll`

assembly). On .NET 2.0, the `BigInteger`

type is also a part of F# PowerPack.

This article is a part of a series that covers some F# and F# PowerPack features for numerical computing. Other articles in this series discuss matrices, defining custom numeric types and writing generic code. For links to other parts, see F# Math - Overview of F# PowerPack.

## Using complex numbers

The first example demonstrates a few basic operations that can be done with `complex`

numbers in F#. In order to run the code in the listing, you first need to reference
`FSharp.PowerPack.dll`

. This can be done either using `#r`

directive in F# Interactive
(when working in an F# Script file such as `Script.fsx`

) or using the “Add Reference”
dialog in Visual Studio when creating an F# project (or using `-r:FSharp.PowerPack.dll`

option of the compiler):

1: #r "FSharp.PowerPack.dll" 2: open Microsoft.FSharp.Math;; 3: 4: let c = complex -1.0 0.0;; 5: val c : complex = -1r+0i 6: 7: let i = sqrt c;; 8: val i : Complex = 6.12303176911189e-17r+1i 9: 10: i * i;; 11: val it : Complex = -1r+1.22460635382238e-16i { ... }

After referencing PowerPack and opening the namespace that contains functionality for
mathematical calculations, the snippet creates a number using the `complex`

function.
The first parameter represents the real part and the second one represents the imaginary part,
so the example creates a complex number representing a real number -1. The next step uses
`sqrt`

function to calculate the square root. Since the calculation uses complex
numbers, this is a valid operation and it returns the number *i* (with some rounding error).
Next, the snippet calculates square of *i* to get a real number -1 again.

Note that both `sqrt`

and * are standard operations that are available in the F#
library and don’t handle the `complex`

type explicitly. Instead, they work with any
type that provides specific members. This is done using static member constraints, which are
discussed in the last two articles of this series (see introduction
for links).

## Using rational numbers

In this section, we look at a similarly simple listing that shows working with the
`BigRational`

type. Literals of this type can be written more easily using the
`N`

suffix. The suffix can be only when the `FSharp.PowerPack.dll`

library is referenced and it can be used to write rational numbers representing
(arbitrary large) integers. To get a rational representing a fraction, we can use
division operator:

1: let r1 = 4N / 6N;; 2: val r : BigRational = 2/3N 3: 4: let r2 = pown r1 10;; 5: val r : BigRational = 1024/59049N 6: 7: let q1 = pown (1N / 2N) 5 8: let q2 = pown (1N / 2N) 6;; 9: val q1 : BigRational = 1/32N 10: val q2 : BigRational = 1/64N 11: 12: q2 < r2 && q1 > r2;; 13: val it : bool = true

Literals such as `4N`

can be only created from integers. However, the overloaded
division operator for `BigRational`

returns a `BigRational`

representing
fractions. As you can see, the number is stored in a normalized form (this means there is no
integer such that the numerator and denominator can be divided by it).

The next couple of lines show code that finds a number *q* such that
*(1/2) ^{q}* is smaller the number

`r2`

and *(1/2)*is larger. Just like when working with complex numbers, we can use standard functions and operators such as

^{(q+1)}`pown`

and *<*. These are overloaded and work with any numeric type.

The literals of `BigRational`

can be constructed using notation such as `4N`

.
This is not a built-in language feature. In fact, you can define your own literals (using
a limited set of suffixes) for your own numeric type. This is discussed in an article that
explains how to define a custom numeric type (see introduction
for links).

### Calculating PI in F#

To look at some larger example that uses the `BigRational`

type, let's write an
F# snippet that calculates an estimate of the number π. The sample uses Gregory–Leibniz series
that is explained on WikiPedia [3]. First few members of the series
are *4/1 - 4/3 + 4/5 - 4/7* etc. It is quite easy to see the pattern - the denominator
always increases by 2 and the operation varies between + and -. The series is quite simple to
calculate, but it does not give a very precise estimate. However, it is good enough to
demonstrate working with rational numbers.

We can make the code nicely functional by representing the series as a value of type
`seq<BigRational>`

. The following `series`

function calculates
a single element of the series (using denominator `n`

) and then calls itself
recursively to calculate the rest:

1: /// Generates series that approximates PI 2: /// 4/1 - 4/3 + 4/5 - 4/7 + 4/9 (starting from q * 4/n) 3: let rec series n q = 4: seq { 5: yield q * 4N / n 6: yield! series (n + 2N) (q * -1N) } 7: 8: let pi1 = series 1N 1N |> Seq.take 10 |> Seq.reduce (+) 9: val pi1 : BigRational = 44257352/14549535N 10: float pi1 11: val it : float = 3.041839619 12: 13: let pi2 = series 1N 1N |> Seq.take 300 |> Seq.reduce (+) 14: val pi2 : BigRational = (...) 15: float pi2 16: val it : float = 3.13825933

If we added all elements of the series, we would get the precise value of π.
Unfortunately, we don't have infinite space and time, so the snippet just takes
first few elements (using `Seq.take`

) and then adds all elements
using `Seq.reduce`

. Every second element is already negative, because
the `series`

function multiplies the elements by `q`

, which
alternates between 1 and -1, so we can use the + operator as the aggregation function.

## Using F# numeric types from C#

The PowerPack library is mainly designed as a library with additional functionality for F#. However,
it is a standard .NET library and can be referenced from C# too. Moreover, F# represents overloaded
operators in the same way as C#, so the types `BigRational`

and `Complex`

(and also `BigInteger`

when using .NET 2.0) can be quite nicely used from C#.

The following example re-implements the previous F# snippet to calculate the number π. It follows the
same approach as F#. The method `Series`

generates elements of the
Gregory–Leibniz series. The implementation uses loop instead of recursion, because recursive
iterators cannot be written efficiently in C#:

static IEnumerable<BigRational> Series() { var n = BigRational.FromInt(1); var q = BigRational.FromInt(1); while (true) { yield return q * BigRational.FromInt(4) / n; n = n + BigRational.FromInt(2); q = q * BigRational.FromInt(-1); } }

As you can see, we can create `BigRational`

from integers using a static method
`BigRational.FromInt`

. The type also implements standard overloaded operators
(the snippet uses `+`

, `*`

and `/`

) and a few additional operations, such as
`BigRational.PowN`

(to calculate power). To get approximate value of π as
a floating point number, we can write:

```
var pi = Series().Take(300).Aggregate((a, b) => a + b);
Console.WriteLine(BigRational.ToDouble(pi));
```

In C#, we can use LINQ to take 300 elements of the series and sum them. The resulting rational
number can be converted to floating point using `BigRational.ToDouble`

:

## Summary

Using F# PowerPack from C# is just a bonus. The library is mainly designed for F#, but it follows standard .NET programming patterns, so it can be nicely used from C# too. The F# PowerPack implementation of rational numbers is likely good enough for many applications, but if you need more features or better performance, you can check out a list of numerical libraries for .NET (and F#) on MSDN [4].

## References & Links

- [1] F# PowerPack (source code and binary packages) - CodePlex
- [2] Numeric Computing - Real World Functional Programming on MSDN
- [3] Pi - Estimating the Value - WikiPedia
- [4] Numerical Libraries for F# and .NET - Real World Functional Programming on MSDN

Full name: Untitled.c

type: complex

implements: System.IComparable

inherits: System.ValueType

val complex : float -> float -> complex

Full name: Microsoft.FSharp.Math.ComplexTopLevelOperators.complex

--------------------

type complex = Complex

Full name: Microsoft.FSharp.Math.complex

type: complex

implements: System.IComparable

inherits: System.ValueType

Full name: Untitled.i

type: Complex

implements: System.IComparable

inherits: System.ValueType

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

Full name: Untitled.r1

type: BigRational

implements: System.IComparable

Full name: Untitled.r2

type: BigRational

implements: System.IComparable

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

Full name: Untitled.q1

type: BigRational

implements: System.IComparable

Full name: Untitled.q2

type: BigRational

implements: System.IComparable

Full name: Untitled.series

*Generates szeries that approximates PI*

4/1 - 4/3 + 4/5 - 4/7 + 4/9 (starting from q * 4/n)

4/1 - 4/3 + 4/5 - 4/7 + 4/9 (starting from q * 4/n)

type: BigRational

implements: System.IComparable

type: BigRational

implements: System.IComparable

val seq : seq<'T> -> seq<'T>

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

--------------------

type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>

type: seq<'T>

inherits: System.Collections.IEnumerable

Full name: Untitled.pi1

type: BigRational

implements: System.IComparable

from Microsoft.FSharp.Collections

Full name: Microsoft.FSharp.Collections.Seq.take

Full name: Microsoft.FSharp.Collections.Seq.reduce

val float : 'T -> float (requires member op_Explicit)

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

--------------------

type float = System.Double

Full name: Microsoft.FSharp.Core.float

type: float

implements: System.IComparable

implements: System.IFormattable

implements: System.IConvertible

implements: System.IComparable<float>

implements: System.IEquatable<float>

inherits: System.ValueType

--------------------

type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>

type: float<'Measure>

implements: System.IComparable

implements: System.IConvertible

implements: System.IFormattable

implements: System.IComparable<float<'Measure>>

implements: System.IEquatable<float<'Measure>>

inherits: System.ValueType

Full name: Untitled.pi2

type: BigRational

implements: System.IComparable

Discuss on twitter, .

Send corrections via GitHub pull requests.