Java 调用 Matlab 程序(Java 和 Matlab 混合编程)

Author Avatar
wshunli 10月 20, 2018
  • 在其它设备中阅读本文章

本文介绍 Java 调用 Matlab 程序(Java 和 Matlab 混合编程)流程方法。

环境搭建

1、 Java 环境,建议使用如下版本 。

Java™ SE Development Kit 8, Update 151 (JDK 8u151)

2、Matlab 工具(开发环境)

编写 Mattlab 代码,本文以最新版 Matlab 2018b 为例。

3、MATLAB Runtime(部署环境)

已经安装过 Matlab 就不需要再安装了,用来执行编译后的 Matlab 程序。

从以下网址下载即可,本文以 R2018b (9.5) 为例。

https://ww2.mathworks.cn/products/compiler/matlab-runtime.html

MATLAB Runtime 相比 Matlab 更加轻量级,免费。

环境确认:

本文建议 Java 版本和 Matlab 自带 JVM 保持一致。

在 Matlab 命令中输入 version -java 查看机器 Matlab 版本。

java-version

在 CMD 中执行 java -version 查看机器 Java 版本,

java-version

Matlab 程序打包

Matlab 支持 C++ 、Java 、.Net 等语言的打包。

我们将 .m 文件打包为 Java 支持的库,如下图:

matlab-package

感觉和 JVM 虚拟机很类似,Matlab 提供基础环境,我们编写 Matlab 代码即可。

Java 调用 Matlab 方法

在 Java 中调用 Matlab 的方法时,有三种方式。

1、functionName(int arg0, Object… agr1): Object[]

其中 arg0 表示返回数据的个数,agr1 为数组;返回值也是数组。

2、functionName(List arg0, List agr1): void

其中 arg0 、agr1 为列表;返回值为空。

3、functionName(Object[] arg0, Object[] agr1): void

其中 arg0 、agr1 为数组;返回值为空。

方式一,输入返回个数

// 定义输出结果  
Object[] results = null;  
Magic magic = new Magic(); // 实例化 

// '2' 表示 2 个输出结果,类似 results=new Object[2];  
// '5' 表示输入的参数 
results = magic.makesqr(2, 5);  
// 输出第一个返回内容  
System.out.println(results[0]);  
// 输出第二个返回内容  
System.out.println(results[1]);

方式二,列表参数

// 定义结果List  
List<Object> results = new ArrayList<Object>(2);  
// 定义参数List  
List<Object> inputs = new ArrayList<Object>(1);  

Magic magic = null;  

magic = new Magic();  
// 注意:结果List要预先加入内容,Null即可  
results.add(null);  
results.add(null);  
// 输入的参数  
inputs.add(5);  
// 调用方法  
magic.makesqr(results, inputs);  
// 显示结果  
System.out.println(results.get(0));  
System.out.println(results.get(1));

方式三,数组参数

// 注意:定义输出结果的时候,要定义数组大小  
Object[] results = new Object[2];  
Magic magic = null;  
magic = new Magic();  

// 这种方式,第二参数必须为数组,而不能为可变数组  
Object[] inputs = new Object[]{5};  
magic.makesqr(results, inputs);  
// 输出第一个返回内容  
System.out.println(results[0]);  
// 输出第二个返回内容  
System.out.println(results[1]);

Java 与 Matlab 数据转换

数据转换内容比较多,这里主要介绍数组的转换。

1、将 Java 数据转化为 Matlab 数据

这里以输入 MWNumericArray 数据为例

使用 newInstance 方法实例化

//new int[]{11,2} 代表矩阵为 11 行 2 列的矩阵
//MWClassID.DOUBLE 代表矩阵中数为 double 类型,MWComplexity.REAL 代表矩阵中是实数
MWNumericArray f = MWNumericArray.newInstance(new int[]{11,2}, MWClassID.DOUBLE, MWComplexity.REAL);
MWNumericArray f = MWNumericArray.newInstance(new int[]{11,2}, data, MWClassID.DOUBLE);

