Archive for the ‘.NET’ Category

NMath Charts in WPF

Tuesday, March 5th, 2013

The NMathChart adapter class makes it easy to generate visualizations of NMath data in as little as one line of code.  The Chart class that is created is a Windows Forms control, but this control can be included in a Windows Presentation Foundation application by using the WindowsFormsHost element.

To do so:

  1. Add references to these namespaces:


  2. In the XAML markup for your WPF window (MainWindow.xaml for example), add a WindowsFormsHost element at the desired location, e.g:

      <WindowsFormsHost Name="ChartHost"/>

  3. In the code-behind for the window (MainWindow.xaml.cs for example), set the Child property of the WindowsFormsHost to a Chart. For example:

    public MainWindow()
      ChartHost.Child = NMathChart.ToChart(NMathFunctions.CosFunction, 
                                            -Math.PI, Math.PI, 100 );

To see this in action, check out the sample code in the new Visualization Examples solution included in NMath 5.3. For more information about visualization of NMath data types, see:

Building ASP.NET web applications with NMath

Thursday, February 21st, 2013

NMath can be used to create ASP.NET web applications, just like any other .NET application. However, there are a few additional considerations for building and deploying ASP.NET applications.

Referencing NMath

To use NMath types in your application, add a reference to NMath.dll, just as you would with other types of .NET applications. If you are using web projects in Visual Studio, you can simply right-click the References folder and select the Add Reference… command. If you specify Copy Local = true in the reference’s properties, then the assembly will be copied to the /bin directory of the web application, facilitating deployment to a web server.

If you are not using web projects in Visual Studio (e.g. using the “Open Web Site” command in Visual Studio, or using other development tools), then you can alternatively specify the reference in the web.config file, like this:

<add assembly=”NMath, Version=<Version>, Culture=neutral, PublicKeyToken=<Token>”/>

We recommend that you do not add references to the kernel assemblies, as the appropriate kernel assembly for your platform is loaded at runtime and the appropriate native DLL is linked to the kernel.  Instead, place the kernel assemblies in the same location as the native DLLs, as described below.

Note: when the web server launches an ASP.NET application for the first time, the assemblies in the /bin directory are loaded into memory. If the /bin directory contains a mixture of 32-bit and 64-bit assemblies (for example, both NMathKernelx86.dll and NMathKernelx64.dll), then depending on the configuration of the web server, the application may fail to start and instead throw an exception like this: “An attempt was made to load a program with an incorrect format.”

Kernel Assemblies and Native DLLs

For ASP.NET applications, Microsoft recommends that the /bin directory contain only .NET assemblies, not native DLLs.

If the deployment web server may not have NMath installed directly, then we recommend that the appropriate kernel assembly (NMathKernelx86.dll or NMathKernelx64.dll) and the appropriate native DLLs (e.g. nmath_native_x86.dll or nmath_native_x64.dll) be placed in a folder within the web application root directory, such as /NativeBin. This folder should then be copied to the deployment web server along with the rest of your application.

NMath Configuration

NMath settings can be configured as described in Chapter 1.5 of the NMath User’s Guide. However, when deploying web applications — especially to a shared hosting environment — it’s quite common not to know the details about the physical structure of the file system, and to have restricted access to the system’s environment variables. The references to resources within web apps are typically relative to the root of the virtual directory for the website, regardless of where they might physically reside on disk.

For this reason, starting in NMath 5.3, the ASP.NET ~ operator can be used to specify the location of the NMath native libraries and the log file, relative to the web application root. That is, these can be specified in the web.config file like this:

<add key=”NMathNativeLocation” value=”~/NativeBin” />
<add key=”NMathLogLocation” value=”~/Logs” />

It is not sufficient to use relative paths (e.g. “bin/”), since the executing assembly is usually the ASP.NET worker process, and depending on the web server configuration, the working directory will usually be a subdirectory of the Windows system directory (e.g. c:\windows\system32).

