*Once again I would like to welcome guest blogger Joshua Kaplan, who continues his series of JMI-related articles*

### Local and remote MatlabControl

Several weeks ago, I discussed the undocumented world of JMI (Java-to-Matlab Interface), that enables calling Matlab from Java. Today I will discuss matlabcontrol, an open-source wrapper I have written for JMI, that is both documented and user-friendly.

*matlabcontrol* supports calling Matlab in two different ways: local control where the Java code is launched from Matlab, and remote control where the Java code launches Matlab. Today we shall explore *matlabcontrol*‘s local control methods; in my next post we’ll create a simple Java program that uses *matlabcontrol* for local control; a later post will discuss the remote control path. These posts assume a medium to high level of Java experience.

*matlabcontrol* is a collection of Java classes, bundled together in a downloadable jar file, which is essentially just a zip file with a different file extension. As of this post the most recent version is matlabcontrol-3.01.jar. Note down where you’ve downloaded the jar file – you’ll need to use this information shortly.

For local control we’ll interact with the classes *LocalMatlabProxy* and *MatlabInvocationException*. *LocalMatlabProxy* contains all the methods required for calling Matlab; instances of *MatlabInvocationException* will be thrown when a problem occurs while attempting to control Matlab.

To tell Matlab where matlabcontrol-3.01.jar is, add the jar file path to Matlab’s dynamic (via the built-in * javaaddpath* function) or static (via

*) Java classpath. You will need to restart Matlab if you have modified the static classpath, but it has the benefit of working better than the dynamic classpath in some situations.*

**edit**(‘classpath.txt’)Matlab now knows where to find the Java class files in

*matlabcontrol*. To save some typing later on, type the following in the Matlab Command Window (or in your JMI-empowered Matlab application):

import matlabcontrol.* |

### LocalMatlabProxy methods

*LocalMatlabProxy* is easy to use. All of its methods are static meaning they can be called without needing to assign *LocalMatlabProxy* to a variable. The methods are:

void exit() java.lang.Object getVariable(java.lang.String variableName) void setVariable(java.lang.String variableName, java.lang.Object value) void eval(java.lang.String command) java.lang.Object returningEval(java.lang.String command, int returnCount) void feval(java.lang.String functionName, java.lang.Object[] args) java.lang.Object returningFeval(java.lang.String functionName, java.lang.Object[] args) java.lang.Object returningFeval(java.lang.String functionName, java.lang.Object[] args, int returnCount) void setEchoEval(boolean echoFlag) |

Detailed javadocs exist for all these methods. Here is an overview:

*exit()*is as straightforward as it sounds: it will exit Matlab. While it is possible to programmatically exit Matlab by other means, they may be unreliable. So, to exit Matlab from Java:LocalMatlabProxy.exit();

- Setting and getting variables can be done using the
*getVariable(…)*and*setVariable(…)*methods. These methods will auto-convert between Java and Matlab types where applicable.

Using*getVariable(…)*:- Java types in the Matlab environment retrieved will be returned as Java types.
- Matlab types will be converted into Java types.

Using

*setVariable(…)*:- Java types will be converted into Matlab types if they can. The rules are outlined here. Java Strings are converted to Matlab char arrays. Additionally, arrays of one of those Java types are converted to arrays of the corresponding Matlab type.

Using these methods is fairly intuitive:

>> LocalMatlabProxy.setVariable('x',5) >> LocalMatlabProxy.getVariable('x') ans = 5

Getting and setting basic types (numbers, strings and Java objects) is quite reliable and consistent. It gets complicated when passing in an array (particularly multidimensional) from Java using

*setVariable(…)*, or getting a Matlab struct or cell array using*getVariable(…)*. The type conversion in such cases is unpredictable, and may be inconsistent across Matlab versions. In such cases you are best off building a Java object with Matlab code and then getting the Java object you created. - The
*eval()*and*feval()*methods were described in detail in my previous post. The functions will return the result, if any, as a Java object. Due to the way the underlying JMI operates, it is necessary to know in advance the number of expected return arguments. Matlab built-infunction reveals this number. Some functions (e.g.,**nargout**) return a variable number of arguments, in which case**feval**returns -1. For instance:**nargout**>> nargout sqrt ans = 1 >> nargout feval ans = -1

