怎么在matlab中调用用c语言编写的程序?

怎么在matlab中调用用c语言编写的程序?,第1张

通过把耗时长的函数用c语言实现,并编译成mex函数可以加快执行速度。Matlab本身是不带c语言的编译器的,所以要求你的机器上已经安装有VC,BC或Watcom

C中的一种。如果你在安装Matlab时已经设置过编译器,那么现在你应该就可以使用mex命令来编译c语言的程序了。如果当时没有选,就在Matlab里键入mex

-setup,下面只要根据提示一步步设置就可以了。需要注意的是,较低版本的在设置编译器路径时,只能使用路径名称的8字符形式。比如我用的VC装在路径C:\PROGRAM

FILES\DEVSTUDIO下,那在设置路径时就要写成:“C:\PROGRA~1”这样设置完之后,mex就可以执行了。为了测试你的路径设置正确与否,把下面的程序存为hello.c。

/*hello.c*/

#include

"mex.h"

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

{

mexPrintf("hello,world!\n")

}

假设你把hello.c放在了C:\TEST\下,在Matlab里用CD

C:\TEST\

将当前目录改为C:\

TEST\(注意,仅将C:\TEST\加入搜索路径是没有用的)。现在敲:

mex

hello.c

如果一切顺利,编译应该在出现编译器提示信息后正常退出。如果你已将C:\TEST\加

入了搜索路径,现在键入hello,程序会在屏幕上打出一行:

hello,world!

看看C\TEST\目录下,你会发现多了一个文件:HELLO.DLL。这样,第一个mex函数就算完成了。分析hello.c,可以看到程序的结构是十分简单的,整个程序由一个接口子过程

mexFunction构成。

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

前面提到过,Matlab的mex函数有一定的接口规范,就是指这

nlhs:输出参数数目

plhs:指向输出参数的指针

nrhs:输入参数数目

例如,使用

[a,b]=test(c,d,e)

调用mex函数test时,传给test的这四个参数分别是

2,plhs,3,prhs

其中:

prhs[0]=c

prhs[1]=d

prhs[2]=e

当函数返回时,将会把你放在plhs[0],plhs[1]里的地址赋给a和b,达到返回数据的目的。

细心的你也许已经注意到,prhs[i]和plhs[i]都是指向类型mxArray类型数据的指针。

这个类型是在mex.h中定义的,事实上,在Matlab里大多数数据都是以这种类型存在。当然还有其他的数据类型,可以参考Apiguide.pdf里的介绍。

为了让大家能更直观地了解参数传递的过程,我们把hello.c改写一下,使它能根据输

入参数的变化给出不同的屏幕输出:

//hello.c

2.0

#include

"mex.h"

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

{

int

i

i=mxGetScalar(prhs[0])

if(i==1)

mexPrintf("hello,world!\n")

else

mexPrintf("大家好!\n")

}

将这个程序编译通过后,执行hello(1),屏幕上会打出:

hello,world!

而hello(0)将会得到:

大家好!

现在,程序hello已经可以根据输入参数来给出相应的屏幕输出。在这个程序里,除了用到了屏幕输出函数mexPrintf(用法跟c里的printf函数几乎完全一样)外,还用到了一个函数:mxGetScalar,调用方式如下:

i=mxGetScalar(prhs[0])

"Scalar"就是标量的意思。在Matlab里数据都是以数组的形式存在的,mxGetScalar的作用就是把通过prhs[0]传递进来的mxArray类型的指针指向的数据(标量)赋给C程序里的变量。这个变量本来应该是double类型的,通过强制类型转换赋给了整形变量i。既然有标量,显然还应该有矢量,否则矩阵就没法传了。看下面的程序:

//hello.c

2.1

#include

"mex.h"

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

{

int

*i

i=mxGetPr(prhs[0])

if(i[0]==1)

mexPrintf("hello,world!\n")

else

mexPrintf("大家好!\n")

}

这样,就通过mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的指针。

但是,还有个问题,如果输入的不是单个的数据,而是向量或矩阵,那该怎么处理呢

?通过mxGetPr只能得到指向这个矩阵的指针,如果我们不知道这个矩阵的确切大小,就

没法对它进行计算。

为了解决这个问题,Matlab提供了两个函数mxGetM和mxGetN来获得传进来参数的行数

和列数。下面例程的功能很简单,就是获得输入的矩阵,把它在屏幕上显示出来:

//show.c

1.0