The ~ operator can only be used in ASP.NET applications; specifying this in a Windows application will cause the path to be resolved incorrectly.

Large matrices and vectors

Friday, July 27th, 2012

Customers frequently ask us the size of the largest matrix they can instantiate. With recent developments at Microsoft the maximum object size now significantly depends on your OS (x86 or x64) and the version of .NET your application is referencing. With .NET 4.5 huge matrices can be created that far exceed the current 2GByte limit.

Pre .NET 4.5

Until 2012 all Microsoft 32-bit .NET processes were limited to 1.2GB of memory. Theoretically a matrix could take up most of that space. Let’s suppose it’s feasible in our application to have a 1 GB matrix. That matrix would contain 134,217,728 doubles or 268,435,456 floats — for example, a 11,585 x 11,585 square DoubleMatrix or a 16,384 x 16,384 square FloatMatrix.

There is a workaround in 32-bit .NET to increase the process memory to 2.4GB.

  1. Add the /3GB switch to boot.ini.
  2. After building the application, run the linker as follows:
link -edit -LARGEADDRESSAWARE application.exe

Increasingly, our customers are switching to 64-bit computing in part to get around these memory limitations. Although a 64-bit .NET process’s memory is only limited by the available RAM, the .NET runtime nevertheless limits any one object to 2GB. For that reason, our matrices are limited to a theoretical maximum of 402,653,184 doubles or 805,306,368 floats —for example, a 20,066 x 20,066 square DoubleMatrix or a 28,377 x 28,377 square FloatMatrix.

The good news is that this memory limit has finally been lifted with the release of .NET 4.5. A big thanks to the Microsoft GC .NET team! As they well know many developers have been requesting this change.

.NET 4.5

With the .NET 4.5 release developers can now create objects that exceed the 2 GB per object limit only in x64 environments. In order create these large objects the application must enable the element gcAllowVeryLargeObjects in the run-time schema. This run-time schema controls the behavior of the .NET garbage collection system.

    <gcAllowVeryLargeObjects enabled="true" />

These very large objects are subject to the following reasonable restrictions

  1. The maximum number of elements in an array is UInt32.MaxValue.
  2. The maximum index in any single dimension is 2,147,483,591 (0x7FFFFFC7) for byte arrays and arrays of single-byte structures, and 2,146,435,071 (0X7FEFFFFF) for other types.
  3. The maximum size for strings and other non-array objects is unchanged.

The brief Microsoft documentation note can be found here.

What does this mean for NMath?

First NMath has not yet been released with .NET 4.5 (as of July 2012) so all of the following will hold in the future under such a release. All current releases are still subject to the limits outlined above. So looking to the near future, underlying all NMath vectors and matrices is a contiguous 1-D array. This means that for matrices the number of elements must be less than 2,146,435,071. The same holds for vectors. The following table summarizes the maximum size of various NMath objects under .NET 4.5 on a x64 OS with gcAllowVeryLargeObjects enabled.

Class object Maximum size - elements Memory size - bytes
FloatVector 2,146,435,071 7.996 GBytes
DoubleVector 2,146,435,071 15.992 GBytes
FloatMatrix 2,146,435,071 7.996 GBytes
DoubleMatrix 2,146,435,071 15.992 GBytes

The Complex versions of these classes would have the same maximum number of elements but occupy twice the memory. This also means that we will soon be able to allocate a square matrix with a maximum size of [ 46329 x 46329 ].

- Trevor & Paul

NMath 5.3

We have confirmed that the currently shipping version of NMath (version 5.3) can handle very large objects if you use gcAllowVeryLargeObjects and you are targeting .NET 4.5. We have created DoubleMatrix objects as large as 30,000 x 30,000 in this way. That’s a 6.7GB object.

- Trevor

Large Matrices in a Web Environment

