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

		}
				
	}
}

有更好的辦法,麻煩大神留言一下。

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