Message Boards Message Boards

14
|
29525 Views
|
21 Replies
|
33 Total Likes
View groups...
Share
Share this post:

Seamlessly call MATLAB from Mathematica

Posted 12 years ago
Disclaimer: I am one of the MATLink developers.

Some of you have already seen it, but for those that haven't, I would like to present the MATLink package available at matlink.org:



This package makes it possible to transfer data between Mathematica and MATLAB as well as seamlessly call MATLAB functions from Mathematica.  Some example applications are shown as http://matlink.org/examples/

As of version 1.0, the package can:
  • Transfer data (variables) between the two systems in both directions.  Most MATLAB data structures are supported, including sparse arrays, cells and structs.
  • Wrap MATLAB functions in the MFunction head and call them directly.  Arguments and return values are translated automatically.
  • It works on all three common platforms (Windows, Mac, Linux).
Note that version 1.0 does not make it possible to call Mathematica functions from MATLAB, only the reverse.  It is useful if Mathematica is your primary work environment but you need to use some MATLAB functionality in your Mathematica code.

Here's a transcript of a short MATLink session as a deomonstration:

 
 In[1]:= << MATLink`
 
 In[2]:= OpenMATLAB[] (* start MATLAB *)
 
 In[3]:= mat = RandomReal[1, {5, 5}]; (* create random matrix *)
 
 In[4]:= MEvaluate["help eig"] (* get help on the eig() MATLAB function *)
 
Out[4]= ">> EIG Eigenvalues and eigenvectors.
    E = EIG(X) is a vector containing the eigenvalues of a square 
    matrix X.  
    ...
"

In[5]:= MFunction["eig"][mat] (* calculate eigenvalues using MATLAB *)
Out[5]= {{2.62592 + 0. I}, {-0.0575 + 0.555101 I}, {-0.0575 - 0.555101 I}, {0.558724 + 0. I}, {0.128974 + 0. I}}

In[6]:= Sort@Flatten[%] == Sort@Eigenvalues[mat] (* check that the result is the same that Mathematica gives *)
Out[6]= True
POSTED BY: Szabolcs Horvát
21 Replies

Kudos to all developers! This is very useful for folks who have access to both systems.

POSTED BY: Matthias Odisio
Posted 11 years ago

I personally would find the capability of single line input in a command window quite useful (although command recall would be highly desirable), but can't speak for others as my use of Matlab and Mathematica may not conform to the way most people use these programs. I sometimes use Matlab almost like a highly capable calculator where I enter commands on the command line and use the results of a command to decide the next command to enter. I often use the Mathematica the same way until I have decided how to proceed to solve a problem. This way of operating, of course, is possible without the command window but each command would need to be quoted and wrapped with an MEvaluate which requires extra typing.

POSTED BY: Mike Luntz

Well, it all comes down to having to implement the command window in pure MATLAB and preferably without using undocumented features.

If anyone has ideas or suggestions on how to do this and come up with a useful and usable command window, please email me.

POSTED BY: Szabolcs Horvát
Posted 11 years ago

Thanks for your explanation of the situation. I have found the command window pretty useful in Windows and was disappointed that it wasn't available on the Mac. I would like to encourage you to pursue the approach you describe in your discussion of v2 should that be possible. Directly performing a Matlab calculation in a Matlab window will usually be easier for a user to input than using MScript and/or MEvaluate.

POSTED BY: Mike Luntz

Good to hear that you found the command window useful. I wasn't sure anyone was using it at all, as it's much more limited than the standard MATLAB command window which has syntax colouring, auto-completion, command recall, etc.

Does that mean that you'd find a command window without these features (without command recall, auto-completion, or even multi-line input) useful too? It may be possible to implement something in terms of input. Try e.g. waitInput=1;while waitInput; cmd=input('> ', 's'); eval(cmd); end in MATLAB. I assumed that something like this is so limited that it is simply not useful.

POSTED BY: Szabolcs Horvát
Posted 11 years ago

Is problem with CommandWindow not being available on OSX a fundamental problem with the way OSX works or is it just something that hasn't yet been implemented?

POSTED BY: Mike Luntz

The command window is a feature of the MATLAB Engine API that is only available on Windows. The Engine API has a different implementation on Windows and Mac/Linux.

Unfortunately the Mac/Linux implementations are not high quality (lots of bugs, stuff breaking with new release, worse performance than Windows). For this reason MATLink 2 will switch to using the MEX API, which means that the command window functionality will be removed even from the Windows version.

So, to sum it up: the command window will not be coming to Mac.

I spent some time on this and unfortunately I haven't found a reasonable way to have an actually useful command window when using the MEX API. MATLAB is single threaded and once an evaluation has started, it's not possible to use the command window to queue additional evaluations. What may be eventually possible in v2 is to start MATLAB separately, then manually connect it to Mathematica for use through MATLink, then disconnect it again and keep working normally in the MATLAB command prompt.

POSTED BY: Szabolcs Horvát
Posted 11 years ago

Thanks for the help. Based on Ravi's recommendation I gave MATLink a try. I am happy to report that, at least for the simple first couple of commands in the "Getting Started" section of the web site, MATLink appears to work with Matlab2008b. Should I encounter any compatibility problems between MATLink and this old version of Matlab would you like for me to report it and, if so, should it be reported in this conversation?

One additional question: Do I need the

SetOptions[MATLink, "Force32BitEngine" -> True]

command each time I load MATLink or, as Ravi seemed to indicate, only once?

POSTED BY: Mike Luntz

This needs to be done only once, and the setting will be remembered across sessions. To verify this, you can retrieve the setting (after loading MATLink) using

Options[MATLink, "Force32BitEngine"]
POSTED BY: Szabolcs Horvát
Posted 11 years ago

Thanks for the quick response to my question. I am currently using Matlab R2008b and Mathematica 10.0.1 on a Windows 7 computer. But I am considering a switch to a Mac and when I do that I will transfer the Mathematica license and upgrade Matlab.

POSTED BY: Mike Luntz
Posted 11 years ago

The earliest version we ourselves tested extensively was R2012b as listed here. We've had users report that it works with R2012a, R2011a,b, R2010a and R2009b (Given this, I'm confident it works for the unreported in-between versions as well).

While I can't say for sure that it'll work in R2008b, there's a good chance it will. It is also quite likely that it is a 32 bit version of MATLAB with a 64 bit OS and 64 bit Mathematica. In this case, you will have to start MATLink as follows the first time:

Needs["MATLink`"]
SetOptions[MATLink, "Force32BitEngine" -> True]

