F# Math (IV.) - Writing generic numeric code
Generic numeric code is some calculation that can be used for working with multiple different numeric
types including types such as int
, decimal
and float
or even our own
numeric types (such as the type for clock arithmetic
from the previous article of the series). Generic numeric code differs from ordinary generic F# code such
as the 'a list
type or List.map
function, because numeric code uses numeric operators
such as +
or >=
that are defined differently for each numeric type.
When writing simple generic code that has some type parameter 'T
, we don’t know anything about
the type parameter and there is no way to restrict it to a numeric type that provides all the operators that
we may need to use in our code. This is a limitation of the .NET runtime and F# provides two ways for
overcoming it.
- Static member constraints can be used to write generic code where the actual
numeric operations are resolved at compile-time (and a generic function is specialized for all required
numeric types). This approach makes resulting code very efficient and is generally very easy to use
when writing a function such as
List.sum
. - Global numeric associations (available in F# PowerPack) give us a way to obtain
an interface implementing required numeric operations dynamically at runtime. This approach has some
runtime overhead, but can be used for complex numeric types (such as
Matrix<'T>
). - Combination of both techniques can be used to implement complex numeric type that is generic over the contained numeric values and has only a minimal runtime overhead.
Static member constraints are a unique feature of F# that is not available in other .NET languages, so if you're interested in writing numeric code for .NET, this may be a good reason for choosing F#. In C# or Visual Basic, you would be limited to the second option (which can be implemented in C#). In dynamic languages (like IronPython), everything is dynamic, so numeric computations can work with any numeric type, but will be significantly less efficient. In the rest of the article, we look at the three options summarized above.
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.
Published: Sunday, 27 November 2011, 5:19 PM
Tags:
c#, functional, f#, math and numerics
Read the complete article
F# Math (III.) - Defining custom numeric types
In this article, we define an F# numeric type for calculating in the modular arithmetic (also called clock arithmetic) [1]. Modular arithmetic is used for calculations where we want to keep a value within a specified range by counting in cycles. For example, a maximal value on clock is 12 hours. When we add 11 hours and 3 hours, the value overflows and the result is 2 hours. Aside from clocks, this numeric system is also essential in cryptography or, for example, in music.
This tutorial shows several techniques that are essential when defining any new numeric type in F#. Most importantly, you’ll learn how to:
- Define a numeric type with overloaded operators
- Define a numeric literal for constructing numbers of our new type
- Enable calculating with our type in F# lists and matrices
- Hide implementation details of a numeric type
We define type IntegerZ5
that implements modular arithmetic with modulus 5, meaning that valid values are in the range
from 0 to 4 and we equip the type with operations such as addition and multiplication. When an operation produces a value that would
be outside of the range, we adjust it by adding or subtracting the modulus (in our case 5). Here are some examples of calculations
that we’ll be able to write:
2 + 1 = 3 (mod 5) 4 * 2 = 3 (mod 5) List.sum [ 0; 1; 2; 3 ] = 1 (mod 5)
In the first case, we can perform the operation without any adjustments. In the second case, we multiply 4 by 2 and get 8 as the
result, which is out of the required range. To correct it, we calculate the remainder after a division by 5 (written as 8 % 5
in F#),
which gives us 3. Finally, the last example shows that we’d also like to be able to use our type with lists. If we add values 0, 1, 2
and 3, we get 6 which is adjusted to 1.
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.
Published: Thursday, 24 November 2011, 7:21 PM
Tags:
functional, f#, math and numerics
Read the complete article
F# Math (II.) - Using matrices for graph algorithms
In the previous article of this
series, we looked at complex
and BigRational
, which are two
numeric types that are available in F# PowerPack. Aside from these two, the PowerPack
library also contains a type matrix
representing a two-dimensional matrix
of floating-point values.
In this article, you'll learn how to work with matrices in F#, using some of the functions provided by F# PowerPack. I'll demonstrate the library using an example that represents graphs using a, so called, adjacency matrix. If you're not familiar with this concept, you don't need to worry. It is quite simple and it will be clear once we look at an example. The matrix represents which vertices of a graph are connected with other vertices by an edge. Many of the standard operations on matrices are useful when working with adjacency matrix, so this tutorial will cover the following:
- Creating matrices from lists and using functions from the
Matrix
module - Using slices to read or modify a part of matrix
- Performing standard operations with matrices such as transposition and matrix multiplication
- Using higher order functions for working with matrices
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.
Published: Wednesday, 9 November 2011, 1:46 AM
Tags:
functional, f#, math and numerics
Read the complete article
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.
Published: Wednesday, 2 November 2011, 2:34 AM
Tags:
c#, functional, f#, math and numerics
Read the complete article
F# Math - Numerical computing and F# PowerPack
This article is the first article of a series where I'll explain some of the F# features that are useful for numeric computing as well as some functionality from the F# PowerPack library. Most of the content was originally written for the Numerical Computing in F# chapter on MSDN (that I announced earlier), but then we decided to focus on using F# with third party libraries that provide more efficient implementation and richer set of standard numeric functionality that's needed when implementing machine learning and probabilistic algorithms or performing statistical analysis. If you're interested in these topics, then the last section (below) gives links to the important MSDN articles.
However, F# PowerPack still contains some useful functionality. It includes two additional numeric types and an implementation of matrix that integrates nicely with F#. The series also demonstrates how to use features of the F# language (and core libraries) to write numeric code elegantly. In particular, we'll use the following aspects:
- Overloaded operators. Any type can provide overloaded version of standard numeric operators such as +, -, * and / as well as other non-standard operators (such as .*). As a result, libraries can implement their own numeric types which are indistinguishable from built-in types such as int.
- Numeric literals. F# math libraries can enable using new numeric literals in the code. For example, you can
write a
BigRational
value representing one third as1N/3N
. TheN
suffix used in the notation is not hardcoded in the F# language and we'll see how to define similar numeric type. - Static constraints. F# supports static member constraints, which can be used for writing functions that
work with any numeric type. For example, the
List.sum
function uses this feature. It can sum elements of any list containing numbers.
These are just a few of the F# language features that are useful when writing numeric code, but there are many others. The usual F# development style using interactive tools, type safety that prevents common errors, units of measure as well the expressivity of F# make it a great tool for writing numeric code. For more information, take a look at the MSDN overview article Writing Succinct and Correct Numerical Computations with F#.
Published: Wednesday, 2 November 2011, 2:30 AM
Tags:
functional, f#, writing, math and numerics
Read the complete article