#include

"mex.h"

#include

"mex.h"

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

{

double

*data

int

M,N

int

i,j

data=mxGetPr(prhs[0])

//获得指向矩阵的指针

M=mxGetM(prhs[0])

//获得矩阵的行数

N=mxGetN(prhs[0])

//获得矩阵的列数

for(i=0i<Mi++)

{

for(j=0j<Nj++)

mexPrintf("%4.3f

",data[j*M+i])

mexPrintf("\n")

}

}

编译完成后,用下面的命令测试一下:

a=1:10

b=[aa+1]

show(a)

show(b)

需要注意的是,在Matlab里,矩阵第一行是从1开始的,而在C语言中,第一行的序数为零,Matlab里的矩阵元素b(i,j)在传递到C中的一维数组大data后对应于data[j*M+i]

输入数据是在函数调用之前已经在Matlab里申请了内存的,由于mex函数与Matlab共用同一个地址空间,因而在prhs[]里传递指针就可以达到参数传递的目的。但是,输出参数却需要在mex函数内申请到内存空间,才能将指针放在plhs[]中传递出去。由于返回指针类型必须是mxArray,所以Matlab专门提供了一个函数:mxCreateDoubleMatrix来实现内存的申请,函数原型如下:

mxArray

*mxCreateDoubleMatrix(int

m,

int

n,

mxComplexity

ComplexFlag)

m:待申请矩阵的行数

n:待申请矩阵的列数

为矩阵申请内存后,得到的是mxArray类型的指针,就可以放在plhs[]里传递回去了。但是对这个新矩阵的处理,却要在函数内完成,这时就需要用到前面介绍的mxGetPr。使用

mxGetPr获得指向这个矩阵中数据区的指针(double类型)后,就可以对这个矩阵进行各种 *** 作和运算了。下面的程序是在上面的show.c的基础上稍作改变得到的,功能是将输

//reverse.c

1.0

#include

"mex.h"

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

{

double

*inData

double

*outData

int

M,N

int

i,j

inData=mxGetPr(prhs[0])

M=mxGetM(prhs[0])

N=mxGetN(prhs[0])

plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL)

outData=mxGetPr(plhs[0])

for(i=0i<Mi++)

for(j=0j<Nj++)

outData[j*M+i]=inData[(N-1-j)*M+i]

}

当然,Matlab里使用到的并不是只有double类型这一种矩阵,还有字符串类型、稀疏矩阵、结构类型矩阵等等,并提供了相应的处理函数。本文用到编制mex程序中最经常遇到的一些函数,其余的详细情况清参考Apiref.pdf。

通过前面两部分的介绍,大家对参数的输入和输出方法应该有了基本的了解。具备了这些知识,就能够满足一般的编程需要了。但这些程序还有些小的缺陷,以前面介绍的re由于前面的例程中没有对输入、输出参数的数目及类型进行检查,导致程序的容错性很差,以下程序则容错性较好

#include

"mex.h"

void

mexFunction(int

nlhs,

mxArray

*plhs[],

int

nrhs,

const

mxArray

*prhs[])