另外一种方式:

int[] dims = {3, 6};
double[] Adata = {1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10, 16, 5, 11, 17, 6, 12, 18};
MWNumericArray A = MWNumericArray.newInstance(dims, Adata, MWClassID.DOUBLE);
System.out.println("A = ");
System.out.println(A);

2、将 Matlab 数据转化为 Java 数据

这里以返回 MWCellArray 数据为例

MWCellArray cellArray = (MWCellArray) result[0];
double[] output = new double[cellArray.numberOfElements()];
for (int i = 1; i <= cellArray.numberOfElements(); i++) {
    output[i - 1] = ((double[][]) cellArray.get(i))[0][0];
}
System.out.print("输出数据:");
System.out.println(Arrays.toString(output));

实战

输入数据为 17行1列 的 MWNumericArray 数据,返回 1行15列 的 MWCellArray 数据。

System.out.println("Running the JAVA client application!!");

AiNet cls = null; // 调用对象
MWNumericArray input = null; // 输入
Object[] result = new Object[1]; // 输出结果

double[] data = new double[]{ // 初始数据
        3.43300000000000,
        3.40500000000000,
        3.37200000000000,
        3.35700000000000,
        3.34800000000000,
        3.31500000000000,
        3.28800000000000,
        3.28000000000000,
        3.26800000000000,
        3.24600000000000,
        3.23900000000000,
        3.24600000000000,
        3.25800000000000,
        3.27100000000000,
        3.28200000000000,
        3.28600000000000,
        3.30000000000000
};

input = MWNumericArray.newInstance(new int[]{17, 1}, data, MWClassID.DOUBLE);

System.out.print("输入数据:");
System.out.println(Arrays.toString(input.getDoubleData()));

try {
    cls = new AiNet();
    result = cls.Net(1, input);

    MWCellArray cellArray = (MWCellArray) result[0];
    double[] output = new double[cellArray.numberOfElements()];
    for (int i = 1; i <= cellArray.numberOfElements(); i++) {
        output[i - 1] = ((double[][]) cellArray.get(i))[0][0];
    }
    System.out.print("输出数据:");
    System.out.println(Arrays.toString(output));
    MWArray.disposeArray(output);

} catch (MWException e) {
    e.printStackTrace();
} finally {
    MWArray.disposeArray(input);
    MWArray.disposeArray(result);
    if (cls != null) {
        cls.dispose();
    }
}

注意使用 MWArray.disposeArray() 方法释放资源。

参考资料
1、Java调用MATLAB - 窃·格瓦拉 - CSDN博客
https://blog.csdn.net/golden1314521/article/details/43526581
2、Java调用Matlab方法的三种方式 - 非技术流 - ITeye博客
http://xiaolongfeixiang.iteye.com/blog/1893621
3、ML0209_calling_java_from_MATLAB_CH.ppt
http://read.pudn.com/downloads85/doc/329263/matlab%E8%AE%B2%E4%B9%89/ML02(11-28)/ML02_09_calling_java_from_MATLAB_CH.pdf
4、Java调用Matlab程序 - 移动的天坑的个人空间 - 开源中国
https://my.oschina.net/pierrecai/blog/829641
5、JAVA调用matlab程序 输入输出数据转换 - 简书
https://www.jianshu.com/p/c008bd9d5a25
6、(1)在java中使用matlab的函数
东东-forest_新浪博客
http://blog.sina.com.cn/s/blog_86aea377010171yq.html

如果本文对您有所帮助,且您手头还很宽裕,欢迎打赏赞助我,以支付网站服务器和域名费用。 https://paypal.me/wshunli 您的鼓励与支持是我更新的最大动力,我会铭记于心,倾于博客。
本文链接:https://www.wshunli.com/posts/45399dc2.html