# Configuration

**Extreme Numerics.NET**
has several configuration options. This section discusses the most
important ones.

## Selecting Implementations

There are several dimensions to how a particular calculation
can be performed. Most fundamental is the numerical type
that is used to represent real number.
Most of the algorithms in
**Extreme Numerics.NET**
use double precision numbers. However, for specific calculations,
like linear algebra and signal processing applications,
other types may be used. For example, single-precision floating-point
numbers or rational numbers.

When a calculation can be done with different types of operands, the implementing classes take a generic type argument that specifies the element types. For example, the Vector<T> type that represents vectors can have elements of arbitrary type. When a computational class doesn't take generic type arguments, it usually means that it only works with double-precision numbers.

The platform is another dimension. Is the code 100% managed? Or does it use optimized native code (based on IntelĀ®'s Math Kernel Library)? Or does it use a CUDA-based GPU?

A *provider* is an object that provides
*implementations* for one or more types
that perform calculations. For example, there is a
ManagedCoreProvider
class that provides implementations for double-precision numbers
for linear algebra (LinearAlgebraOperations<T>)
and FFT's (FftOperations<T>).

When using double precision, no further action is needed. The managed provider is loaded automatically.

### Using single-precision

To use single precision, two things need to be done:

First, a reference must be added to the
*Extreme.Numerics.SinglePrecision.Net40.dll*
assembly in your project. This assembly contains the
managed implementations of single-precision calculations.

Second, the provider for single precision calculations must be registered. This can be done by calling the RegisterSinglePrecisionProvider(ProviderManager, Boolean) method on the Providers property of the NumericsConfiguration class. This ensures that, when calculations are to be done in single-precision, the correct implementation can be found.

### Using other numerical types

Many calculations can also be done in arbitrary precision, or using Decimal or with rational numbers.

To use other types in calculations, a reference must be added to the
*Extreme.Numerics.Generic.Net40.dll*
assembly in your project. This assembly contains
generic implementations of calculations.

Second, the provider for generic calculations must be registered. This can be done by calling the RegisterGenericProvider(ProviderManager) method on the Providers property of the NumericsConfiguration class. This method does not take a type argument: one provider supplies the implementation for all element types.

## Using Implementations

The algorithms and objects in
**Extreme Numerics.NET**
automatically use the best available implementation.
In the vast majority of cases, you won't need to use the implementation
objects directly.

However, there may be times when this is necessary. For example, when performance is critical, some of the overhead inherent in encapsulating calculations in vector and matrix objects may be avoided by calling the linear algebra implementations directly. The CoreImplementations<T> class defines the main implementations. It has the following properties:

Property | Description |
---|---|

The core linear algebra operations, such as multiplying vectors and matrices, computing norms and dot products, solving triangular systems. The functionality is roughly equivalent to what is in the BLAS (Basic Linear Algebra Subroutines) library. | |

Linear algebra operations that operate on sparse vectors and matrices. | |

Functions that compute matrix decompositions (LU, QR, SVD...) and use these decompositions for other calculations. The functionality is a subset of what is available in the LAPACK library. | |

ArrayFunctions | Elementary functions that operate on the elements of vectors. |

Fast Fourier Transforms and related functionality. |

Although operations on real and complex vectors and matrices are very similar, there are some differences. Most importantly, some operations like norms produce real results even for complex arguments. Also, some operations like doing a rank update of a Hermitian matrix, require a value to be real. The way you call operations on real or complex vectors and matrices can sometimes be slightly different.

To access complex linear algebra operations, you have two options. The standard way is to use the LinearAlgebra property with the generic type argument of CoreImplementations<T> equal to the type of real values. This gives access to the full range of operations.

The second way is through the LinearAlgebra property where the generic type argument of CoreImplementations<T> equals the element type of the operation. When the element type is real, this gives exactly the same methods as the LinearAlgebra. When the element type is complex, however, there are a few differences. Most notably, methods that return norms of complex vectors and matrices also return complex numbers.