{

double

*inData

double

*outData

int

M,N

//异常处理

//异常处理

if(nrhs!=1)

mexErrMsgTxt("USAGE:

b=reverse(a)\n")

if(!mxIsDouble(prhs[0]))

mexErrMsgTxt("the

Input

Matrix

must

be

double!\n")

inData=mxGetPr(prhs[0])

M=mxGetM(prhs[0])

N=mxGetN(prhs[0])

plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL)

outData=mxGetPr(plhs[0])

for(i=0i<Mi++)

for(j=0j<Nj++)

outData[j*M+i]=inData[(N-1-j)*M+i]

}

在上面的异常处理中,使用了两个新的函数:mexErrMsgTxt和mxIsDouble。MexErrMsgTxt在给出出错提示的同时退出当前程序的运行。MxIsDouble则用于判断mxArray中的数据是否double类型。当然Matlab还提供了许多用于判断其他数据类型的函数,这里不加详述。

需要说明的是,Matlab提供的API中,函数前缀有mex-和mx-两种。带mx-前缀的大多是对mxArray数据进行 *** 作的函数,如mxIsDouble,mxCreateDoubleMatrix等等。而带mx前缀的则大多是与Matlab环境进行交互的函数,如mexPrintf,mxErrMsgTxt等等。了解了这一点,对在Apiref.pdf中查找所需的函数很有帮助。

至此为止,使用C编写mex函数的基本过程已经介绍完了。

matlab有多少api函数,因为数量很多,而且不同版本的函数数量也或许不一样,因为会把常用的需求去添加成新的api函数,不完全统计,matlab的api函数不少于420个。

例如,下面列举其中的一部分较为常用的api函数。

1.

sym函数--定义符号矩阵

2.

syms函数--定义矩阵的又一函数

3.

sym的另一职能--把数值矩阵转化成相应的符号矩阵

4.

cat函数--创建多维数组

5.

zeros函数--零矩阵的生成

6.

eye函数--单位矩阵的生成

7.

ones函数--生成全1阵

8.

rand函数--生成均匀分布随机矩阵

9.

randn函数--生成正态分布随机矩阵

10.

randperm函数--产生随机序列

11.

linspace函数--线性等分向量的生成

12.

logspace函数--产生对数等分向量

13.

blkdiag函数--产生以输入元素为对角线元素的矩阵

14.

compan函数--生成友矩阵

15.

hankel函数--生成Hankel方阵

16.

hilb函数--生成Hilbert(希尔伯特)矩阵

17.

invhilb函数--逆Hilbert矩阵生成

18.

pascal函数--生成Pascal矩阵

19.

toeplitz函数--生成托普利兹矩阵

20.

wilkinson函数--生成Wilkinson特征值测试阵

21.

dot函数--向量的点积

22.

cross函数--向量叉乘

23.

conv函数--矩阵的卷积和多项式乘法

24.

deconv函数--反褶积(解卷)和多项式除法运算

25.

kron函数--张量积

26.

intersect函数--求两个集合的交集

27.

ismember函数--检测集合中的元素

28.

setdiff函数--求两集合的差

29.

setxor函数--求两个集合交集的非(异或)

30.

union函数--求两集合的并集

31.

unique函数--取集合的单值元素

32.

expm函数--方阵指数函数

33.

logm函数--求矩阵的对数

34.

funm函数--方阵的函数运算

35.

sqrtm函数--矩阵的方根

36.

polyvalm函数--求矩阵的多项式

37.

det函数--求方阵的行列式

38.

inv函数--求矩阵的逆

39.

pinv函数--求矩阵的伪逆矩阵

40.

trace函数--矩阵的迹

41.

norm函数--求矩阵和向量的范数

42.

cond函数--求矩阵的条件数

43.

condest函数--1-范数的条件数估计

44.

rcond函数--矩阵可逆的条件数估值

45.

condeig函数--特征值的条件数

46.

rank函数--矩阵的秩

47.

diag函数--矩阵对角线元素的抽取

48.

tril函数--下三角阵的抽取

49.

triu函数--上三角阵的抽取

50.

reshape函数--矩阵变维

51.

rot90函数--矩阵旋转语法说明

52.

fliplr函数--矩阵的左右翻转

53.

flipud函数--矩阵的上下翻转

54.

flipdim函数--按指定维数翻转矩阵

55.

repmat函数--复制和平铺矩阵

56.

rat函数--用有理数形式表示矩阵

57.

rem函数--矩阵元素的余数

58.

sym函数--数值矩阵转化为符号矩阵

59.

factor函数--符号矩阵的因式分解

60.

expand函数--符号矩阵的展开

61.

simple或simplify函数--符号简化

62.

numel函数--确定矩阵元素个数

63.

chol函数--Cholesky分解

64.

lu函数--LU分解

65.

qr函数--QR分解

66.

qrdelete函数--从QR分解中删除列

67.

qinsert函数--从QR分解中添加列

68.

schur函数--Schur分解

69.

rsf2csf函数--实Schur向复Schur转化

70.

eig函数--特征值分解

71.

svd函数--奇异值分解

72.

gsvd函数--广义奇异值分解

73.

qz函数--特征值问题的QZ分解

74.

hess函数--海森伯格形式的分解

75.

null函数--求线性齐次方程组的通解

76.

symmlq函数--线性方程组的LQ解法

77.

bicg函数--双共轭梯度法解方程组

78.

bicgstab函数--稳定双共轭梯度方法解方程组

79.

cgs函数--复共轭梯度平方法解方程组

80.

lsqr函数--共轭梯度的LSQR方法

81.

qmres函数--广义最小残差法

82.

minres函数--最小残差法解方程组

83.

pcg函数--预处理共轭梯度方法

84.

qmr函数--准最小残差法解方程组

85.

cdf2rdf函数--复对角矩阵转化为实对角矩阵

86.

orth函数--将矩阵正交规范化

87.

sparse函数--创建稀疏矩阵

88.

full函数--将稀疏矩阵转化为满矩阵

89.

find函数--稀疏矩阵非零元素的索引

90.

spconvert函数--外部数据转化为稀疏矩阵

91.

spdiags函数--生成带状(对角)稀疏矩阵

92.

speye函数--单位稀疏矩阵

93.

sprand函数--稀疏均匀分布随机矩阵

94.

sprandn函数--生成稀疏正态分布随机矩阵

95.

sprandsym函数--稀疏对称随机矩阵

96.

nnz函数--返回稀疏矩阵非零元素的个数

97.

nonzeros函数--找到稀疏矩阵的非零元素

98.

nzmax函数--稀疏矩阵非零元素的内存分配

99.

spfun函数--稀疏矩阵的非零元素应用

100.

spy函数--画稀疏矩阵非零元素的分布图形

101.

colmmd函数--稀疏矩阵的排序

102.

colperm函数--非零元素的列变换

103.

dmperm函数--Dulmage-Mendelsohn分解

104.

randperm函数--整数的随机排列

105.

condest函数--稀疏矩阵的1-范数

106.

normest函数--稀疏矩阵的2-范数估计值

107.

luinc函数--稀疏矩阵的分解

108.

eigs函数--稀疏矩阵的特征值分解

109.

sin和sinh函数--正弦函数与双曲正弦函数

110.

asin、asinh函数--反正弦函数与反双曲正弦函数

111.

cos、cosh函数--余弦函数与双曲余弦函数

112.

acos、acosh函数--反余弦函数与反双曲余弦函数

113.

tan和tanh函数--正切函数与双曲正切函数

114.

atan、atanh函数--反正切函数与反双曲正切函数

115.

cot、coth函数--余切函数与双曲余切函数

116.

acot、acoth函数--反余切函数与反双曲余切函数

117.

sec、sech函数--正割函数与双曲正割函数

118.

asec、asech函数--反正割函数与反双曲正割函数

119.

csc、csch函数--余割函数与双曲余割函数

120.

acsc、acsch函数--反余割函数与反双曲余割函数

121.

atan2函数--四象限的反正切函数

122.

abs函数--数值的绝对值与复数的幅值

123.

exp函数--求以e为底的指数函数

124.

expm函数--求矩阵以e为底的指数函数

125.

log函数--求自然对数

126.

log10函数--求常用对数

127.

sort函数--排序函数

128.

fix函数--向零方向取整

129.

roud函数--朝最近的方向取整

130.

floor函数--朝负无穷大方向取整

131.

rem函数--求余数

132.

ceil函数--朝正无穷大方向取整

133.

real函数--复数的实数部分

134.

imag函数--复数的虚数部分

135.

angle函数--求复数的相角

136.

conj函数--复数的共轭值

137.

complex函数--创建复数

138.

mod函数--求模数

139.

nchoosek函数--二项式系数或所有的组合数

140.

rand函数--生成均匀分布矩阵

141.

randn函数--生成服从正态分布矩阵

142.

interp1函数--一维数据插值函数

143.

interp2函数--二维数据内插值

144.

interp3函数--三维数据插值

145.

interpn函数--n维数据插值

146.

spline函数--三次样条插值

147.

interpft函数--用快速Fourier算法作一维插值

148.

spline函数--三次样条数据插值

149.

table1函数--一维查表函数

150.

table2函数--二维查表

151.

max函数--最大值函数

152.

min函数--求最小值函数

153.

mean函数--平均值计算

154.

median函数--中位数计算

155.

sum函数--求和

156.

prod函数--连乘计算

157.

cumsum函数--累积总和值

158.

cumprod函数--累积连乘

159.

quad函数--一元函数的数值积分

160.

quad8函数--牛顿?康兹法求积分

161.

trapz函数--用梯形法进行数值积分

162.

rat、rats函数--有理数近似求取

163.

dblquad函数--矩形区域二元函数重积分的计算

164.

quad2dggen函数--任意区域上二元函数的数值积分

165.

diff函数--微分函数

166.

int函数--积分函数

167.

roots函数--求多项式的根

168.

poly函数--通过根求原多项式

169.

real函数--还原多项式

170.

dsolve函数--求解常微分方程式

171.

fzero函数--求一元函数的零点

172.

size函数--符号矩阵的维数

173.

compose函数--复合函数运算

174.

colspace函数--返回列空间的基

175.

real函数--求符号复数的实数部分

176.

image函数--求符号复数的虚数部分

177.

symsum函数--符号表达式求和

178.

collect函数--合并同类项

179.

expand函数--符号表达式展开

180.

factor函数--符号因式分解

181.

simplify函数--符号表达式的化简

182.

numden函数--符号表达式的分子与分母

183.

double函数--将符号矩阵转化为浮点型数值

184.

solve函数--代数方程的符号解析解

185.

simple函数--求符号表达式的最简形式

186.

finverse函数--函数的反函数

187.

poly函数--求特征多项式

188.

poly2sym函数--将多项式系数向量转化为带符号变量的多项式

189.

findsym函数--从一符号表达式中或矩阵中找出符号变量

190.

horner函数--嵌套形式的多项式的表达式

191.

limit函数--求极限

192.

diff函数--符号函数导数求解

193.

int函数--符号函数的积分

194.

dsolve函数--常微分方程的符号解

195.

ezplot函数--画符号函数的图形

196.

ezplot3函数--三维曲线图

197.

ezcontour函数--画符号函数的等高线图

198.

ezcontourf函数--用不同颜色填充的等高线图

199.

ezpolar函数--画极坐标图形

200.

ezmesh函数--符号函数的三维网格图

201.

ezmeshc函数--同时画曲面网格图与等高线图

202.

ezsurf函数--三维带颜色的曲面图

203.

ezsurfc函数--同时画出曲面图与等高线图

204.

fourier函数--Fourier积分变换

205.

ifourier函数--逆Fourier积分变换

206.

laplace函数--Laplace变换

207.

ilaplace函数--逆Laplace变换

208.

ztrans函数--求z-变换

209.

iztrans函数--逆z-变换

210.

vpa函数--可变精度算法计算

211.

subs函数--在一符号表达式或矩阵中进行符号替换

212.

taylor函数--符号函数的Taylor级数展开式

213.

jacobian函数--求Jacobian矩阵

214.

jordan函数--Jordan标准形

215.

rsums函数--交互式计算Riemann

216.

latex函数--符号表达式的LaTex的表示式

217.

syms函数--创建多个符号对象的快捷函数

218.

maple函数--调用Maple内核

219.

mfun函数--Maple数学函数的数值计算

220.

mhelp函数--Maple函数帮助

221.

sym2poly函数--将符号多项式转化为数值多项式

222.

ccode函数--符号表达式的C语言代码

223.

fortran函数--符号表达式的Fortran语言代码

224.

binornd函数--二项分布的随机数据的产生

225.

normrnd函数--正态分布的随机数据的产生

226.

random函数--通用函数求各分布的随机数据

227.

pdf函数--通用函数计算概率密度函数值

228.

binopdf函数--二项分布的密度函数

229.

chi2pdf函数--求卡方分布的概率密度函数

230.

ncx2pdf函数--求非中心卡方分布的密度函数

231.

lognpdf函数--对数正态分布

232.

fpdf函数--F分布

233.

ncfpdf函数--求非中心F分布函数

234.

tpdf函数--求T分布

235.

gampdf函数--求Γ分布函数

236.

nbinpdf函数--求负二项分布

237.

exppdf函数--指数分布函数

238.

raylpdf函数--瑞利分布

239.

weibpdf函数--求韦伯分布

240.

normpdf函数--正态分布的概率值

241.

poisspdf函数--泊松分布的概率值

242.

cdf函数--通用函数计算累积概率

243.

binocdf函数--二项分布的累积概率值

244.

normcdf函数--正态分布的累积概率值

245.

icdf函数--计算逆累积分布函数

246.

norminv函数--正态分布逆累积分布函数

247.

sort函数--排序

248.

sortrows函数--按行方式排序

249.

mean函数--计算样本均值

250.

var函数--求样本方差

251.

std函数--求标准差

252.

nanstd函数--忽略NaN计算的标准差

253.

geomean函数--计算几何平均数

254.

mean函数--求算术平均值

255.

nanmean函数--忽略NaN元素计算算术平均值

256.

median函数--计算中位数

257.

nanmedian函数--忽略NaN计算中位数


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/7953269.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-11
下一篇 2023-04-11

发表评论

登录后才能评论

评论列表(0条)

保存