Saturday, June 8, 2019

Tutorial: How to use a compiled Matlab function in C#

In this small tutorial I will explain you:


  • How to compile a Matlab function into a DLL
  • Use the generated Matlab dll into a small C#-console program

Requirements:


  • VisualStudio 2015 or greater
  • Matlab 2018b 

Creating the .Net Matlab DLL

Create a matlab-file: MatlabThreeFunc.m

With the following content:


function [x2, sinx, expx]=MatlabThreeFunc(xIn)
% [x2, sinx, expx]=MatlabThreeFunc(xIn)
% Matlab test function

    x2=xIn.*xIn;
    sinx = sin(xIn);
    expx = exp(xIn);

end



As you see this simple function calculate the squared-, sin- and the exp- values of the input array xIn.

Navigate to the folder containing the file/function just created and execute the fololwing command:


mcc -W 'dotnet:MyMatlab.V2018b,WrapperClass,4.5,Private,local'  -T link:lib   ./MatlabThreeFunc.m;



This  will create a .Net dll, named V2018b.dll (version 4.5 of the Framework), containing a Class named WrapperClass and located in the namespace: MyMatlab.V2018b

In my My personal convention is to use part of the namespace (V2018b) to indicate which Matlab version I used to generate the dll. This is important when distributing your application. 

In my case, I want to run the application on other Computer I need to install the required Matlab Runtime 9.5 (=> https://www.mathworks.com/products/compiler/matlab-runtime.html)


Using the DLL in a C# project

Create a new Console Application:








Before you add a reference to the Just created DLL (=> V2018b.dll) it is important that you remove the VisualStudio default setting Prefer 32 Bit, otherwise you'll get a Runtime Type Exception from the Matlab dll. (=> Since Version 2015b, Matlab is ONLY 64 bit!)



Remove"Prefer 32Bit" 





Add the TWO Matlab-References to your project:

  • V2018b.dll 
  • MWArray.dll (this is located under :  C:\Program Files\MATLAB\R2018b\toolbox\dotnetbuilder\bin\win64\v4.0\MWArray.dll)

And now the code:




CODE:


using System;
using MathWorks.MATLAB.NET.Arrays;

namespace MatlabFuncInCSharp
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Running...");

            // a basic double-array for the tests
            double[] dArrayInput = new double[5] { 0.1, 0.2, 0.3, 0.4, 0.5 };

            // convert the C#-array into the equivalent MatLab class
            MWNumericArray matArrayInput = new MWNumericArray(dArrayInput);

            Console.WriteLine("Instantiating WrapperClass...");

            MyMatlab.V2018b.WrapperClass oWrapperClass = new MyMatlab.V2018b.WrapperClass();

           
            int iExpectedNumberOfOutputs = 3;  // we want ALL 3 outputs of "MatlabThreeFunc"

            Console.WriteLine("Callinng MatlabThreeFunc...");
            MWArray[] matOutput = oWrapperClass.MatlabThreeFunc(iExpectedNumberOfOutputs, matArrayInput);

            

            // matOutput contains 3 elements
            MWNumericArray matX2Array = (MWNumericArray)matOutput[0]; // casting required!
            MWNumericArray matSinXArray = (MWNumericArray)matOutput[1]; // casting required!
            MWNumericArray matExpXrray = (MWNumericArray)matOutput[2]; // casting required!

            Console.WriteLine("Converting output into C#-Arrays...");
            // back to the C#-world...
            double[] dX2array = (double[])matX2Array.ToVector(MWArrayComponent.Real);
            double[] dSinXarray = (double[])matSinXArray.ToVector(MWArrayComponent.Real);
            double[] dExpXarray = (double[])matExpXrray.ToVector(MWArrayComponent.Real);


            Console.WriteLine("Press any key to exit!");
            Console.ReadKey();
        }
    }
}


I hope you found this post useful. A small video would have been wayyyyyyyyyyy better but I don't have the time for it. 

References:

Friday, April 26, 2019

C# Defining Application/User Settings: appSettings Vs. ApplicationSettings

Basically there are two WAYs to define settings for a C# Application:

Manually update the app.config xml file (and access the properties via ConfigurationManager.AppSettings["key1"]; )


