|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
背景
- N* F. V/ @% WMatlab可以轻易处理非常复杂的数学计算,Java具有多变的应用场景,如Web开发。本文讲述如何将两者优势结合起来,基本思路是将Matlab核心程序打包成Jar,供普通的Java程序调用。 T( |0 h$ A: m% h/ L9 u
4 B3 U. X" E5 U$ [9 i% H
具体步骤; x i# N0 D7 u7 n. @" P8 Q
1. 检查Matlab内置的Java版本和系统安装的Java版本是否一致?+ U6 D7 U1 Y$ ~ J6 d
0 J1 \# m$ ^2 R
检查MATLAB内置的Java版本
u8 L% \+ f/ n! a5 B' b* L4 R
& S" E, F& U% K
?# P# B) _8 u" j1 C o检查系统的Java版本, H% i+ K% W2 v5 Q. t' b
* r; N& n- G2 Z6 \' ^6 ]4 N9 R8 t. N$ v* I% U
2. 准备一份要调用的Matlab代码
, x4 a8 e3 Q+ x- X0 k# S4 U9 z5 U$ \! m" J) q
为了测试各种数据类型(如Matlab的矩阵数据类型)的使用,本文采用稍稍复杂的Matlab测试程序:基于测距的网络定位。其包含多个M文件,其中主函数代码如下。输入参数7个:gCov是矩阵,其他为标量。输出参数2个,都是矩阵。
" Z8 X, q ~2 F; W4 K# {8 R, t6 `2 \% S7 n
function [ nodeLoc, pMds ] = main_localization( N, dim, space, nGps, gCov, sigma, numMiss )
& E1 ^4 h2 B! h; u
6 @7 F0 h) Y K1 \4 H nodeLoc = diag(ones(dim,1)*space)*(rand(dim,N)-0.5);9 q2 T6 E& t8 p5 R
dltSec = zeros(N,1);
6 g7 c6 z5 [8 G9 T6 }! C+ i: a! n& V/ u7 J
achrIdx = 1:nGps;' Z# q+ }/ R8 y
covMats = zeros(dim,dim,nGps);
& w! V6 f: l# X8 }$ L' A for n = 1:nGps. h5 T/ q" j# ]9 p9 B
covMats(:,:,n) = gCov;
9 W* S1 I/ t: w( I end
# I, G+ `. d# W& z- X) q
' W# E" l1 l/ u; t [CT,CR] = round_robin(nodeLoc,dltSec,sigma);
7 @+ H; H9 x; \( r# K9 D: l2 t+ Q [A,~,y] = gen_Ay(CT,CR,ones(N));
! Z( g0 ^2 _9 B' |3 ~( D% E: V* {) v t1 X( C* J, b1 L
connMat = gen_connMat(N,numMiss);+ d+ ~- }* D ?0 U6 K
R6 L: P% g, x: I, l9 u
dltEst = est_dlt_ls(A,y,connMat);
/ Y& y$ K4 k3 w; q+ G& h/ n5 I distVec = y-A*dltEst;1 r0 D. Y* e" ]% o" R" Q' S
7 t! H) r1 s( d, g/ y' s. H/ o( Q distMat = diag_vec2mat(distVec);3 N3 U) g9 @ K. U( [
edm = distMat.^2;$ d) G) T) G4 U3 H) v4 G
a- |, t5 \% }' G" d+ b- r1 b pGps = mvnrnd(nodeLoc(:,achrIdx)',gCov)';, D6 F$ K, r4 s- u c, I ?3 n
) Y2 M4 ~; a3 S! h, _ pMds = classic_mds(edm, dim);
/ L0 v; _ r7 N) z! p pMds = orthogonal_procrustes(pMds, pGps, achrIdx);
5 M+ L, o3 G5 L9 \ aend
/ p* |, F/ n( B/ [4 l3 ~1 p$ E+ i3 o4 J9 n4 M |+ A l; i& T8 l
% n& U1 M7 ~# {9 j$ Y其他多个M文件列表如下图所示:
- [) T1 i: v6 u
8 P7 |2 ~" {, D) Z
, [( O: t4 f4 ?" I! X6 B
3. 将Matlab代码打包成Jar包- @2 K' v8 j% j4 y* X' P. A. C
! s* O" P) F& J$ U( }# x' B; I. K(1) 在Matlab命令行窗口输入deploytool指令,唤起打包部署工具3 q9 n4 h. h5 W9 M; R% _* s/ f. r
# |& k, d2 z$ {$ D
/ @; _; E+ E1 a) g. p& ~6 w(2) 配置打包类型、包名、类名;选择待打包的M的文件
4 ]4 Z9 E& b# G) t# K
; A- r; y1 V* {) ^/ t) n2 c
; |) i. H9 Y3 f& X! K q(3) 等待打包完成,应有3个对勾
% l: ^' k: T. c4 ~- B" y: e
. L$ v# |' j& D
6 ]3 {) f6 d0 v(4) 打包生成的工程目录结构如下
6 g& S( p; m& @9 @. D. q0 S$ ?' A; ^; s
2 J- m% ?8 W6 q& Z7 ]3 ^) S
* f) W( N3 |- |% z9 Q4. 新建Java项目,调用由Matlab得到的Jar包" E4 v2 N/ f5 m% g/ K
0 D a1 k; A$ k) k. ]) i(1) Eclipse新建Java项目(不赘述)7 F9 n/ R* x, e2 y0 Y
(2) 添加两个Jar包到Java项目中
2 s2 ]* c( p- u$ L( {* D
! O+ \% e6 V& k! o6 J8 x2 R+ A- Matlab安装目录下的Jar包:...\MATLAB\R2017a\toolbox\javabuilder\jar\javabuilder.jar
- 前面M文件生成的Jar包:...\localization_matlab\for_redistribution_files_only\localization_matlab.jar
" Z, u+ `. O3 }6 z7 y 4 ]; l* z- v" w6 W4 {8 S
6 L+ o4 x7 c1 [, |, C8 Q
; v4 H1 q2 _0 i# C2 T(3) 写Java程序调用Matlab生成的Jar包,源码如下:3 o( e: Y8 H% p }" h
# y# @: K- E# @6 F3 {8 W8 `# X$ opackage com.csrl.localization;' @% H9 u3 R7 z/ q2 K& q# i
$ F" ], E. j7 p/ Pimport com.mathworks.toolbox.javabuilder.MWClassID;
# q; k: l! T* S, limport com.mathworks.toolbox.javabuilder.MWException;
4 W, F" J# B) D# ?import com.mathworks.toolbox.javabuilder.MWNumericArray;* [5 k! w$ Z4 `- S
import localization_matlab.MdsLocalization;
% o+ @6 b1 q0 j# d7 w8 x4 ]+ C6 \: L* w" Y. B
public class TestLocalization {" j! h \: {9 [) L& F! t
8 E5 O. f7 p- C2 j
public static void main(String[] args) {
1 f' Y! Y+ h" ~% L try {, @! ]" i2 U8 J# q6 p- M
MdsLocalization matrixCompletion = new MdsLocalization();
. e+ S6 P& [/ y. I8 A
! n- k j8 A! [) o double N = 10;
3 M: c8 N. k. G d5 [ s double dim = 2;
d2 t* V4 C7 a4 l- ]$ Y double space = 500;3 \; t1 S8 i4 `8 l* k0 K
double sigma = 2;8 o4 o" k' O" ?5 O5 M' u3 ?
double nGps = 5;
0 u& n& F5 c, T: w& [' L double numMiss = 0;
8 k! \" C& U& {) f9 q double[][] gCovArr = {{1,0},{0,1}};
* l) [6 K! p! O6 z, y: }, F MWNumericArray gCov = new MWNumericArray(gCovArr,MWClassID.DOUBLE); // 将二维数组转化为矩阵
" p& u* E* g$ s* b9 I% { J( ]( ?9 j% f* p, f
// 第一个参数“2”代表原Matlab函数输出参数的个数,后面的都是原Mat了吧函数输入参数;输出参数用Object数组保存4 O7 g& Q" v3 {; ^% b9 J
Object[] result = matrixCompletion.main_localization(2, N, dim, space, nGps, gCov, sigma, numMiss);
8 P1 f! j3 a) d8 @9 i! q8 H
7 |% ]7 k: i6 e$ b: X" e MWNumericArray data = (MWNumericArray) result[0]; // 第一个输出参数
: d' V2 ]3 t' C double[][] nodeLoc = (double[][]) data.toDoubleArray(); // 将矩阵转化为二维数组/ t% [- P6 p8 F' H) v. Z: @
- \# V' N% ^4 Y0 }8 I$ l data = (MWNumericArray) result[1]; // 第二个输出参数
, \ i O5 I4 e7 H8 a double[][] pMds = (double[][]) data.toDoubleArray(); // 将矩阵转化为二维数组- I. w! y/ ^' w4 s6 [6 S
( t0 z7 q7 F; D1 f+ z" ] F! g8 y
System.out.println(result[0]); // 同Matlab输出格式,输出矩阵
7 H- Y( B4 S0 @9 G% i' q& @) s: f! i System.out.println(result[1]);: ]7 S3 H9 k3 v- A, i) p
' Y4 }! q' u r
System.out.println(nodeLoc[0][0]); // 通过二维数组索引输出矩阵中某个元素
' [5 p3 ?& [5 g. ~ System.out.println(pMds[0][0]);
1 }9 g# J- {9 C& F2 o
* N4 l3 ?: p2 v$ T% L& y3 G/ z9 U } catch (MWException e) {, N, Y3 K& G4 L# Y
e.printStackTrace();
$ v1 l- v% [1 T" j! K6 V }. u+ B' ~3 j. N7 s$ K
}
- L: T" I f* x}+ r8 V5 x* P6 K
2 q( D6 P' N/ Q R+ W' [+ e
! _* z+ R( ]3 q- p
R( D4 Y. Z% c
|
|