*LocalMatlabProxy*‘s*returningFeval(functionName, args)*method uses theinformation to determine the number of returned arguments and provide it to JMI. It will likely not function as expected if the function specified by functionName returns a variable number of arguments. In such a case, call**nargout***returningFeval(…)*with a third input argument that specifies the expected number of returned arguments. Since an*eval()*function can evaluate anything, just as if it were typed in the Command Window, there is no reliable way to determine what will be returned. All of this said, in most situations*returningEval(…)*can be used with a return count of 1, and the*returningFeval(…)*that automatically determines the return count will operate as expected.

### Some simple usage examples

Let’s perform some of the same simple square root operations we did in the pure-JMI article, this time using *matlabcontrol*. First we’ll take the square root of 5, assigning the result to the Matlab variable y (note that we are calling Matlab from Java, that is called from within Matlab):

>> LocalMatlabProxy.eval('sqrt(5)') ans = 2.2361 >> y = LocalMatlabProxy.returningEval('sqrt(5)',1) y = 2.2361 >> LocalMatlabProxy.feval('sqrt',5) >> y = LocalMatlabProxy.returningFeval('sqrt',5) y = 2.2361 >> y = LocalMatlabProxy.returningFeval('sqrt',5,1) y = 2.2361 |

In this situation there is no major difference between using *eval()* or *feval()* in the above situation. However, if instead of taking the square root of 5 we want to take the square root of a variable, then *eval()* is our only option.

>> a = 5 a = 5 >> LocalMatlabProxy.eval('sqrt(a)') ans = 2.2361 >> y = LocalMatlabProxy.returningEval('sqrt(a)',1) y = 2.2361 >> LocalMatlabProxy.feval('sqrt','a') ??? Undefined function or method 'sqrt' for input arguments of type 'char'. ??? Java exception occurred: matlabcontrol.MatlabInvocationException: Method could not return a value because of an internal Matlab exception at matlabcontrol.JMIWrapper.returningFeval(JMIWrapper.java:256) at matlabcontrol.JMIWrapper.feval(JMIWrapper.java:210) at matlabcontrol.LocalMatlabProxy.feval(LocalMatlabProxy.java:132) Caused by: com.mathworks.jmi.MatlabException: Undefined function or method 'sqrt' for input arguments of type 'char'. at com.mathworks.jmi.NativeMatlab.SendMatlabMessage(Native Method) at com.mathworks.jmi.NativeMatlab.sendMatlabMessage(NativeMatlab.java:212) at com.mathworks.jmi.MatlabLooper.sendMatlabMessage(MatlabLooper.java:121) at com.mathworks.jmi.Matlab.mtFevalConsoleOutput(Matlab.java:1511) at matlabcontrol.JMIWrapper.returningFeval(JMIWrapper.java:252) ... 2 more |

The automatic Matlab/Java type conversions discussed above are equally applicable to *eval()* and *feval()*. *feval()* automatically converted the argument ‘a’ into a Matlab char, instead of considering it as a Matlab variable. As seen above, the *feval()* invocation fails with a Java *MatlabInvocationException*. So, the only way to interact with Matlab variables is via *eval()* methods; *feval()* will not work.

Lastly there is the *setEchoEval(echoFlag)* method: If this method is called with a *true* argument, then all Java to Matlab calls will be logged in a dedicated window. This can be very helpful for debugging.

In my next post we shall put together this knowledge to create a small Java program that uses *matlabcontrol* to interact with Matlab.

hey, i wanted to use the ‘

‘ command available in matlab in my java program. Can you tell me which package i should use for it?plot@Laksmi – take a look at the next article in the JMI series for an explanation on how to use the MatlabControl package to activate Matlab commands from within your Java code.

Hi,

I disagree with the: “only way to interact with Matlab variables is via eval() methods; feval() will not work” . I think that it can be made with feval way too, its more code but functional:

@georgeek – your example just illustrated the point that you need to use

… 🙂evalHi Yair

I tried both(dynamic using JAVAADDPATH and static editing classpath.ext) ways of adding matlabcontrol-4.0.0.jar file but still matlab throws following error

??? Undefined variable “LocalMatlabProxy”

Please help me to resolve above error , I’m using matlab R2007a version

Hi,

could you post an example, how to get/set cell and struct arrays with matlabcontrol library form remote java code?

for example i have a 1×1 struct array variable S in workspace (marker: ‘p’, value: 80, factor: ‘0.001’, unit: ‘mm’) and want to get it

thanks, Vlad