0% found this document useful (0 votes)
323 views

Using Matlab From A C#

- The document discusses how to use Matlab from a C# application by creating a Matlab COM server instance and calling Matlab functions. - Simple examples are provided to execute Matlab commands from C# and retrieve the results, including passing matrices between Matlab and C#. - Tips are included on handling different data types returned from Matlab like empty matrices, and managing Matlab instances to avoid memory leaks.

Uploaded by

Saurav Keshri
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
323 views

Using Matlab From A C#

- The document discusses how to use Matlab from a C# application by creating a Matlab COM server instance and calling Matlab functions. - Simple examples are provided to execute Matlab commands from C# and retrieve the results, including passing matrices between Matlab and C#. - Tips are included on handling different data types returned from Matlab like empty matrices, and managing Matlab instances to avoid memory leaks.

Uploaded by

Saurav Keshri
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 10

Using Matlab from a C# application.

During writing application for my Masters degree diploma I wrote simple application that
was using COM Matlab server. I have found hard to using it mainly to lack of
documentation, which is really basic with only few code examples for C#. I guess
writing programs that use Matlab for calculating is not encouraged by MathWorks, you
would became competition that way
. Nonetheless I accomplished why I have
required to do so I decided to share this with rest of the world.
Important: I was using R2010a version of Matlab. I realize that there is newer version.
But I had only this version at my disposal. Since interface for communicating with
Matlab server is dependent of installed Matlab version and registry entries it may have
been different with yours. But I suspect not to much. I also tries with 7.1 and (if I
remember correctly) it required only to swap reference in Visual Studio. But again... it
was only test so there might be other problems that I am not aware of.
Let's start with simple console application. Lets call it MatlabTest. First we will add dll
reference with COM interface. Click RMB on project and choose [Add Reference] option.
In new window click COM tab. In search text box write 'Matlab'. Then choose "Matlab
Application (Version 7.10) Type Library".
You should get new reference like below:

Great. Now we should test if it is working. In order to use it we should create our Matlab
server from C# application. To that we can add code to our main program:
Hide Copy Code

var activationContext = Type.GetTypeFromProgID("matlab.application.single");


var matlab = (MLApp.MLApp)Activator.CreateInstance(activationContext);
Console.WriteLine(matlab.Execute("1+2"));
Console.ReadKey();

This code will create single Matlab COM server through Activator class. Program Id
"matlab.application.single" means single Matlab COM server for our application. When it
will try to create another Matlab, it will just return reference to the same object.

Contrary to that we could use "matlab.application" which will create another instance of
Matlab any time Activator.CreateIntance method will be executed. In more complex
applications or for web applications or other programs which run for long time it may
creates big memory leaks since 1 instance cost around 220 Mb (on 64 bit Windows 7
and Matlab R2010a).
After creating Matlab program execute simple sum of 2 integers, just for test of
communication we don't need anything more sophisticated. It should return also simple
string in console:

It's really simple and more important it works!


This way we can send and receive string messages with MATLAB only. It's not much
useful. Also there is one way to find out if our statement had errors. It will have 'error'
string in response.
Let's try to run something like this: '1*', which will result in error:

So to check our command had errors we have to check if output string have "??? Error"
in it.
To send some parameters along with our command we have to use on of 'Put*' methods.
Best is one calledPutWorkspaceData. It takes three parameters. First is desired name of
our new Matlab variable. Two other are much more tricky. To set variable correctly (so
you could reference it in command) you must use global workspace. But it is called?
This one took much more time then I would want. It is not mentioned in documentation
of this method. If I remember it right I found it in some code example and it should be
only "base". In the end I created in my application another method that
encapsulated PutWorkspaceData and forget about it
. Third parameter is value of our
variable. It should be simple. Let's change our code to:

Hide Copy Code

matlab.PutWorkspaceData("a", "base", 2);


Console.WriteLine(matlab.Execute("a*a"));

Result will as below:

But it is just int. What about more complicated structures? How about multiplication of
two vectors? Matlab is using .NET type double to send and receive information with our
application. Again I did not find it anywhere in documentation, but rather reverse
engineered this from data returned from Matlab.So let us try send 2 arrays of doubles.
and multiplicate them in Matlab. First will be named 'a' and second 'b'. Matlab command
will be "a'*b". Transposition will give us nice matrix instead for single number.
Hide Copy Code

matlab.PutWorkspaceData("a", "base", new[]{2d,3d,1d});


