EDA365电子论坛网

标题: Java调用Matlab程序 [打印本页]

作者: pulbieup    时间: 2020-5-6 10:48
标题: Java调用Matlab程序
背景
. M, x8 m" ]2 w3 |  m* u1 I6 mMatlab可以轻易处理非常复杂的数学计算,Java具有多变的应用场景,如Web开发。本文讲述如何将两者优势结合起来,基本思路是将Matlab核心程序打包成Jar,供普通的Java程序调用。3 Q! E* L+ i6 `- b8 b
. I0 Y. y/ Z$ E
具体步骤
1 ]. M8 K7 N7 r- A2 O5 T2 H1. 检查Matlab内置的Java版本和系统安装的Java版本是否一致?
( }7 u$ {  h" E" H+ c7 N
  f0 `, i. w7 p0 t0 K检查MATLAB内置的Java版本& ]' p9 h/ M) Q

4 Y1 o+ P2 g1 w. k- z
3 G% P9 k. @+ N" x检查系统的Java版本
& T; t1 ^+ q) k
* ^7 Z+ t7 Q# N5 W! {4 b
4 B; Q$ v8 x% o* F$ `7 u2. 准备一份要调用的Matlab代码
' Q5 M; J! z2 W5 M+ N0 t  h5 g/ B+ f
为了测试各种数据类型(如Matlab的矩阵数据类型)的使用,本文采用稍稍复杂的Matlab测试程序:基于测距的网络定位。其包含多个M文件,其中主函数代码如下。输入参数7个:gCov是矩阵,其他为标量。输出参数2个,都是矩阵。* ~* w1 f1 O5 }, m
" R6 j. y' A) ]  G
function [ nodeLoc, pMds ] = main_localization( N,  dim, space, nGps, gCov, sigma, numMiss )5 G6 f8 r2 ]) M5 w0 r# r4 Y
$ t; q& t4 e5 f7 T
    nodeLoc = diag(ones(dim,1)*space)*(rand(dim,N)-0.5);; v# I$ a2 n- x& S: X$ U
    dltSec  = zeros(N,1);
6 F% M" l" g  @5 }; e* }6 U% s. l) Z- q5 O5 Z1 ?
    achrIdx = 1:nGps;
7 ^: [0 N, ^1 M, ^: Z9 b    covMats = zeros(dim,dim,nGps);: U( C" y, F( [, I' h9 Q6 N! h
    for n = 1:nGps  i& h) ?3 K  I# }
        covMats(:,:,n) = gCov;
3 r0 A' B6 d- l# z' J    end5 ^3 {' T' P& C9 O
1 ^" I  ^8 P# W/ i
    [CT,CR] = round_robin(nodeLoc,dltSec,sigma);
5 Q/ L. h) b& z& b% Z2 I, `; {    [A,~,y] = gen_Ay(CT,CR,ones(N));
' f/ |: {& d; {$ b- j) m5 z7 [3 X' J; M; v5 ~! t
    connMat = gen_connMat(N,numMiss);6 B: W! O5 a) I" h* c% U5 k

5 h7 ^# A: u4 ^; t$ |# ?    dltEst = est_dlt_ls(A,y,connMat);' n8 J# G9 @* @! i; f: e
    distVec = y-A*dltEst;9 m" P7 l4 D( k0 d5 H
) F7 N7 Y. a6 `4 }
    distMat = diag_vec2mat(distVec);9 q# V" I% U( @* ]1 H* J/ x
    edm = distMat.^2;/ J1 v( e. t% B* B- f" c
0 B  S+ p$ P7 R! ^0 n5 Y
    pGps = mvnrnd(nodeLoc(:,achrIdx)',gCov)';( G7 W9 j- x2 ^4 q# M& h; t

. J3 {. e, z' [% z    pMds = classic_mds(edm, dim);
- X! L) c5 I" l; ]" @/ ~    pMds = orthogonal_procrustes(pMds, pGps, achrIdx);0 }: _8 [) |: T8 _* C3 m
end
4 H; Q( l. I" n, K( h6 ?9 \; y. S& p. g- `. o8 I$ n
( w8 F" ?+ X; t
其他多个M文件列表如下图所示:
/ L2 \# g! e; d  I: `" Y
: j5 e6 V6 S5 s! v# [7 ~+ A% t5 e; o+ Y: t' h9 u* g9 m9 L3 {
3. 将Matlab代码打包成Jar包( l! ]+ `, P9 f1 Q- |
$ g# M  {$ E4 L3 a  |+ H: I6 V# J7 i
(1) 在Matlab命令行窗口输入deploytool指令,唤起打包部署工具
1 `0 \, M) g% _  |# L
& m3 B6 V; m  S/ G0 x4 k
7 i/ n9 o0 v$ j2 r(2) 配置打包类型、包名、类名;选择待打包的M的文件3 N; S2 l0 }) ~
/ R" U0 _7 x; |( b3 O& D. u% U8 E

& U! _  \7 ~4 ]: L(3) 等待打包完成,应有3个对勾5 A: p6 n! j/ @) J) }. ?

