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部分
! {) ^5 D8 w# g7 k2.如何编写可以被编译成matlab可执行文件的c语言代码我是在matlab中文论坛(地址见reference第2条)里找到如何编写的,不过他写的有点乱,我来消化后写一下自己的理解 mex接口函数跟一般的C语言文件主要是两点区别, 第一是必须引入头文件mex.h #include "mex.h"第二是多了一个叫mexFunction的函数 void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])举个栗子: - ~) g( ^3 O3 A' ]/ Q; W
7 g# `" Q+ N* _6 p3 x#include "mex.h" // 使用MEX文件必须包含的头文件
7 g: P+ Z# |! T+ D" O3 s. z
2 L% J9 c. u' O, o& T' L# \
]% Y" n. ~0 d
4 z+ C' c/ K- c1 l7 p" U( L// 执行具体工作的C函数/ Y% L+ A' d! x. x; K
: A& C% c$ z D2 v7 g5 H1 \8 G1 ^
7 l( K: f! R, R/ {" ]( |4 r* S: K1 x9 H/ A" O: Z
double add(double x, double y)
7 ?- f, v% r! l& ?$ V) D7 N4 _5 H. y( v3 T1 _9 n! k
; q+ Z b! [; o0 K1 d. W
# B* a' A* Z$ N4 o s{
% q1 G) h8 ]0 J" D3 V5 [% L% P0 f* d' s9 t% _) U B
. K" J+ ^" j A" `5 l1 F3 G2 f1 V% [& _) w* F7 `
return x + y;7 }0 t L; ]( q8 L* i0 o
3 }. I2 e& [- i5 k' p4 q0 Z
& B t! M# q. ~7 X2 u4 i9 ^; c2 R! H. Z6 p( G3 J
}2 w6 f2 K* z* T
! v' w/ J1 F( ]: _5 |
- ; a+ h$ `# H/ `# q) |
9 O& V! u) g$ ]/ w0 ?6 v; `
// MEX文件接口函数
# b8 j3 O+ z. Z6 s8 y3 P" j5 M0 m9 \
- 9 x5 Z x' {& d) E4 Z. ~
, r! a. f9 [( n$ x) svoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])9 @9 W: V4 b5 l* k, j6 Y0 l
, ^* `. X/ _# P! m! O - ; o P- v8 z% }: d9 e# X
: R5 J8 _7 r. w! ]$ q{& A* k! s0 b9 ^( z3 N2 }
. k7 W! p+ R n @/ _+ g - , d/ G) c+ r3 e
7 F1 W; g0 K) o$ u, l! j( v( S( O" U- S double *z;
* g' y$ V+ Z/ w
|6 |1 S. h# t# t4 l+ v( D - # O5 k# [3 U2 n! |3 |3 ~7 ^6 W9 M
$ v% E. O5 D, }
double x, y;
& ^0 z) O! w0 w! F- v% H8 H$ x
: u8 T) Y( `) A4 Y( ^! X
8 R! a3 c) Q' z9 V
8 W: x* @9 o0 q6 L u plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);8 A! F2 B. z3 s2 ^
; d* y0 ]6 V+ [3 \# p" N- - y6 W2 Q, x& H# B5 L/ {& S8 ^/ N
4 j1 ]* B9 f% `- p1 L% ], v
z = mxGetPr(plhs[0]);( f2 V/ Z$ z" W$ Q/ L, x
& y$ w6 U) E& H) X
7 r) p9 G6 C8 t* @3 w' Q. h H) h/ J2 m4 B7 V
x = *(mxGetPr(prhs[0]));. q' o! ~1 H& x6 e. v/ Z$ c) Z0 f
: G. [# q" ]% N
- . U" Q% \. U2 r
& S: p# r+ f2 I/ Y% _& | y = *(mxGetPr(prhs[1]));* W. l9 s! d: m( x* J6 ?
2 K+ z) W# k6 ]
: v- A g/ n% k3 @5 w% g9 q9 g& N A3 A- w
*z = add(x, y);* F6 s% T5 b5 ~3 o) }: k: i
' G5 l; L1 j( N3 V
- ?2 Y( o, r0 B; m$ I6 h5 ?! y5 E
4 | u( H3 v1 G l: U}' q4 U8 `) K5 ?5 Q# d
) ?9 R' D2 X S
& |8 n! o, x' }) J" B
也可以写成:
5 T1 u; G* h' i
0 v a; ?, W2 ?#include "mex.h" // 使用MEX文件必须包含的头文件
0 `- M% ]( l$ t7 H |5 m+ E9 J+ y! ?( W. u4 P% c
- 4 |! W' W/ ^+ [3 o
+ C6 _1 q. ^1 K4 s3 w// MEX文件接口函数
1 H* X& T4 ?7 n4 g2 S. u2 m# f3 A; p7 Z4 R9 h, @
5 o" P7 s0 G k! g' e) \; B) |2 Q9 _
1 a* w. R6 w) C( W$ l/ M' @3 Hvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
4 O) S7 p, k2 D0 u6 j1 k% N
6 `; ]4 a9 K$ F E5 t$ O
% y) P0 L% Q* z x3 @9 T; g
# c3 B. D9 x! j# T/ D8 L{
* i8 {) |. E7 Q0 w8 N
, g: Q' l# Y, U1 W+ s
0 d5 [- S# ` W3 o: T8 U
$ c3 g7 L* Z/ q3 r' S0 c double *z;
/ P% g ]3 i+ J6 \7 j8 o+ j3 _. Q- ~( _8 X
! w: J! Y8 J1 r) e) Y/ l4 D$ r
% B: v6 Q4 X& W# i5 l# R double x, y;
8 ?1 E" P( G/ p
3 ]- a( Q- `' N1 p/ R- 1 [6 q$ \& {! V3 `1 s4 e( H- y4 @
0 m; `6 \# }) `! y9 n3 O plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
6 t& T! P: Z: a+ y0 E j& Y1 ?! Y& M( m7 e! |
7 }' O, Z( }3 g5 M( e! r' G! Z$ M, y+ x
( v+ [0 ]; \) V& @3 W9 o z = mxGetPr(plhs[0]);
6 X. c2 I( Y+ h8 G* G" x8 X$ Y$ f `& p: a. ]- e, M4 y
- + i& n" p$ s, g# S- H8 Y- }
; z, \; i7 T: ?; O" z; n x = *(mxGetPr(prhs[0]));1 M/ ]+ l q2 U5 i
2 z. [4 v) X4 T# F
) J% p6 m1 Z3 P' I1 k" s3 A! u8 e' O x
y = *(mxGetPr(prhs[1]));; V# q1 s1 o# k1 O2 s% O
: B+ m5 [6 i& k i1 J0 @+ ?* s
6 I2 e9 U9 R+ A6 C7 ~" b }
4 P: C! i. L5 H *z=x+y;
( C: d( B: ]6 r0 |4 f! W
0 J( `9 V9 t+ q; v/ {
6 @, Y: f! G( c: X4 G* {- T) d( D9 I1 s: H
}
8 K( k- y) `$ c+ o
* w( s! G# C4 F: D% N
; O$ ^( i+ z+ a: }' O3 c5 r. ^
也就是说执行具体功能可以通过编写一个独立的c语言函数在接口函数里调用,也可以直接写在mexFunction接口函数里 我个人推荐将具体功能独立出来,这样一来: c语言函数负责执行具体功能 mexFunction接口函数负责数据的输入输出(将matlab数据输入c语言环境,运算后再输出回matlab)形式组织 再调用c语言函数
分工明确。 于是关键问题就是如何编写mexFunction接口函数了 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])下面解释一下mexFunction各个参数的含义(这里看到是void,即无返回值,因为传值是通过指针数组plhs[]传出的) 参数 意义 英文全称 类型 8 ?# C+ K1 w2 \) b6 y# A/ I( v
nlhs左边输出参数的数目number of left-hand side整型(int)
* F. r4 k* U2 n0 vplhs指向输出参数的指针pointer of left-hand side指针数组) m0 F# k$ j! C' J6 G% D3 Z0 C( W
nrhs右边输入参数的数目number of right-hand side整型(int)
. _& m% Z. ]% ~# I' Gprhs指向输入参数的指针pointer of right-hand side指针数组, z+ i- X- R' n! Y! P8 I- U" _+ t( I
第一个参数nlhs是输出参数的数目,第二个参数plhs是指向输出参数的指针 第三个参数nrhs是输入参数的数目,第四个参数prhs是指向输入参数的指针 其中plhs和prhs类型都是指向mxArray类型数据的指针,prhs这里还加了个const,这里的const跟之前c语言中是一样的,代表不改变,因为prhs是指向输入参数的指针,mxArray这个数据类型是在头文件mex.h中定义的,in fact ,在matlab中大多数数据都是以这种类型存在。 还是拿之前的栗子来解释:
% s! w( ]7 j* F$ f9 Z0 h3 J
' ?2 P+ J/ N c: X$ z#include "mex.h" // 使用MEX文件必须包含的头文件
0 \ }9 k- B% D# }# N% [. z7 k5 U9 {
0 P$ S) I# L2 q$ N! A7 t: W7 O4 f. z6 z
// MEX文件接口函数
1 E1 g, r( A" Z6 N1 J& l, e) M$ W2 b0 E: C/ ]2 q8 r0 {
* u2 f4 ~+ F3 H& W, q/ A
) @; U2 F% v g- m$ ivoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
/ M2 D1 ]9 E3 c3 n, z @. {1 d$ {- C* i8 K
- ; ^7 m: U5 @5 V; v
3 U. T; m8 }1 u5 v- d+ o{
6 X ~4 i. e/ s' Y3 D, Y6 \' P2 I2 o
- 4 D& C8 m i" C) ~4 M" R
7 p6 D) u* {/ u4 f$ ^$ g9 ^ double *z;
6 O; f8 _/ L# k, U+ w( q. z: y& T
' D6 Q5 [+ t1 |' T! H1 C9 k! B - ! t9 z7 t+ i6 V4 M* p& F
/ j& G" B. _/ {; e double x, y;" ~2 d# y& ?( N7 F# D* B4 v: H5 |/ e
) `5 y0 `" u1 \" |" o6 O5 j7 {
; Q0 t% o. f' }% j) u5 w% ]* g, c
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
& X \2 z0 U1 ^1 k+ m: y2 e( }) Q
8 n5 \7 R: m a- D9 C- , S9 u! c+ g4 | Q( v6 Q
, m9 m: j7 x" ?6 f
z = mxGetPr(plhs[0]);
5 V2 s B5 T2 x
5 N- V) @9 l: U% d7 v, [2 x" X7 u - ' Y" W: Y* _! w6 Y
9 X9 ~2 k' |' V
x = *(mxGetPr(prhs[0]));
8 M$ `7 {. ?3 G, k1 Y
1 K& x% S) d& {* M! K$ k! \4 g$ S
) J1 G, j q% o! G8 E
/ G* [6 S" K2 j y = *(mxGetPr(prhs[1]));
. U' J! ^' x0 a5 U4 l: N0 A% N9 W& K, P B
* h+ J, Y" i3 l+ s/ C
: `" {8 p5 A4 m' n/ E# L- U$ Z: ^8 i *z=x+y;
: l% c3 y0 E: c' @: @' \
/ i/ @* j8 S2 t" n( ~2 l
1 V; b) l; E! y: {( F
# l6 J% [( w/ N2 L" M}4 m( ~! [- `: M- i
i9 Q1 h# [" U
! J: I" n9 H9 d0 n" E7 P u1 H2 O
在这个栗子中,输入参数是x,y,输入参数是z(虽然没有返回) plhs和prhs其实都是指针数组 prhs[0]代表指向第一个输入数据的指针,mxGetPr代表获得这个指针,后面再加个*就是c语言里面再正常不过的按指针取内容了 所以就这样x,y通过下面这两句传入到了mexFunction中
! J( L6 G' X( ]- [5 b; S/ q
7 B1 t+ n4 d! v: U* L9 @' Jx = *(mxGetPr(prhs[0]));
2 n3 Y* ]8 c, I% F+ x' e6 H6 t" u4 Z
% l5 w; X* y# X$ F: u: F( Y y8 Z7 Q! v& `" X3 S/ ]
y = *(mxGetPr(prhs[1]));
% M% p$ S& i V4 T. q* W0 i
: Q, ]3 M5 z! A. T
: k7 v1 F6 Y f4 v+ W) r7 k
mxGetPr函数的功能是从指向mxArray类型数据的指针prhs[0]、prhs[1]中获得了指向double类型的指针 另一个函数是mxGetScalar,Scalar即标量,功能是把通过prhs传递进来的mxArray类型数据的指针所指向的数据(标量)赋给c程序里的变量。前面的mxGetPr是传递矢量的,否则矩阵或者向量就没有办法传进来 这里由于传入的每个参数是单个值,于是也可以用mxGetScalar改写: - g# v ^: Q2 ~0 {3 ]
) `, w" J' q# ?6 m+ ]+ O1 |
#include "mex.h" // 使用MEX文件必须包含的头文件
0 N/ |4 _5 U' L6 n$ w; }1 j& c) N/ g9 K- i/ \
- & e8 P1 t: R' ?6 h1 N, S6 P
1 I0 ?# ~( `* x8 C- S5 r
// MEX文件接口函数" ~" g. t! R; A. D$ M
3 d0 D+ g; z. t1 B2 a* Z& E
% Z. Y$ `# w* T! l% u5 g: M* U0 ^9 t/ l$ A6 D
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
8 S) c% k% _: r; D9 E
9 F0 R% \6 ^, T7 U
6 o; u5 d. w0 H5 B3 _( T
/ t* Q. J Y. c4 B$ r9 f{
" X/ u) Z- a+ W i! M% W1 P
' F5 @6 N0 \0 f5 N0 U$ R/ B- " L; }: k! w0 m% U
+ e" d5 U9 Y; W# H( W& I3 `/ R
double *z;
* ~, y5 m1 F: B" @/ e
7 G, l9 l" \- g# N
: x& L$ u- h) v: y2 @
0 ^8 _1 D- o& y( u double x, y;( R3 s) T' w/ h( v
+ v/ a; G/ t" U4 Y0 D; z2 l" S
) z1 }6 K% n2 Z/ H& ]4 _2 O2 I* C) X2 @% W# _( Z) c1 L
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
$ e1 s0 \* \$ Y4 m9 ]( N
, D+ n& l7 \; R- n2 U, K' |
; G8 T5 L) L3 G: K$ q0 @
! \+ R% }! y. N3 _: I0 b# e; v z = mxGetPr(plhs[0]);
' I8 e- t( X$ j
9 Q* ^& T7 n0 c7 ^ K2 e( T- ; E b) Z) {& m5 X
- ~5 t. N, R& q, b4 Q- J2 Z x = mxGetScalar(prhs[0]));* M8 Z; i% A& s5 Y r5 T
% ~" J) x. D$ d- ^; u8 a& d* A1 h
- 5 n3 {1 O; z% V" j; E& A% l
* `8 q: o, x6 p4 ?! E y = mxGetScalar(prhs[1]));* V& M! z: {& W# X# J0 W
2 m' j) p3 F7 b; \( \+ ^1 M3 O L4 r' C
- 6 W& C8 m2 |6 j, b! W/ Z0 L
6 q0 {3 t7 [4 N1 g
*z=x+y;: L/ P3 n4 S0 U0 K4 k% ]
0 J6 @/ e+ E) m) ]+ Q
" _4 v- Q1 m* l9 J1 H: A9 {
+ m2 c5 h; \6 q/ b4 c: a( V}
% f8 C5 _6 P0 ? _) d0 j
+ F) `6 f/ a# j1 ^8 c
- m: g% ~: [! ~! L
(注意:输出参数因为需要通过指针传出,因此这里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]
举个栗子:
/ b% Q0 v1 M% j# i% m7 z; g# E" T$ H3 R, C- E
#include "mex.h"
9 N* e: _0 C2 N& t4 ^% _0 r6 h: l: y9 q- r3 E9 G0 ?" h
s# ]; g1 x3 R$ ~7 w# O5 [6 c' E
5 C0 D. N( `/ ]0 v: n5 C" v void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){0 e" E, E8 t s) P+ J$ V4 U
+ K7 Q) V' B4 W9 A" }' V6 }6 v: s/ d
8 U/ ~3 p0 B0 h( k+ Z' w' B$ a$ J, C3 X% G# u) }; ]8 U. {8 v
4 v- Y. r: A8 u8 r6 L J" G
) @! e9 B, i( c( ~3 }3 I, d/ A
, F3 A5 b f0 q. [" x* @
( Y' n1 {( W' u6 G! zdouble *data;
7 M$ {5 P& l7 [0 |1 s. Y6 W0 A1 ^
, N- ~5 F6 |( f- - ?6 ]6 ] [7 Q; F
6 V3 \' n" j2 k4 C$ t" e: F8 S/ ?int M,N;' m/ }6 L3 M* j9 `. g6 [) H
. T; C. T$ a$ E) W( O
! o+ _8 z( Z5 @, Y& @4 v+ M# q
+ R: F; w1 ]% b c7 J: _+ zint i,j;6 n |9 g4 X- J2 T1 }
9 D# w& |$ e5 b7 b7 j- ! p# R, c9 O# P I0 t' m. W: V5 U
- P* N) h" P, v2 T2 E w( z& k. adata=mxGetPr(prhs[0]); //获得指向矩阵的指针( }5 h$ k8 S8 E
. h! y/ f' C/ l0 o" K1 W
- - c$ _) _, E2 x, ?
0 e4 [; n9 D% L8 z7 bM=mxGetM(prhs[0]); //获得矩阵的行数0 G9 {* x {6 U" G3 B' t
& O, f$ H$ { A q
4 c- W. _) I$ Z3 c+ k m5 e5 w8 w, G% w6 }: J. J
N=mxGetN(prhs[0]); //获得矩阵的列数: X2 P( F! M& O8 G# b. Z2 `6 |
# }1 A: u6 b8 P) [3 ?8 ~
) J" D& _; q3 d* L# K2 s2 K0 u+ z8 x. B: R: X! X
for(i=0;i<M;i++)( ]* T7 J% \9 S- n7 d/ F! i, c
" |6 M. x8 x1 [- m8 }2 `& I% ]0 ~# K
, X# {4 M1 A$ u, L
+ Q# ?: i) n& b( ~# i( f- d; J{
- a6 T* N) c% K0 ] J, E9 _& [# W
6 Y6 z+ [7 |2 s2 m
" m1 u1 g) s" I- R6 M" {% w/ N5 R' T+ |- _4 b" j3 A5 j
for(j=0;j<N;j++)1 p( w5 b( H! y, ?
. t" B' \! n" ?
- 3 Y2 Q* y w2 d9 m: k3 k
! \' s- V; B( O4 S mexPrintf("%4.3f ",data[j*M+i]);
3 ]6 D! a( L% \* K- s
% |+ h9 A3 r0 s+ _& {& V) W H9 k - y5 U' ^, W1 W8 M S% M
1 |1 o5 e. b# u2 ?( j
mexPrintf("\n");! l0 R! y1 c) }8 D" R. y1 G% H" W
3 z3 l" }/ o7 t) g: H" ] - 0 q9 A* b6 P; Q0 N% U9 D
% t9 |3 ?) s' T: V. C
}
- M% g2 K$ X o7 ?0 X$ ?# J" R8 ]! y8 v" k
: }, O. R S. y9 E
7 ^' Y) m! l& l% F }
6 j+ g6 G! E! s H+ f1 E. _
' `% n& ]& _+ o+ @, y- }1 V$ w/ ?: r! r; }$ T
假如是一个形如[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 - - d7 d% {/ x) U4 ?' ~ H
5 [5 v! w6 a8 R: _ t$ b- j9 n
. C9 V/ L D9 t
) y. {" y( X) Y# t. i1 ? - * u" h/ R& ?1 u& J" p2 x1 }
' X! m6 N) b2 \1 {* Z/ w double *z;) B B; o- A) M3 f0 W
9 L, O; o' T. ?
- ( U$ A8 B4 V- G9 ]! c0 |
8 ^3 |6 X2 k2 ^9 _( E7 x3 y: @ plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
6 M; F2 X$ [1 u3 M- Z$ @5 `0 c
. ^: y' C Z" c/ ~ J5 z - % s1 s' I: l8 A' X7 n
0 \ B' r6 V$ e z = mxGetPr(plhs[0]);' t3 F# ?( X5 U- }' j* `6 v
6 |' K6 S0 S D9 P: A# Z) G d$ h/ F
% P/ A! e1 @" b2 ~. E: q/ N: f, q& P: R. w
x = *(mxGetPr(prhs[0]));/ y5 d& ^% j! v; b& p6 P
3 o$ Q$ W7 ]* ]! j# o
- # O7 j! P) a; ?" m9 p
" u/ N# i. A5 ?. p) w# S y = *(mxGetPr(prhs[1]));
% y: x5 b6 I/ S
+ w. Q( }/ O# e
$ m" F) [' p5 R% D& [5 l2 e$ c
, m; U) F9 d2 I6 y1 c& w2 K *z=x+y;
3 a( [+ `' D. B9 h; E& D; i/ e& i$ R
, u5 ~# ?1 T0 c7 y
当然,matlab里使用到的并不只是double类型这一种矩阵,还有字符串类型,结构类型矩阵等,并也提供了对应的处理函数。
3 P* o. b# J5 z! Z( H2 t2 X |