It was reported to CenterSpace that the configuration change did not work in web environments. We confirmed this to be true. The good news is that there’s a workaround developed by Microsoft. A Microsoft developer says:

Essentially, the reason it can’t be done at the application-level Web.config is that this particular setting can only be set per-process and only when the CLR is initializing. Since the CLR is already initialized by the time we start reading your Web.config, it’s too late to do anything about it at that time. Using CLRConfigFile should work around this by allowing you to specify an intermediate configuration file that the CLR can use for initialization. Then once the CLR is up, ASP.NET will read your Web.config and run your application as normal.

More info here: here

We have verified that this works.

- Trevor

NMath API updated with .NET Func<> delegates

Wednesday, May 2nd, 2012

At CenterSpace we are always working hard to keep the core NMath processing kernel start of the art, however changes to our libraries’ API usually lag behind any .NET framework developments in a process of deprecation and introduction. The .NET Func<> and Action<> delegates have been a part of the .NET framework now since .NET 3.5 and VS2008. Therefore, we are now deprecating all of our custom delegates in the NMath API and replacing them with .NET Func<> generic delegates. This improves interoperability between NMath and our customers’ code and between our C# API and other .NET languages. Customers will see this change in the NMath 5.2 and NMathStats 3.5.

For those not familiar with the usage and definition of Func<> types within .NET there is a short primer at the end of this post.

Compiler Warning for [Obsolete] NMath defined delegates

All of our NMath delegate types have been deprecated using the .NET [Obsolete()] attribute. The generated compiler warnings will provide the suggested Func type replacement.

Warning 52 'CenterSpace.NMath.Core.NMathFunctions.FloatUnaryFunction'
   is obsolete: 'Use Func< float, float >'   ...

To further clarify, the following table lists the deprecated NMath float delegate types side by side with their replacements. All NMath delegates should be redefined in your code using the generic Func types.

List of float-precision deprecated NMath delegate types
Old NMath delegates Replacement
float FloatFunction() Func< float >
float FloatUnaryFunction( float x ) Func< float, float >
float FloatBinaryFunction( float x, float y ) Func< float, float, float >
float FloatIntFunction( float x, int y ) Func< float, int, float >
float FloatVectorFloatFunction( FloatVector v ) Func< FloatVector, float >
FloatVector FloatVectorFloatVectorFunction( FloatVector x ) Func< FloatVector, FloatVector >

There are many other deprecated NMath delegates that should be similarly replaced in your code.

Code examples for updating your code

Where previously you might have created a delegate that takes a double argument and returns a double like this:

NMathFunctions.DoubleUnaryFunction soln =
   delegate(double x) {return (x*x*x) / 3.0 + y0; };

you should now do it like this:

Func soln =
   new Func< double, double >(  x => (x*x*x) / 3.0 + y0 );

All methods in NMath and NMath Stats now take Func<> type delegates. If you use the old NMath delegates types to call a NMath method, an obsolescence warning will be issued by the compiler.

NMath and NMath Stats contain many functors that have now been obsolesced and redefined using a generic Func<> type. The new functor naming convention simply drops the “tion” from “Function” to make the new name. For example, the delegate NMathFunctions.AtanFunction should now be replaced with NMathFunctions.AtanFunc. The old delegate has a type of NMathFunctions.DoubleUnaryFunction, and the new delegate has a type of Func< double, double >. This kind of replacement can be done safely with a global search and replace operation to rid yourself of compiler obsolescence warnings. The table below list a few functor redefinitions that demonstrate the renaming pattern that was applied across the API.

Sampling of deprecated NMath functors
Old NMath functor Replacement
DoubleUnaryFunction AbsFunction Func< double, double > AbsFunc
DoubleUnaryFunction AcosFunction Func< double, double > AcosFunc
DoubleUnaryFunction AsinFunction Func< double, double > AsinFunc
DoubleBinaryFunction PowFunction Func< double, double, double > PowFunc
DoubleIntFunction RoundFunction Func< double, int, double > RoundFunc
DoubleVectorDoubleFunction DoubleNaNMedianFunction Func< DoubleVector, double > DoubleNaNMedianFunc

