我是靠谱客的博主 甜甜楼房,最近开发中收集的这篇文章主要介绍【Matlab】1. Matlab效率提升——调用C语言编写的函数 (mex,matlab C API),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我在计算VIX的时候,使用的是 TS 的分钟线,我的基本思路是把数据保存到本地,然后用C#计算出数据,生成mat文件,供以后使用。

由于TS使用Cell作为数据保存的载体,所以,我需要把cell写入为CSV格式的文件。问题出现了!!!网上几乎没有关于Cell保存为CSV的matlab函数介绍,好不容易找到一个,但是效率实在是太低了,严重影响了运行速度。一咬牙,一跺脚,我决定挑战一下自己的C语言功底,用C语言写一个保存函数,用来让matlab调用!!这个函数我命名为 my_Cell2CSV。


首先,我先把这个函数的代码放上。我是用NotePad++编写的,然后调试的时候就是用Matlab的mex加载,如果遇到错误就返回notepad,继续修改。(当中有碰到过错误要我不得不重启Matlab的,心累。。)

/*=================================================================
Made by White Hacker, any question please contact by wh_wing@126.com
Bon courage et bonne chance!
 *============================================================*/

#include "mex.h"
#include "string.h"

void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    //变量定义
    size_t elements;	//Cell Table 中的元素数量
	size_t nRow = 0;	//Cell Table 中的行数
	size_t nCol = 0; 	//Cell Table 中的列数
	mxArray *tempCell;	
	mwIndex i,j,cur;
	FILE *fp;                
	char* path;
	mxArray *cellTable;
	
    //保证有有且仅有两个参数    
    if (nrhs != 2) {
        mexErrMsgIdAndTxt( "MATLAB:my_Cell2CSV:invalidNumInputs",
                "Two input arguments required.");
    }
	
    //判断第一个参数是否是Cell类型
    if (!(mxIsCell(prhs[0]))){
        mexErrMsgIdAndTxt( "MATLAB:my_Cell2CSV:invalidInputType",
                "Input array must be of type CELL.");
    }
    //判断第二个参数是否是string类型
    if (!(mxIsChar(prhs[1]))){
        mexErrMsgIdAndTxt( "MATLAB:my_Cell2CSV:invalidInputType",
                "PATH input must be of type STRING.");
    }
	
    //得到所有元素数量
	cellTable = prhs[0];
	path = mxArrayToString(prhs[1]);
    elements = mxGetNumberOfElements(cellTable);
	mexPrintf("Total elements number: ");
	mexPrintf("%dn",elements);
	
	//获得行数和列数
	nRow = mxGetM(cellTable);
	nCol = mxGetN(cellTable);
	
	//写入文件
	fp=fopen(path, "w+");
	if(fp!=NULL)
	{
		//循环打印数据 
		for(i = 0; i < nRow; i++)
		{//行循环
			for(j=0; j < nCol; j++)
			{//列循环
				cur = j * (mwIndex)nRow + i;	//当前索引
				tempCell = mxGetCell(cellTable,cur);	//获得当前Cell Table中的Cell
				//根据类型输出数据
				if(mxIsChar(tempCell))
				{//如果元素是字符串(char*)
					fprintf(fp,"%s",mxArrayToString(tempCell));
				}
				else if(mxIsDouble(tempCell))	
				{//如果元素是小数(Double)
					double* doubleNum = (double*)mxGetData(tempCell);
					fprintf(fp,"%f",*doubleNum);
				}
				else if(mxIsInt32(tempCell))	
				{//如果元素是整数(Int32)
					int* intNum = (int*)mxGetData(tempCell);
					fprintf(fp,"%d",*intNum);		
				}
				//行尾以外的列,打印","
				if(j < nCol-1)
				{
					fprintf(fp,",");
				}
			}
			fprintf(fp,"n");	
		}
		//关闭文件
		fclose(fp);
		mexPrintf("Storage is completed!n");
	}
	else
	{
		mexErrMsgIdAndTxt( "MATLAB:my_Cell2CSV:invalidInputType",
                "File is not opened correctly!.");
	}
}

matlab如何调用.c程序呢?答案是matlab的自带命令 mex XXX.c (注意:c文件要放在当前文件夹下),具体的窗口如下:


命令成功后,会有一个mexwXX的文件。至此,调用准备就做好了。

为了测试程序的时间,我特意先使用原来用matlab语言写的程序做,结果如下:


再用my_Cell2CSV函数写入cell table到CSV中,结果如下:


结果真的是快了近200倍!!!真的是很大的性能提升!!!

下面是我的调用代码,tic和toc没有写。。


clc;
clear;

%% Time and Path Setting
curYear = 2015;
curMonth = 11;
curDay = 4;
path = 'F:Internship_ProjectsVIX';

%% Data Parameters
date = datenum(curYear,curMonth,curDay)-693960;
current = 10000 * curYear + 100 * curMonth + curDay;

%% Connect TS And Get info and trade tables
ts = actxserver('TSExpert.CoExec');
infoMat = ts.RemoteCallFunc('my_GetAllOptions',{date,'SH510050'});
trdMat = ts.RemoteCallFunc('my_Get1mData',{date});

%% Load Function
mex my_Cell2CSV.c;

%% Write data to CSV
fprintf('Writing the data to CSV file...n');
my_Cell2CSV(infoMat,[path,'DataOptionInfo_',int2str(current),'.CSV']);
my_Cell2CSV(trdMat,[path,'DataTradingData_',int2str(current),'.CSV']);
fprintf('Writing is finished!n');

%% Call exe to Calculate VIX
fprintf('Doing the VIX Calculation...n');
cmd = [path,'VIXVIXbinDebugVIX.exe',...
    ' ',path,...
    ' ',num2str(0.045),...
    ' ',num2str(0),...
    ' ',int2str(current)];
fprintf('Finish!');
system(cmd);




【总结】

以前上学的时候就说matlab不太适合用for循环,如今发现果然如此。幸好之前磨python源代码的时候还复习了一下C语言的知识,才可以马上写matlab C API层的程序。今天这篇只是开始,以后应该会写更多的C函数!

【PS】其实我自己挺喜欢C#这门语言的,但是和同事交流下来,大家都用的是R语言或者matlab。说实话,C#做统计、做量化的确是有不方便的地方,但是我现在有个想法,想要自己做一些能够方便开发的C#类,将在以后的博客中写出来。

最后

以上就是甜甜楼房为你收集整理的【Matlab】1. Matlab效率提升——调用C语言编写的函数 (mex,matlab C API)的全部内容,希望文章能够帮你解决【Matlab】1. Matlab效率提升——调用C语言编写的函数 (mex,matlab C API)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部