Java与Matlab混合编程+Web呈现的详细流程

Java与Matlab混合编程是一种运用Matlab数学方面的优势处理一些数学算法、数据、图像后,转换成Java可识别的一种Jar包,在Java中继续编程其余后台功能的一种手段,实现了技术优势的结合。
一般来讲,很多数学问题基本上需要用python和matlab去编程才能简单、高效地解决。我作为一名数学+软件双专业的学生,因为需要做一个数学课题的应用网站,所以在核心数学功能编写上采用了此种混合编程的方法。可能是因为这个技术很low(现在比较流行的方法可能是直接用python去编写或者调用python的数学库),所以资料还是比较少的,在这边记录一下自己使用过程。

1.matlab编程并打包

首先需要下载一个matlab应用程序,下载安装的过程中最好工具都下载全,不然后续可能会出现缺乏某些组件或工具的情况。接着在自己的电脑上安装好与你下载的matlab版本内置要求的jdk相一致的jdk(不同版本需要的jdk版本不一样,像我下载的是matlab2015a,它要求的jdk版本就是jdk1.7及以下的版本)。上述步骤完成后进行编程,matlab可打包的是function函数,参考代码如下


image.png

需要New 一个function函数,X,D,count是要输出的结果,也是你在后面Java调用时得到的结果,A,eps为未知变量,也是你在Java调用时需要赋值的参数。接着在主窗口敲入deploytool,然后在跳出的选项中点击Library Compiler


image.png

选择Java Package,点+号选择要打包的.m文件,然后可以对包名和类名进行修改,最后点击Package进行打包
image.png

打包后会出现如下文件夹,打开for_redistribution_files_only


image.png

将其中的jar复制,同时还要去\matlab\bin\test\for_redistribution_files_only中去复制javabuilder.jar
image.png

image.png

2.Jar包放入Java

我用的编辑器是Idea,直接把Jar包拷入项目中,右键点击Add as Library


image.png

因为项目是web项目,还需要把jar包添加进/WEB-INF/lib。步骤是点击file-点击project structure-点击Artifacts,右键jar包点击Put into/WEB-INF/lib


image.png

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();
    }
}

运行结果如下


image.png

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;
    }
}

表格页面展示如下


image.png

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>&nbsp;&nbsp;&nbsp;
                                        </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>

展示结果如下


image.png

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(是这个人写过的,这位老哥是真的能写,啥都有)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容