Marcin Drobik

software journeyman notes

Playing with C# type system - Part 2

Last time I introduced the strongly typed Matrix class with some simple operation. Let's try to leverage this so that compiler can help us construct more advanced formulas.

The formula

Imagine that writing down following formula (s, q and H are matrices):

var dH = (s * s.T) / (s.T * q) - (H * q) * ((H * q).T / (q.T * H * q));

To use strongly typed matrices in this formula we need several operations defined: + (defined in last post), - (same as +), Transposition, / and *.

Let's do Transposition first. It quite simple - the returned matrix will have swapped dimensions:

public class Matrix<D1, D2>
{    
    // ...

    public Matrix<D2, D1> T => Inner.Transpose().As<D2, D1>();

    // ...
}

Multiplication

It's bit more complex for multiplication. From Wikipedia: if A is an n × m matrix and B is an m × p matrix, their matrix product AB is an n × p matrix. Let's give it a try:

// I changed type parameter names to match the definition above
public class Matrix<n, m>
{    
    // Type p is not defined!
    public static Matrix<n, p> operator *(Matrix<n, m> a, Matrix<m, p> b) => a.Inner.Multiply(b.Inner).As<n, p>();
}

The problem is that type p is not defined - it cannot be a type parameter, so the only option is to actually have if defined as a class:

public class p { }

A bit dirty hack but it compiles and gives a necessary compiler check:

public class n { }
public class m { }

public void MultiplicationTest()
{
    Matrix<n, m> A = null; // some actual values go here
    Matrix<m, p> B = null;

    Matrix<n, p> AB = A*B; 
}

However if you try this:

public void NotValid()
{
    Matrix<m, m> A = null; // some actual values go here
    Matrix<m, p> B = null;

    // Does not compile - operator * is not defined for those matrices
    var AB = A*B; 
}

... you'll get a compiler error.

comments powered by Disqus