Java调用MATLAB

作者:金良([email protected]) csdn博客:http://blog.csdn.net/u012176591

Java调用MATLAB_第1张图片

一、版本确认和系统环境变量

    • MATLAB命令确认当前MATLAB版本,操作系统版本,该版本MATLAB要用的Java版本。查询命令如下
      >> ver
       
      ------------------------------------------------------------------------------------------------
      MATLAB Version: 8.1.0.604 (R2013a)
      MATLAB License Number: 724504
      Operating System: Microsoft Windows 7 Version 6.1 (Build 7601: Service Pack 1)
      Java Version: Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode
    • MATLAB命令确认当前MATLAB是32位or64位
      >> computer('arch')
       
      ans =win32
      ------------------------------------------------------------------------------------------------
    • Dos窗口确认当前系统安装的Java版本
      C:\Windows\System32>java -version 
      java version "1.8.0_25" 
      Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
      Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode, sharing)
可以看到当前系统安装的MATLAB对应的Java版本是1.6,而系统当前安装的事Java1.8,最好换成对应的Java版本。各版本JDK下载地址http://www.oracle.com/technetwork/java/javase/archive-139210.html,注意i586也是x86 都是32位的;x64是64位的。
  • 替换Java JDK的方法很简单,首先将原来的JDK安装文件(包括JDK和JRE)都删掉,然后安装刚刚下载的JDK,安装成功后添加JDK和JRE的环境变量 
    C:\Program Files\Java\jdk1.6.0_17\bin;C:\Program Files\Java\jdk1.6.0_17\jre\bin;
  • 另外还要添加mclmcrrt8_1.dll的环境变量D:\Program Files\Matlab\runtime\win32;,否则运行时可能提示如下错误
    java.lang.UnsatisfiedLinkError: Failed to find the library mclmcrrt8_1.dll, required by MATLAB Builder JA, on java.library.path.
     This library is typically installed along with MATLAB or the MCR, its absence may indicate an issue with that installation or the current path configuration.
    The MCR version that this component is trying to use is: 8.1.
    
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ProxyLibraryDir.get(
     MCRConfiguration.java:162)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ProxyLibraryDir.<clinit>(
     MCRConfiguration.java:168)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getProxyLibraryDir(
     MCRConfiguration.java:173)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$MCRRoot.get(
     MCRConfiguration.java:74)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$MCRRoot.<clinit>(
     MCRConfiguration.java:84)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getMCRRoot(
     MCRConfiguration.java:89)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ModuleDir.<clinit>(
     MCRConfiguration.java:63)
           at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getModuleDir(
     MCRConfiguration.java:68)
           at com.mathworks.toolbox.javabuilder.internal.MWMCR.<clinit>(
     MWMCR.java:1462)
           at plotdemo.PlotdemoMCRFactory.newInstance(
     PlotdemoMCRFactory.java:50 )
           at plotdemo.PlotdemoMCRFactory.newInstance(
     PlotdemoMCRFactory.java:61 )
           at plotdemo.plotter.main(
     plotter.java:115 )

添加环境变量后,重启系统使环境变量有效。

二、一个小例子


在MATLAB中Command窗口中输入deploytool调出部署工具DeploymentTool。新建一个工程,输入工程名plotdemo.prj,选择路径,并选择Target为 Java Package。
Java调用MATLAB_第2张图片
在MATLAB右侧会出现我们新建的工程。
将画图的MATLAB文件封装成函数drawplot(x,y),文件名drawplot.m
function drawplot(x, y)
plot(x, y);


将刚刚编写的m文件直接拖拽进去,并重命名类名为plotter(plotter就是Java中的类名,函数文件名就是该类的方法,这一点可以从下面的Java文件中得到验证),点击Build编译:

Java调用MATLAB_第3张图片

完成之后就会在我们选择的路径下看到 plotdemo的文件夹,里面有个jar包plotdemo\distrib\plotdemo.jar就是我们在Java工程中要调用的文件。
Java工程目录如下图
Java调用MATLAB_第4张图片
Java文件内容
package jinliang.javaMatlab;

import ExampleMatlabLib.PlotExampleMatlab;

/* Necessary package imports */
import com.mathworks.toolbox.javabuilder.*;

/*
 * PlotExample class demonstrates plotting x-y data into 
 * a MATLAB figure window by graphing a simple parabola.
 */
public class PlotExample
{
   public static void main(String[] args)
   {
      MWNumericArray x = null;   /* Array of x values */
      MWNumericArray y = null;   /* Array of y values */
      PlotExampleMatlab plotExampleMatlab = null;    /* Plotter class instance */
      int n = 15;                /* Number of points to plot */

      try
      {
         /* Allocate arrays for x and y values */
         int[] dims = {1, n};//维度设置一行n列
         x = MWNumericArray.newInstance(dims,MWClassID.DOUBLE, MWComplexity.REAL);
         y = MWNumericArray.newInstance(dims,MWClassID.DOUBLE, MWComplexity.REAL);

         /* Set values so that y = x^2 */
         for (int i = 1; i <= n; i++) {
            x.set(i, i);
            y.set(i, i*i);
         }
         byte [] rx =  x.getByteData();//将MWNumericArray转换成以为数组
         for(int i=0;i<rx.length;i++) {
        	 System.out.print(rx[i]);
        	 System.out.print(" ");
         }
         /* Create new plotter object */
         plotExampleMatlab = new PlotExampleMatlab();

         /* Plot data */
         plotExampleMatlab.drawplot(x, y);
         plotExampleMatlab.waitForFigures();
      } catch (Exception e) {
         System.out.println("Exception: " + e.toString());
      } finally {
         /* Free native resources */
         MWArray.disposeArray(x);
         MWArray.disposeArray(y);
         if (plotExampleMatlab != null)
            plotExampleMatlab.dispose();
      }
   }
}

