Matlab混合编程7.ppt
Matlab语言 No.1,MATLAB基础篇、混合编程篇参考书:朱衡君 MATLAB 语言及实践教程(第2版)北京交通大学出版社 其它MATLAB混合编程参考书:杨高波 精通MATLAB7混合编程 电子工业出版社 刘维 精通MATLAB与C+混合程序设计 北航出版社 何强 MATLAB扩展编程 清华大学出版社,MATLAB混合编程篇,第7章 MATLAB外部接口概述第8章 创建C语言MEX文件,第7章 MATLAB外部接口概述,7.1 外部接口应用的类型7.2 mxArray数据结构7.3 mx函数应用7.4 MATLAB的环境配置,7.1 外部接口应用的类型,MATLAB同其它软件开发工具或者语言交互的能力是非常强大的。1)特别是MATLAB在Windows平台上支持Microsoft提出的COM标准;2)同时支持Java语言;3)因此,MATLAB几乎可以同Windows平台上任何一种软件或者开发语言进行交互。不过,使用不同的工具解决不同的问题,往往一类问题又有很多种解决方法,但不是每一种都适合或者最佳。例如:在解决利用C语言调用MATLAB算法的问题上,可以分别通过计算引擎和MATLAB函数库的方法解决,但是不同的方法各有优点和缺点,需要针对用户的需要来选择。,表7-1 MATLAB与其它开发工具语言交互的能力,1.使用MEX文件调用已有的C代码或者Fortran代码创建MEX文件是外部接口应用的重点,也是所讲述内容的重点。MEX从字面上是MATLAB Executable 两个单词的缩写。1)MEX文件类似于M文件,是一种能够在MATLAB环境中可以被 MATLAB的解释器解释并执行的函数文件;2)MEX文件可以直接使用C语言或者Fortran语言来编写,在相应的C语言或者Fortran语言代码中,就可以调用已有的大量C语言或者Fortran语言算法。3)在MATLAB中调用MEX文件时,就好像调用MATLAB的内建函数或者M文件函数一样,语法结构和输入、输出参数都符合MATLAB的标准。利用MEX文件可以完成:,利用MEX文件可以完成如下:*在MATLAB中使用已有的C语言或者Fortran语言代码,避免重复劳动。*解决M语言运行速度的瓶颈。*隐藏算法的细节。*通过C语言对计算机硬件设备进行操作,扩展MATLAB的能力。,2.通过MATLAB计算引擎在C代码或者Fortran代码中调用MATLABMATLAB计算引擎应用程序是那些通过特殊的通信方式与MATLAB进程相互交互的C语言或者Fortran语言应用程序。1)计算引擎在不同的平台上使用不同的通信方法。例如在UNIX平台上使用管道(pipes),而在Windows平台上使用COM接口-IEngine。2)MATLAB计算引擎从应用上与MEX文件正好相对,它提供在C/Fortran语言应用程序中调用MATLAB,将MATLAB作为后台计算处理平台的能力。,利用MATLAB计算引擎可以完成:1)利用C语言或者Fortran语言开发前台应用程序,调用MATLAB丰富的算法库,充分利用不同开发工具的优势和长处。2)在UNIX平台中,用户不仅可以在本地计算机上调用MATLAB计算引擎服务,而且可以通过网络调用其它计算机平台上的MATLAB计算引擎服务,充分利用网络上的计算资源。3)MATLAB的计算引擎应用简单、灵活。但是惟一的缺点:就是C语言或者Fortran语言开发的应用程序无法脱离MA TLAB环境,所以使得应用计算引擎必须安装一套MATLAB。,3.C语言或者Fortran语言应用程序读写MAT数据文件MAT数据文件是MATLAB独有的一种数据文件格式,这种数据文件是一种二进制文件,能够跨平台使用。MAT数据文件的后缀名称是.mat。一般地,MAT数据文件都是在MATLAB环境中进行读写的,不过可以利用MATLAB提供的函数库完成:C语言或者Fortran语言读写MAT数据文件的程序开发,这样就能够充分利用MAT数据文件跨平台应用的优势了。,4.在M语言中调用Java类 MATLAB的Java接口包括:1)调用Java API类(class)和包(package),完成Java核心功能。2)调用第三方定义的Java类(class)。3)在MATLAB 环境下创建Java对象。4)使用Java语法或MATLAB语法使用Java对象的方法。5)在Java对象和MATLAB之间交互数据。,5.在MATLAB中加载动态链接库Windows平台下的动态链接库包含了一组函数,这些函数可以被不同的应用程序来调用,这些文件就是共享库在Windo ws平台下的实现,这些文件的扩展名为.dll。在应用程序运行的时候,动态库被自动加载到内存中,利用库函数完成计算或者某些操作。MATLAB提供了相应的接口函数,可以将通用的动态链接库加载到MATLAB环境中,这样在M语言程序中就可以直接调用动态链接库包含的函数了。,注意:在MATLAB中加载动态链接库是MATLAB 6.5.1版新增加的功能,MATLAB早期的版本还不具备这些能力。如果需要在MATLAB 6.5版本中实现加载动态链接库的功能,则需要在Mathworks公司的网站上下载一个补丁文件,该文件的超链接如下:ftp:/s33513/GenericDll_1p1.exe 将该文件下载并安装后,就可以在MATLAB 6.5中实现该功能了。,6.MATLAB的COM应用Windows 平台上的MATLAB可以完成COM客户端或者服务器应用程序的开发,尽管MATLAB的COM应用也是外部接口的内容,但是由于COM应用相对难度较大,涉及的软件工具种类多,所以关于COM应用的内容在MATLAB应用程序集成与发布一书中详细讲述。同样有关动态数据交换(DDE)的内容也在MATLAB应用程序集成与发布一书中详细讲述。在上述各种外部接口应用中,最重要也是最常用的就是MEX文件,所以在本课程中,将重点讲解MEX文件的混合编程方法。,7.2 mxArray 数 据 结 构,1)Matlab 是以矩阵为基本单位的。2)与C语言不同,在C语言中,只有基本的双精度、整数、字符类型的变量定义,与MATLAB中的相应类型变量定义是不一样。3)为了能够在C语言中表示MATLAB的数据,MATLAB提供了一个特殊的C语言结构mxArray。4)这结构就是用来在C语言中表示MATLAB数据的,在MATLAB的C语言外部接口编程中将大量使用该结构。,7.2 mxArray 数 据 结 构,7.2.1 mxArray的定义mxArray本身是一个C语言的结构(实现在C语言中表示MATLAB的数据),该结构的定义在Matrix.h文件中,它的定义如下:struct mxArray_tag void*reserved;int reserved12;void*reserved2;int number_of_dims;,unsigned int reserved3;struct unsigned int scalar_flag:1;unsigned int flag1:1;unsigned int flag2:1;unsigned int flag3:1;unsigned int flag4:1;unsigned int flag5:1;unsigned int flag6:1;unsigned int flag7:1;unsigned int private_data_flag:1;unsigned int flag8:1;,unsigned int flag9:1;unsigned int flag10:1;unsigned int flag11:4;unsigned int flag12:8;unsigned int flag13:8;flags;unsigned int reserved42;union struct void*pdata;void*pimag_data;void*reserved5;,int reserved63;number_array;data;,mxArray结构由很多个字段组成,这些字段完成了记录MATLAB数据的工作。一般地,mxArray在记录一个数据时,需要保存下列信息:数据类型。数组维数。与数组相关的数据(尺寸和数据)。如果是数值对象,则保存数据对象是实数还是虚数。如果是稀疏矩阵,则保存矩阵中非零元素的个数和索引。如果是结构和对象,则保存字段的数量和相应的名称。,从图7-1可以看出,mxArray将MATLAB数据的信息分别保存在不同的字段里;例如m和n分别表示二维矩阵的行数和列数;对于多维数组,m是矩阵的行数,而n是数组中每一个矩阵的列数、页面数和其它数据的乘积。维数保存着数据对象实际的维数。而size字段存储着每个维存储数据元素的个数。pr为实部数据的指针,pi是虚部数据的指针,如果没有虚部数据,则pi为NULL。但是,在mxArray数据结构的定义中是不能直接找到这些字段的对应关系的,如果需要操作该数据对象,则需要使用专门的函数。,一般的情况下,直接操作mxArray对象比较困难,而且在使用mxArray数据对象时,都必须使用mxArray数据类型的指针来完成工作。为了便于创建和访问mxArray数据对象,MATLAB提供了相应的函数,这些函数就是MATLAB提供的mx函数,该函数具有C语言的形式和Fortran语言的形式,利用这些函数不需要直接对mxArray结构对象的字段进行赋值或者读取了。关于C语言的mx函数创建数据对象的方法将在下一小节进行介绍,而详细的C语言和Fortran语言mx函数的解释请参阅MATLAB的帮助文档。,在进行外部接口编程时,获取数据类型信息是经常需要的一种操作。在mxArray结构中同样也保存着这样的信息,这类信息是通过mxClassID的枚举类型变量来保存的,该枚举类型定义如下:,typedef enum mxUNKNOWN_CLASS=0,mxCELL_CLASS,mxSTRUCT_CLASS,mxLOGICAL_CLASS,mxCHAR_CLASS,mxSPARSE_CLASS,/*OBSOLETE!DO NOT USE*/,mxDOUBLE_CLASS,mxSINGLE_CLASS,mxINT8_CLASS,mxUINT8_CLASS,mxINT16_CLASS,mxUINT16_CLASS,mxINT32_CLASS,mxUINT32_CLASS,mxINT64_CLASS,/*place holder-future enhancements*/,mxUINT64_CLASS,/*place holder-future enhancements*/mxFUNCTION_CLASS,mxOPAQUE_CLASS,mxOBJECT_CLASS mxClassID;,在MEX文件中进行数据类型判断时,将返回mxClassID类型的变量。此外,针对复数和实数也定义了一个枚举类型,该枚举类型的变量将在C语言应用程序中加以定义。它的定义如下:typedef enum mxREAL,mxCOMPLEX mxComplexity;,在C语言中创建mxArray数值类型对象需要指定数据是复数类型还是实数类型。为了能够保存字符串类型的变量,在Matrix.h文件中还专门定义了相应的数据类型mxChar。mxChar 是 mxArray存储字符类型数据时使用的变量类型,该数据类型使用了16位的无符号整数,定义如下:typedef uint16_T mxChar;这里unit16_T是MATLAB自定义的数据类型符号,相当于C语言中unsigned int的定义。,为了便于用户学习外部接口编程,MATLAB也提供了相应的示例。在Windows平台下,这些示例都保存在MATLABROOT extern examples目录中,在mex子目录下都是相应的MEX函数文件例子,其中有一个实例文件名为explore.dll,它是一个C语言的MEX函数文件,功能是显示MATLAB数据对象的维数、尺寸和类型信息,将该文件拷贝到当前的工作路径下,然后在MATLAB中运行下面的指令:,x=3;explore(x)-Name:prhs0Dimensions:1x1Class Name:double-(1,1)=3,在自己的MATLAB中运行下面的指令:explore(1 2 3 4 5)explore 1 2 3 4 5 explore(1 2 3 4 5)explore(int8(1 2 3 4 5)explore 1 2 3 4 5 explore(sparse(eye(5)explore(struct(name,Joe Jones,ext,7332)explore(1,2,3,4,5)可查看MATLAB相应的输出。,7.2.2 外部接口函数前一小节曾经提及为了完成创建、访问mxArray数据对象的操作,MATLAB提供了相应的函数,这些函数是mx函数。mx函数是MATLAB外部接口函数的一种,针对不同外部接口应用,MATLAB提供了不同类型的函数,其中mx是这些函数共有的前缀。在表7-2中对C语言和Fortran语言外部接口应用程序中常用的函数进行了分类总结。,表7-2 MATLAB外部接口函数类型,7.3 mx 函 数 应 用,7.3.1 数值矩阵MATLAB中基本的数据类型有两种,一种是双精度数据,另外一种是字符串,其中双精度数据可以是标量、向量或者矩阵,也可以是多维的数组。MATLAB都将其看作矩阵或者数组,又由于这些数组或者矩阵的元素都是数字,因此又将其称之为数值矩阵或者数值数组。本小节将介绍外部接口编程中通过mx函数创建使用数值矩阵的方法。,1.标量所谓标量,就是具有一个元素的矩阵,也就是11的矩阵。利用mx函数创建标量的方法非常简单,只需要用函数mxCreateDoubleScalar就可以了,该函数的C语言定义如下:mxArray*mxCreateDoubleScalar(double value);函数的输入参数是双精度类型的数据,可以是常量或者变量,而输出参数是mxArray数据结构的对象。使用该函数的方法参见下面的代码片段:,double realdata=1.0;mxArray*Data;/*创建mxArray数据对象-双精度标量*/Data=mxCreateDoubleScalar(realdata);见data.c,2.向量和矩阵由于在C语言中向量和矩阵都可以看作为二维数组,不过向量是1n或者n1的二维数组(矩阵),所以在C语言中创建向量和矩阵都是使用同一个函数。创建双精度类型矩阵可以使用mxCreateDoubleMatrix函数,该函数的定义如下:mxArray*mxCreateDoubleMatrix(int m,int n,mxComplexity ComplexFlag);,该函数的输入参数是:矩阵的行数m和列数n;以及数据是复数或者实数的标志。该函数若成功执行,则返回变量为mxArray数据结构的对象指针。若不能成功执行,则在独立可执行应用程序中返回NULL,在MEX函数中返回MATLAB命令行窗口。通过该函数创建的双精度类型矩阵还没有实际的元素,而矩阵具体的元素的创建还需要通过另外的操作才能完成。创建双精度类型矩阵的完整过程参阅下面的代码片段:,double realdata=1,2,3,4,imagdata=1,2,3,4;double*pr,*pi;mxArray*Data;/int flag;/*创建mxArray数据对象-22复数矩阵*/Data=mxCreateDoubleMatrix(2,2,mxCOMPLEX);/*获取双精度类型矩阵的实部和虚部数据指针*/pr=mxGetPr(Data);pi=mxGetPi(Data);/*复制数据完成赋值*/memcpy(pr,realdata,4*sizeof(double);memcpy(pi,imagdata,4*sizeof(double);见data1.c,在上面的代码片段中完成了双精度类型矩阵的创建,其中使用mxGetPr函数和mxGetPi函数获取了矩阵实部和虚部的指针,然后通过memcpy函数通过复制内存数据的方法完成整个矩阵数据的赋值。上述mxArray数据类型对象创建的过程完整地说明了在C语言中创建MATLAB数据对象的完整过程:首先使用mx函数创建指针完成mxArray数据类型指针的内存分配;然后通过mxGetPr和mxGetPi函数获取mxArray数据类型的实部数据指针和虚部数据指针;最后是用内存复制的方法完成数据的赋值。而操作mxArray类型数据指针的过程是通过mxGetPr和mxGetPi函数获取mxArray数据对象的指针,然后通过内存复制的方法将具体的数据赋值给相应的C语言双精度类型变量。,3.任意数值数组众所周知,除了双精度类型,MATLAB还支持整数类型、单精度类型等其它数值类型,也可以创建三维甚至更多维的数组。在外部接口应用中,通过不同函数可以完成同样的操作。如果需要创建任意类型数据的矩阵可以使用mxCreateNume ricMatrix函数,该函数的定义如下:mxArray*mxCreateNumericMatrix(int m,int n,mxClassID class,mxComplexity ComplexFlag);该函数的输入参数是:矩阵的行数m和列数n、矩阵的数据类型class以及实数或者复数的标志。,下面的代码片段说明了创建32位整数类型复数矩阵的方法:/*实部数据和虚部数据*/long realdata=1,2;long imagdata=1,2;/*实部虚部数据的指针*/long*pr,*pi;mxArray*Data;/*创建mxArray数据对象-双精度标量*/Data=mxCreateNumericMatrix(1,2,mxINT32_CLASS,mxCOMPLEX);/*获取实部数据和虚部数据的指针*/,pr=mxGetPr(Data);pi=mxGetPi(Data);/*通过内存复制的方法完成赋值*/memcpy(pr,realdata,2*sizeof(long);memcpy(pi,imagdata,2*sizeof(long);见data2.c,上述代码片段创建的数据为ans=1.0000+1.0000i 2.0000+2.0000i其数据类型为Name Size Bytes Class ans 1x2 16 int32 array(complex)Grand total is 2 elements using 16 bytes,如果需要创建任意类型数据的多维数组可以使用mxCreateNumericArray函数,该函数的定义如下:mxArray*mxCreateNumericArray(int ndim,const int*dims,mxClassID class,mxComplexity ComplexFlag);该函数的输入参数分别为:数组的维数ndim、每一维的尺寸*dims、数组的数据类型class以及实数或者复数的标志。其中每一维的尺寸需要保存在一个数组中ndims,返回的参数为mxArray数据类型的指针。,使用mxCreateNumericArray函数创建多维数组的过程参见下面的代码片段:/*数组的实际数据*/double realdata=0,1,2,3,4,5,6,7,8,9,10,11;/*多维数组的每一维尺寸*/int ndims=2,2,3;double*pr;mxArray*Data;/*创建mxArray数据对象-双精度三维数组*/Data=mxCreateNumericArray(3,ndims,mxDOUBLE_CLASS,mxREAL);/*获取数组的实部数据指针*/,pr=mxGetPr(Data);/*通过内存赋值的方法完成数据的赋值*/memcpy(pr,realdata,12*sizeof(double);上述代码片段创建的多维数组是ans(:,:,1)=0 2 1 3ans(:,:,2)=4 6 5 7ans(:,:,3)=8 10 9 11 见data3.c,这里主要需要说明:C语言中数组的序列是以行元素优先的,而MATLAB的数组是以列元素优先的,所以在上述代码创建的数组中,realdata数组数据出现在MATLAB的顺序为列元素排列。另外,C语言数组的起始元素序号为0,而MATLAB数组元素起始序号为1。在创建多维数据的时候需要注意,当数组数据的个数不满足实际多维数组的个数时,不足的数据将自动使用数据0来初始化。,7.3.2 字符串MATLAB另外一种的基本数据类型就是字符串类型。同C语言不同的是,MATLAB中只有字符串一种数据类型来表示文本信息,而C语言中有字符类型和字符串类型两种不同的数据表示文本信息。在外部接口应用程序中创建mxArray数据类型对象表示字符串数据可以通过不同的函数来完成,其中,将C语言的字符串转变为MATLAB字符串最简单的函数是mxCreateString函数,它的定义如下:mxArray*mxCreateString(const char*str);,1)该函数的输入参数是字符串的内容,输入参数是C语言的字符串常量,而输出参数就是mxArray数据类型的对象,该对象就是MATLAB的字符串。使用mxCreateString函数创建字符串的方法参见下面的代码片段:mxArray*Data;/*创建mxArray数据对象-字符串*/Data=mxCreateString(Isnt MATLAB Great?);见data4.c,2)Matlab 还提供其他函数创建字符数组(向量、矩阵或多维数组)mxArray*mxCreateCharArray(int ndim,const int*dims);函数输入参数:数组维数ndim,每一维的尺寸*dims;数组数据通过mx内存复制。Unsigned short data=65,66,67,68,69,70,71,72,73,74,75,76;int ndims=2,2,3;unsigned short*pr;,/*创建mxArray 数据对象-字符类型多维数组*/Data=mxCreateCharArray(3,ndims);/*获取数据指针*/Pr=mxgetpr(Data);/*通过内存赋值的方法完成数据赋值*/mempcy(pr,data,12*sizeof(short);结果:Ans(:,:,1)ACBDAns(:,:,2)EGFHAns(:,:,3)IKJL 见data5.c,注意:在MATLAB中每个字符数组元素占用两个字节的内存空间,所以在C语言代码中,使用unsigned short类型的数据为字符数组进行赋值。数组元素的顺序是以列元素优先的。3)如果创建字符串矩阵,还可以使用函数mxCreateChar MatrixFormString,该函数可以用来创建二维的字符串矩阵,它的定义如下:mxArray*mxCreateCharMatrixFromStrings(int m,const char*str);,该函数的输入参数:字符串矩阵的行数以及矩阵中的内容,该函数能够自动判断输入的字符串内容的长度,并且使用所有字符串中最长的长度来分配MATLAB字符串占用的内存。该函数创建字符串矩阵的方法参考下面的代码片段:/*字符串矩阵的内容*/char*string=MATLAB,外部接口,编程;mxArray*Data;/*创建mxArray数据对象-字符串矩阵*/Data=mxCreateCharMatrixFromStrings(3,string);,上述代码片段创建的字符串矩阵为 ans=MATLAB外部接口 编程 whos Name Size Bytes Class ans 3x6 36 char array见data6.c,7.3.3 逻辑数组逻辑数组在MATLAB中是一类特殊的数据类型,一般进行任何关系运算得到的结果就是逻辑类型的数据。在其它的高级语言中,一般将这种数据称之为布尔类型变量,这种变量只有两种可能的取值。在MATLAB中,用1代表逻辑真,用0表示逻辑假。逻辑数组每一个元素占用一个字节的内存。外部接口应用程序同样提供了不同的函数来创建逻辑数组。和创建数值矩阵类似,逻辑数组也分为创建标量、矩阵和多维数组的函数。,)创建逻辑类型的标量需要使用的函数定义如下:mxArray*mxCreateLogicalScalar(mxLOGICAL value);该函数输入参数的类型为mxLOGICAL;这种数据类型就是C语言中表示布尔类型的数据类型,一般为bool。函数的输出参数是mxArray数据类型的对象,表示逻辑量。)如果创建逻辑类型的矩阵,则需要使用函数mxCreateLogicalMatrix,该函数的定义如下:mxArray*mxCreateLogicalMatrix(int m,int n);,该函数的输入参数是逻辑矩阵的行数m和列数n,函数的输出参数是mxArray数据类型的对象,它表示逻辑量矩阵。如果创建逻辑类型的多维数组,则可以使用函数mxCreateLogicalArray,该函数的定义如下:mxArray*mxCreateLogicalArray(int ndim,const int*dims);该函数的输入参数:数组的维数ndim;每一维的尺寸*dims函数的输出参数:mxArray数据类型的对象,它表示逻辑数组。,下面的代码片段说明了使用mxCreateLogicalArray函数创建逻辑数组的过程:/*逻辑数组的数据*/bool data=0,1,0,1,0,1,0,1,0,1,0,1;/*数组的尺寸*/int ndims=3,4;/*数据的指针*/mxLogical*pr;mxArray*Data;/*创建mxArray数据对象-逻辑类型数组*/Data=mxCreateLogicalArray(2,ndims);,/*获取数据的指针*/pr=mxGetLogicals(Data);/*通过内存赋值的方法完成数据的赋值*/memcpy(pr,data,12*sizeof(mxLogical);)在创建逻辑数组时,不能使用mxGetPr函数来获取数据的指针,而是使用mxGetLogicals函数获取逻辑数组数据的指针,该函数的定义如下:mxLogical*mxGetLogicals(const mxArray*array_ptr);函数的输入参数是表示逻辑数组的mxArray数据类型对象,返回的输出参数是mxLogical类型的数据指针,为mxArray数据类型对象中所包含的数据首地址。,上述代码片段得到的逻辑类型矩阵如下:ans=0 1 0 1 1 0 1 0 0 1 0 1 whos Name Size Bytes Class ans 3x4 12 logical arrayGrand total is 12 elements using 12 bytes 见data7.c,在MATLAB中存在大量的以is为前缀的函数,这些函数主要是完成逻辑判断操作的函数,函数返回的变量类型也是逻辑类型数组。在外部接口编程中同样也存在相应的函数可以完成逻辑判断操作。这些函数就是以mxIs为前缀的mx函数,这些函数多数是用来完成数据类型的判断,但是返回的变量不是逻辑类型的mxArray数据对象,而是bool类型的数据,也就是mxLogical类型的数据。,7.3.4 元胞数组元胞数组是MATLAB特有的一种数据类型,用户可以将元胞数组看作成为广义矩阵。组成元胞数组的元素可以是各种类型的MATLAB数据,既可以是标量、向量,也可以是矩阵甚至是多维数组。在外部接口应用程序中,通过mx函数创建元胞数组的过程比创建普通的数据要略微繁琐:,首先,创建元胞数组的各个元胞数据;然后,创建元胞类型的数据对象指针;最后,将元胞数据赋值给元胞数组的各个元素。创建其它类型数据的函数在其它小节都已经介绍了,而创建元胞数组的函数有两个,分别用来创建元胞类型的矩阵和元胞类型的数组。,)创建元胞类型矩阵函数定义如下:mxArray*mxCreateCellMatrix(int m,int n);该函数的输入参数:矩阵的行数m和列数n;返回的输出参数:元胞矩阵的mxArray数据类型对象指针。,)创建元胞类型数组函数定义如下:mxArray*mxCreateCharArray(int ndim,const int*dims);该函数的输入参数:数组的维数ndim;每一维的尺寸*dims。返回的输出参数:元胞数组的mxArray数据类型对象指针。,3)创建了元胞数组的mxArray数据类型对象指针后,需要使用mxSetCell函数将已经创建好的元胞数据赋值给具体的元胞数组。mxSetCell函数的定义如下:void mxSetCell(mxArray*array_ptr,int index,mxArray*value);该函数没有返回的输出参数。输入参数:分别为元胞数组的mxArray数据类型对象指针array_ptr;元胞元素的索引index;元胞数据的mxArray数据类型对象指针value。,下面的代码片段说明了创建元胞数组的过程:/*元胞数组的指针*/mxArray*Data;/*实际数据的指针*/mxArray*string;mxArray*multi;mxArray*scalar;int ndims=2,2,2;double realdata=1,2,3,4,5,6,7,8;double*pr;,/*创建字符串类型变量*/string=mxCreateString(Isnt MATLAB Great?);/*创建多维数值数组*/multi=mxCreateNumericArray(3,ndims,mxDOUBLE_CLASS,mxREAL);pr=mxGetPr(multi);memcpy(pr,realdata,8*sizeof(double);/*创建标量*/scalar=mxCreateDoubleScalar(10);/*创建元胞数组*/Data=mxCreateCellMatrix(1,3);/*使用mxSetCell函数设置元胞的数据*/mxSetCell(Data,0,string);mxSetCell(Data,1,multi);mxSetCell(Data,2,scalar);,上述代码片段创建的元胞数组为 见data8.c ans=Isnt MATLAB Great?2x2x2 double 10 whos Name Size Bytes Class ans 1x3 290 cell arrayGrand total is 31 elements using 290 bytes,需要注意:在C语言中数组的起始元素序号为0,所以,使用mxSetCell函数设置元胞数组数据的时候,第一个元胞数据应该用数字0作为序号。,7.3.5 结构数组结构类型的数据和元胞类型的数据非常类似,在MATLAB中还有专门的函数完成两者之间的转换。结构类型的数据是由若干记录组成的;每一个记录保存在结构的字段中;结构保存的数据可以是任意类型的MATLAB数据。,在外部接口应用程序中,创建结构数组的过程和创建元胞数组的过程也非常类似,基本过程如下:首先,准备不同字段的数据。其次,创建结构类型的数据对象指针。最后,使用mx函数完成结构数据的赋值。,1)创建结构类型矩阵 函数定义如下:mxArray*mxCreateStructMatrix(int m,int n,int nfields,const char*field_names);结构矩阵的函数输入参数比较多:矩阵的行数m和列数n,字段的个数nfields,字段名称的字符串数组field_names。结构矩阵函数的输出参数:mxArray数据类型的数据对象指针表示一个结构矩阵。,2)创建结构类型数组 函数定义如下:mxArray*mxCreateStructArray(int ndim,const int*dims,int nfields,const char*field_names);创建结构数组函数的输入参数:分别为数组的维数ndim,数组每一维的尺寸*dims,字段的个数nfileds,字段名称的字符串数组field_names。函数的输出参数:mxArray数据类型的数据对象指针,表示一个结构类型的数组。,/*结构类型数据的指针*/mxArray*Data;/*结构中实际数据对象*/mxArray*string;mxArray*scalar;int field_num=0;/*字段名称*/char Fields=String,Scalar;/*创建结构的数据*/string=mxCreateString(Isnt MATLAB Great?);scalar=mxCreateDoubleScalar(10);,/*创建结构矩阵*/Data=mxCreateStructMatrix(1,1,2,Fields);/*设置结构的字段数据*/field_num=mxGetFieldNumber(Data,Fields0);/*返回域名的索引值,即结构体的字段序号*/mxSetFieldByNumber(Data,0,field_num,string);/*设置结构的字段数据*/field_num=mxGetFieldNumber(Data,Fields1);mxSetFieldByNumber(Data,0,field_num,scalar);,上述代码创建的结构矩阵如下:见data9.c ans=String:Isnt MATLAB Great?Scalar:10,在上面的代码片段中注:首先,使用mxGetFieldNumber函数获取字段序号,然后,利用mxSetFiledByNumber函数设置不同字段数据。mxSetField(Data,0,Fields0,string);/*设置字段的数值*/mxSetField(Data,0,Fields1,scalar);/*设置字段的数值*/,注意(续):函数的第二个参数是整个结构数组的元素序号,所以在上面的代码片段中,这个参数都被设置成为0,表示结构数组的第一个元素。,7.3.6 稀疏矩阵稀疏矩阵是一类特殊的数值矩阵,这些矩阵中多数数据都是0,只有一小部分的元素为非零数据。在一般情况下,矩阵中的零元素没有什么特殊意义,但是,如果编程中使用矩阵的完整表示,则这些零元素将会占用很多内存空间,所以,在数据结构上提出了保存稀疏矩阵的算法,做到既能够有效地完成稀疏矩阵的存储和运算,又能够达到节约内存空间的目的。,在MATLAB中保存稀疏矩阵是通过以下三个数组来完成的:1)第一个数组保存所有的非零元素,一般该数组为双精度类型,数组的长度为nzmax。2)第二个数组为整数类型数组,保存每个非零元素的行序号索引。3)第三个数组是长度为N+1的整数类型数组,其中N为矩阵的列数。该数组保存非零元素的列索引信息。该数组最后一个元素是稀疏矩阵的非零元素个数。有关稀疏矩阵的存储算法可以参阅有关的数据结构数据或者MATLAB的帮助文档。,1)在外部接口程序中,可以使用不同的函数创建不同数据类型的稀疏矩阵,其中最常用的就是创建双精度类型的稀疏矩阵,其函数为mxCreateSparse定义如下:mxArray*mxCreateSparse(int m,int n,int nzmax,mxComplexity ComplexFlag);该函数的输入参数分别为:矩阵的行数m和列数n,矩阵中非零元素的个数nzmax,以及矩阵数据的复数或者实数标志。函数的输出参数:稀疏矩阵的mxArray数据类型指针。,在创建了稀疏矩阵数据指针之后,需要通过其它的函数向数据指针进行