<appSettings>
 <add key="key1" value="value1"/>
 <add key="key2" value="value2"/>
</appSettings>

Or you can Select your Project, then Properties and Settings:

( access the properties in the code with Properties.Settings.Default.TestEnvironment)

<applicationSettings>
    <Projectname.Properties.Settings>
        <setting name="TestEnvironment" serializeAs="String">
            <value>True</value>
        </setting>
    </Projectname.Properties.Settings>
</applicationSettings>
References:

Thursday, November 22, 2018

Get the list of filenames in a folder

1) Open PowerShell
2) Navigate to the folder which content you wanna export
3) Type & Enter this command :

Get-Childitem -PAth . > C:\path\where\to\store\the\file\filenames.txt

That's it!


Wednesday, August 22, 2018

ORACLE PL/SQL ... if dbms_output.put_line('Hello World'); does not work...

If  dbms_output.put_line('Hello World'); in your PL/SQL script does not work, you probably forgot to activate the output in your SQLPLUS.exe or SQL Developer!


To activate the output, enter the following command:


set serveroutput on


Now you can execute your function/procedure:



begin
dbms_output.put_line('Hello World');
end;
/


Sunday, April 15, 2018

C#: A Linear Regression example with the NelderMead solver from Microsoft Solver Foundation (MSF)


Given that you installed the Microsoft Solver Foundation (msdn.microsoft.com)
and referenced the MSF dll (Microsoft.Solver.Foundation.dll) in your VisualStudio Project here is a simple code to test the NonLinear solver (aka NelderMead solver)  that ships with the library.

I hope Microsoft will revive this nice library in the future (at the moment the project is abandoned :( )

// here is the code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;
using Microsoft.SolverFoundation.Solvers;

namespace LinearRegressionMSF
{
    class Program
    {

    // We want to get a this line's coefficients back: y = 11.22*x + 77.99
   
        static double[] xData = new double[] { 0, 1, 2, 3, 4, 5, 6, 7 };
        static double[] yData = new double[] { 0 * 11.22 + 77.99, 1 * 11.22 + 77.99, 2 * 11.22 + 77.99, 3 * 11.22 + 77.99, 4 * 11.22 + 77.99, 5 * 11.22 + 77.99, 6 * 11.22 + 77.99, 7 * 11.22 + 77.99 };


        static void Main(string[] args)
        {

            LinearRegressionWithNelderMeadSolver();

            Console.ReadKey();
        }



        private static void LinearRegressionWithNelderMeadSolver()
        {
            // initial values for the two parameters
            double[] pInitial = new double[] { 1, 1 };
           
            // lower and upper limits for the two paramenters           
            double[] pLower = new double[] { -100, -100 };
            double[] pUpper = new double[] { 100, 100 };

            var solution = NelderMeadSolver.Solve(SumOfSquares, pInitial, pLower, pUpper);

            Console.WriteLine(solution.Result);
            Console.WriteLine("solution = {0}", solution.GetSolutionValue(0));
            Console.WriteLine("x = {0}", solution.GetValue(1));
            Console.WriteLine("y = {0}", solution.GetValue(2));
        }


        private static double SumOfSquares(double[] p)
        {
            double q = p[0];
            double m = p[1];

            double dSumOfSquares = 0;

            for (int i = 0; i < xData.Length; ++i)
            {
                dSumOfSquares += Math.Pow(yData[i] - m * xData[i] - q, 2);
            }

            return dSumOfSquares;
        }
    }

}

Monday, March 12, 2018

Entity Framework: Model successfully updated but changes are not available in code

I lost quite some time on this annoying issue that sometimes affects my VisualStudio 2015 with the Devart Oracle Driver for using Entity Framework.

My changes in the database (for example a modification of a view) were reflected ONLY in the entity framework model (after selecting the usual Update Model from Database...) but the modified classes WERE NOT available in the code!

The solution is very simple: "Run Custom Tool"

Select your model file (the one with extension with .edml), right click an choose "Run Custom Tool".

Now the changes to your database are available in your code too.

Source:

https://blog.jongallant.com/2012/08/entity-framework-manual-update/