概述
我在计算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)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复