Pass Java Objects to MATLAB

Purpose

The purpose of this example is to show you how to:

  • Use the MATLAB® Compiler SDK™ product to create a package that applies MATLAB optimization routines to objective functions implemented as Java® objects.

  • Access the MATLAB functions in a Java application , including use of the MWJavaObjectRef class to create a reference to a Java object and pass it to the generated Java methods.

    Note

    For complete reference information about the MWArray class hierarchy, see the com.mathworks.toolbox.javabuilder Javadoc package in matlabroot/help/toolbox/javabuilder/MWArrayAPI.

  • Build and run the application.

OptimDemo Package

  • The OptimDemo package finds a local minimum of an objective function and returns the minimal location and value.

  • The package uses the MATLAB optimization function fminsearch, and this example optimizes the Rosenbrock banana function used in the MATLAB fminsearch documentation.

  • The class, Optimizer, performs an unconstrained nonlinear optimization on an objective function implemented as a Java object.

  • A method of this class, doOptim, accepts an initial guess and Java object that implements the objective function, and returns the location and value of a local minimum.

  • The second method, displayObj, is a debugging tool that lists the characteristics of a Java object.

  • The two methods, doOptim and displayObj, encapsulate MATLAB functions. The MATLAB code for these two methods is in doOptim.m and displayObj.m, which can be found in matlabroot\toolbox\javabuilder\Examples\ObjectRefExample\ObjectRefDemoComp.

Prerequisites

  • Start this example by creating a new work folder that is visible to the MATLAB search path. In this example, we will use the following folders:

    Windows®: c:\matlab\work

    Linux®: ~/matlab/work

  • If you have not already done so, set the environment variables that are required on a development machine. For more information, see Configure Your Java Environment.

  • Copy the following files to the work folder:

    File(s)FromTo

    javabuilder.jar

    matlabroot\toolbox\javabuilder\jar\win64

    Windows: c:\matlab\work

    Linux: ~/matlab/work

    doOptim.m

    displayObj.m

    matlabroot\toolbox\javabuilder\Examples\ObjectRefExample\ObjectRefDemoComp

    Windows: c:\matlab\work

    Linux: ~/matlab/work

    BananaFunction.java

    PerformOptim.java

    matlabroot\toolbox\javabuilder\Examples\ObjectRefExample\ObjectRefDemoJavaApp

    Windows: c:\matlab\work

    Linux: ~/matlab/work

    Your work folder should now have the following five files:

    c:\matlab\work

    javabuilder.jar
    doOptim.m
    displayObj.m
    BananaFunction.java
    PerformOptim.java

