本文介绍 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 版本。
在 CMD 中执行 java -version
查看机器 Java 版本,
Matlab 程序打包
Matlab 支持 C++ 、Java 、.Net 等语言的打包。
我们将 .m 文件打包为 Java 支持的库,如下图:
感觉和 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、ML02_09_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
评论 (0)