首页 用C语言编写MEX文件

用C语言编写MEX文件

举报
开通vip

用C语言编写MEX文件 用C语言编写MEX文件 1.1 为什么要用 C语言编写 MEX文件 MATLAB是矩阵语言,是为向量和矩阵操作设计的,一般来说,如果运算可以 用向量或矩阵实现,其运算速度是非常快的。但若运算中涉及到大量的循环处理, MATLAB的速度的令人难以忍受的。解决方法之一为,当必须使用 for循环时, 把它写为 MEX文件,这样不必在每次运行循环中的语句时 MATLAB都对它们进行 解释。 1.2 编译器的安装与配置 要使用 MATLAB编译器,用户计算机上应用事先安装与 MATLAB适配的以下任...

用C语言编写MEX文件
用C语言编写MEX文件 1.1 为什么要用 C语言编写 MEX文件 MATLAB是矩阵语言,是为向量和矩阵操作 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 的,一般来说,如果运算可以 用向量或矩阵实现,其运算速度是非常快的。但若运算中涉及到大量的循环处理, MATLAB的速度的令人难以忍受的。解决 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 之一为,当必须使用 for循环时, 把它写为 MEX文件,这样不必在每次运行循环中的语句时 MATLAB都对它们进行 解释。 1.2 编译器的安装与配置 要使用 MATLAB编译器,用户计算机上应用事先安装与 MATLAB适配的以下任 何一种 ANSI C/C++编译器: 5.0、6.0版的 MicroSoft Visual C++(MSVC) 5.0、5.2、5.3、5.4、5.5版的 Borland C++ LCC(由 MATLAB自带,只能用来产生 MEX文件) 下面是安装与配置 MATLAB编译器应用程序 MEX的设置的步骤: (1)在 MATLAB命令窗口中运行 mex –setup,出现下列提示: Please choose your compiler for building external interface (MEX) files: Would you like mex to locate installed compilers [y]/n? (2)选择 y,MATLAB将自动搜索计算机上已安装的外部编译器的类型、版本 及所在路径,并列出来让用户选择: Select a compiler: [1] Borland C++Builder version 6.0 in C:\Program Files\Borland [2] Digital Visual Fortran version 6.0 in C:\Program Files\Microsoft Visual Studio [3] Lcc C version 2.4 in D:\MATLAB6P5P1\sys\lcc [4] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio [0] None Compiler: (3)选择其中一种(在这里选择了 3),MATLAB让用户进行确认: Please verify your choices: Compiler: Lcc C 2.4 Location: D:\MATLAB6P5P1\sys\lcc Are these correct?([y]/n): (4)选择 y,结束 MATLAB编译器的配置。 1.3 一个简单的 MEX文件例子 【例 1】用 m文件建立一个 1000×1000的 Hilbert矩阵。 tic m=1000; n=1000; a=zeros(m,n); for i=1:1000 for j=1:1000 a(i,j)=1/(i+j); end end toc elapsed_time = 0.1100 在记事本中输入以下程序: [Matlab_1.cpp] #include "mex.h" //计算过程 void hilb(double *y,int n) { int i,j; for(i=0;i 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的 C语 言子程序。 (2)入口过程。该过程提供计算过程与 MATLAB之间的接口,以入口函数 mxFunction实现。在该过程中,通常所做的工作是检测输入、输出参数个数和 类型的正确性,然后利用 mx-函数得到 MATLAB传递过来的变量(比如矩阵的维数、 向量的地址等),传递给计算过程。 MEX文件的计算过程和入口过程也可以合并在一起。但不管那种情况,都要 包含#include "mex.h",以保证入口点和接口过程的正确声明。注意,入口过程 的名称必须是 mexFunction,并且包含四个参数,即: void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) 其中,参数 nlhs和 nrhs表示 MATLAB在调用该 MEX文件时等式左端和右端 变量的个数,例如在 MATLAB命令窗口中输入以下命令: [a,b,c]=Matlab_1(d,e,f,g) 则 nlhs为 3,nrhs为 4。 MATLAB在调用 MEX文件时,输入和输出参数保存在两个 mxArray*类型的指 针数组中,分别为 prhs[]和 plhs[]。prhs[0]表示第一个输入参数,prhs[1]表 示第二个输入参数,…,以此类推。如上例中,d→prhs[0],e→prhs[1], f→prhs[2],f→prhs[3]。同时注意,这些参数的类型都是 mxArray *。 接口过程要把参数传递给计算过程,还需要从 prhs中读出矩阵的信息,这 就要用到下面的 mx-函数和 mex-函数。 1.5 常用的 mex-函数和 mx-函数 在 MATLAB6.5版本中,提供的 mx-函数有 106个,mex-函数有 38个,下面我 们仅介绍常用的函数。 1.入口函数 mexFunction 该函数是 C MEX文件的入口函数,它的格式是固定的: void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) 说明: MATLAB函数的调用方式一般为:[a,b,c,…]=被调用函数名称(d,e,f,…), nlhs保存了等号左端输出参数的个数,指针数组 plhs具体保存了等号左端各参 数的地址,注意在 plhs各元素针向的 mxArray内存未分配,需在接口过程中分 配内存;prhs保存了等号右端输入参数的个数,指针数组 prhs具体保存了等号 右端各参数的地址,注意 MATLAB在调用该 MEX文件时,各输入参数已存在,所 以在接口过程中不需要再为这些参数分配内存。 2.出错信息发布函数 mexErrMsgTxt,mexWarnMsgTxt 两函数的具体格式如下: #include "mex.h" void mexErrMsgTxt(const char *error_msg); void mexWarnMsgTxt(const char *warning_msg); 其中 error_msg包含了要显示错误信息,warning_msg包含要显示的警告信 息。两函数的区别在于 mexErrMsgTxt显示出错信息后即返回到 MATLAB,而 mexWarnMsgTxt显示警告信息后继续执行。 摘自北京理工大学 BBS MATLAB 是什么东东?不用我多说了,大批的高手会告诉你它的 无数好处。但是 MATLAB 程序存在的一般问题是: 1、运算速度较慢,特别是有 for i=1:??? for j=1:??? ...... end end 时,那你就死定了。 2、无法脱离 MATLAB 环境运行,虽然你可以用 MATLAB 自带的 工具把 M 文件转成可执行程序,但是执行时,你只能看到一个黑黑 的窗口,难道,这就是......Windows? 3、GUI 功能差。许多大侠不愿意看到 2 中所述的 DOS-Windows 界面,于是使用了 MATLAB 带的 GUI 生成工具。(不要扔臭鸡蛋! 我知道你用 Graphic Editor 改了一下界面,发现以前的工作全都白 做了——因为被覆盖了,西西)但是 MATLAB 提供的控件和事件实 在有限。GUI 界面做好后放在机器里,向尚未进实验室的师妹(们) 炫耀一下,还勉强可以增加一些魅力值。如果被专家看到了,西西。 只怕效果不太美妙。 因此,如果能够实现 MATLAB 与 VC 或者 BC 或者 C++BUILDER 等可视化设计语言的交互,提高速度,美化界面,使程序更符合 Windows 的规范,同时又利用 MATLAB 的强大功能,对任何人来 说都很有意义。 我在课题中涉及到了部分 MATLAB 与 C++的接口知识,在这里总 结出来,算是抛砖引玉吧。其中错误以及偏颇的地方,尚请各位大侠 以及高手多多指教,谢谢! (一)接口种类 用 C++(或者 C)语言操作 MATLAB,有三种途径: ·MEX 文件 在 MATLAB 中可调用的 C 或 Fortran 语言程序称为 MEX 文件。 MATLAB 可以直接把 MEX 文件视为它的内建函数进行调用。MEX 文件是动态链接的子例程,MATLAB 解释器可以自动载入并执行它。 MEX 文件主要有以下用途: 对于大量现有的 C或者 Fortran程序可以无须改写成 MATLAB专 用的 M 文件格式而在 MATLAB 中执行。 对于那些 MATLAB 运算速度过慢的算法,可以用 C 或者 Frotran 语言编写以提高效率。 ·MAT 文件应用程序 MAT 文件是 MATLAB 专用的用于保存数据至磁盘和向 MATLAB 导入、从 MATLAB 导出数据的数据文件格式。MAT 文件提供了一种 简便的机制,它允许你在两个平台之间以灵活的方式移动数据。而且, 它还提供了一种途径来向其它单机 MATLAB 应用导入或者导出数 据。 为了简化在 MATLAB 环境之外对 MAT 文件的使用,MATLAB 给 出了一个操作例程库,通过它,我们可以使用 C/C++或者 Fortran 程序读写 MAT 文件。 ·引擎应用程序 MATLAB 提供了一系列的例程使得别的程序可以调用 MATLAB, 从而把 MATLAB 用作一个计算引擎。MATLAB 引擎程序指的是那些 通过管道(在 UNIX 系统中)或者 ActiveX(在 Windows 系统中) 与独立 MATLAB 进程进行通信的 C/C++或者 Fortran 程序。 MATLAB 同样提供了一个函数库来启动或者结束 MATLAB 进程、 与 MATLAB 交换数据以及发送 MATLAB 命令。 (二)MEX 文件 1、一个 MEX 的例子 #include "mex.h" /* * timestwo.c - example found in API guide * * Computational function that takes a scalar and doubles it. * * This is a MEX-file for MATLAB. * Copyright (c) 1984-1998 The MathWorks, Inc. */ /* $Revision: 1.5 $ */ /* 本 MEX 文件的目的是实现 timestwo 的功能 void timestwo(double y[], double x[])是你的 C++函数 */ void timestwo(double y[], double x[]) { y[0] = 2.0*x[0]; } /*下面这个 mexFunction 的目的是使 MATLAB 知道如何调用这 个 timestwo 函数*/ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) /* nlhs 是 MATLAB 命令行方式下输出参数的个数; *plhs[]是 MATLAB 命令行方式下的输出参数; nrhs 是 MATLAB 命令行方式下输入参数的个数; *prhs[]是 MATLAB 命令行方式下的输入参数; */ { double *x,*y; int mrows,ncols; /* Check for proper number of arguments. */ if(nrhs!=1) { mexErrMsgTxt("One input required."); } else if(nlhs>1) { mexErrMsgTxt("Too many output arguments"); } /* 在 MATLAB 命令行方式下,本 MEX 文件的调用格式是 y=timestwo(x) 输入参数(x)个数=1,输出参数(y)个数=1,所以在程序一 开始就检查 nrhs 是否=1 以及 nlhs 是否>1(因为 MATLAB 有 一个缺省 输出参数 ans,所以 nlhs 可以=0 */ 输出参数 ans,所以 nlhs 可以=0 */ /* The input must be a noncomplex scalar double.*/ mrows = mxGetM(prhs[0]); /* 获得输入矩阵的行数 */ ncols = mxGetN(prhs[0]); /* 获得输入矩阵的列数 */ if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows==1 && ncols==1) ) { mexErrMsgTxt("Input must be a noncomplex scalar double."); } /* 判断输入矩阵是否是 double 类,以及它是否只包括单个元素 */ /* 为输出创佳一个矩阵,显然这个矩阵也应该是 1x1 的 */ plhs[0] = mxCreateDoubleMatrix(mrows,ncols, mxREAL); /* 获得指向输入/输出矩阵数据的指针 */ x = mxGetPr(prhs[0]); y = mxGetPr(plhs[0]); /* 调用 C++函数 timestwo(y,x) */ timestwo(y,x); } 把上面这个文件用 MEX 编译后,MATLAB 命令行下调用的实例 x = 2; y = timestwo(x) y = y = 4 2、MEX 文件的编程规则 (1)编制自己的 C++算法程序 (2)紧跟着定义 mexFunction 函数,mexFunction 的定义法 唯一: 它只能是如下形式: void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) 其名称和参数类型不许有任何改变,在 mexFunciton 函数中可以 调用你刚定义好的 C++程序。 3、MEX 文件的编译 MATLAB 提供了专门编译 MEX 文件的工具:mex,它可以把你 做好的 C++源程序编译成 .mex 文件供 MATLAB在命令行方式下调 用。调用时输入你的 C++函数名(上例中为 timestwo)。具体 mex 的设置和使用方法可以在 MATLAB 命令行方式下用 help mex 命令 获得。 (三)MAT 文件 1、概述 .MAT 文件是 MATLAB 专用的数据存储格式,由于 MATLAB 提供 了一套可供 MATLAB 调用的 API 函数集,所以我们完全可以在 C++ 中访问 .MAT 文件。这样做的意义是:你可以把计算过程留给 MATLAB,而用 C++对计算结果进行 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 或者可视化处理。 2、接口 MATLAB 提供的 API 函数集封装于下面两个标准 DLL 文件中: libmat.dll, libmx.dll。前者用于对 MAT 文件的操作,后者用于对 MAT 文件中矩阵的操作。他们的存放路径为:\bin。 在\extern\include 中有与前面两个 DLL 对应的 DEF 文件: libmat.edf, libmx.dbf。 其导出函数的原型位于同一目录下的 mat.h 和 matrix.h 中 有了这些 DLL、DEF、H 文件,该怎么用 C++调用 API 函数就不 用我多说了吧。 3、MATLAB 中常用的矩阵类型 ·(复)双精度矩阵(Complex Double-Precision Matrices) MATLAB 中最常用的数据类型便是(复)双精度、非稀疏矩阵, 这些矩阵的元素都是双精度(double)的,矩阵的尺寸为 m×n,其 中 m 是总行数,m 是总列数。矩阵数据实际存放在两个双精度向量 中——一个向量存放的是数据的实部,另一个向量存放的是数据的虚 部。指向这两个向量的指针一般被写做“pr” (pointer to real data, 指向实数据的指针)和“pi” (pointer to imaginary data,指向虚 数据的指针)”。如果一个矩阵的 pi 为空的话,说明它是实双精度矩 阵。 ·稀疏矩阵(Sparse Matrices) MATLAB 中稀疏矩阵的存储格式与众不同。如同双精度矩阵一样, 它拥有参数 pr 和 pi,同时它还具用三个附加的参数:nzmax,ir 以 及 jc。 nzmax 是个整型数,其值为向量 ir 及 pr、pi(如果存在的话)可 能的最大长度。它是稀疏矩阵中不为零的元素的个数。 ir 指向一个长度为 nzmax 的整型数阵列,阵列包含的是 pr 和 pi 中对应元素的行号。 jc 指向一个长度为 N+1 的整型数阵列(N 为矩阵的列数),其中包 含的是列号信息。对于任意的 j,如果 0≤j≥N-1,jc[j]是第 j 列中第一 个非零项在 ir、pr(以及 pi)中的序号,jc[j+1]-1 是第 j 列最后一个 非零项的序号。因此 jc[N]总等于 nnz——矩阵中非零项的总个数。 如果 nnz 小于 nzmax,可以继续向矩阵中添加非零项而无需分配额 外的存储空间 。 4、主要函数举例: ·MATFile *matOpen(const char *filename, const char * mode)——打开/创建 ·MATFile *matOpen(const char *filename, const char * mode)——打开/创建一个 MAT 文件; ·int matClose(MATFile *pMF)——关闭一个 MAT 文件; ·mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity flag) ——创建一个(复)双精度矩阵; ·mxArray *mxCreateSparse(int m, int n, int nzmax, mxComplexity flag) ——创建一个稀疏矩阵; ·mxArray *matGetNextArray(MATFile *pMF)——获得 MAT 文 件里面下一个矩阵; ·const char *mxGetName(const mxArray *pa)——获得矩阵pa 的名称; ·void mxSetName(mxArray *pa,const char *s)——为矩阵 pa 设置一个名称; ·int mxGetM(const mxArray *pa)——获得矩阵 pa 的总行数; ·int mxGetN(const mxArray *pa)——获得矩阵 pa 的总列数; ·double *mxGetPr(const mxArray *pa)——获得矩阵 pa 的 pr 指针; ·int *mxGetIr(const mxArray *pa)——获得稀疏矩阵 pa 的 ir 指 针; ·int *mxGetJc(const mxArray *pa)——获得稀疏矩阵pa的 jc指 针; ·int matPutArray(MATFile * pMF, const mxArray * pA) ——把矩阵 pA 存储入 MAT 文件 pMAF; ·void mxDestroyArray(mxArray *pa)——释放矩阵 pa(把它从 内存中撤销); 5、两个例子: ·获取一个 MAT 文件中第一个矩阵的信息 ·获取一个 MAT 文件中第一个矩阵的信息 typedef struct { char szFileName[256]; MATFile* pMatFile; mxArray* pArray; char szArrayName[64]; char szErrMsg[256]; unsigned int nArrayDim[2]; bool bIsSparse; } MATFileStruct; int GetMATFileStruct(MATFileStruct *pMAThdr) { if((pMAThdr->pMatFile=matOpen(pMAThdr->szFileName,"r "))==NULL) { strcpy(pMAThdr->szErrMsg,"Can't open this mat file"); return(0); }/*打开一个 MAT 文件*/ if((pMAThdr->pArray=matGetNextArray(pMAThdr->pMatFil e))==NULL) { strcpy(pMAThdr->szErrMsg,"Can't get arrays"); matClose(pMAThdr->pMatFile); return(0); }/*获取 MAT 文件中的第一个矩阵*/ }/*获取 MAT 文件中的第一个矩阵*/ pMAThdr->nArrayDim[0]=mxGetM(pMAThdr->pArray); /*获 取其行数*/ pMAThdr->nArrayDim[1]=mxGetN(pMAThdr->pArray); /*获 取其列数*/ strcpy(pMAThdr->szArrayName,mxGetName(pMAThdr->pA rray)); /*获取其名称*/ pMAThdr->bIsSparse=mxIsSparse(pMAThdr->pArray); /*判 断它是否是系数矩阵*/ mxDestroyArray(pMAThdr->pArray); /*在内存中撤销这个矩 阵*/ matClose(pMAThdr->pMatFile); /*关闭 MAT 文件*/ return(1); } ·创建稀疏矩阵并赋值 int i,j,k,m,n,nzmax,*ir,*jc; double *pr; unsigned short *pData; mxArray *pa; file://初始化。 m=pLCMShdr->TrueHdr.nArrayDim[0]; file://获得原矩阵行 数。 n=pLCMShdr->TrueHdr.nArrayDim[1]; file://获得原矩阵列数。 nzmax=0; for(i=0;iTrueHdr.szArrayName); /*为稀 疏矩阵 pa 设置名称。*/ pr=mxGetPr(pa); file://获得 pa 的 pr 指针。 ir=mxGetIr(pa); file://获得 pa 的 ir 指针。 jc=mxGetJc(pa); file://获得 pa 的 jc 指针。 k=0; for(j=0;j> "); /*要求用户输入一个 MATLAB 命令*/ fgets(str, BUFSIZE–1, stdin); /*获得用户输入*/ /* * Evaluate input with engEvalString. */ engEvalString(ep, str); /*执行用户输入的 MATLAB 命令*/ engEvalString(ep, str); /*执行用户输入的 MATLAB 命令*/ /* * Echo the output from the command. First two characters * are always the double prompt (>>). */ printf("%s", buffer+2); /*显示该 MATLAB 命令的执行情况*/ /* * Get result of computation. */ printf("\nRetrieving X...\n"); if ((result = engGetArray(ep,"X")) == NULL) /*判断是否可以 从 MATLAB 引擎中获得矩阵“X”*/ printf("Oops! You didn't create a variable X.\n\n"); else printf("X is class %s\t\n", mxGetClassName(result)); /*显示 矩阵“X” 的类型*/ } /* while(result==NULL)*/ /* * We're done! Free memory, close MATLAB engine and exit. */ printf("Done!\n"); mxDestroyArray(result); /*从内存中撤销矩阵“T”*/ engClose(ep); /*关闭 MATLAB 引擎*/ return EXIT_SUCCESS; /*返回*/ } 4、引擎应用程序的编译 对于象上例中的控制台程序,可以在 MATLAB 命令行中直接使用 带-f 参数的 mex 命令编译。 如果在普通 win32 application 中使用 MATLAB 引擎,情况则比 较复杂。在 Windows 中,MATLAB 引擎是通过 ActiveX 被调用的。 因此你需要先 Create 一个 OLE Automation Sever 和一个 OLE Client,然后通过 OLE 方式调用这个 MATLAB 引擎。具体做法可参 阅相关 MATLAB 随机文档。 5、 总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf MATLAB 引擎的调用与其它引擎(例如数据库引擎)的调用很类 似,其步骤是联接\启动引擎,然后向引擎发送命令,获得引擎处理 结果。 结束语 上面简要介绍了 MATLAB 与 C++的几种接口方式,我们可以根据 要求的不同采用相应的方式。 此外,MATLAB 还提供了一个数学库,由此数学库,我们可以获 得对 MATLAB 内部命令更多的访问权和更灵活的访问方式。具体内 容可参考 MATLAB 的相关随机文档。
本文档为【用C语言编写MEX文件】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_373610
暂无简介~
格式:pdf
大小:206KB
软件:PDF阅读器
页数:0
分类:工学
上传时间:2013-05-15
浏览量:22