matlab.PutWorkspaceData("b", "base", new[]{4d,3d,2d});
Console.WriteLine(matlab.Execute("a'*b"));

And in return we will get:

Next step will be to return this output to our console app. To do that we can
use GetWorkspaceData that works similar to PutWorkspaceData or... we can
use GetVariable method. This one returns dynamic so our application needs to run
on .NET 4. It takes to parameters name of variable we want to return from Matlab and
again name of workspace. You really should save this string as const somewhere
Change our code to:

Hide Copy Code

matlab.PutWorkspaceData("a", "base", new[]{2d,3d,1d});


matlab.PutWorkspaceData("b", "base", new[]{4d,3d,2d});
Console.WriteLine(matlab.Execute("c=a'*b"));
var c = matlab.GetVariable("c", "base");

After that in our console app we will have variable c and it will be two dimensional array
of doubles. To show values of this array in console we can just iterate it with
simple foreach loop. But instead that we will iterate two of the dimensions. This will give
us info about values and dimensions of this matrix.
Hide Copy Code

for (var i = 0; i < c.GetLength(0); i++)


{
for (var j = 0; j < c.GetLength(1); j++)
Console.Write(c.GetValue(i, j) + " ");
Console.WriteLine();
}

Ok.That was matrix. How about vectors? Luckily vectors are for Matlab just special case
of matrix so it will spit out two dimensional array also. More complex is case of empty
matrix. No it is not null. It would be to easy. Instead it is special type Missing. I guess it
have some logic behind. Null would indicate that variable have no value at all or this is
not defined. But we have empty matrix so this is not defined nor this is lack of value. So
why not just array with zero values in it? No idea.
Lets try run code like below to test it:
Hide Copy Code

Console.WriteLine(matlab.Execute("c=a'*b"));
Console.WriteLine(matlab.Execute("d=[]"));
var c = matlab.GetVariable("c", "base");
var d = matlab.GetVariable("d", "base");
for (var i = 0; i < d.GetLength(0); i++)
{
for (var j = 0; j < d.GetLength(1); j++)
Console.Write(d.GetValue(i, j) + " ");
Console.WriteLine();
}

Running those command in Matlab will work just fine. Instead of that error will be
throwed on first for loop:

Not very nice. To prevent this errors application have to check if dynamic type returned
from matlab is in fact empty (Missing). Not very clean it is better to wrap this in other
method that will perform this check for us whenever we want to get our data from
Matlab. In my project I ended up writing few methods for returning vectors, matrices,
numbers, strings etc. Vector one looked like this:
Hide Copy Code

public static Vector GetVector(this MLApp.MLApp matlabComObject, string variabla_name)


{
var dynamicVariable = matlabComObject.GetBaseWorkSpaceVariable(variabla_name);
var dataList = new Vector();
if (TypeChecker.IsVector(dynamicVariable))
{
dataList = Vector.DynamicToVector(dynamicVariable);
}
else if (TypeChecker.IsNumber(dynamicVariable))
{
dataList.Add(dynamicVariable);
}
else if (TypeChecker.IsEmptyMatrix(dynamicVariable))
{
//do nothing empty vector or matrix ([0x0] or [1x0])
}
else throw new Exception(string.Format(
"Type of dynamic variable ({0}) is not supproted!", dynamicVariable.GetType()));
return dataList;
}

TypeCheker checks for type of dynamic. It's pretty straightforward. For our Missing type
it's just one line:
Hide Copy Code

public static bool IsEmptyMatrix(object dynamicVariable)


{ return dynamicVariable.GetType() == typeof(Missing); }

After checking type of dynamic we can just cast it to another type to take advantage of
static properties of language. Why use dynamic at all? First I think that ref and out
method parameters are messy and second: I prefer
Hide Copy Code

var d = matlab.GetVariable("d", "base");

from
Hide Copy Code

object e;
matlab.GetWorkspaceData("d", "base", out e);

It is only 1 line. And since object you have to create first and then cast it also don't
bother and just use dynamic. But I guess it is just what will you like better.
String are much more friendly and there are just string. Or null.
Now we know how to put and get data from Matlab. How to execute commands and
check them for errors.
If you executed any of these example you probably take notice of very simple Matlab
window which have opened during life of your console app. If you terminate it by
disabling debugging or it will close due to error, Matlab window will remain opened. If
not it will close nicely with console window. But still it huge memory leak risk if no
maintained properly. To that I recommend creating some special class that will create
instance or instances of Matlab. It should track or of created instances and in case
anything bad happens (but dynamic variable cast is probability
) it will close all
instances prior of application exit. Tracking should be employed
throughWeakReference class, so whenever Garbage Collector would want to destroy
Matlab instance it should not be stopped by our tracking class. To destroy COM instance
we can use methodMarshal.FinalReleaseComObject. So with weak reference code for
that will look like this:
Hide Copy Code

