[R] Rcpp
jacinthe at gmx.de
jacinthe at gmx.de
Mon Feb 19 12:28:13 CET 2007
Hello all,
using GNU WinGW under Windows, I have experimented with the Rcpp package. Powerful package. Many thanks to Dominick Samperi.
Now I have tried to modify the RccpExample.cpp file in order to calculate two different moving averages, a simple moving average and an exponential moving average.
I call the function in R with:
params <- list(nobs=10,matype=2)
tempC <- .Call("Test_fun",x,params,PACKAGE = "RcppTemplate")
where nobs are the number of observation to calculate the moving average and matype could be 1 for a simple moving average and 2 for an exponential moving average. x is a dataframe containing the relevant data in the column labeled "Close".
For matype=1 it works fine and the output looks like:
$mab
[1] 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 1450.710 1453.658 1459.822 1467.564
[14] 1477.226 1487.114 1495.231 1496.560 1499.667 1498.295 1488.754 1478.958 1469.565 1460.120 1445.006 1429.891 1417.258
[27] 1405.487 1393.141 1384.933 1382.347 1379.085 1370.778 1363.517 1359.175 1364.777 1365.676 1368.880 1370.997 1369.357
[40] 1368.533 1368.512 1374.000 1379.464 1387.269 1387.010 1389.155 1393.638 1400.011 1407.004 1413.114 1421.691 1432.297
[53] 1441.165 1450.033 1456.677 1467.145 1480.899 1495.727 1509.590 1522.596 1534.066 1545.307 1554.237 1561.848 1567.405
[66] 1565.960 1561.789 1557.102 1559.802 1561.216 1563.193 1559.656 1560.993 1558.660 1562.106 1567.487 1569.686 1570.313
[79] 1562.673 1556.586 1548.386 1543.358 1536.041 1532.702 1527.327 1524.134 1526.599 1529.143 1536.038 1542.074 1548.256
[92] 1552.895 1559.588 1567.022 1574.884 1581.358 1585.991 1590.170 1591.420 1590.616
$nobs
[1] 10
$n
[1] 100
But for matype=2 it seems not to work. The output is
$mab
[1] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
[16] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
[31] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
[46] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
[61] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
[76] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
[91] 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36 1483.36
$nobs
[1] 10
$n
[1] 100
The modified RcppExpamle.cpp file looks like:
#include "Rcpp.hpp"
// simple moving average
vector<double> SMAVG(vector<double> data, int nobs, int n) {
int i,j;
double sum;
vector<double> mab(n);
for (i=0;i<(n-nobs+1);i++)
{
sum=0.0;
for (j=i;j<(i+nobs);j++)
{
sum += data[j];
}
mab[i+nobs-1]=sum/nobs;
}
return mab;
}
// exponential moving average
vector<double> EMAVG(vector<double> data, int nobs, int n) {
int i;
double optInK;
optInK=2/(nobs+1);
vector<double> mab(n);
mab[0] = data[0];
for (i=1;i<n;i++)
{
mab[i] = ((data[i]-mab[i-1])*optInK) + mab[i-1];
}
return mab;
}
// choose between simple and exponential moving average
RcppExport SEXP Test_fun(SEXP data, SEXP params) {
SEXP rl=R_NilValue;
char* exceptionMesg=NULL;
try{
int i=0;
RcppParams rparam(params);
int nobs = rparam.getIntValue("nobs");
int matype = rparam.getIntValue("matype");
RcppFrame datafm(data);
vector<vector<ColDatum> > table = datafm.getTableData();
int nrow = table.size();
RcppVector<double> close(nrow);
for(int row=0; row < nrow; row++) {
close(row)= table[row][4].getDoubleValue();
}
vector<double> stlvec(close.stlVector());
vector<double> res(nrow);
if (matype==1)
{
res = SMAVG(stlvec,nobs,nrow);
}
if (matype==2)
{
res = EMAVG(stlvec,nobs,nrow);
}
RcppVector<double> mab(nrow);
for (i=0; i<nrow; i++) {
mab(i)=res[i];
}
RcppResultSet rs;
rs.add("mab",mab);
rs.add("nobs",nobs);
rs.add("n",nrow);
rl = rs.getReturnList();
} catch(std::exception& ex){
exceptionMesg = copyMessageToR(ex.what());
} catch(...){
exceptionMesg = copyMessageToR("unknown reason");
}
if(exceptionMesg != NULL)
error(exceptionMesg);
return rl;
}
It seems that the problem is in the EMAVG function. I am not an C++ expert, perhapes I have made a mistake there. Could someone with stonger C++ skills check this function? Or have I made a mistake by calling the function in the Test_fun function, which is later called by R?
Besides, is there a more elegant way to access in the Test_fun the Close-Column of the dataframe data which contains the columns (Date, Open, High, Low, Close, Volume)?
Best regards
Jaci
--
"Feel free" - 10 GB Mailbox, 100 FreeSMS/Monat ...
Jetzt GMX TopMail testen: www.gmx.net/de/go/mailfooter/topmail-out
More information about the R-help
mailing list