EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
前言:众所周知对于循环这种运算,matlab的运算速度是不快的 想起来个冷笑话,黑客帝国里的主角呢奥之所以能快过子弹,因为Matrix是matlab写成的hhhh 因此将循环部分用C语言写,然后编译成matlab可以调用的mex文件,无疑可以加快循环运算速度,从而加快整个代码速度 之前因为合并数据需要不会数据库,强行在matlab里利用类似excel的vlookup功能,无奈太慢,只能想办法最后知道了这种方法,最近偶然在桥哥的知识星球里又提到了,也顺便复习和记录一下。 ps:今天在闲鱼上买了小车车,高兴! 1.环境配置我的是matlab2019a,win10-64bit,c语言编译器我选的是TDM-GCC(gcc/g++),安装起来很简单,推荐matlab2015及以后的选择这种,详细安装过程可以见文末链接1中的For Matlab 2015部分
3 @+ u/ V& a3 t5 Z4 `6 E9 R, ]% n2.如何编写可以被编译成matlab可执行文件的c语言代码我是在matlab中文论坛(地址见reference第2条)里找到如何编写的,不过他写的有点乱,我来消化后写一下自己的理解 mex接口函数跟一般的C语言文件主要是两点区别, 第一是必须引入头文件mex.h #include "mex.h"第二是多了一个叫mexFunction的函数 void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])举个栗子: - ( j2 D; ?0 a: |$ k' {
3 d; A b0 O( Y. S" ^ o0 `' i
#include "mex.h" // 使用MEX文件必须包含的头文件
- b* ]: p" G4 ?/ ~2 b0 W
+ {# }6 G# G# v( W; O/ ^
- }' p1 e& k+ o: i3 d8 w; }! O2 J9 L0 q& U4 _! L, f) q& ^
// 执行具体工作的C函数 n* w' m8 a. V# I
% ]- s, x( T' m! m
- ) ]$ R" E: k, m8 X' u9 b1 O, L3 G) O
# L! G& t2 V0 q: c' |. Ndouble add(double x, double y); C8 w" i+ a* J! J: x8 A3 L
& J. A1 a) d0 m# H3 T
S1 T2 G" Y [- A: B" C$ x3 P) Q) Q/ f( M4 i c" B$ y
{* }0 S" K( b `8 z% W0 f
: [- J* @. s; I% D- 8 E5 n4 E/ V2 S* N* K
5 e& P/ ~6 A% u0 K. W- I. _
return x + y;
1 o, v6 ~) D2 _
# G0 j4 N5 a: w, m% t/ B - 7 C9 ]; m" ^* f. P0 t- x
* I) u+ a c4 d. p) N( h% [& {, V
}
) O8 } ^: _# a# K* \, q/ D/ w8 {# D
$ V- E- f2 ~ E+ B
7 a$ m, E7 U. p, x! K' l1 a7 _8 X// MEX文件接口函数
3 G3 g/ h, r/ j/ Z0 A- Q9 U; t1 t. s" L# ]
$ `4 }5 d# g! b: b0 J9 q3 v3 u2 K. J; }: J' O& [/ D
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
1 N9 D; f( t; q) Q2 j' [5 F: b
. ^+ M2 s% m; B8 D! H- % F* |# z2 ]+ h5 N$ O
3 B. m/ Y; ?$ C- H. n{
) |! C5 W5 V7 M5 t- D- D( h; J( k6 h9 m
1 _3 `5 E: W$ Y3 ~ [
4 w X# m9 Z; H& O: t) B. L# E double *z;4 v, N$ o; K0 A q$ A* h8 W
' P, X/ z1 G/ L ]/ L9 k7 {5 }2 t- 9 T$ V2 k( ^- O$ y( N- g/ {
4 H2 J2 G" W$ a7 E! G double x, y;
( ]! g: o5 H- }5 r! D
* ]& u1 M- M* A9 Z J - 3 R& ~2 B: h0 J
! v' y5 j0 {( @3 L plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); d2 z. _; }7 g7 G8 o7 w
& A1 {) e- L. w& [% ]6 R) R
0 X7 }. B% b9 g( e0 k z/ H, q1 _. L! H
z = mxGetPr(plhs[0]);1 p A2 u$ K% r, b: t: O1 x
( d' h) z1 t+ S* y- ^& O
+ `& P- p* c6 Y7 o7 H" `- _ Y0 d- w' G, ?4 Z& R
x = *(mxGetPr(prhs[0]));
7 @8 Z% |! U w9 q
2 { O0 {, m; s. F- / L9 i- `. H( W6 ?2 c9 N" Y, m1 s
" Y% F; G1 u7 V0 [9 N y = *(mxGetPr(prhs[1]));
: c( |/ m5 J2 ` b4 [6 _
5 Z) @# u( H- g( T& w - 2 F+ }) p) j2 @
0 p F, r& `, O, I b3 j2 L$ t' b; ^
*z = add(x, y);
2 m3 T. f- q$ j# ?; X+ R6 O' L. x$ B7 v$ ~
' b) c' c7 w- G- Q( Z' p& A; u* N8 Y% n7 `9 W
}; p) o$ _/ b5 u0 h3 R) z5 `
# ?9 ~9 y D( [! b7 w+ Y( x
0 d$ n/ ]) D ?
也可以写成: - + J! ?9 D" C: |0 V# R5 \5 d
3 f% V5 C+ u3 M#include "mex.h" // 使用MEX文件必须包含的头文件
2 @2 ]2 b: F4 s, J( I: |
; N# ^6 O; E+ G( j) z. j. p& l
' R& x4 ?( I3 I" X$ h D- I; ]( b6 M& T2 r6 ?5 c
// MEX文件接口函数
" e7 ?" Q+ t4 ^: x% S6 x A& f0 J/ E9 |! O
- g( h |4 S0 \* N) s9 C/ R1 p1 |) \3 y6 ^; f7 i3 \
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
+ T+ r) E( q X: ?8 x0 L- z2 a4 x$ s; m- N/ E* M7 I' P$ Y8 ]( X7 y
1 ?* {0 B# I! l( d
, X" \0 W0 B! Z1 |2 o8 |{: u! O3 G) S& X5 E9 F! X s
! a1 G& D/ O( u9 V+ y: P7 ]
- 7 I1 K# m) V+ n% O
% K) d, K# B, i0 U) m
double *z;
( Y* o; g4 }, X
: E; m! i H6 a, B - - v" t# A% q' \8 f: P, [
4 @. j/ [5 }- P6 |; a x/ r
double x, y;3 m& o4 h: K* m# v9 B* l3 L: q
! ]! E& ?4 ?* w. K/ e
- ! U. ~8 ^: P/ W5 _3 {* T- R
1 P6 t2 D' T8 [6 K1 A plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
5 G8 i: ^3 E% l6 N/ x2 n
% v4 }) x7 p& p, K1 U8 ~/ y - 6 x4 o0 H, A1 _- k: o
1 c3 B( P- y9 s
z = mxGetPr(plhs[0]);% N* t+ b8 ^- H
( D7 g1 | z4 f, {: Y0 y2 e$ M1 o2 j
. F/ M3 U3 Q7 f3 d: t: F
* u! M* [% ^ n& ]+ R/ E x = *(mxGetPr(prhs[0]));* R7 H: m5 y" B5 \0 a k& o
/ q0 q' r8 P* v4 B/ E: q0 q
$ C# _( |5 g: h$ k& L9 g: b. D# X! D1 D/ Y3 Y2 c) Q7 s" d$ X
y = *(mxGetPr(prhs[1])); t' @$ u2 i- B( G
! Z3 B# [' ^0 ` ?
/ t) `& ?5 G8 Q) d' e
( n* n, z, U4 N7 t) F *z=x+y;
* }4 [. h( z* G( B& t
, J O8 z$ `/ x6 H1 G g* _# O" ~
! B1 C! c0 ~. }7 V4 b) `4 t
& V) |$ Y! G3 {# H$ n}
6 F) l$ l# I( u- T
4 _ C1 l1 k3 f1 Y" q6 h5 m5 p# g) E2 b9 v( L, c
也就是说执行具体功能可以通过编写一个独立的c语言函数在接口函数里调用,也可以直接写在mexFunction接口函数里 我个人推荐将具体功能独立出来,这样一来: c语言函数负责执行具体功能 mexFunction接口函数负责数据的输入输出(将matlab数据输入c语言环境,运算后再输出回matlab)形式组织 再调用c语言函数
分工明确。 于是关键问题就是如何编写mexFunction接口函数了 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])下面解释一下mexFunction各个参数的含义(这里看到是void,即无返回值,因为传值是通过指针数组plhs[]传出的) 参数 意义 英文全称 类型
) }4 E% M8 |! z; lnlhs左边输出参数的数目number of left-hand side整型(int)
, x$ N8 y6 z' Y6 n1 ^+ u0 C0 `plhs指向输出参数的指针pointer of left-hand side指针数组
3 f* c9 r; i2 P- ~- P% H' [9 q* Pnrhs右边输入参数的数目number of right-hand side整型(int)
6 m$ u( t6 {; e0 gprhs指向输入参数的指针pointer of right-hand side指针数组: @, E+ z7 _! w: A
第一个参数nlhs是输出参数的数目,第二个参数plhs是指向输出参数的指针 第三个参数nrhs是输入参数的数目,第四个参数prhs是指向输入参数的指针 其中plhs和prhs类型都是指向mxArray类型数据的指针,prhs这里还加了个const,这里的const跟之前c语言中是一样的,代表不改变,因为prhs是指向输入参数的指针,mxArray这个数据类型是在头文件mex.h中定义的,in fact ,在matlab中大多数数据都是以这种类型存在。 还是拿之前的栗子来解释: - 2 o1 {3 ?. Y+ _0 T4 T
% t* g' N9 @. p8 s; M#include "mex.h" // 使用MEX文件必须包含的头文件
5 s2 V5 x" X2 A) a7 B6 C( n; W9 w' m, P
8 Q+ A4 I4 k3 K/ r; D0 S7 d' U& o7 ?' O7 T* \) H/ O. _0 ` c- B( z
// MEX文件接口函数- P3 |* W; |0 F' q- ]4 l
2 e( v% R5 H% }
- / c |( K8 C8 q
5 W) K1 T: d# E5 V1 }$ e
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])" [2 ]" \7 l. z7 _ |; U: \6 R
+ A! d n8 D. u4 V* m- ~1 N. d
% q1 i* n6 C' d7 o
- U, `8 a0 d5 s! E{7 | F8 y1 [" Z4 P: E3 U
5 W/ y$ S/ n1 k( ] }9 K# C
& o3 L* ^4 M3 D9 ^$ {5 M8 ^( K) ]. g. X
double *z;
- I6 X/ k6 \' t, v' M* l; Y9 X) d8 u( l8 r9 D# K& G
- 9 q3 y. b( q4 N( E2 F l
9 d4 t4 S5 @& j! a8 H
double x, y;
1 M: ~0 m* X* k8 x6 g. J) q/ m/ \ }- V# j
- 1 B' u- p- @5 r! W& x) E
6 S/ ^1 g; A `+ J plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
2 \# J, u1 e) x) _8 \2 _7 B3 _$ i/ z, a) F
# ]+ G1 p t$ w/ k1 ^3 d" u* G
" C- G) I" F$ Y4 N z = mxGetPr(plhs[0]);1 u& G. d9 Y1 k' ^! [7 y. `* `+ N
0 `/ Y$ e$ B9 |$ p0 }( Q
- - @9 J- C6 j% ^0 g, R, g
9 P/ y" G8 T5 T. b" a3 i5 H x = *(mxGetPr(prhs[0]));/ Y* l; f. V# c5 l3 K8 b
; U. z" u& @8 w F; b. C( u
2 u7 M( y$ w8 ~1 O- k: h0 H& w0 g* o6 ^( x3 _8 o- O! j e; c
y = *(mxGetPr(prhs[1]));
R5 V! N% B8 k, C9 J7 Z2 H
8 J) Z* ]$ c; l( d1 _- : v7 M+ I% ?+ T% m% v4 }
' T- Z( A6 g9 d* M# p: Z0 b: d& `
*z=x+y;# m! ^4 h, Q+ V5 g$ n1 }
, |( G u, V+ Z, l$ [
' Y. i, M7 g8 R% Y3 k) P# {; N
) ?) h; [/ y( C9 p}6 U$ f8 ~, Q5 ?$ l! j* c
4 Z# n: b: A5 X( ]' h$ S X6 s! @3 w8 V/ _2 \* B
在这个栗子中,输入参数是x,y,输入参数是z(虽然没有返回) plhs和prhs其实都是指针数组 prhs[0]代表指向第一个输入数据的指针,mxGetPr代表获得这个指针,后面再加个*就是c语言里面再正常不过的按指针取内容了 所以就这样x,y通过下面这两句传入到了mexFunction中
$ f% I# [% n7 Z! A# T: B! v, M3 s! p- _3 w& g
x = *(mxGetPr(prhs[0]));4 O/ i- ^) O: W. H7 ]$ n
" J* X% _% z, k# ~% G
, Q) M' n" y+ C( G" r% @( m0 k# `' v# O [5 K* Q; ^$ X U
y = *(mxGetPr(prhs[1]));; U9 C/ T- A( s4 R$ J# N# K
% v1 E" @' U5 d0 L$ B* `$ f, s# H! X
& a% S" o" ?4 ?+ }7 w i+ o
mxGetPr函数的功能是从指向mxArray类型数据的指针prhs[0]、prhs[1]中获得了指向double类型的指针 另一个函数是mxGetScalar,Scalar即标量,功能是把通过prhs传递进来的mxArray类型数据的指针所指向的数据(标量)赋给c程序里的变量。前面的mxGetPr是传递矢量的,否则矩阵或者向量就没有办法传进来 这里由于传入的每个参数是单个值,于是也可以用mxGetScalar改写:
. C# ^! z% ^: j, H L
, |/ q1 z; c9 A3 E- Q7 V#include "mex.h" // 使用MEX文件必须包含的头文件
& X7 s ^6 w1 a# E" |9 H J1 D9 T% x3 G) x" q
, @! X5 }1 r$ V* \7 ^8 c9 S1 {* R" m( P2 @0 d5 i' [/ j# H3 I, k
// MEX文件接口函数
$ w- r4 @& Y9 w0 P) L+ z; |% I
0 c/ |7 b1 v1 g% F3 I
# N# F. B5 H) v$ H f7 V
$ I0 ?( q5 H9 C& ?# Yvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])+ n1 k/ m; C( z9 K4 W2 N
& Q' ?5 }+ l0 g
4 W8 s; z* @) A: ~0 d N: g; I9 l, d* ~
{
" H% p" K, `2 Q9 l. V6 T4 D6 [8 N, a: G; O9 Z
; j$ a E) k. d7 t# c! [* h8 K @3 Z- y' s: s: C
double *z;/ h* f1 a$ t& d1 F. V/ I
- W# E2 J+ U# ^* s1 T
9 R6 n G2 P( R9 G: } l7 n& H. z( Y! a- f3 U5 B7 [
double x, y;
/ B4 \1 T/ ~3 R) [* l4 I, X. M3 y- y9 }1 @
- 2 w# ^+ U8 ]) Q3 U+ J3 k
- P; O* {% h( `7 q
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
8 `. I0 L+ s2 l- T" x# W! z- p, L! E3 s `7 |" X1 W
' Q" c* M$ o2 v! c; V0 H+ L' G& J3 `$ T. i! Z/ }
z = mxGetPr(plhs[0]);
8 H+ w& t7 U+ e4 }5 Z7 L& a1 s/ Z3 X% R4 I( l
- 4 j- S% ^) A5 k0 x( G& W; \
/ K5 G; ~: S8 L x = mxGetScalar(prhs[0]));
4 T+ [/ r. Q/ {
J/ I7 w$ D8 R# m0 M0 T# s
3 W! Q2 n7 I& v" {3 g+ u! @' T/ h6 s! p- c! T
y = mxGetScalar(prhs[1]));
/ A7 g/ I" u/ D) h* m" S* x s1 ?3 i$ Q- f
- : S' j) N" K3 s9 l7 T1 I
. W& b/ @# p+ O) u, a7 e7 G
*z=x+y;4 \) `" ^. G5 B; ]8 q s6 G. s
" O1 i w2 s1 N$ y+ z# ] - 1 V( c# e6 N5 r; B
% F6 p2 G: u* b" O0 h P o
}
& e: J- a9 r) K' D' R9 E: R) U {" F0 l$ o' v/ l
% b/ s ?1 I; V0 w1 |- c' \# A6 s2 Y d
(注意:输出参数因为需要通过指针传出,因此这里z必须用mxGetPr这个函数来从mxArray指针获取double指针) 但是这样还是有个问题:如果输入的不是单个的数据,是向量或者矩阵,即使我们通过mxGetPr获得了矩阵或者向量的指针,但是我们假如不知道矩阵的shape,还是不好取值或者计算,所以这里又有两个函数mxGetM和mxGetN可以通过传入参数指针获得传入参数(矩阵)的行和列数。 需要注意的是: 在matlab中矩阵的第一行和第一列的序号是从1开始的,而在c语言中是从0开始的,而且在c语言中的一维数组存储矩阵的数据时,是一列列从上到下,从左到右来存储的,也即 matlab中一个m*n的矩阵M(i,j)对应于c语言中一维数组N中的N[j*m+i]
举个栗子: - 8 k5 g. P$ |0 I) @/ o% P, `, |
% D. U" T Q+ [) F3 I
#include "mex.h"
. J; Y+ Z S( \0 o1 r7 w9 ?* B" I: z
- 6 K& T8 W$ T( T+ r, C# ^. k0 A" W
4 w3 D! ^, v$ Z
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
2 _4 ~+ J; X7 [# x: M- Q$ z5 M4 s" X; m! F( f4 w( K2 p, j+ `
$ n. G- L2 Z9 v" g+ i9 `! f4 V: W" p% M( B% h% n
7 h1 \6 f: n2 t. `- k5 q# ?8 O) o8 o' w: B
1 J, o! Q5 |- K) S- |0 b2 i* D" y' s5 N. C: c) d
double *data;4 d7 ^/ `( j* i1 M
! Q$ J* y! F0 F, t6 l
6 q4 m: h8 I, U' ~% W8 O. p* P2 Z4 Q0 j$ ]8 z
int M,N;
3 T; D+ S2 C3 x2 D
' W' \+ A& j2 |0 ^- 5 a) H7 t9 U4 h3 K
3 y/ W) V- c/ x1 J" t
int i,j; f2 r4 O- B; {6 S: u2 S2 [
9 q9 V( Y; W6 Y& U5 X5 N8 {) a; r
- 7 P0 v/ l" y" v; x- C
- k7 X" h+ @$ xdata=mxGetPr(prhs[0]); //获得指向矩阵的指针
4 T! a3 `, i) a0 c J* C# K3 d7 K# s6 v+ t% a8 |2 d
. n8 N$ p$ T" o: d1 N
* g% p. G7 O1 E3 o" a6 QM=mxGetM(prhs[0]); //获得矩阵的行数. ]3 }6 @$ F6 S3 Z! I
6 e2 ]( M8 h5 u( p* t) P
7 I4 }# G4 G' P7 C `( |
$ V G, K T" Q0 UN=mxGetN(prhs[0]); //获得矩阵的列数7 R1 q0 r2 T- ^- G' |2 P( _
6 ^+ x1 |5 ?; l% t) |9 q
$ r! A9 h! k: ^2 E% [. V
: q& p6 V) k: m4 D, [2 L( j; x- V7 cfor(i=0;i<M;i++)
4 y) e9 e& n, w# q# s% |; D+ X8 m( n* M& }# C
- " G) i5 v, q9 w4 O0 C% e& K
" ^ o P% P) ^" k2 e4 z{
3 Q3 W, p* r4 s9 \& I |8 f: H8 h4 Z. W' x
- " s2 y; \! M- T9 `# g4 P8 |
4 O4 U1 Y! c- n% J
for(j=0;j<N;j++); ?) b$ B$ v! k1 ^1 h
5 d3 q! P- s( d% r2 O; p& {4 U% x
! u" `" k% ^, e- i0 R# \2 g8 q& h0 a' @2 [, L! c. U2 D3 J5 l: D- S) g
mexPrintf("%4.3f ",data[j*M+i]);
2 Z4 L0 w! V1 {0 W7 D r c
* h! M( Y5 f9 {) m% H0 o- , p/ V9 ?. v0 b" `6 v
1 {, P4 h* v5 Y: ~6 ? mexPrintf("\n");( D* t" G- E7 a, F8 Q6 U4 t9 |
^4 v2 V0 E5 A" x+ u
9 } }6 Z3 g6 r; r- B/ H* R* j! G1 B2 i, W
}
4 x, w+ q5 Y9 A$ n" R5 ], _. H7 m. p* Z( B! g0 j4 h4 ~( f
( F+ B$ E$ v7 s# u
/ d1 V8 Z% z* C* K! J3 M5 T }
% M, i' c( Y. ?# U6 w& r* J5 `/ |4 a L* l8 ]+ T
- D K5 ~1 E. {; t2 T, y( g- a W
假如是一个形如[1,2,3;4,5,6]的矩阵,则执行上述后会先后打印出1,4,2,5,3,6 以上讲的都是输入参数,由于输入数据在函数调用前就已经在matlab里申请过内存,由于mex函数与matlab共用一个地址空间,因此通过prhs传递指针即可传入输入参数。但输出参数却需要在mex函数里申请内存,才能将指针放在plhs中传递出去。由于返回指针类似必须是mxArray,所以matlab专门提供了一个函数:mxCreateDoubleMatrix来实现内存申请,函数原型为: mxArray * mxCreateDoubleMatrix(int m,int n,mxComplexity ComplexFlag)m,n分别是待申请矩阵的行数和列数,需要注意的是为矩阵申请内存后得到的是mxArray类型的指针,就可以放在plhs[]中传递出去了。但是对这个矩阵的处理(包括赋值)却需要在mex函数或者c语言函数中完成,这就需要通过前面的mxGetPr或者mxGetScalar。使用mxGetPr获得指向这个矩阵的double类型指针后,就可以对这个矩阵进行各种操作和运算了。 还是拿这个栗子讲,这里由于输出是一个数,于是m,n都是1,通过mxGetPr进一步获得指向double数据类型指针z
6 ?6 r0 v7 f. r! ]2 J9 a0 u, C# ~9 B1 n- D0 D& _
9 o4 b: y0 G f( G
+ N& Y8 L: T7 U; [+ @
- 8 @; F: x; X3 ~/ O; q# E+ c9 w
) `: `7 @& W: A
double *z;
/ {6 Y! g1 y) r: k4 l# z5 J- b7 N
; t |+ k3 j) T- X- A7 Z/ Y! M
1 L, u+ F! s1 j! d% e" E S& e) D' \3 @
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
" t, T, W- E1 G# ]) u- B3 V1 {% p9 h# N Y& M+ v- H7 o
- % }6 P' G* r( u; E. b, C
L0 m! R, I, k# n3 a6 c z = mxGetPr(plhs[0]);
2 D7 s& d6 _% d+ H1 i K/ W
+ M, M( y7 o, n# c* q3 u- } - " [ ~, S7 w: K) M7 }4 d7 ]3 B. y
9 t3 z7 [4 J0 d3 N+ Q9 N0 S+ }
x = *(mxGetPr(prhs[0]));; y) t z+ M- A) U: {
* C$ i5 Z: J) [5 K0 z
0 ]- `3 O. G- L
8 E: \6 s( z* I y = *(mxGetPr(prhs[1]));
1 o& Z6 Q |& d! t/ D7 [6 g" O3 j& }: [) S+ o, p
- + ^' _1 A+ T1 i. T5 {
- e4 q0 O4 K# `0 K *z=x+y;
6 \3 H' {* X# h: K, E
# h1 O9 ^, S; `% J
' `* u7 o7 G; K9 L
当然,matlab里使用到的并不只是double类型这一种矩阵,还有字符串类型,结构类型矩阵等,并也提供了对应的处理函数。
0 y' k% M* X% `0 I; r7 J |