public static void Release(WeakReference instance)


{
if (instance.IsAlive)
{
Marshal.FinalReleaseComObject(instance.Target);
}
}

Method Quit of matlab server instance does not close it immediately and code above
will.
If you want to hide that popup Matlab window you can set this in it's instance:
Hide Copy Code

matlab.Visible = 0;

This way it will fade away and run as service.


This most basic info about Matlab in C#, but it will get you started. So happy coding.

There is nice example in the MATLAB Central.


It shows three ways on how to communicate with MATLAB:
1.
COM
2.

MATLAB .NET Bulider

3.

MATLAB compiler

COM (I do not have any experience with it)


Cons: MATLAB is required to be installed on the target computer.
MATLAB .NET builder compiles your MATLAB code to the .NET assembly and you can
use it directly.
Pros: MATLAB is not required to be installed on the target computer
Cons: It's expensive
MATLAB compiler compiles your MATLAB code into a C/C++ library or EXE file. You can
use it through P/Invoke.
Pros: MATLAB is not required to be installed on the target computer
Cons: It's expensive, a lot of P/Invoke.

Yes, this is possible. For details, take a look at:

Calling a MATLAB function from C#

Integrating MATLAB with C#


MATLAB Compiler

If you need a quick and dirty way to wrap MATLAB code with a C# GUI (e.g. WinForms), one
option is to create an exe from your MATLAB code (.m) - from .NET, you can then easily start this
exe as a new process. Note that this approach may not be the best in some situations, beacuse the
delay introduced with an exe call can be quite substantial (as the other answer explains).
An example: first, write MATLAB code as a function:
function y=SamplePlot(p, d, w, t)
numericValueP=str2num(p);
numericValueD=str2num(d);
numericValueW=str2num(w);
time=str2num(t);
%... do stuff ...
plot(...);

Input parameters will be passed to this code as string parameters via command line, hence they are
converted via str2num. E.g. a MATLAB call
SamplePlot('1', '2', '3', '4')

will be represented as
SamplePlot.exe 1 2 3 4

Now, create a standalone console app from .m file: in MATLAB console, write:
deploytool

Name: SamplePlot.prj (for example). Target: Console application. Add .m file. Package: add MCR
(this is MATLAB Compiler Runtime - this is what an end-user will need if he doesn't have MATLAB
installed; for local testing, you don't need to add this). Then use:
mbuild -setup

Finally, click 'build' icon. After some time, an exe is generated. Now, you can start this exe as a
process from a C# application, e.g. on button click:
private void button1_Click(object sender, EventArgs e)
{
string p=TextBox1.Text;
string d=TextBox2.Text;
string w=TextBox3.Text;
string t=TextBox4.Text;
string params = String.Format("{0} {1} {2} {3}",p,d,w,t);
System.Diagnostics.Process.Start("SamplePlot.exe", params);

I left out some minor details, but this is one possible option.
(If I recall correctly, an assembly can be generated this way as well; you can then call the assembly
instead of an exe file).
shareimprove this answer

edited Sep 10 '13 at


20:15

answered Sep 10 '13 at


19:10

w128
1,0472826

1 MATLAB has a product (MATLAB Builder NE) built on top of


generate .NET assemblies: mathworks.com/products/netbu
files, you could use the generated assembly as any other .
dependent on the MCR Amro Sep 11 '13 at 2:12
add a comment

up
vote1do
wn vote

I'm pretty unfamiliar with C# but eventually happened to use .NET classes from
MATLAB.
So, you could also do it the other way round, than the previous answers suggest:
Since MATLAB is able to create/open .NET gui-elements like dialog, I guess you
should also be able to open your .NET-GUI from MATLAB an then plug in your
MATLAB-Code via Callbacks. See
e.g.:http://www.mathworks.de/de/help/matlab/matlab_external/getting-started-withnet.html
Depending on how frequently you want to execute matlab-code from your gui and how
long the matlab-processing time usually is, this also avoids the pretty large overhead
that's e.g. introduced by using a .exe generated with the MATLAB compiler. Say, you'd
like to do quick matrix-calculation operations taking less than a second with every other
button-click, than starting a standalone.exe everytime would make your gui pretty

useless.

You might also like