Page 1 of 2
Number crunching in C# (or any .NET language) is a problem because it doesn't have a long tradition of implementing numerical methods. So why not use a library that was originally implemented in Fortran, the language of choice, when you want to work something out?
Yes I know the temptation is to always do it yourself. You have the paper that describes the method so why not just implement it from scratch? After all it can't take long as numerical programs are never complicated or run to many lines.
Yes, I have done it myself and well remember the hours of work spent testing and finding the bugs in my principle components (eigenvalue) routine and at the end of the day did I really trust it? No not really.
The problem with numerical methods is that even if you understand the theory actually implementing the calculation is usually not as simple as writing down the theory in code. You have to take account of the extreme cases, consider accuracy and stability. You also have to test in ways that normal software just isn't subjected to and you have to know the limits of the methods and implementations. So it is much easier to get some well trusted off the shelf solution. But... it's then a matter of figuring out how it all works.
NAG Library for .NET
For a recent project I decided to try The Numerical Algorithms Group's NAG Library for .NET. The reason for the choice is that the NAG Library has been round almost as long as I can remember and for this reason alone it is worthy of your trust. It can be used from C#, VB, C++ or F# and it works in a 32-bit or 64-bit environment. The .NET library takes the form of managed wrappers around the Fortran library.
Before you worry about not using a 100% native managed approach think how much better it is to have the security and robustness of the original Fortran library. You can't code a new library from scratch, even with the model of something that works in front of you, and not expect to put some bugs in.
The library includes routines for:
It is important to stress that each category includes multiple methods and there are over 200 methods in total.
- Local and global optimization
- Statistics including:
- nearest correlation matrix
- regression analysis
- time series analysis
- Pseudorandom number generators
- Quasi-random number generators
- Wavelet transforms
- Special functions
- Numerical integration (Quadrature)
- Roots of one or more transcendental equations
- Summation of Series
- Least-squares and eigenvalue problems
- Curve and surface fitting
- Linear equations
Getting started with NAG
To use the NAG Library for .NET all you have to do is to install it, start a new C# project in Visual Studio and add a reference to the DLL - Naglibrary32 or Naglibrary64 and add:
Before you do start to make use of it, though, you probably need to use the example program included in the install. This isn't really an example more a verification application. You can run any of the methods in the library simply by selecting it and then you can compare the output with that produced by a reference installation. This is a good way to pick up any problems before they find their way into your code. It seems like a good idea to check any routine in this way before you start using it and it provides a good way to determine that updates haven't broken the system while you weren't looking.
So how do you use the numerical method of your choice?
The first thing to say is that you won't find a method called eigenvectors or anything human readable. All of the methods are grouped together into families of similar types indicated by a three character name. So G03 is multivariate methods, G05 is random number generators and so on. Each three letter family has been implemented as a static class with methods that correspond to each of the numerical techniques in the family.
For example the static class X01 includes x01aa and X01ab which give the constants pi and gamma respectively. So to get pi into a double you would use:
double NagPi = X01.x01aa();
It is true that at first the use of a systematic but not meaningful naming system seems very strange but you soon find the routines you want to use and it has the advantage that variations and related methods are close by in the naming structure. There is also the very useful intellisense prompting which gives you not only the possible methods you could use but a short description of what they do.