|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
背景% W. L% s* i. R6 q1 H3 ]
Matlab可以轻易处理非常复杂的数学计算,Java具有多变的应用场景,如Web开发。本文讲述如何将两者优势结合起来,基本思路是将Matlab核心程序打包成Jar,供普通的Java程序调用。: {( F1 e4 ~& J. u$ ?! P' B
: N) W+ {0 F# T- M% e/ F- G& g4 }具体步骤
4 P' u+ `" h& t% u; _# a1. 检查Matlab内置的Java版本和系统安装的Java版本是否一致?2 V; b3 O/ i8 n, d# C$ Q4 Q% \
( e: J) \* g/ N3 O+ y检查MATLAB内置的Java版本
: g6 V0 W- d/ j$ K' y3 u, d
1 q; m8 V& q( @ M. J% r: @+ @: e( R7 m( H, u
检查系统的Java版本
2 d5 ?% A, W9 x2 |/ |/ X; z
, C+ A" q* Q- S! X
5 {% |% a. I g
2. 准备一份要调用的Matlab代码
$ L( }; H2 e8 V/ b' z. s+ E# i& E1 _' x3 ~: H/ N" a4 [
为了测试各种数据类型(如Matlab的矩阵数据类型)的使用,本文采用稍稍复杂的Matlab测试程序:基于测距的网络定位。其包含多个M文件,其中主函数代码如下。输入参数7个:gCov是矩阵,其他为标量。输出参数2个,都是矩阵。
5 \ h; L5 ^2 W9 V0 S9 A E: y% w4 d( T
function [ nodeLoc, pMds ] = main_localization( N, dim, space, nGps, gCov, sigma, numMiss )& l: ?3 Y/ {) d
, O. ]5 Z1 |4 \, w1 c# S5 v5 v( s nodeLoc = diag(ones(dim,1)*space)*(rand(dim,N)-0.5);$ p/ I6 y% C+ t+ N
dltSec = zeros(N,1);) ?# @1 k3 a5 w
* N! b4 Q4 m0 H* M7 ]$ t
achrIdx = 1:nGps;
* o( e3 H, [5 }7 k( l* F2 e covMats = zeros(dim,dim,nGps);
: t8 X0 Q1 Z0 ? p# Q for n = 1:nGps
, X! z* \: A; ]7 |/ {4 } covMats(:,:,n) = gCov;
6 B k7 R/ i% k& _ end
]9 W# k+ C0 Q1 D
0 A1 z. E8 R9 G+ D" M [CT,CR] = round_robin(nodeLoc,dltSec,sigma);0 f* n S' j- H( d0 K
[A,~,y] = gen_Ay(CT,CR,ones(N));
7 L* @8 Y- b* ?3 I" x0 w. h3 v3 Y3 N7 d' H; l% {2 X! F
connMat = gen_connMat(N,numMiss);- ~* Z' y6 m$ n9 B) n( }
, T6 n3 v# r* A
dltEst = est_dlt_ls(A,y,connMat);1 P+ s- M1 d* d, r' M1 N3 ^
distVec = y-A*dltEst;- |- [# U ^# v: v; z5 W
$ A0 }) |3 i! T) C+ s, L( L8 d
distMat = diag_vec2mat(distVec);
0 w, b [, g) @- M edm = distMat.^2;
M- e; M! k% c; B t# I$ e9 o7 e) J4 q3 G
pGps = mvnrnd(nodeLoc(:,achrIdx)',gCov)';
. @8 C. z7 @* X" f1 ?2 i C; r7 t: ^
pMds = classic_mds(edm, dim);& U, x, ?2 O$ t6 g- y/ i( h6 {
pMds = orthogonal_procrustes(pMds, pGps, achrIdx);
' Q$ ~6 |# Z' u& |( c0 O4 E; w# Z) Bend
1 d- k) f5 m0 I! {) K1 t9 F t% H6 o8 g" M4 ^, [
8 @4 O1 j0 ~0 b N" v
其他多个M文件列表如下图所示:
6 [+ @' k4 A0 [. d
' ]2 _# g8 t- a2 v6 g7 ~4 N
, Y& H3 ^" L0 K$ t
3. 将Matlab代码打包成Jar包1 e2 S7 ^7 U2 U( D; y
' ~4 D" p% Y9 G2 F# T( [
(1) 在Matlab命令行窗口输入deploytool指令,唤起打包部署工具3 v9 V3 T* b$ e5 Y
e* @% H& t% O: T
8 q) J. I/ B; b8 v# }& ]; G
(2) 配置打包类型、包名、类名;选择待打包的M的文件& ^" c m0 P8 y
`% j/ \9 a+ H0 o7 |
0 t( m# L4 z3 ]4 B! c(3) 等待打包完成,应有3个对勾+ t4 S6 S; w, W- Q" L. W. Y# G
" V+ @* F* u' |% p
% g$ K" _5 x- u* Y! Q) z$ u7 B(4) 打包生成的工程目录结构如下" h' m/ h8 e( G$ N1 I6 _" Q
4 |. W" t( M0 [- e' W4 f
" j ~4 ]/ H6 T" R# L' x# [7 S4. 新建Java项目,调用由Matlab得到的Jar包
; _5 ^0 _9 }; o, k6 K( _6 F$ Z; ]# ~4 e4 S5 e/ n6 i
(1) Eclipse新建Java项目(不赘述)6 r& D/ T y1 n; V4 P: w
(2) 添加两个Jar包到Java项目中4 Y* @. n1 W8 ] O* y
0 F& Y& O, [% ?. X4 m3 c h
- Matlab安装目录下的Jar包:...\MATLAB\R2017a\toolbox\javabuilder\jar\javabuilder.jar
- 前面M文件生成的Jar包:...\localization_matlab\for_redistribution_files_only\localization_matlab.jar5 A: b) `' R( M
5 R* S! c y7 i% G! L2 M' e
& M5 X; v7 [ H' i6 [ E0 n
* ]: b( M5 O1 F9 M, H& d(3) 写Java程序调用Matlab生成的Jar包,源码如下:2 ?* f9 o# y( `' I% j
" I! J, Z# L4 F( V% ]& C' E( M( wpackage com.csrl.localization;) g+ v) ~) h7 u: C4 @
: g+ k# z' d1 ~
import com.mathworks.toolbox.javabuilder.MWClassID;
7 G8 z5 y# H; Y! N& oimport com.mathworks.toolbox.javabuilder.MWException;
" e! d3 z* M4 a/ ?; z! Rimport com.mathworks.toolbox.javabuilder.MWNumericArray;
* B6 }& Q6 Y# |0 A9 [- g" f9 i/ fimport localization_matlab.MdsLocalization; h4 X; Q$ `: i; U/ ?
. Z9 O) q$ \- Y: D" _: ^8 V0 r, a
public class TestLocalization {9 u6 V) ?% k- B( u0 t/ N( v
& M4 f8 `, k5 N3 x/ m$ G public static void main(String[] args) {. z! X1 R3 H4 O) r1 l E
try {
* v) C0 T9 G2 ~% o MdsLocalization matrixCompletion = new MdsLocalization();
, r! K3 ?. p7 n( a- ~; Z5 \, b( d* m9 ]0 Q4 d( L- w2 [4 w
double N = 10;. V% A3 T" \! X' o
double dim = 2;0 H" U; D& \. I% L; o
double space = 500;( u4 u8 K. s3 H! l6 g7 a
double sigma = 2;0 E( J- x' @8 B. Y$ v. I
double nGps = 5;3 \2 o% A4 h$ C; K: }
double numMiss = 0;$ v2 ^+ P8 U. `1 `( P4 y3 T
double[][] gCovArr = {{1,0},{0,1}};8 U/ Q, ?. F G1 p, T# X4 [, R
MWNumericArray gCov = new MWNumericArray(gCovArr,MWClassID.DOUBLE); // 将二维数组转化为矩阵
9 ?) [( E- p4 k; S) ]6 l& R, w8 s
$ H! D; f& N5 _& D. ] P! X0 b' G2 y // 第一个参数“2”代表原Matlab函数输出参数的个数,后面的都是原Mat了吧函数输入参数;输出参数用Object数组保存
% C7 ^' O* S4 T# H- c Object[] result = matrixCompletion.main_localization(2, N, dim, space, nGps, gCov, sigma, numMiss);' y2 V2 Z6 I; {7 X/ `
" u+ W [6 c0 {$ L0 O; @
MWNumericArray data = (MWNumericArray) result[0]; // 第一个输出参数: @9 ^! I! T- _5 o+ Q# x
double[][] nodeLoc = (double[][]) data.toDoubleArray(); // 将矩阵转化为二维数组
" i" d- h- z3 w5 q2 v; c7 w! ~, g! L& C
data = (MWNumericArray) result[1]; // 第二个输出参数
( D3 Q$ m4 b/ D: c- b5 O1 x, s double[][] pMds = (double[][]) data.toDoubleArray(); // 将矩阵转化为二维数组, c$ m2 U' L% H7 |1 s
: a5 t# j0 }) H, h! Z3 q: y) O
System.out.println(result[0]); // 同Matlab输出格式,输出矩阵
/ P8 i& C" X* Q6 i( F! q' G$ n System.out.println(result[1]);2 a1 u* K( X- |" ?2 _1 p/ B
# W$ B0 |. _, h
System.out.println(nodeLoc[0][0]); // 通过二维数组索引输出矩阵中某个元素
8 ~3 }! B4 S' [0 j8 a# Z: I$ N( A5 g System.out.println(pMds[0][0]);& J+ E- C+ L6 t
" t+ E* O% [' X/ t0 O
} catch (MWException e) {
( O# v. |. P5 m* B5 a e.printStackTrace();( Y( l$ G1 E3 @; Y& m J7 o- ]
}- n* U# W9 u7 V$ V3 M1 E
}
4 j- |+ U0 O& ?3 i" `}% M. {+ D# v* w5 d, x8 R' g* S6 O8 n7 g( F
P! }8 Y! U6 V9 W
r" ?# g% f( I# v# V4 ~# X) q
4 l0 v( K( U& S7 e, z" V |
|