最近的项目需要用到一些比较繁琐的数学理论计算
过于复杂靠自己弄懂再写成java代码的工作量过大,而且难度较大
所以这里就需要用到matlab这个工具了
上面有很多现成的封装好的函数,然后具体怎么去做网上能找到比较多的一些matlab代码
1.matlab java 版本问题
首先,matlab已经提供了很多编译器,能将.m文件编译成支持不同语言的库,但是这个版本问题,是很敏感的,一般matlab仅支持某些特定版本运行环境,要是你拿不同版本过高或过低的去编译,这样往往会报错或者编译出来的也用不了
对于java matlab 的混合编程,首先要确定matlab支持的版本
在命令行输入:
version -java
查看支持的版本,这里我电脑上的matlab的java虚拟机版本是
1.7.0_60-b19 with Oracle Corporation Java HotSpot™ 64-Bit Server VM mixed mode
我电脑的jdk版本是jdk-11.0.2
首先要从官网上下载一个jdk7的版本,然后安装
然后有两个方法:
第一个是将本机的系统环境变量 JAVA_HOME从指向你本机原来的版本,修改为指向下载下来的jdk7的路径
第二个是新增另一个环境变量 MATLAB_JAVA,指向jdk7的路径
然后重启matlab
2.matlab 函数
要将你的matlab代码封装成一个或多个函数到同一个.m文件下
函数格式一般是:
[out1,out2,out3,…]=FunctionName(in1,in2,in3,in4,…)
…函数内容
End
matlab这个工具虽然强大,但是运行速度不算很快(和java,c,c++相比),所以要对matlab代码进行一定的优化
比如:
每次在循环内执行同一个函数可以将其抽出,提取为一个变量
避免出现某个矩阵在循环内不停的进行迭代,之前却没为其分配好空间的情况
matlab混合编程除非说需要matlab生产的图,否则千万要将之前画图展示的相关代码去掉或注释
3.编译
在matlab界面App菜单下搜索lib,选择最后面的Library Compiler
打开编译器界面
如上述步骤
选择语言类型,选择.m文件,填好相关信息,重命名输出后的类名
最后再点击打包
有两种编译模式,一种是
Runtime Downloaded fromWeb
另一种是
Runtime inclued in package
这两种编译模式貌似没发现太大差别,编译出来的都能用,可能区别就是
项目编译出来之后for_redistribution文件夹里面的东西大小和名称有所不同,不影响使用
4.java调用
编译后所用到的jar就在for_redistribution_files_only里
同时还需要另一个jar,目录在:
…\R2017a\toolbox\javabuilder\jar下的javabuilder.jar
将这两个jar导入到所在的java项目中
我用的是Maven,所以写了个bat右键以管理员身份运行先将这个jar包注册到Maven的本地仓库之内,然后再在Maven项目中增加引用
pom.xml:
<dependency>
<groupId>javabuilder</groupId>
<artifactId>javabuilder</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>get_Dwt</groupId>
<artifactId>get_Dwt</artifactId>
<version>1.1</version>
</dependency>
调用相关代码:
import com.mathworks.toolbox.javabuilder.*;
import getDwt.*;
public static class Dwt_Analyze {
private static Solution Dwt_AnalyzeSolution;
public static Double[] getDwt(Object[] Xn) {
try {
if (Dwt_AnalyzeSolution == null)
Dwt_AnalyzeSolution = new Solution();
var res = Dwt_AnalyzeSolution.getDwt(4, Xn, "dmey", 512, true);
return null;
} catch (MWException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
具体调用:就是将自己封装好的那个类实例化后,调用封装好的方法
参数如下:
第一个参数是数字,表示有多少个输出
之后的参数全是输入参数,有多少个输入参数就传多少个进去
返回的值是一个MWNumericArray数组
如果返回参数是一个值,直接.getDouble()或.getInt()等即可
如果返回的是一个矩阵,则.getDoubleData()或.getIntData()等即可
此时返回的是一个一维矩阵,还需要自己另行处理
5.其他需要注意的地方
1.刚开始版本的问题卡了我很久,想明白之后感觉也就那么一回事,不管你的项目用的是哪个版本的jdk,只要你参与编译matlab的jdk版本对上了,编译出来的jar自然就能用了,并不需要考虑项目是否也要跟着换jdk版本的问题
2.在实际使用中最好将这个类弄成单例模式,只要你的函数越复杂,每次创建实例就越慢,不要多次重复创建这个类(每次创建还要不小的开销),哪怕无法避免需要多次创建这个类,也要注意对象的销毁(有一个dipose方法),如果不及时调用dipose会导致内存溢出的问题,然后java虚拟机会直接跑挂(虚拟机不会回收这个的缓存)
3.如果很简单的功能,或者自己了解了一下相关算法可以直接用java代码写出来的东西就不要用matlab了,之前写过一个java版本的FFT,就没有想过要通过matlab去调用,用java自己写的话效率会比这种方式高,(前提是自己写的没错)
转载:https://blog.csdn.net/weixin_40683787/article/details/101617574