#include "ARIMA_R.h"
#include "BSDCoreLibrary.h"
using namespace bsd;
BSDLogger* pbsdlog = getBSDSysLogger();
BSDLogger& bsdlog = *pbsdlog;
bool ARIMA_R::AnayParam() {
AnaWord aw;
bsdlog.info("解析输入输出参数!");
aw.Import(m_strParameter);
//if (AnaSyntax::exist("/XDATA",aw))
//{
// AnaSyntax::getVAR("/XDATA",aw,m_aryFeildName);
//} else
//{
// bsdlog.error("变量字段名输入不正确!");
// return false;
//}
// int period;
// bool includemean;
if(AnaSyntax::exist("/CSV",aw))
{
csvpath=AnaSyntax::getSingleStr("/CSV",aw);
}
else
{
bsdlog.error("无数据源!");
return false;
}
if(AnaSyntax::exist("/NONAME",aw))
{
hasnoname=false;
}
if(AnaSyntax::exist("/ZHIBIAOFU",aw))
{
m_sepator="\" \"";
}
if(AnaSyntax::exist("/KONGGE",aw))
{
m_sepator="\" \"";
}
if(AnaSyntax::exist("/DOUHAO",aw))
{
m_sepator="\",\"";
}
if(AnaSyntax::exist("/FENHAO",aw))
{
m_sepator="\";\"";
}
if(AnaSyntax::exist("/MODEL",aw))
{
m_ar=AnaSyntax::getvalue("/MODEL","AR",aw);
m_df=AnaSyntax::getvalue("/MODEL","DF",aw);
m_ma=AnaSyntax::getvalue("/MODEL","MA",aw);
}
if(m_ar<0||m_df<0||m_ma<0)
{
bsdlog.error("order参数必须大于等于0的");
return false;
}
if(AnaSyntax::exist("/SEASONAL",aw))
{
m_period=AnaSyntax::getvalue("/SEASONAL","PERIOD",aw);
}
else
{
m_periodNA="NA";
}
if (AnaSyntax::findstr("/INCLUDE","FALSE",aw))
{
m_includemean = false;
}
if (AnaSyntax::findstr("/TRANSFORM",aw))
{
m_transformpars = false;
}
if (AnaSyntax::findstr("/METHOD","css-ML",aw))
m_nMethod = 0; //全部选入[默认]
else if (AnaSyntax::findstr("/METHOD","ML",aw))
m_nMethod = 1;
else if(AnaSyntax::findstr("/METHOD","CSS",aw))
m_nMethod = 2;
return true;
}
ARIMA_R::ARIMA_R() {
m_periodNA="";
m_includemean=true;
m_transformpars=true;
m_nMethod=0;
hasnoname=true;
m_sepator=",";
}
ARIMA_R::~ARIMA_R() {
}
#include <fstream>
bool ARIMA_R::CreateProcess_R(string csvpath,double AR,double DF,double MA)
{
STARTUPINFO startupinfo;
ZeroMemory(&startupinfo,sizeof(STARTUPINFO));
startupinfo.cb=sizeof(STARTUPINFO);
startupinfo.wShowWindow=SW_HIDE;
startupinfo.dwFlags=STARTF_USESHOWWINDOW;
PROCESS_INFORMATION process_info;
string r_Cmdpath="D:\\Program Files\\R\\R-3.0.0\\bin\\Rscript "; //绝对路径 R //TODO
// string csvpath="D:/adl_arima.csv";
string strr="\\",str_t="/";
int pos=csvpath.find(strr);////查找指定的串
while (pos != -1)
{
csvpath.replace(pos,strr.length(),str_t);////用新的串替换掉指定的串
pos = csvpath.find(strr);//////继续查找指定的串,直到所有的都找到为止
}
fstream rSourceFile("RsourceFile.R",ios::in|ios::out|ios::trunc);
// rSourceFile<<"x<-read.csv(\""+csvpath+"\")"<<endl;
if(hasnoname)
rSourceFile<<"x<-read.csv(\""+csvpath+"\""+",TRUE,"+m_sepator+")"<<endl;
else
rSourceFile<<"x<-read.csv(\""+csvpath+"\""+"FALSE"+m_sepator+")"<<endl;
rSourceFile<<"arima(x";
//double ar转为string
string ar_string;
stringstream ar_ss;
ar_ss<<m_ar;
ar_ss>>ar_string;
//double df转为string
string df_string;
stringstream df_ss;
df_ss<<m_df;
df_ss>>df_string;
//double ma转为string
string ma_string;
stringstream ma_ss;
ma_ss<<m_ma;
ma_ss>>ma_string;
rSourceFile<<",c("+ar_string+","+df_string+","+ma_string+")"<<endl;
if(m_periodNA.compare("NA")==0)
rSourceFile<<",seasonal=list(order=c("+ar_string+","+ma_string+"),"+"NA)"<<endl;
else
{
//double ma转为string
string period_string;
stringstream period_ss;
period_ss<<m_period;
period_ss>>period_string;
rSourceFile<<","+period_string+")"<<endl;
}
rSourceFile<<",xreg = NULL";
if(m_includemean)
rSourceFile<<",include.mean=TRUE"<<endl;
else
rSourceFile<<",include.mean=FALSE"<<endl;
if(m_transformpars)
rSourceFile<<",transform.pars = TRUE";
else
rSourceFile<<",transform.pars = FALSE";
rSourceFile<<",fixed = NULL,init = NULL";
if(m_nMethod==0)
rSourceFile<<",method = c(\"css-ML\")";
if(m_nMethod==1)
rSourceFile<<",method = c(\"ML\")";
if(m_nMethod==2)
rSourceFile<<",method = c(\"CSS\")";
rSourceFile<<")";
rSourceFile.close();
string cmd_all=r_Cmdpath+"RsourceFile.R"+" >result.txt";
::CreateProcess(NULL,(LPSTR)cmd_all.c_str(),NULL,NORMAL_PRIORITY_CLASS,&startupinfo,&process_info);
::CloseHandle(process_info.hThread);
::CloseHandle(process_info.hProcess);
return true;
}
bool ARIMA_R::AddResult()
{
//写入result集中
RsltElementTextPtr RText;
RText.setName("ARIMA输出结果");
string result_string;
fstream file("result.txt",ios::in|ios::out);
while (!file.fail())
{
getline ( file,result_string);
string strr=" ",str_t=" ";
int pos=result_string.find(strr);////查找指定的串
while (pos != -1)
{
result_string.replace(pos,str_t);////用新的串替换掉指定的串
pos = result_string.find(strr);//////继续查找指定的串,直到所有的都找到为止
}
if(result_string.compare("Call:")==0)
RText.addString("输入参数情况<br>");
else
RText.addString(result_string+"<br>");
}
m_pResult->add(RText);
file.close();
return true;
}
bool ARIMA_R::RunArithmetic(Result& result) {
m_pResult = &result;
if(!AnayParam()) //读取输入参数
return false;
CreateProcess_R(csvpath,m_ar,m_df,m_ma); //调用R进程
AddResult();
return true;
}
代码是基于本公司的相关底层库,除了解析字符串过程,其他和底层无关。主要分析调用进程的问题::CreateProcess的部分各参数说明,调用R语言的Rscript.exe来运行R代码
startupinfo.wShowWindow=SW_HIDE;
startupinfo.dwFlags=STARTF_USESHOWWINDOW; //隐藏弹出的cmd窗口
@H_404_650@原型:
@H_404_650@BOOL CreateProcess(
@H_404_650@LPCSTR lpApplicationName,
NULL,
@H_404_650@//
@H_404_650@进程安全性
@H_404_650@,
@H_404_650@设为
@H_404_650@NULL
@H_404_650@表示使用默认安全属性
@H_404_650@LPSECURITY_ATTRIBUTES lpProcessAttributes,
@H_404_650@LPSECURITY_ATTRIBUTES lpThreadAttributes
@H_404_650@DWORD dwCreationFlags,220)">
@H_404_650@LPVOID lpEnvironment,220)">
@H_404_650@//
@H_404_650@指定了新进程使用的环境变量
/
@H_404_650@/
@H_404_650@返回新建进程的标志信息
@H_404_650@,
@H_404_650@如
@H_404_650@ID
@H_404_650@号
@H_404_650@,
@H_404_650@句柄等
@H_404_650@LPPROCESS_INFORMATION lpProcessInformation
@H_404_650@)
@H_404_650@上面的参数的数据类型是
@H_404_650@Windows
@H_404_650@自定义的数据类型
@H_404_650@,
@H_404_650@具体定义在
@H_404_650@WINDEF.h
@H_404_650@文件中
@H_404_650@,
@H_404_650@下面列出一部分常用的数据类型
@H_404_650@typedef unsigned long DWORD;
@H_404_650@typedef intBOOL;
@H_404_650@typedef unsigned charBYTE;
@H_404_650@typedef unsigned shortWORD
@H_404_650@typedef floatFLOAT;
@H_404_650@typedef void far*LPVOID;
@H_404_650@typedef intINT;
@H_404_650@typedef unsigned intUINT;
@H_404_650@lpProcessInformation
@H_404_650@参数是一个指向
@H_404_650@PROCESS_INFORMATION
@H_404_650@结构的指针
@H_404_650@,CreateProcess
@H_404_650@函数返回之前会初始化这些结构成员
@H_404_650@,
@H_404_650@结构定义如下
@H_404_650@:
@H_404_650@typedef struct
@H_404_650@{
@H_404_650@}
@H_404_650@创建进程以后
@H_404_650@,
@H_404_650@必须调用
@H_404_650@CloseHandle
@H_404_650@函数关闭所创建的进程内核对象和线程内核对象
@H_404_650@,
@H_404_650@否则进程虽然终止了
@H_404_650@,
@H_404_650@但是该进程占用的资源依然没有释放
#include
<windows.h>
intAPIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
//
默认线程安全属性
//
使用默认的创建方式
//
使用本进程的环境变量
//
使用本进程的目录
}