|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
背景: X3 S1 ^; \3 d5 N0 U
Matlab可以轻易处理非常复杂的数学计算,Java具有多变的应用场景,如Web开发。本文讲述如何将两者优势结合起来,基本思路是将Matlab核心程序打包成Jar,供普通的Java程序调用。
1 E8 s+ R$ `- s3 M7 G9 |0 N$ _/ Q" [- \, e
具体步骤
$ S4 n: f) r9 a( C: ~2 V1. 检查Matlab内置的Java版本和系统安装的Java版本是否一致?/ b$ n( ^; |% ?, w. ~, Z
# X. e5 L; z. x9 O2 j( ?9 m! E. ~
检查MATLAB内置的Java版本
$ ~& C" u6 w7 |( P
( y4 o; n3 _1 N8 [
: K( {1 P: S- Y/ Y% E$ ]检查系统的Java版本2 Q( i j3 Q! Z h7 E4 b$ ~
) d0 ]9 f% L4 r
, W+ u ~/ m- T p, U/ G2 C2. 准备一份要调用的Matlab代码0 t( f3 m8 @$ `
2 G: ]/ f) n0 v. |: y为了测试各种数据类型(如Matlab的矩阵数据类型)的使用,本文采用稍稍复杂的Matlab测试程序:基于测距的网络定位。其包含多个M文件,其中主函数代码如下。输入参数7个:gCov是矩阵,其他为标量。输出参数2个,都是矩阵。
- E3 U5 x; E8 [' @& t4 v1 a) X
+ U0 X4 Q3 g6 D% [function [ nodeLoc, pMds ] = main_localization( N, dim, space, nGps, gCov, sigma, numMiss ), \+ ^2 L. o7 y4 v9 d0 p
( N" e2 L& h" \ b! D
nodeLoc = diag(ones(dim,1)*space)*(rand(dim,N)-0.5);
& n1 `0 T$ r* i+ D dltSec = zeros(N,1);
1 W5 W8 g7 o! p, M5 E% K. Q8 {/ h4 C' I
achrIdx = 1:nGps;
. c9 f; Z6 g8 `, ]$ Y2 O1 D covMats = zeros(dim,dim,nGps);
% @6 Q1 F, j7 r9 @& | for n = 1:nGps! M0 f9 a- K' f) O
covMats(:,:,n) = gCov;
& Q' O" I% X; H: n: ], q U end' }& F Z- Z5 P! B1 }; y
5 |8 D! f5 X; P: I. _( x5 `9 Q! _ [CT,CR] = round_robin(nodeLoc,dltSec,sigma); E! }) M+ C( C" Z
[A,~,y] = gen_Ay(CT,CR,ones(N));1 ?- o4 m! l/ T7 p% a
$ g5 t* K) w( ~ f connMat = gen_connMat(N,numMiss);
; ]; L8 U( \2 o2 X) _* n0 B9 t: y3 G9 z7 @1 L
dltEst = est_dlt_ls(A,y,connMat);
) p# ?0 w! Z" F9 g, N* N- R! J7 D distVec = y-A*dltEst;
! a7 c8 @$ a- E8 y. p% q5 P/ C3 r% \# E
distMat = diag_vec2mat(distVec);3 `& y: ?& k% B @ B% n
edm = distMat.^2;3 C4 Y# J# p0 S4 Q; g
4 y% w9 b9 y$ r( {2 `
pGps = mvnrnd(nodeLoc(:,achrIdx)',gCov)';& q* B B* F4 n- N" e: A+ r
9 z+ N: @$ `7 w pMds = classic_mds(edm, dim);9 B) g" U1 `. m# S; k# l* O7 s3 k
pMds = orthogonal_procrustes(pMds, pGps, achrIdx); Q( [1 w( c8 A( h$ J( G
end
) x- a% v5 O/ P. J% z% W, d6 `1 D6 j+ [, r* |2 I+ F
' `! x* Z9 H! Y) ~7 b* ^
其他多个M文件列表如下图所示:
" }( C9 w; t$ t" N$ D
; i5 t( @* i% ] y+ J3 n6 X8 B% r. G2 _3 Y% S+ l
3. 将Matlab代码打包成Jar包
3 Q% L* s: \1 U& P+ U. x- d0 T# D5 G# U
(1) 在Matlab命令行窗口输入deploytool指令,唤起打包部署工具6 Q! h3 p, K9 w$ C4 U9 N6 w; U
! x+ s' X3 z1 Z- p
0 M. L3 s7 i* D5 x(2) 配置打包类型、包名、类名;选择待打包的M的文件9 M6 m% P9 J: `3 h, O
, T! Q1 @4 b6 R- J, x0 w Z
$ u' l( A- q% S$ _2 W0 W(3) 等待打包完成,应有3个对勾2 Z9 X. u# e5 I% U: u+ E5 F
7 }) |4 ^, E6 G! S/ x# P |; z9 U" _0 y) d( K* ~
(4) 打包生成的工程目录结构如下
6 e/ A1 [! X+ ]9 R
( ]0 ^4 O( e0 Z1 j. P
4 p: l1 q( z, T& D* Q4. 新建Java项目,调用由Matlab得到的Jar包
5 m8 w7 T- I7 `2 l6 A G5 G" J2 X; [# Q. V
) X2 Q; M1 |) h S t& X(1) Eclipse新建Java项目(不赘述)
4 j0 p9 y# e8 B. P(2) 添加两个Jar包到Java项目中5 o' F% }0 }+ O, Z! v
1 x/ ^. ?4 S' a4 ?* ^/ }/ r: I- Matlab安装目录下的Jar包:...\MATLAB\R2017a\toolbox\javabuilder\jar\javabuilder.jar
- 前面M文件生成的Jar包:...\localization_matlab\for_redistribution_files_only\localization_matlab.jar* ?7 D3 a$ n- M1 u+ |1 f' P& @- {
8 l( [. |1 e& k
. b$ O0 O, z8 n8 w& Q& c" E. Y
C6 M7 s* w: U1 E7 f(3) 写Java程序调用Matlab生成的Jar包,源码如下:! y/ j9 v( E+ p; }
& P% R$ a+ o6 ]# ~4 V
package com.csrl.localization;
3 A. n- k! R2 u& U8 F1 q4 f, s- d. W. d6 w
import com.mathworks.toolbox.javabuilder.MWClassID;
: @( ~" c1 f1 F7 Z( bimport com.mathworks.toolbox.javabuilder.MWException;& j+ Z. D$ N: p- ~7 h! w
import com.mathworks.toolbox.javabuilder.MWNumericArray;
' V# @3 ]& n9 s, r: L( qimport localization_matlab.MdsLocalization;! ~$ v( R& v4 \6 g' q! D
B3 ~. Z$ j% ?. hpublic class TestLocalization {
! [% g; w+ @* e% b
9 a& z' [" p; E7 u public static void main(String[] args) {
& t) R6 e u( Q* a try {
6 ], G& D. S8 f" w MdsLocalization matrixCompletion = new MdsLocalization();
; h+ d9 {' B: w3 N$ ]$ Z
5 U* f6 q- M7 y6 ^# P$ w' y double N = 10;0 D1 V# t1 f* w- P
double dim = 2;$ o* v; J2 x! ^: S% z$ C' g
double space = 500;
$ r2 n5 G y; x double sigma = 2;9 }2 h5 R, L+ N
double nGps = 5;
( Z4 O! d8 H% Z& b9 k& c; s; [6 e4 X double numMiss = 0;
# d* H, F* Z" N6 o% G+ r, x double[][] gCovArr = {{1,0},{0,1}};
! `) V9 u; s) C7 p( J s6 o! m MWNumericArray gCov = new MWNumericArray(gCovArr,MWClassID.DOUBLE); // 将二维数组转化为矩阵
( t3 T6 ~4 m8 F* |/ V0 A: A# ~; }5 B( |6 w: ?
// 第一个参数“2”代表原Matlab函数输出参数的个数,后面的都是原Mat了吧函数输入参数;输出参数用Object数组保存
% h5 z; n. S1 ^4 ? Object[] result = matrixCompletion.main_localization(2, N, dim, space, nGps, gCov, sigma, numMiss);* Q' c( e8 W, t9 u
! Y3 p6 H# R; G& c: v/ G
MWNumericArray data = (MWNumericArray) result[0]; // 第一个输出参数2 Z2 L/ J' m7 a# E1 E
double[][] nodeLoc = (double[][]) data.toDoubleArray(); // 将矩阵转化为二维数组
+ z- e6 s4 c% o
% a4 a* x) U J( J data = (MWNumericArray) result[1]; // 第二个输出参数9 N4 w( o; m6 k8 g" A: X C
double[][] pMds = (double[][]) data.toDoubleArray(); // 将矩阵转化为二维数组, ? P; Q- h( Z( t
1 P: ?2 H3 D' ]$ y- e6 F: V7 w& U System.out.println(result[0]); // 同Matlab输出格式,输出矩阵$ a, g) l. t1 Q
System.out.println(result[1]);' _# m9 ~' N/ }
3 p1 n* [ U+ a$ k
System.out.println(nodeLoc[0][0]); // 通过二维数组索引输出矩阵中某个元素
- T& W4 j5 B: ` System.out.println(pMds[0][0]);
/ h8 o$ b8 Z' x: u/ e
8 @- q1 l: W/ B4 j& `# j9 `) D$ Q } catch (MWException e) {
% ?* U5 K, d: ~7 E4 r9 l e.printStackTrace();( ?0 U7 ^ m/ Y/ J3 A! ]/ c L
}( T9 J" H8 w0 h" {
}
* u; H; z; N3 ?* ]8 M } Z4 Y/ V}
/ F. c- A6 p/ f! L; X6 J7 ?; }! t2 K: v+ P9 f. y( m8 b B3 _5 A
$ X* u( I- q1 E
9 d" Z1 _8 F2 @ |
|