Potential Issues

The deprecation process requires us to maintain the old custom delegate defintions in the API methods while introducing the new Func<> based API. As a result, every method call in our API which previously consumed a custom NMath delgate type, a functionally identical signature was added which consumes a Func<> based delegate. This duplication can cause an easy-to-fix compiler error in situations when an anonymous delegate was used instead of a NMath delegate type. Consider the follow line of code which inverts the singular values of a SVD.

      DoubleVector wInverse =
              delegate( double w )
                 { return w < eps ? 0.0 : 1.0 / w; }

Written this way will now cause the following compiler error.

Error	43
The call is ambiguous between the following methods or properties:
    CenterSpace.NMath.Core.NMathFunctions.DoubleUnaryFunction )'
'CenterSpace.NMath.Core.DoubleVector.Apply( System.Func )' ....

In this error message, the first Apply() is the old method signature and the second Apply() is the new Func<> based signature. The C# compiler can’t choose between the two when provided an anonymous delegate. Exactly why this ambiguity error is generated by the compiler is carefully explained by Eric Lippert over on stackoverflow. Briefly, the ambiguity error arises because both methods equally satisfy the Apply() method signature and the C# standard does not provide a way to judge which would be ‘better’, and so reports an error. The fix is simple, we just specified explicitly that we want to use the method that takes a generic Func<>.

      DoubleVector wInverse =
              new Func< double, double >
                 ( delegate( double w )
                    { return w < eps ? 0.0 : 1.0 / w; }

Or, somewhat more concisely using a lamda expression.

      DoubleVector wInverse =
              new Func< double, double >
                 ( w => w < eps ? 0.0 : 1.0 / w  )

A brief Func<> & Action<> primer

The generic delegate types, Func<> and Action<>, were introduced with the .NET 3.5 framework to unify delegate types across various .NET libraries. This allows a .NET library developer like CenterSpace to create an API that accepts generic delegates that are defined elsewhere in client code. The Func and Action are differentiated by their return values: Actions have no return value, Funcs always have a single return value of type TResult. For each of them, the .NET framework defines a type signature that takes between 0 and 16 generically typed arguments.

.NET Func<> and Action<> definitions
Func Action
TResult Func() void Action<>()
TResult Func( T arg ) void Action( T arg )
... ...
TResult Func( T1 arg1, T2 arg2, ... T15 arg15, T16 arg16 ) void Action( T1 arg1, T2 arg2, ... T15 arg15, T16 arg16 )

This is still all abstract. Here’s how we create a Func using a lambda expression.

Func mySquaringFunc =
   new Func< double, double> ( x =>  x*x ); 
double xSquared = mySquaringFunc( 45 );  // xSquared = 2025

This Func delegate takes single double value and returns a double value. Lamda expressions are commonly used today to generate delegates, however an anonymous delegate could also be used for the same purpose.

Func mySquaringFunc =
   new Func< double, double> ( delegate( double x ) { return x*x; } ); 
double xSquared = mySquaringFunc( 45 );  // xSquared = 2025

I find the lambda syntax to be more expressive and succinct. From the table above, T1 = double, and TResult = double.

Action types are not used within the NMath API because we are always dealing with functions and return values. However, Actions are similarly defined, and may be used for example in queuing code where a queue manager takes work in the form of Action delegates.

Action< DoubleVector > FFTWorker =
   new Action< DoubleVector >( v =>
         DoubleComplexForward1DFFT fft = new DoubleComplexForward1DFFT( v.Length );
         fft.FFTInPlace( v );
       } );
QueueManager.AddWork( FFTWorker, bigDataVector );

The Action above computes the in-place FFT, and the QueueManager can now generically schedule this work on the queue.

