Industrial Data Science
in C# and .NET:
Simple. Fast. Reliable.
 
 

ILNumerics - Technical Computing

Modern High Performance Tools for Technical

Computing and Visualization in Industry and Science

tgt

ILNumerics® Computing Engine

This section deals with the foundation of mathematical algorithms: it gives general usage rules, shows how to work with n-dimensional arrays, and describes how to write ILNumerics functions in a way that brings excellent performance. 

The big picture

Today numerical algorithms are mostly created by help of mathematical prototyping languages: they represent data by means of n-dimensional arrays and provide a set of functions working on those arrays. Algorithm syntax becomes much more concise, easier to write, understand and fix. However, if it comes to deploying such algorithms in a production environment all popular frameworks expose certain limitations: targeting academia they lack of support for large projects and large teams, lack strongly typed languages, lack of performance, lack of efficient developer toolchains. The result: developers often have to reimplement algorithms in an industrial-grade language, like C# or C++. 

ILNumerics bridges this gap by providing an efficient domain specific language (DSL) embedded into C# or Visual Basic. It provides all features known from mathematical prototyping frameworks, tailored to the feature set of Matlab(R) and numpy. Users coming from any of these languages will immediately feel home. No tedious translation of algorithms is required, no new bugs produced. Time to market is significantly decreased.

In contrast to other 'numerical libraries' ILNumerics considers the specifics of the managed .NET environment. It abstracts away the complexity of the underlying computer architecture(s) and provides outstanding execution performance - transparent to the programmer.

Numerical, n-dimensional Arrays

Flexible array classes serve many important tasks: they hold the actual data and allow their efficient manipulation. They realize short, expressive syntax for numerical algorithms and can be seen as the foundation of every numerical language. ILNumerics arrays support the feature sets of both popular prototyping languages. Where features mutually exclusive differ, a simple switch let's you decide which ArrayStyle ILNumerics ought to prefer. This switch affects the behavior of the array classes in well defined aspects, including the number of dimensions, prefered storage order and others. While affecting the array classes only the switch thus also controls properties of arrays returned from computational functions.

Computational functions

ILNumerics offers a large number of static functions in the ILNumerics.ILMath class. Out of historical reasons most of them expose the Matlab & Co. API. However, they work with ILNumerics arrays - regardless of the current array style. This way users can stay within their known feature set - or even pick the best of both worlds by using features from both frameworks in their algorithms.

Figure: the mapping of features from numpy or Matlab® & Co. to ILNumerics:  ILNumerics arrays are fully compatible with both languages by help of the Settings.ArrayStyle switch. Computational functions are provided in the ILMath class and in Toolbox classes. They mostly expose the Matlab® API but are suitable to be used by any ILNumerics array - regardless of the current ArrayStyle. 

In addition to that, ILNumerics arrays expose some computational functions as member functions directly on an array instance. And, to increase compatibility with numpy one can import many member functions known from numpy's ndarray to be available on ILNumerics arrays as extension methods.

Focus on Performance - Why / How?

.NET is well known for its efficient and automatic garbage collection. This is great for most business scenarios. However, when it comes to mathematical applications the requirements for memory management are more complex. Without special care the runtime - namely the GC - often cause a serious performance hit. Therefore, ILNumerics implements an efficient memory management which saves this GC overhead and brings excellent execution speed. This is achieved by:

  • Strong types manage array lifetime and (im)mutability 
  • Prompt, deterministic but transparent clean-up.
  • Memory is reused for subsequent array allocations.
  • Lazy 'copy on write' copies memory only when really needed.
  • Array operations are done in-place, whenever possible.
  • Efficient resource utilization: parallel execution. 

All this is done automatically, transparently to the user. Read more about ILNumerics usage rules

 

Further readings: