Matlab与VC混合编程 - MEX文件
近日将以前做的蚁群算法的程序进行了重新调整,采用 MATLAB的MEX文件将复杂而繁琐的for循环运算改成VC代码,然后在Matlab中调用VC下的函数,这样可以通过调用VC的编译器计算复杂的处理过程,可以大大提高运算速度。其实早就想用VC来实现这个代码,但是一直觉得麻烦,因为VC环境下文件的提取、最终结果的图形化显示都不如MATLAB 方便,但是MATLAB的计算速度让我一直没有勇气去完成这个仿真。这次总算横下一条心,干了!
用半天的时间来了解MATLAB与VC的接口技术,并编写简单的MEX文件进行测试,摸清楚MATLAB在调用VC编写的函数时,参数的传递过程,特别是多维矩阵的传递。再用半天的时间将原先的 MATLAB程序改写成VC代码,并测试数据传递的正确性,晚上对修改的
程序作仔细的分析,排除一切由于语法不一致而出现的错误,并了解VC下调试MEX 文件的方法。终于经过一天在加半天的时间搞定了整个转移过程。由于程序的主体都在VC中实现,程序运算速度大大提高,由原先的20分钟提高到现在只需要3 秒就能计算完成,总算没有白费!具体方法如下:
1、在MATLAB中配置VC编译器
在MATLAB的命令窗口输入MEX -setup,根据提示配置C编译其为VC
2、在VC中编制相应的MEX文件
首先需要确定从MATLAB中传入VC函数的参数有哪些,这些参数都需要在函数void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])中进行映射,一个简单的例子如下:
#include "mex.h" //该头文件必须包含
#include "math.h"
#include
#include
//VC 要实现的主函数,传入的参数必须是double型的指针或者数组指针,以下两种定义方式都可以
void MyFun(double var[], double data[], double num[])
//void MyFun(double *var, double *data, double *num)
//其中data为一维向量,N为维数,var为向量的方差
{
int N = num[0];
int i;
double sum = 0, ave =0;
//int k=
for(i=0;i {
sum=sum+data;
}
ave = sum/N;
sum = 0;
for(i=0;i {
sum = sum + (data-ave)*(data-ave);
}
var[0] = sqrt(sum)/N;
}
//与MATLAB的接口函数,定义格式比较固定
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* nlhs是MATLAB命令行方式下输出参数的个数;
*plhs[]是 MATLAB命令行方式下的输出参数;
nrhs是MATLAB命令行方式下输入参数的个数;
*prhs[]是MATLAB命令行方式下的输入参数; */
//传递到函数中的参数都是double型的指针,分为输入参数和输出参数
double *outvar, *data;
//int mrows, ncols;
double *N;
//mrows = mxGetM(prhs[0]); /* 获得输入矩阵的行数 */
//ncols = mxGetN(prhs[0]); /* 获得输入矩阵的列数 */
plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
//分配输
出参数的存储空间,格式为mxCreateDoubleMatrix(行数,列数,mxREAL),其中mxREAL为固定格式
outvar=mxGetPr(plhs[0]); //与输出参数进行映射
data=mxGetPr(prhs[0]); //映射输入参数
N = mxGetPr(prhs[1]); //映射输入参数
MyFun(outvar, data, N); //调用函数
}
3、将以上文件保存为与函数同名的文件MyFun.cpp
4、在MATLAB的命令窗口输入mex -g MyFun.cpp对该文件进行编译,建立MEX文件MyFun.mexw32
5、在MATLAB的m文件中调用方法为:
N=100;
data=rand(1,N);
var = MyFun(data,N)