Happy Computing,
Paul Shirkey

NMath and Silverlight

Thursday, February 9th, 2012

From time to time, we’re asked about the best way to use NMath to build Silverlight applications. Unfortunately, like so many answers in software development, the answer is: it depends.

Silverlight is a great way to build line of business applications, but at its core, Silverlight runs within a sandboxed environment, typically within a browser, and usually within a networked intranet or Internet environment.  NMath, on the other hand, uses native libraries to provide high-performance math capabilities to managed code.  While it’s possible to build a Silverlight application that calls NMath functions, it’s worth taking a step back to look at what you really want to accomplish with your software project.

Most often, we find that developers are tasked with building dashboard-style business applications that allow the user to initiate some sort of data analysis, and then see a visualization of results.  In these cases, we generally recommend:

1) Use Silverlight (or HTML5) on the client, perform the analysis on one or more servers, and expose web services to initiate the analysis and deliver the results.

This is probably the most favorable approach, and usually the architecture to default to unless there’s a compelling reason to the contrary.  Some of the advantages of this approach:

  • It’s consistent with typical Silverlight application architecture; capabilities in Silverlight and ASP.NET make it easy to build this kind of application.
  • It retains the deployment advantages of Silverlight: there’s no need to distribute and install native components to every client machine.
  • It retains the cross-platform advantages of Silverlight: the application will work smoothly regardless of client hardware (including on Mac OS).
  • Centralizing the analysis on a server makes it easier to scale up with improved server hardware and/or server farms.
  • It makes efficient use of network bandwidth: usually there’s little need to transfer all of the source data between client and server, just the results of the analysis.

The primary disadvantages of this approach include:

  • This might drive an architectural shift if it’s not already working in a client-server environment.
  • It doesn’t take maximum advantage of available computing resources on the client, at least for the analysis (although the application can potentially use the client’s GPU for the visualization).

If you’re certain that you want to perform the analysis on the client using a Silverlight application, you can:

2) Use Silverlight 4+, and use COM interop to invoke COM components that were previously installed on the client.

3) Use Silverlight 5, and use Platform Invoke (P/Invoke) to invoke native components.

There are significant disadvantages to these approaches, in particular:

  • You would need to separately distribute your components and get them preinstalled on the local machine.
  • The client applications will only run on Windows; you cannot invoke native code on Mac OS from Silverlight.
  • Users will need to explicitly grant elevated trust to the Silverlight application.
  • You would also need to build your application with out of browser support (if you’re using COM interop).

For the COM interop approach you would use ComAutomationFactory.CreateObject() to instantiate dynamic COM objects, which would also mean that you would require C# 4, Silverlight 4, and Visual Studio 2010.  This approach is less than ideal for new applications; it’s primarily intended for interaction within controlled environments (e.g. interop with Microsoft Office).  For more about this, see:

For information about P/Invoke in Silverlight 5, see:

However, if you’re certain that you want to build a rich client application to perform the analysis on Windows, then you should also evaluate whether Silverlight is the best choice for doing so.  Some alternatives include:

4) Create a rich client application using Windows Presentation Foundation, and run in within the browser using XBAP.

XBAP applications are WPF applications that run in partial trust inside a web browser.  You do have access to more local resources than you do in Silverlight, and you can request the user to grant additional trust if needed.  You’re restricted to using Internet Explorer and Firefox.  For more about this, see:

5) Create a rich client application using Windows Presentation Foundation or Windows Forms, and distribute it via ClickOnce Deployment.

In this scenario, you’re running a full client application within Windows, but taking advantage of some of the deployment advantages of the web, including initial distribution and facilities for automatic application updates.  Generally speaking, this is the preferred way to build rich client applications on Windows.  For more about ClickOnce, see:

Our experienced consulting team is available to help you work through the architectural options that would make the most sense for your specific application; just contact us at