I you can upgrade your MATLAB, I would highly recommend doing so. Please note that there is a bug in R2014a which causes MATLink to not work properly on OS X. This is fixed in R2014b.

POSTED BY: R Menon
Posted 11 years ago

I have a list in Mathematica of the form

lis= {{1,"abcd"},{2,"ef"},{3,"xyzwabc"}}

and I am wondering if MATLink would be capable of transferring this list to Matlab as a cell array and, if so, how would I do the transfer. I unfortunately do not currently have a new enough version of Matlab to use MATLink or I would try it to see if it worked.

POSTED BY: Mike Luntz

Yes, this is possible and happens automatically. Numerical arrays are by default transferred as matrices. Non-homogeneous arrays or arrays with non-numeric types are transferred as cells.

This transfers as a matrix:

In[12]:= MSet["a", {1, 2, 3}]

In[13]:= MEvaluate["a"]

Out[13]= ">> 
a =

     1     2     3

"

This transfers as a cell:

In[14]:= MSet["a", {1, 2, "asd"}]

In[15]:= MEvaluate["a"]

Out[15]= ">> 
a = 

    [1]    [2]    'asd'

"

Force a numerical array to transfer as a cell:

In[16]:= MSet["a", MCell[{1, 2, 3}]]

In[17]:= MEvaluate["a"]

Out[17]= ">> 
a = 

    [1]    [2]    [3]

"

(This is usually useful when we want to have a cell, each element of which is a matrix.)

Your array:

In[18]:= lis = {{1, "abcd"}, {2, "ef"}, {3, "xyzwabc"}}

Out[18]= {{1, "abcd"}, {2, "ef"}, {3, "xyzwabc"}}

In[19]:= MSet["lis", lis]

In[20]:= MEvaluate["lis"]

Out[20]= ">> 
lis = 

    {1x2 cell}    {1x2 cell}    {1x2 cell}

"

MATLink is geared towards one-dimensional cells, so this transfers as a cell of cells, not as a 2D cell. If you need a 2D cell, you'd need to change the data structure on the MATLAB side.

