Java与Matlab混合编程是一种运用Matlab数学方面的优势处理一些数学算法、数据、图像后,转换成Java可识别的一种Jar包,在Java中继续编程其余后台功能的一种手段,实现了技术优势的结合。
一般来讲,很多数学问题基本上需要用python和matlab去编程才能简单、高效地解决。我作为一名数学+软件双专业的学生,因为需要做一个数学课题的应用网站,所以在核心数学功能编写上采用了此种混合编程的方法。可能是因为这个技术很low(现在比较流行的方法可能是直接用python去编写或者调用python的数学库),所以资料还是比较少的,在这边记录一下自己使用过程。
1.matlab编程并打包
首先需要下载一个matlab应用程序,下载安装的过程中最好工具都下载全,不然后续可能会出现缺乏某些组件或工具的情况。接着在自己的电脑上安装好与你下载的matlab版本内置要求的jdk相一致的jdk(不同版本需要的jdk版本不一样,像我下载的是matlab2015a,它要求的jdk版本就是jdk1.7及以下的版本)。上述步骤完成后进行编程,matlab可打包的是function函数,参考代码如下
需要New 一个function函数,X,D,count是要输出的结果,也是你在后面Java调用时得到的结果,A,eps为未知变量,也是你在Java调用时需要赋值的参数。接着在主窗口敲入deploytool,然后在跳出的选项中点击Library Compiler
选择Java Package,点+号选择要打包的.m文件,然后可以对包名和类名进行修改,最后点击Package进行打包
打包后会出现如下文件夹,打开for_redistribution_files_only
将其中的jar复制,同时还要去\matlab\bin\test\for_redistribution_files_only中去复制javabuilder.jar
2.Jar包放入Java
我用的编辑器是Idea,直接把Jar包拷入项目中,右键点击Add as Library
因为项目是web项目,还需要把jar包添加进/WEB-INF/lib。步骤是点击file-点击project structure-点击Artifacts,右键jar包点击Put into/WEB-INF/lib
3.编写调用类
我这个主要是输入矩阵,输出矩阵特征值、特征向量和迭代次数
MWNumericArray q = null;
MWNumericArray z=null;
Object[] result1 = null;
Jacobi js=null;
int[][] data={{2, -1, 1}, {1, -2, 1}, {1, 1, -1}};
double ps=Math.pow(Math.E,-12);
try
{
q =new
MWNumericArray(data, MWClassID.DOUBLE);
z=new
MWNumericArray(ps,MWClassID.DOUBLE);
String str2 = String.valueOf(q);
System.out.println(str2);
js=new Jacobi();
result1 =js.eig_Jacobi(2,q,z);
System.out.println(result1[0]);
System.out.println(result1[1]);
String value= String.valueOf(result1[0]);
System.out.println(value);
} catch(
MWException e)
{
e.printStackTrace();
} finally
{
MWArray.disposeArray(z);
MWArray.disposeArray(q);
MWArray.disposeArray(result1);
js.dispose();
}
}
运行结果如下
4.矩阵输入的前端页面处理
动态表格传入矩阵,html代码
<form action="/jacobi/jacobiMethod/",method="post">
<table class="table table-striped"style="font-size: 1.2rem;margin-bottom: 1rem;" >
<tr><td style="padding:0.5rem">您要输入<input id="hang" type="text" class="input" size="5" name="hang"/>行<input id="lie" type="text" class="input" size="5" name="lie"/>列的矩阵</td></tr>
</table>
<input name="" style="font-size: 1rem" type="button" value="确定" class="btn btn-outline-primary" onclick="table()"/></br>
<br>
<div id="div1" style="display: none;width:350px;" mce_style="display: none">
<div id="table1" >
<div id="errmsg1" class="formmsg1"></div>
<div id="errmsg2" class="formmsg2"></div>
</div>
js代码
function table() {
if (document.getElementById("hang").value == "" || document.getElementById("hang").value.search("^[0-9]*$") == -1) {
document.getElementById("errmsg1").style.display = "block";//判断payNum是否为空或不是数字 提示错误
document.getElementById("errmsg1").innerHTML = "提示信息:行数为空或不是数字!";
}else if(document.getElementById("lie").value == "" || document.getElementById("lie").value.search("^[0-9]*$") == -1){
document.getElementById("errmsg2").style.display = "block";//判断payNum是否为空或不是数字 提示错误
document.getElementById("errmsg2").innerHTML = "提示信息:列数为空或不是数字!";
}
else {
document.getElementById("errmsg1").style.display = "none";//隐藏提示信息
document.getElementById("errmsg2").style.display = "mall";//隐藏提示信息
var Num1 = parseInt(document.getElementById("hang").value); //获取分期数
var Num2 = parseInt(document.getElementById("lie").value); //获取分期数
var flag = true;
var data = "";
data += " <table >";
for (var i = 0; i <= Num1-1; i++) {
data += "<tr >";
for (var j = 0; j <= Num2-1; j++){
data += "<td><input name='CollDay"+i+j+"' type='text' size='10' class='INPUT' value='1'></td>";
}
data += "</tr>";
}
data += "</table>";
document.getElementById("div1").style.display = "block";
document.getElementById("table1").innerHTML = data;
}
}
表格页面展示如下
5.矩阵结果的后端处理
调用jar求出的矩阵特征值等结果是一个result[]对象,为了让其在前端页面以矩阵的形式展示,我使用的是将对象转换为String类型的字符串,取出其中的元素,在前端页面进行拼接,处理的后端代码如下
public static List<List<String>> conversion(String matrix) {
String[] str = matrix.split("\n");
List<List<String>> list1 = new ArrayList<>();
for (String s : str) {
List<String> list11 = new ArrayList<>();
s = s.trim();
String[] strings = s.split(" ");
for (String string : strings) {
if (string != "" && string != null && string != " " && string != " " && string.length() != 0&& !"".equals(string)){
string = string.trim();
list11.add(string);
}
}
list1.add(list11);
}
return list1;
}
前端的拼接如下
<div>
<h3>特征值:</h3>
</div>
<div style="position: relative;width: ${width}px;height: ${height}px;">
<span style="display:inline-block;position: absolute;left: 0px;top: 0px;width: ${ww}px;height: ${height}px;"><img src="${ctx}/static/img/left.jpg" style="width: 38%"/></span>
<div style="position: absolute;left: 10px;top: 9px;">
<c:forEach items="${value}" var="obj">
<c:forEach items="${obj}" var="val">
<span style="display:inline-block;width: 55px;text-align: center">${val}</span>
</c:forEach>
<br>
</c:forEach>
</div>
<span style="display:inline-block;position: absolute;right: 0px;top: 0px;width: ${ww}px;height:${height}px;"><img src="${ctx}/static/img/right.png" style="width: 46%"/></span>
</div>
展示结果如下
6.web展示matlab图像的方法
如果在function函数中有plot画一些函数图像,可以参考如下方法将matlab生成的图像展示到web页面
https://zhidao.baidu.com/question/745824287999373692.html?qq-pf-to=pcqq.c2c
https://blog.csdn.net/xd15010130025/article/details/89508732
里面的配置还是很详细,没有什么大问题的,以下是我在Controller层、Service层、页面上的一些代码
@Controller("methodController")
@RequestMapping("/difference")
public class MethodController {
@Autowired
private DifferenceService differenceService;
//
// int array[][]={{2,-1,0},{-1,-2,-1},{0,-1,2}};
// String data=String.valueOf(array);
// double ps=1.1;
@RequestMapping("/go")
public String differenceMethod(@Param("a")double a ,@Param("h") double h, @Param("tao")double tao,@Param("t")double t,@Param("l")double l,
@Param("method")int method, HttpSession session, Model model) {
Difference difference=new Difference();
difference.setA(a);
difference.setH(h);
difference.setTao(tao);
difference.setT(t);
difference.setL(l);
if(method==0){
model.addAttribute("error","请选择求解方法");
return "bouncy";
}
ArrayList<WebFigure> FC = differenceService.difference(difference);
WebFigure wb1=FC.get(0);
WebFigure wb2=FC.get(1);
// model.addAttribute("wb",wb);
session.setAttribute("wb1",wb1);
session.setAttribute("wb2",wb2);
return "Result";
}
}
@Service("differenceService")
public class DifferenceServiceImpl implements DifferenceService {
@Override
public ArrayList<WebFigure> difference(com.tt.Domain.Difference difference) {
// int a=1;
// double h=0.1;
// double tao=0.0025;
// double T=0.4;
// int l=1;
MWNumericArray A = null, B = null, C = null, D = null, E = null;
Object[] result = null;
Difference dd = null;
WebFigure wb1=null;
WebFigure wb2=null;
ArrayList<WebFigure> fc=new ArrayList<WebFigure>();
try {
A = new MWNumericArray(difference.getA(), MWClassID.DOUBLE);
B = new MWNumericArray(difference.getH(), MWClassID.DOUBLE);
C = new MWNumericArray(difference.getTao(), MWClassID.DOUBLE);
D = new MWNumericArray(difference.getT(), MWClassID.DOUBLE);
E = new MWNumericArray(difference.getL(), MWClassID.DOUBLE);
dd = new Difference();
result = dd.forward(2, A, B, C, D, E);
System.out.println(result[0]);
System.out.println(result[1]);
wb1 = (WebFigure) ((MWJavaObjectRef) Array.get(result, 0)).get();
wb2 = (WebFigure) ((MWJavaObjectRef) Array.get(result, 1)).get();
} catch (Exception e) {
e.printStackTrace();
} finally {
MWArray.disposeArray(A);
MWArray.disposeArray(B);
MWArray.disposeArray(C);
MWArray.disposeArray(D);
MWArray.disposeArray(E);
// MWArray.disposeArray(result);
//
// dd.dispose();
fc.add(wb1);
fc.add(wb2);
return fc;
}
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="wf" uri="/WEB-INF/webfigures.tld" %>
<%@ page import="com.mathworks.toolbox.javabuilder.webfigures.WebFigure" %>
<%@ page import="com.mathworks.toolbox.javabuilder.MWJavaObjectRef" %>
<%@ page import="difference.Difference" %>
<%@ page import="com.mathworks.toolbox.javabuilder.*" %>
<%@ page import="com.mathworks.toolbox.javabuilder.internal.*" %>
<html>
<head>
<title>结果</title>
</head>
<body>
<wf:web-figure name="wb1" scope="session"/>
<wf:web-figure name="wb2" scope="session"/>
</body>
</html>
相关参考文章
https://me.csdn.net/myFavorite/weixin_34082854(是这个人写过的,这位老哥是真的能写,啥都有)