运行得到的图像
Java调用MATLAB_第5张图片

三、数据的交换

第二部分的数据传输过程是:Java把数据传给MATLAB函数,MATLAB函数根据该数据画图。
下面的例子是,Java首先把数据传给MATLAB函数,然后MATLAB把运行结果传给Java
MATLAB文件:cholesky.m
function [L] = cholesky(A)
L = chol(A);
disp(L)
Java文件
package jinliang.javaMatlab;

import ExampleMatlabLib.MatrixMathExampleMatlab;

import com.mathworks.toolbox.javabuilder.*;

public class MatrixMathExample {
	   public static void main(String[] args) throws MWException
	   {
	      MWNumericArray mat = null;   /* Stores matrix to factor */
	      Object[] result = null;    /* Stores the result */
	      MatrixMathExampleMatlab theFactor = new MatrixMathExampleMatlab();   /* Stores factor class instance */

	      try {
	    	 int n=3;
	    	 int[] dims = {n, n};
	         double[][] data = {{2,-1,0},{-1,2,-1},{0,-1,2}};
	         mat = MWNumericArray.newInstance(dims,MWClassID.DOUBLE, MWComplexity.REAL);

	         /* Set matrix values */
	         int[] index = {1, 1};

	         for (index[0]= 1; index[0] <= dims[0]; index[0]++) {
	            for (index[1] = 1; index[1] <= dims[1]; index[1]++) {
	            	mat.set(index,data[index[0]-1][index[1]-1]);
	            }
	         }



	         /* Print original matrix */
	         System.out.println("Original matrix:");
	         System.out.println(mat);

	         /* Compute cholesky factorization and print results. */
	         result = theFactor.cholesky(1, mat);
	         System.out.println("Cholesky factorization:");
	         System.out.println(result[0]);
	         //double[] a = (double [])((MWArray)result[0]).getData();
	         //for(int i=0;i<a.length;i++)
	         //	 System.out.println(a[i]);
	         MWArray.disposeArray(result);

	      } catch (Exception e) {
	         System.out.println("Exception: " + e.toString());
	      } finally {
	         /* Free native resources */
	         MWArray.disposeArray(mat);
	         MWArray.disposeArray(result);
	         if (theFactor != null)
	            theFactor.dispose();
	      }
	   }
}

上面的例子中,Java把一个矩阵传给MATLAB,MATLAB对该矩阵进行分解,然后将结果传给Java。

MATLAB也可以返回多个数据给Java,如下
function [L,U] = ludecomp(A)
[L,U] = lu(A);
package jinliang.javaMatlab;

import ExampleMatlabLib.MatrixMathExampleMatlab;

import com.mathworks.toolbox.javabuilder.*;

public class MatrixMathExample {
	   public static void main(String[] args) throws MWException
	   {
	      MWNumericArray mat = null;   /* Stores matrix to factor */
	      Object[] result = null;    /* Stores the result */
	      MatrixMathExampleMatlab theFactor = new MatrixMathExampleMatlab();   /* Stores factor class instance */

	      try {
	    	 int n=3;
	    	 int[] dims = {n, n};
	         double[][] data = {{2,-1,0},{-1,2,-1},{0,-1,2}};
	         mat = MWNumericArray.newInstance(dims,MWClassID.DOUBLE, MWComplexity.REAL);

	         /* Set matrix values */
	         int[] index = {1, 1};

	         for (index[0]= 1; index[0] <= dims[0]; index[0]++) {
	            for (index[1] = 1; index[1] <= dims[1]; index[1]++) {
	            	mat.set(index,data[index[0]-1][index[1]-1]);
	            }
	         }

	         /* Compute LU factorization and print results. */
	         result = theFactor.ludecomp(2, mat);
	         System.out.println("LU factorization:");
	         System.out.println("L matrix:");
	         System.out.println(result[0]);
	         System.out.println("U matrix:");
	         System.out.println(result[1]);
	         MWArray.disposeArray(result);

	      } catch (Exception e) {
	         System.out.println("Exception: " + e.toString());
	      } finally {
	         /* Free native resources */
	         MWArray.disposeArray(mat);
	         MWArray.disposeArray(result);
	         if (theFactor != null)
	            theFactor.dispose();
	      }
	   }
}

四、数据类型之间的转换
第一个Java文件中的语句

byte [] rx =  x.getByteData();//将MWNumericArray转换成以为数组
for(int i=0;i<rx.length;i++) {
    System.out.print(rx[i]);
    System.out.print(" ");
}
把一维的MWNumericArray转换成了一维byte数组。
第二个Java语句
double[] a = (double [])((MWArray)result[0]).getData();
for(int i=0;i<a.length;i++)
	 System.out.println(a[i]);
把一个3*3的MWArray转换成了一维的double []。


Package com.mathworks.toolbox.javabuilder的API的学习资料
http://wind.isi.edu/marbles/assets/components/workflow_portal/users/lib/CombinedCNV/MCR/v79/help/toolbox/javabuilder/MWArrayAPI/com/mathworks/toolbox/javabuilder/package-summary.html

本博客代码见 http://download.csdn.net/detail/u012176591/8426473

MATLAB自带的例子目录 D:\Program Files\Matlab\toolbox\javabuilder\Examples

你可能感兴趣的:(java,matlab,画图)