java springBoot 中调用 Matlab软件 进行 二维矩阵计算 matlabcontrol

最近,公司的一个项目要结合matlab 做一些算法预测。传递的参数大部分是矩阵结构,在java中可以用二维数组表示。

首先百度搜索资料,尝试过matlab 的.m文件打包成jar的形式,这个是可行的,只不过jar的形式受限比较大,jdk运行版本要求严格,而且后期的.m文件的修改,要重新打包,增加运维成本。

最终参照这篇博客的经验,,https://blog.csdn.net/qq_27731689/article/details/81068516。其实使用的是matlabcontrol  api。

因我的是web项目,防止每次计算都会启动matlab,创建一个Listener来代理;只要springboot启动后,后面就无需在次启动,Listener代码结构如下:

MatlabListener.java



import java.io.File;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import matlabcontrol.MatlabConnectionException;
import matlabcontrol.MatlabInvocationException;
import matlabcontrol.MatlabProxy;
import matlabcontrol.MatlabProxyFactory;
import matlabcontrol.MatlabProxyFactoryOptions;

public class MatlabListener implements ServletContextListener {
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		File file = new File("D:\\m");//m文件所在根目录,可以任意,并不是m文件的绝对路径噢。
		MatlabProxyFactoryOptions options = new MatlabProxyFactoryOptions.Builder()
		.setProxyTimeout(300000L)
		.setMatlabStartingDirectory(file)
		.setHidden(false)
		.build();
		MatlabProxyFactory factory = new MatlabProxyFactory(options);
		MatlabProxy proxy = null;
		try {
		proxy = factory.getProxy();
		}catch (MatlabConnectionException e) {
		e.printStackTrace();
		}
		sce.getServletContext().setAttribute("proxy", proxy);

		System.out.println("matlab连接成功");
	}
 
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		MatlabProxy proxy=(MatlabProxy) sce.getServletContext().getAttribute("proxy");
		try {
			proxy.exit();
		} catch (MatlabInvocationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("matlab销毁");
	}
}

MatlabConfig.java  //@Configuration  springBoot 启动时加载运行

import java.util.EventListener;

import org.jeecg.listener.MatlabListener;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MatlabConfig {
	@Bean
	public ServletListenerRegistrationBean myListener(){
	    ServletListenerRegistrationBean<EventListener> servletListenerRegistrationBean = new ServletListenerRegistrationBean<>();
	    servletListenerRegistrationBean.setListener(new MatlabListener());
		return servletListenerRegistrationBean;
	}

}

代码结构:

 

 

只要完成编写上方的两个文件,就可以在web中连接matlab进行计算。那么怎么调用matlab的方法呢,一维数组参数可以参照https://blog.csdn.net/qq_27731689/article/details/81068516,我这里是二维数组为参数的demo

首先准备.m文件demo

function [out,out2] = demo(in,in2)
out = 2*in;
out2=3*in2;
end

java 调用代码:

package org.jeecg.modules.emb.controller;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;

import matlabcontrol.MatlabProxy;
import matlabcontrol.extensions.MatlabNumericArray;
import matlabcontrol.extensions.MatlabTypeConverter;

public class MatlabTestController {
	@Autowired
    private ServletContext servletContext;

	@PostMapping(value = "/calculateStarts")
	public void calculateStarts() {

		try {
			
			MatlabProxy proxy=(MatlabProxy)servletContext.getAttribute("proxy");
			double[][] in = {{1,1},{2,2}};//第1个二维矩阵入参
			double[][] in2 = {{2,2},{3,3}};//第2个二维矩阵入参
			MatlabNumericArray input = new MatlabNumericArray(in,null);
			MatlabNumericArray input2 = new MatlabNumericArray(in2,null);
			MatlabTypeConverter mtc=new MatlabTypeConverter(proxy);
			mtc.setNumericArray("in", input);
			mtc.setNumericArray("in2", input2);
			proxy.eval("[out,out2]=demo(in,in2)");
            //计算结果
			double[][] out=mtc.getNumericArray("out").getRealArray2D();
			double[][] out2=mtc.getNumericArray("out2").getRealArray2D();

		} catch (Exception e) {
			e.printStackTrace();

		}
				
	}
}

有更好的办法,麻烦大神留言一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章