Search code examples
javamatlabmatlab-deployment

Error using eval in matlabcontrol


I used MatlabConrol to connect Java and MATLAB. I want to send an image path to MATLAB to process it with matching functions and give me back a number of similar images and paths, to show in the Java GUI.

I always get the same error when passing an image path to MATLAB:

Error using eval
Undefined function 'getinput' for input arguments of type 'char'.

Here's my MATLAB function:

function matlab = getinput(input)
results = hgr(input);

And my Java code:

imag = ImageIO.read(fileChoose.getSelectedFile());
ImagePath = fileChoose.getSelectedFile().getAbsolutePath();

public void SendingMatlabControl() throws MatlabConnectionException,
  MatlabInvocationException {
  // create proxy
  MatlabProxy proxy;
  // Create a proxy, which we will use to control MATLAB
  MatlabProxyFactory factory = new MatlabProxyFactory();
  proxy = factory.getProxy();
  // Display 'hello world' like before, but this time using feval
    try {
      // call builtin function
      proxy.eval("getinput('imagepath')");
      // call user-defined function (must be on the path)
      proxy.eval("addpath('E:\\vm')");
      proxy.feval("matlab");
      proxy.eval("rmpath('E:\\vm)");
    } catch (MatlabInvocationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    // Disconnect the proxy from MatLab
    proxy.disconnect();
  }

Solution

  • Let me give an example of calling a function, passing it input, and retrieving the output. There are two ways, either:

    • use eval and assign the result of the function inside the MATLAB workspace, then retrieve those variables using getVariable, or
    • use returningFeval to evaluate the function with its inputs, and directly retrieve the output.

    Suppose we had a MATLAB function myfunc.m that takes a string as input, and returns a cell array containing a string, a number, and a vector:

    function out = myfunc(str)
        out = cell(3,1);
        out{1} = sprintf('Welcome to %s!', str);
        out{2} = 99;
        out{3} = rand(10,1);
    end
    

    Here is the Java code:

    import matlabcontrol.*;
    
    public class TestMyFunc
    {
        public static void main(String[] args)
            throws MatlabConnectionException, MatlabInvocationException
        {
            // create proxy
             MatlabProxyFactoryOptions options =
                new MatlabProxyFactoryOptions.Builder()
                    .setUsePreviouslyControlledSession(true).build();
            MatlabProxyFactory factory = new MatlabProxyFactory(options);
            MatlabProxy proxy = factory.getProxy();
    
            // call function and get output cell array
            String in = "Stack Overflow";
            Object[] out = proxy.returningFeval("myfunc", 1, in);
    
            // extract stuff from cell array
            out = (Object[]) out[0];
            String str = (String) out[0];
            double x = ((double[]) out[1])[0];
            double[] arr = (double[]) out[2];
    
            // show result
            System.out.println("str =\n " + str);
            System.out.println("x = \n " + x);
            System.out.println("arr =");
            for(int i=0; i < arr.length; i++) {
                System.out.println(" " + arr[i]);
            }
    
            // shutdown MATLAB
            //proxy.feval("quit");
    
            // close connection
            proxy.disconnect();
        }
    }
    

    I get the output:

    str =
     Welcome to Stack Overflow!
    x =
     99.0
    arr =
     0.5974901918725793
     0.3353113307052461
     0.29922502333310663
     0.45259254156932405
     0.42264565322046244
     0.35960631797223563
     0.5583191998692971
     0.7425453657019391
     0.42433478362569066
     0.42935578857620504