My internet connection is very limited at the moment, so I might not be able to respond to further questions right away (but I'll surely get to them in a couple of days).

POSTED BY: Szabolcs Horvát

I unfortunately do not currently have a new enough version of Matlab to use MATLink or I would try it to see if it worked.

What version of MATLAB do you have and what operating system are you using?

POSTED BY: Szabolcs Horvát

Can I use CVX in MATLAB through MATLink?

http://cvxr.com/cvx/

POSTED BY: Frank Kampas

I am not familiar with CVX, so I do not know.

Things that might prevent you from using it:

  1. Does it rely on callbacks to Mathematica? E.g. would you need to pass a function implemented in Mathematica to it? That is not supported at the moment.

  2. Would it require transferring MATLAB objects (i.e. classes) between MATLAB and Mathematica? This isn't supported either, but structs do work (you can convert the class to a struct first). All major datatypes are supported except classes, function handles and certain rarely used integer types. (We can add support for these integer types on request).

  3. Does it require a very large number of calls to MATLAB? There is an overhead to each call so this might be slow.

If none of these apply then you should be able to use MATLink with CVX.

Point 1. will eventually be dealt with in MATLink 2.x (not 2.0). Point 3: the overhead will be significantly reduced in MATLink 2.0. Point 2 might be partially dealt with in MATLink 2.0, but full support for bi-direction transfer of arbitrary classes is unlikely.

Now if only I had time to work on version 2 ... My job doesn't leave much time for it these days.

POSTED BY: Szabolcs Horvát
Posted 11 years ago

You can definitely use MATLink with CVX or any other toolbox for that matter! The only constraint is that the quantities you transfer back to Mathematica should be ones that are supported by MATLink. (As a fun fact, my personal motivation for developing MATLink with Szabolcs was so that I can use Mathematica + CVX in my research.)

The following is an example of fitting an optimal $L_?$ norm polynomial using CVX and Mathematica via MATLink. First, we setup the problem in CVX and use MEvaluate to run it on the MATLAB side (note: You will need to know how to use CVX).

MEvaluate["
    n = 6;
    m = 40;
    randn('state',0);

    % generate 50 ponts ui, vi
    u = linspace(-1,1,m);
    v = 1./(5+40*u.^2) + 0.1*u.^3 + 0.01*randn(1,m);

    A = vander(u');
    A = A(:,m-n+[1:n]);     

    % L-infty fit
    cvx_begin quiet
       variable x_inf(n)
       minimize (norm(A*x_inf - v', inf))
    cvx_end
"]

CVX is quite verbose and it is a bit more efficient to use quiet when running it via MATLink. There are other CVX global variables (starting with cvx_) that you can use to programmatically check which solver was used, whether the problem was solved or if it is infeasible, etc. rather than relying on the textual output. If you are doing active algorithm development using CVX, then it might be better to use MATLAB directly for this part and then use MATLink once you are satisfied and have frozen the routine.

Next, we transfer the optimal solution and the original quantities to Mathematica using MGet:

{u, v, A, xinf} = MGet[{"u", "v", "A", "x_inf"}];

Finally, we compute the optimal $L_2$ norm solution in Mathematica, construct the polynomial using Horner's method and plot them in Mathematica:

With[{hornerPoly = Function[{var, x}, Fold[# var + #2 &, x]]},
    Show[
        ListPlot[Transpose@{u, v}, PlotStyle -> {AbsolutePointSize[5], Gray}],
        Plot[{hornerPoly[x, x2], hornerPoly[x, xinf]}, {x, -1, 1}, Evaluated -> True,
            PlotLegends -> {"!(*SubscriptBox[(L), (2)])",  "!(*SubscriptBox[(L), ([Infinity])])"}]
    ]
]

![](http://i.stack.imgur.com/QhzzL.png)

Hope that helped!

POSTED BY: R Menon

Thanks

POSTED BY: Frank Kampas

MATLink 1.1 is now released.

This version brings full compatibility with Mathematica 10. If you use Mathematica 10, please upgrade.


Also, a warning: on Linux & OS X MATLAB R2014a has a bug which prevents MATLink from working correctly. Please do not use this version of MATLAB with MATLink on Linux or OS X. R2013b works fine, and so will R2014b when it is released (probably this September).

Windows users can use R2014a without problems.

POSTED BY: Szabolcs Horvát
In its current state MATLink does not work with Octave.

Theoretically it should be possible to adapt MATLink to work with Octave (except for a few features such as unicode support), however, Octave's licensing seems to make this inconvenient at best.  Octave is licensed under the GPL.  This means that we can't link MATLink both against Octave and the (closed source) MathLink libraries and distribute the resulting software.   At least this is what one of the Octave developers told me.

We are not planning to work on Octave support because:
  1. Octave's licensing wouldn't allow distributing compiled MATLink binaries (and at least one Octave developer made it clear that we should comply)
  2. MATLink is primarily useful because it makes it possible to call library/toolbox functions that are available in MATLAB but not Mathematica, and not because it provides access to MATLAB the language.  Octave doesn't have nearly as many tooboxes as MATLAB.  Thus it's less useful to call Octave than to call MATLAB.
  3. While theoretically Octave support is possible, it would require a non-trivial amount of work. Because of point 2. above it doesn't seem to be worth the effort.
POSTED BY: Szabolcs Horvát
Does it work with Octave?
POSTED BY: Frank Kampas
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract