|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
3 F+ T2 g& [0 A
Matlab是矩阵语言,如果运算可以用矩阵实现,其运算速度非常快。但若运算中涉及到大量循环,Matlab的速度令人难以忍受的。当必须使用for循环且找不到对应的矩阵运算来等效时,可以将耗时长的函数用C语言实现,并编译成Mex文件,Matlab便可以像调用内建函数一样调用C编写的函数。Mex文件其实是一种动态链接库,旧版本Matlab可以直接调用.dll,新版本要调用.mexw32或.mexw64文件。
, G$ ] @( u; L1 m4 A. @. h# F
% `$ v$ L" J. A( z" X编译过程需要C语言编译器,在Matlab中键入mex –setup进行安装与配置。. R4 X# }; k6 Z; B; I
$ B; P! }8 g6 Z6 s' @7 p$ |
MEX文件的源代码组成:8 T& [6 R9 x+ ~- s, ?( n
* _/ g9 z+ S7 J
(1)功能子程序。该过程包含了Mex文件实现计算功能的代码,是标准的C语言子程序。 W6 q) @1 a1 `, V0 |$ e6 O5 _
* {5 _0 y" S- B4 D- N' M) e
(2)入口子程序。该过程提供功能子程序与Matlab之间的接口,以mexFunction函数实现。注意,入口过程的名称必须是mexFunction,并且包含四个参数,即* q k/ d3 l1 F: ?
% S* x8 k% f5 o* `' y
void mexFunction(int nlhs,mxArray*plhs[],int nrhs,const mxArray *prhs[]);
+ P: t: F+ Q/ {! ?) W+ i7 D, k) i5 U0 Y
nrhs(left hand side): 输入参数的个数; [( C/ R& P, |6 ~; i- X! M
7 R# @: u+ r/ Q7 j/ B; e+ L, P
prhs是一个输入数组,其内容为指针,指向mxArray类型的数据(MATLAB中所有数据都是以矩阵的形式mxArray保存的)。% _6 V" ?& G4 p) ]! X
- n6 u2 E- ]& n2 G' c* q2 |nlhs, plhs含义类似。0 O, o/ e0 \, [+ s
% P' S5 G5 f0 r8 O1 U
具体地,若在Matlab中执行[a,b]=test(c,d,e) ,则nlhs=2, nrhs=3,prhs[0]指向c,prhs[1]指向d,prhs[2]指向e(可以理解为:prhs[0]=&c, prhs[1]=&d, prhs[2]=&e),注意prhs是const指针数组,故不能改变其指向内容;函数返回时将plhs[0],plhs[1]指向的内容赋给a,b(可以理解为a=*plhs[0], b=*plhs[1])。
4 G! r- h# _0 [9 g1 h0 S: ?# t! k* J2 a8 k% w/ k" n# j5 w+ l
实例:
7 `0 O+ V. ~) O1 {. q ]5 U% x3 Q; H
C语言函数,按照上述方式建立。
( [9 @. z9 ^- I; F( W( J
# H( O2 T# ^1 q/ P# ?C
4 I" {* ^! Y! W6 e
+ y/ i0 g/ p/ a& e" O' x5 o8 ]9 J#include "mex.h" - N; ^' `( t/ h2 Q
double add(double x, double y) ^3 ]9 t& |, @5 n& {$ v
{ # ? j$ g$ M* W8 n. g
return x + y;
: L2 O+ ]1 s) h4 | F}
$ z# }& f, r& E3 r5 _void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
$ X. l- K9 }/ V8 } I{ ' W5 ?) F) m+ T; x& ]
double * a; 6 U$ R( P8 q8 l, y( L i0 [+ X
double b, c; 6 n* h$ B1 V4 d3 i9 S
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); " X J; x) j$ J4 b1 w, l
a = mxGetPr(plhs[0]); % f* {) H/ m: r
b = *(mxGetPr(prhs[0]));
+ L* t ?7 G2 L0 d$ S c = *(mxGetPr(prhs[1])); 6 A! \( G9 X* m" I( d
*a = add(b, c);
+ V$ k# s M" L9 ]' U% U: x0 T}( X# b0 x" {6 e1 M( _* P
1+ ]5 K3 x6 s% @2 F0 [* i: M
2
/ ^9 J: E$ x" C% p) m+ W35 L" V4 }8 ?' x2 H" o3 m* C
4
2 T; b8 d* E: o. p, U5
8 i3 K; J8 ~6 V$ j% h) `. Z$ L6
8 b/ N' N3 G: E6 j78 \$ I" N1 b, e% w
8
/ B6 y' ]* R8 v. [6 [6 v* ^7 p98 s0 a4 t; \4 U
10& G5 r. m8 r# ^
11
/ E+ V! r& R3 Q& _5 R3 W; e$ }12
# q6 `' s8 u) [; s5 E13& c) x0 A. e) f0 `4 A
14
( {% `( M$ S: P' C9 ?3 V$ S15* J% P# N& T$ V' _% m6 q: K; A
#include "mex.h"
/ f0 _1 K% G; v8 s) j; v) v4 Wdouble add(double x, double y)
y8 l3 h/ A2 W6 F! i$ P' j% p{
! C# B& Q. Y T1 X/ q return x + y; ( ~& W6 k5 q; a
}
$ r* `; E1 i9 [! R a c& Bvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
: T) \- ~, w w j. ?6 X# f{
4 V/ y/ Z% r+ n; M { double * a;
( H: g/ B Q8 | double b, c; ) X. S% A' q( Z* T: |' v% d
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
$ | m; t1 k: }# W8 c7 t- j* i a = mxGetPr(plhs[0]); # D& z2 z A+ V7 ?! S" ^9 O4 e
b = *(mxGetPr(prhs[0]));
* g* @& v# F9 X5 q4 Q; [6 Y c = *(mxGetPr(prhs[1])); & i% A ~% x: ?2 B
*a = add(b, c);
3 {9 J9 n. P3 @$ Y) I+ c}
6 W& O# J8 ?! H- J2 r4 }接着,在MATLAB控制台输入:! }: @* T: h( z; T3 l- `8 p' m- e
% m% f, ~( U) {' t# Q. pMATLAB" i1 z6 H& w$ R1 Q; R3 W) z
) P6 V2 v2 }$ {3 z5 {$ x8 D* ~2 M4 n
mex add.c
+ W% `) R# E8 k% H1! o$ x: U& I' N$ X
mex add.c. j' a* O9 x+ g
格式:mex C文件.c! u6 s& s: q6 }; }
5 Q/ S. M% g$ I" ]$ N) y
这时,路径目录下出现:$ P5 C( u! w; d$ [
7 @! q6 P) j; p+ Y
最后在MATLAB控制台调用add函数即可。
% o! W! B5 t- M9 j; w+ D2 o, @3 d/ l" \4 i) K
add(2,3)+ ]+ W* i, \0 W& E. r. x7 a8 _
3 ~0 }- B1 P+ r+ X
当然这个简单的函数不能体现C语言的快。9 B8 B P! U0 P
当有for循环或者大的计算函数时,调用C语言效率就会变得很高。 |
|