Procedure

  1. Open MATLAB and cd to the work folder you created in the prerequisite section.

  2. Write the MATLAB code you want to access from Java. This example uses doOptim.m and displayObj.m, which are already in your work folder.

    For reference, the code from doOptim.m is displayed here:

    function [x,fval] = doOptim(h, x0)
    directEval = h.evaluateFunction(x0)
    wrapperEval = mWrapper(x0)
    [x,fval] = fminsearch(mWrapper,x0)
    For reference, the code from displayObj.m is displayed here:
    function className = displayObj(h)
    h
    className = class(h)
    whos('h')
    methods(h)

  3. At the MATLAB command prompt, type libraryCompiler to open the Library Compiler app.

  4. Use the Library Compiler app to create a Java package from the MATLAB functions doOptim.m and displayObj.m. Use the following naming conventions for your package:

    Save the project in your work folder using the name:OptimDemo
    Library Name:OptimDemo
    Class Name:Optimizer
    Exported Functions (files to compile) :doOptim.m and displayObj.m

    The Java classes created by the Library Compiler app serve as wrapper around the MATLAB code.

    The Library Compiler app will create a folder by the name OptimDemo in the c:\matlab\work directory. The OptimDemo folder contains the following sub folders:

    for_redistribution
    for_redistribution_files_only
    for_testing

    The files that you will need for the rest of the example are located in the for_testing folder.

    For more information on working with the Library Compiler app, see Compile Java Packages with Library Compiler App.

  5. Write source code for a class that implements an object function to optimize. The code for this example is in file BananaFunction.java. The program listing is shown here:

    public class BananaFunction {
    	public BananaFunction() {}
    	public double evaluateFunction(double[] x)
    	{
    		/* Implements the Rosenbrock banana function described in 
    		 * the FMINSEARCH documentation
    		 */
    		double term1 = 100*java.lang.Math.pow((x[1]-Math.pow(x[0],2.0)),2.0); 
    		double term2 =  Math.pow((1-x[0]),2.0);
    		return term1 + term2;
    	}
    }
    

    The class implements the Rosenbrock banana function described in the MATLAB fminsearch documentation.

  6. Write source code for an application that accesses the MATLAB functions. The code for this example is in the file PerformOptim.java. The program listing is shown here:

    /* Necessary package imports */
    import com.mathworks.toolbox.javabuilder.*;
    import OptimDemo.*;
    /*
     * Demonstrates the use of the MWJavaObjectRef class
     * Takes initial point for optimization as two arguments:
     *    PerformOptim -1.2 1.0
     */
    class PerformOptim
    {
    	public static void main(String[] args)
    	{
    		Optimizer theOptimizer = null;		/* Stores component 
                                           instance */
    		MWJavaObjectRef origRef = null;	/* Java object reference to 
                                         be passed to component */
    		MWJavaObjectRef outputRef = null;	/* Output data extracted 
                                            from result */
    		MWNumericArray x0 = null;	/* Initial point for optimization */
    		MWNumericArray x = null;	/* Location of minimal value */
    		MWNumericArray fval = null;	/* Minimal function value */
    		Object[] result = null;	/* Stores the result */
    
    		try
    		{
    			/* If no input, exit */
    			if (args.length < 2)
    			{
    				System.out.println("Error: must input initial x0_1 
                                                and x0_2 position");
    				return;
    			}
    
    			/* Instantiate a new Java object */
    			/* This should only be done once per application instance */
    			theOptimizer = new Optimizer();
    
    			try {
    				/* Initial point --- parse data from text fields */
    				double[] x0Data = new double[2];
    				x0Data[0] = Double.valueOf(args[0]).doubleValue();
    				x0Data[1] = Double.valueOf(args[1]).doubleValue();
    				x0 = new MWNumericArray(x0Data, MWClassID.DOUBLE);
    				System.out.println("Using x0 =");
    				System.out.println(x0);
    
    				/* Create object reference to objective function object */
    				BananaFunction objectiveFunction = new BananaFunction();
    				origRef = new MWJavaObjectRef(objectiveFunction);
    
    				/* Pass Java object to a MATLAB function that lists its 
                                  methods, etc */            
    				System.out.println("*********************************");
    				System.out.println("** Properties of Java object   **");
    				System.out.println("*********************************");
    				result = theOptimizer.displayObj(1, origRef);     
    				MWArray.disposeArray(result);
    				System.out.println("** Finished DISPLAYOBJ **********");
    
    				/* Call the Java component to optimize the function */
    				/* using the MATLAB function FMINSEARCH */
    				System.out.println("**********************************");
    				System.out.println("** Unconstrained nonlinear optim**");
    				System.out.println("**********************************");
    				result = theOptimizer.doOptim(2, origRef, x0);
    				try {
    					System.out.println("** Finished DOOPTIM ****** *********");
    					x = (MWNumericArray)result[0];
    					fval = (MWNumericArray)result[1];
    
    					/* Display the results of the optimization */
    					System.out.println("Location of minimum: ");
    					System.out.println(x);
    					System.out.println("Function value at minimum: ");
    					System.out.println(fval.toString());
    				}
    				finally
    				{
    					MWArray.disposeArray(result);
    				}
    			}
    			finally
    			{
    				/* Free native resources */
    				MWArray.disposeArray(origRef);
    				MWArray.disposeArray(outputRef);
    				MWArray.disposeArray(x0);
    			}
    		}
    		catch (Exception e)
    		{
    			System.out.println("Exception: " + e.toString());
    		}
    
    		finally
    		{
    			/* Free native resources */
    			if (theOptimizer != null)
    				theOptimizer.dispose();
    		}
    	}
    }
    

    The program accomplishes the following:

    • Instantiates an object of the BananaFunction class above to be optimized.

    • Creates an MWJavaObjectRef that references the BananaFunction object, as shown: origRef = new MWJavaObjectRef(objectiveFunction);.

    • Instantiates an Optimizer object.

    • Calls the displayObj method to verify that the Java object is being passed correctly.

    • Calls the doOptim method, which uses fminsearch to find a local minimum of the objective function.

    • Uses a try/catch block to handle exceptions.

    • Frees native resources using MWArray methods.

  7. Compile the PerformOptim.java application and BananaFunction.java helper class using the Java command javac. When entering this command, ensure there are no spaces between path names separated by a semicolon (;).

    1. Open a Command Prompt or Terminal window and cd to the work folder.

    2. Compile the application according to which operating system you are running on:

      Windows

      To compile BananaFunction.java, type:

      javac -classpath .;
      c:\matlab\work\javabuilder.jar;
      c:\matlab\work\OptimDemo\for_testing\OptimDemo.jar BananaFunction.java
      To compile PerformOptim.java, type:
      javac -classpath .;
      c:\matlab\work\javabuilder.jar;
      c:\matlab\work\OptimDemo\for_testing\OptimDemo.jar PerformOptim.java

      Linux

      To compile BananaFunction.java, type:

      javac -classpath .:
      ~/matlab/work/javabuilder.jar:
      ~/matlab/work/OptimDemo/for_testing/OptimDemo.jar BananaFunction.java
      To compile PerformOptim.java, type:
      javac -classpath .:
      ~/matlab/work/javabuilder.jar:
      ~/matlab/work/OptimDemo/for_testing/OptimDemo.jar PerformOptim.java

  8. Execute the PerformOptim class file as follows:

    On Windows, type:

    java -classpath .;
    c:\matlab\work\javabuilder.jar;
    c:\matlab\work\OptimDemo\for_testing\OptimDemo.jar PerformOptim -1.2 1.0 
    

    On Linux, type:

    java -classpath .:
    ~/matlab/work/javabuilder.jar: 
    ~/matlab/work/OptimDemo/for_testing/OptimDemo.jar PerformOptim -1.2 1.0
    

    Note

    You should be using the same version of Java that ships with MATLAB. To find out what version of Java MATLAB is running, enter the following MATLAB command:

    version -java

    Caution:MathWorks® only supports the Oracle® JDK™ and JRE™. A certain measure of cross-version compatibility resides in the Oracle software and it may be possible to run applications with compiled MATLAB functions with non-Oracle JDKs under some circumstances—however, compatibility is not guaranteed.

    Note

    If you are running on the Mac 64-bit platform, you must add the -d64 flag in the Java command. See Limitations of the MATLAB Compiler SDK Java Target for more specific information.

When run successfully, the PerformOptim program should display the following output:

Using x0 =
-1.2000    1.0000
*****************************************************
** Properties of Java object                       **
*****************************************************
 
h =
 
BananaFunction@1766806
 
className =
 
BananaFunction
 
  Name      Size            Bytes  Class             Attributes
 
  h         1x1                    BananaFunction              
 
Methods for class BananaFunction:
 
 BananaFunction    getClass          notifyAll         
equals            hashCode          toString          
evaluateFunction  notify            wait              
 
** Finished DISPLAYOBJ ******************************
*****************************************************
** Performing unconstrained nonlinear optimization **
*****************************************************
 
directEval =
 
   24.2000
 
 wrapperEval =
 
   24.2000
 
 x =
 
    1.0000    1.0000
 
 fval =
 
   8.1777e-10
 
Optimization successful
** Finished DOOPTIM *********************************
Location of minimum: 
1.0000    1.0000
Function value at minimum: 
8.1777e-10

Was this topic helpful?