【例2】试用MEX文件求5阶完全图邻接矩阵的特征值及对应的特征向量。
下面是求该矩阵的MEX文件。
#include "mex.h"
void mexFunction(int nlhs,mxArray
*plhs[],int nrhs,const mxArray *prhs[])
{
double
x;
mxArray
*y,*z,*w;
int n;
if
(nrhs!=1)
mexErrMsgTxt("One inputs required.");
if (nlhs !=
3)
mexErrMsgTxt("Three output required.");
if
(!mxIsDouble(prhs[0])||mxGetN(prhs[0])*mxGetM(prhs[0])!=1)
mexErrMsgTxt("Input must be a scalar.");
x=mxGetScalar(prhs[0]);
plhs[0]=mxCreateDoubleMatrix(x,x,mxREAL);
plhs[1]=mxCreateDoubleMatrix(x,x,mxREAL);
plhs[2]=mxCreateDoubleMatrix(x,x,mxREAL);
n=mxGetM(plhs[0]);
y=plhs[0];
z=plhs[1];
w=plhs[2];
//利用mexCallMATLAB计算特征值
mexCallMATLAB(1,&plhs[1],1,prhs,"ones");
mexCallMATLAB(1,&plhs[2],1,prhs,"eye");
mexCallMATLAB(1,&plhs[0],2,&plhs[1],"-");
mexCallMATLAB(2,&plhs[1],1,&plhs[0],"eig");
//演示mexEvalString的功能
mexEvalString("y=y*2");
mexEvalString("a=a*2");
}
在MATLAB命令窗口输入以下命令:
>> mex
Matlab_2.cpp
>>
clear
>>
a=magic(5)
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>>
[y,z,w]=Matlab_2(5)
??? Undefined function or variable
'y'.
a =
34 48 2 16 30
46 10 14 28 32
8 12 26 40 44
20 24 38 42 6
22 36 50 4 18
y =
0 1 1 1 1
1 0 1 1 1
1 1 0 1 1
1 1 1 0 1
1 1 1 1 0
z =
0.8333 -0.1667 -0.1667 0.2236 0.4472
-0.1667 0.8333 -0.1667 0.2236 0.4472
-0.1667 -0.1667 0.8333 0.2236 0.4472
-0.5000 -0.5000 -0.5000 0.2236 0.4472
0 0 0 -0.8944 0.4472
w =
-1 0 0 0 0
0 -1 0 0 0
0 0 -1 0 0
0 0 0 -1 0
0 0 0 0 4
由上面可以看出,K5的特征值为–1和4,其中–1是四重根。MATLAB提供了mexGetVariable、mexPutVariable函数,以实现MEX空间与其它空间交换数据的任务,具体可以参看MATLAB帮助文档。
5.4建立二维双精度矩阵函数mxCreateDoubleMatrix
其格式具体如下:
#include "matrix.h"
mxArray *mxCreateDoubleMatrix(int m,
int n, mxComplexity ComplexFlag);
其中m代表行数,n代表列数,ComplexFlag可取值mxREAL
或mxCOMPLEX。如果创建的矩阵需要虚部,选择mxCOMPLEX,否则选用mxREAL。
类似的函数有:
mxCreateCellArray
创建n维元胞mxArray
mxCreateCellMatrix
创建二维元胞mxArray
mxCreateCharArray
创建n维字符串mxArray
mxCreateCharMatrixFromStrings
创建二维字符串mxArray
mxCreateDoubleMatrix
创建二维双精度浮点mxArray
mxCreateDoubleScalar
创建指定值的二维精度浮点mxArray
mxCreateLogicalArray
创建n维逻辑mxArray,初值为false
mxCreateLogicalMatrix
创建二维逻辑mxArray,初值为false
mxCreateLogicalScalar
创建指定值的二维逻辑mxArray
mxCreateNumericArray
创建n维数值mxArray
mxCreateNumericMatrix
创建二维数值mxArray,初值为0
mxCreateScalarDouble
创建指定值的双精度mxArray
MxCreateSparse
创建二维稀疏mxArray
mxCreateSparseLogicalMatrix
创建二维稀疏逻辑mxArray
MxCreateString
创建指定字符串的1 n的串mxArray
mxCreateStructArray
创建n维架构mxArray
mxCreateStructMatrix
创建二维架构mxArray
5.5 获取行维和列维函数mxGetM、mxGetN
其格式如下:
#include "matrix.h"
int mxGetM(const mxArray
*array_ptr);
int mxGetN(const mxArray
*array_ptr);
与之相关的还有:
mxSetM:设置矩阵的行维
mxSetN:设置矩阵的列维
5.6 获取矩阵实部和虚部函数mxGetPr、mxGetPi
其格式如下:
#include "matrix.h"
double *mxGetPr(const mxArray
*array_ptr);
double *mxGetPi(const mxArray
*array_ptr);
与之相关的函数还有:
mxSetPr:设置矩阵的实部
mxSetPi:设置矩阵的虚部
【例3】实现字符串的倒序输出。
#include "mex.h"
void revord(char *input_buf,int
buflen,char *output_buf)
{
int i;
//实现字符串倒序
for(i=0;i
*(output_buf+i)=*(input_buf+buflen-i-2);
}
void mexFunction(int nlhs,mxArray
*plhs[],int nrhs,const mxArray *prhs[])
{
//定义输入和输出参量的指针
char
*input_buf,*output_buf;
int
buflen,status;
//检查输入参数个数
if(nrhs!=1)
mexErrMsgTxt("One input required.");
else
if(nlhs>1)
mexErrMsgTxt("Too many output arguments.");
//检查输入参数是否是一个字符串
if(mxIsChar(prhs[0])!=1)
mexErrMsgTxt("Input must be a string.");
//检查输入参数是否是一个行变量
if(mxGetM(prhs[0])!=1)
mexErrMsgTxt("Input must a row vector.");
//得到输入字符串的长度
buflen=(mxGetM(prhs[0])*mxGetN(prhs[0]))+1;
//为输入和输出字符串分配内存
input_buf=mxCalloc(buflen,sizeof(char));
output_buf=mxCalloc(buflen,sizeof(char));
//将输入参量的mxArray结构中的数值拷贝到C类型字符串指针
status=mxGetString(prhs[0],input_buf,buflen);
if(status!=0)
mexWarnMsgTxt("Not enough space. String is truncated.");
//调用C程序
revord(input_buf,buflen,output_buf);
plhs[0]=mxCreateString(output_buf);
}
这个程序中需要注意的地方是mxCalloc函数,它代替了标准C程序中的calloc函数用于动态分配内存,而mxCalloc函数采用的是MATLAB的内存管理机制,并将所有申请的内存初始化为0,因此凡是C代码需要使用calloc函数的地方,对应的Mex文件应该使用mxCalloc函数。同样,凡是C代码需要使用realloc函数的地方,对应的Mex文件应该使用mxRealloc函数。
在MATLAB命令窗口中对revord.cpp程序代码编译链接:
>> mex
revord.cpp
在MATLAB命令窗口中对C-MEX文件revord.dll进行测试:
>> x='I
am student.';
>>
revord(x)
ans =
.tneduts ma I