MATLAB compiled as Java Package

Compared to languages such as java, MATLAB can be too powerful in matrix calculation. If only Java could directly adjust MATLAB.

Sure! By chance, I found this idea and tossed around for several days.

(Some of the drawbacks are that it costs a lot of money to invoke and we don't know how to make a reasonable call yet,)

MATLAB Compilation

Scripting

Write a script for the MATLAB function. Here I take the drawing function as an example.

% Custom Drawing Functions drawplot.m
% With two 1*n The matrix of x,y Draw a line with coordinates
% parameter x y  
function drawplot(x, y)    
plot(x, y, 'r'); %%Use matlab function plot()Mapping      
xlabel('X axis')  
ylabel('Y axis') 
end

There is also a drawplot2Line.m is used to output two lines (red + blue)

Pack

  1. Enter deploytool in the MATLAB command line window to open the deployment tool

  2. Select Library Compiler

  3. Add script and configure

    1. Select export type (I choose Java Package)
    2. Select a script file to convert (can import multiple)
    3. Exported package name
    4. Classes to be generated in jar packages and methods within classes (class names can be customized)
    5. Whether to package the MATLAB runtime environment MCR together (default is not packaged, download it from the web)
    6. Pack
  4. Waiting for packaging to complete

  5. The resulting three folders contain the exported jar package and javadoc document

    • for_redistribution
    • for_redistribution_files_only
    • for_testing

    (I don't understand the difference between the three, as long as I know to take out the package and import it into the java project)

Java Calls

The jar package exported by the above method and \toolbox\javabuilder\jar\javabuilder in the MATLAB installation directory are required. The jar package is imported into the Java project together. I won't talk about Java importing local jar packages here.

For matrix data, you need to use javabuilder. The MWNumericArray provided in jar is passed in.

input

When passed to the MATLAB function, the basic types can be brought in directly, and the matrix needs to use MWNumericArray

Conventional matrix input methods:

MWNumericArray input = null; // Used to save the input matrix
//Mode 1:
input = MWNumbericArray.newInstance(int, int[], MWClassID.DOUBLE, MWComplexity.REAL);
//Parameter 1 denotes the dimension of the matrix, parameter 2 denotes the size of each dimension, that is, several rows and columns, parameter 3 denotes the data type, and parameter 4 denotes the real or complex number.

//Mode 2:
double array[] = { 3, 2, 4, 5 };//Number to be calculated
//int array[]={3,2,4,5}; Yes, too.
input = new MWNumericArray(array, MWClassID.DOUBLE);
result = c1.myFunction(1, intput);

call

Class1 c1=null;
try{
    //Input parameter configuration
    ...
    c1 = new Class1();
    c1.draw.plot(x,y); //No return
    output = c1.myFunction(1, intput); //Has a return (returns a parameter, Object[1])
    output2 = c1.myFunction2(3, intput); //Has returned (returns three parameters Object[3])
    //Processing return values
    ...
}catch(Exception e){
    System.out.println(e);
}finally{
    //Release Resources
    ...
}

There are two structures for the exported function:

  1. For those with no data output, function(Onject... obj), simply enter the parameters;
  2. For those with data output, function(int i, Object... obj), I means the number of parameters returned, Object... Obj is the parameter entered for the corresponding MATLAB function.

output

For functions returned with data, the return value is an Objecct[] array.

Processing method:

MWNumericArray output = null;  //Used to save the output matrix
output=(MWNumericArray) result[0]; //Convert Result Object[] to MWNumericArray
double res = output.getDouble(1); //Reading data from MWNumericArray objects

Other ways to read data can be found in [4. MWNumericArray method]

Post-processing

Release local resources

MWArray.disposeArray(input);  //Build a matrix using this sentence
WArray.disposeArray(output);  // Build a matrix using this sentence
MWArray.disposeArray(result);  //Create an Object array using this sentence
c1.dispose();  //The matlab class object created with this sentence
//The above release must be guaranteed not to be null.

MWNumericArray method

  • getDouble(): Gets the first number of a matrix from MWNumericArray in double format, often used for matrices with only one number
  • getDouble(int i): Gets the ith number of matrices from MWNumericArray in double format
  • getDouble(int[] i): Gets the number of i[0] rows and i[1] columns in a matrix from MWNumericArray in double format (multidimensional I has multiple elements)
  • getDoubleData(): Gets a matrix from MWNumericArray in the form of a double[] one-dimensional array (connected by columns)
  • toDoubleArray(): Returns a matrix as an Object, but as a multidimensional double array, requiring a forced conversion to a multidimensional array.
  • set(int[] i, double): assigns values to the i[0] row i[1] column of the matrix

Other examples are getByte, getInt, getShort, getLong, getFloat.

Example

Here I'll call drawplot2Line() as an example.

MWNumericArray x = null;
MWNumericArray y = null;
Plotter plotter = null;
try {
    int[] dims = {1, 120001};
    x = MWNumericArray.newInstance(dims, MW
    y = MWNumericArray.newInstance(dims, MW
    for (int i = 1; i <= 120001; i++) {
        double t=0.001*i-6;
        x.set(i, 16*Math.pow(Math.sin(t),3)
        y.set(i, 13*Math.cos(t)-5*Math.cos(
    }
    plotter = new Plotter();
    plotter.drawplot( x, y);
    plotter.waitForFigures();
} catch (Exception e) {
    System.out.println(e);
} finally {
    // Release local resources
    MWArray.disposeArray(x);
    MWArray.disposeArray(y);
    if (plotter != null) {
        plotter.dispose();
        System.out.println("over");
    }
}

Here I use a simpler function to draw love

X=16*(sin(t)^3 and y=13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t), where -6<=t<=6

Of course, you can also use other graphics.

Environment Deployment

Generally speaking, there is no MATLAB in the running environment.

Calling jar packages in the absence of MATLAB can cause NoClassDefFoundError problems with MWNumericArray classes. On this issue in [How to resolve the java.lang.NoClassDefFoundError error] Has a good explanation

But MATLAB is too big, 10+G starts, the better way is to install MATLAB Compiler Runtime (MCR), although for my R2018a(9.4) version of the MCR is also 1G+large.

The MCR installed needs to be consistent with the MATLAB version used at compile time, and I'm using R2018(9.4)

Windows

Double-click the installation after downloading

Ubuntu

download

wget https://ssd.mathworks.com/supportfiles/downloads/R2018a/deployment_files/R2018a/installers/glnxa64/MCR_R2018a_glnxa64_installer.zip

decompression

unzip MCR_R2018a_glnxa64_installer.zip

install

Default at/usr/local/MATLAB/MATLAB_Runtime/v94

Note that the last version number here depends on your situation

# Normal Installation
sudo -H ./install
# Silent Installation (without UI under Ubuntu)
sudo ./install -mode silent -agreeToLicense yes
# Specify directory
sudo ./install -mode silent -agreeToLicense yes -destinationFolder  /data/tomcat/MCR

Environment Configuration

Although it was an official walk, it did not succeed, and subsequent attempts to write to/etc/profile were not possible, so continue playing when you are free. After all, ubuntu only tries to use it, mainly on Windows, and Windows installs MCR automatically to configure the environment.

  1. View the current SHELL environment

    echo $SHELL
    
  2. Choose different based on different SHELL environments Configuration Method (My environment is/bin/bash)

  3. Save the current library path as a mypath variable and output

    mypath=$LD_LIBRARY_PATH && echo $mypath
    
  4. Attach the MATLAB environment to mypath.

    mypath="${mypath:+${mypath}:}
    <MATLAB_RUNTIME_INSTALL_DIR>/runtime/glnxa64:
    <MATLAB_RUNTIME_INSTALL_DIR>/bin/glnxa64:
    <MATLAB_RUNTIME_INSTALL_DIR>/sys/os/glnxa64:
    <MATLAB_RUNTIME_INSTALL_DIR>/extern/bin/glnxa64"
    

    The above command needs to be entered in one line, for example:

    mypath="${mypath:+${mypath}:}/usr/local/MATLAB/MATLAB_Runtime/v94/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v94/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v94/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v94/extern/bin/glnxa64"
    
  5. Print out again to see mypath

    echo $mypath
    
  6. Assign mypath to LD_in the current session LIBRARY_ PATH

    export LD_LIBRARY_PATH=$mypath
    
  7. Permanent settings require the following commands, written to ~/. In bashrc

    echo "export LD_LIBRARY_PATH=$mypath" >> ~/.bashrc
    
  8. Apply changes

    source ~/.bashrc
    
  9. Check GNU version

    ldd --version
    

    If it is 2.17 or below, you will need to follow the steps above to <MATLAB_ RUNTIME_ INSTALL_ DIR>/bin/glnxa64/glibc-2.17_ Shim. So added to LD_PRELOAD environment variable.

uninstall

rm -rf <MATLAB_RUNTIME_INSTALL_DIR>

Keywords: Java MATLAB IDE

Added by aktome2001 on Thu, 27 Jan 2022 03:47:20 +0200