5 c0 M5 M( `5 \- n. ?9 v
  j& A, P6 F3 ]: S8 y  l(4) 打包生成的工程目录结构如下
) u; B, f0 L# `5 f 6 [7 W- t6 B4 C) p5 [/ m

8 Y# s* `- y9 N3 I5 W" U% `4. 新建Java项目,调用由Matlab得到的Jar包
7 y& _8 D/ r9 ~+ P3 m! A4 s& q6 @& a3 `
(1) Eclipse新建Java项目(不赘述)
' `2 A9 x- ?+ |5 h. X- ]4 Q( r(2) 添加两个Jar包到Java项目中. L2 G, d. I4 o, |

8 _  Q1 L8 D) m: O; P  \, j6 h: ?
; g/ M# S, |5 \1 B6 `
1 ^  `. g0 Z, o* R3 K. T! ?2 W
(3) 写Java程序调用Matlab生成的Jar包,源码如下:5 e+ y3 k! i" ]! t( z# }
, ^* H3 [2 \& E/ n7 q" t
package com.csrl.localization;: [4 [" ?$ K  o% B5 ]+ k7 ]% n6 e

* @+ x2 S. i  S1 G. k: R! nimport com.mathworks.toolbox.javabuilder.MWClassID;
" Q4 o+ u' [3 `4 o0 T. u1 {) {import com.mathworks.toolbox.javabuilder.MWException;
+ z& ^" A) B" j0 s' c: himport com.mathworks.toolbox.javabuilder.MWNumericArray;
1 z4 k+ ]3 T  M' wimport localization_matlab.MdsLocalization;
) Q9 V: i7 x: J3 \! Y6 b. T/ E/ \
5 Z7 a0 J# [1 }3 O' `. s. O7 |+ Bpublic class TestLocalization {; \( l% ?* U( U4 Q6 a
7 d9 U% L, E! [5 x
    public static void main(String[] args) {" T# H' U  m5 v( z+ B) M- T
        try {
, \/ U) n+ g) v/ @/ J7 {            MdsLocalization matrixCompletion = new MdsLocalization();
- Z) v2 O0 q, ~2 [* }1 e9 }, ]& t* w/ ~3 V1 k+ r) s$ i
            double N = 10;. E/ {- |* ]! H- O4 z: O
            double dim = 2;
* o5 J' A# I; Y            double space = 500;
2 T2 L! ?. U* N* i% X            double sigma = 2;4 Z' Z6 {  m/ `7 @8 F4 G+ y
            double nGps = 5;8 O5 }/ x9 ?0 L
            double numMiss = 0;
% }7 w- m4 A- v; M2 n, o            double[][] gCovArr = {{1,0},{0,1}};
6 i& e( R- d' r  Z            MWNumericArray gCov = new MWNumericArray(gCovArr,MWClassID.DOUBLE);         // 将二维数组转化为矩阵  `! }3 R* W% d# z0 }4 N
) v6 a- a6 C5 z: `" L7 j
                        // 第一个参数“2”代表原Matlab函数输出参数的个数,后面的都是原Mat了吧函数输入参数;输出参数用Object数组保存) s, O2 j9 N2 V. x+ ~, z
            Object[] result = matrixCompletion.main_localization(2, N,  dim, space, nGps, gCov, sigma, numMiss);
2 K# I" H' ?  U: {! o. I% x, ^/ F  t0 D. _
            MWNumericArray data = (MWNumericArray) result[0];                                        // 第一个输出参数2 n( G/ ]% l! x* E
            double[][] nodeLoc = (double[][]) data.toDoubleArray();                    // 将矩阵转化为二维数组/ O7 ~  _7 `7 {
5 }  o. ^7 H( m4 F# Y
            data = (MWNumericArray) result[1];                                                                        // 第二个输出参数: ?2 f, ~, B5 f: k
            double[][] pMds = (double[][]) data.toDoubleArray();                // 将矩阵转化为二维数组
8 p. O# X" f$ Z5 [% f  [4 ]" S+ G1 ^, \: f& a# p9 f8 M* b
            System.out.println(result[0]);                                                                                // 同Matlab输出格式,输出矩阵
% G& {$ `. m- Z. ?            System.out.println(result[1]);0 g( Z5 V5 G- t: T. ~

/ C- }- a$ `+ \5 h6 b5 P& k, L: ?            System.out.println(nodeLoc[0][0]);                                                                        // 通过二维数组索引输出矩阵中某个元素2 T+ j! O% \0 I5 \
            System.out.println(pMds[0][0]);
) L2 q) `% I+ t" [- G6 C. N- b) P0 e( P# |
        } catch (MWException e) {2 w) U  a3 x7 |. d" y
            e.printStackTrace();: P) n5 ]; F) m3 o
        }. d$ S0 X, M, `( L
    }* {. W/ y. j* k/ j4 n. X
}( q# b: R0 o7 K9 d

' q* p  ]9 S; s9 o; ]: o
6 X& d3 x0 F) a/ o: E7 S! F3 a$ ~

作者: ExxNEN    时间: 2020-5-6 14:04
Java调用Matlab程序




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2