[Rd] How do I access class slots from C?
Dirk Eddelbuettel
edd at debian.org
Tue Sep 29 20:55:49 CEST 2009
This is so much fun. The C code posted wasn't exactly legible. So here is a
new C++ variant that I just committed to the RInside SVN as a new example.
And it mine works (against RInide and Rcpp as on CRAN):
edd at ron:~/svn/rinside/pkg/inst/examples> ./rinside_sample4
Package 'sn', 0.4-12 (2009-03-21). Type 'help(SN)' for summary information
Using the GLPK callable library version 4.37
Title:
MV Feasible Portfolio
Estimator: covEstimator
Solver: solveRquadprog
Optimize: minRisk
Constraints: LongOnly
Portfolio Weights:
SBI SPI SII LMI MPI ALT
0.1 0.1 0.1 0.1 0.3 0.3
Covariance Risk Budgets:
SBI SPI SII LMI MPI ALT
-0.0038 0.1423 0.0125 -0.0058 0.4862 0.3686
Target Return and Risks:
mean mu Cov Sigma CVaR VaR
0.0548 0.0548 0.4371 0.4371 1.0751 0.6609
Description:
Tue Sep 29 13:43:36 2009 by user:
SBI -0.00380065
SPI 0.142261
SII 0.0125242
LMI -0.00576251
MPI 0.486228
ALT 0.368551
edd at ron:~/svn/rinside/pkg/inst/examples>
The final few lines are C++ accessing the result, earlier in the code I
assign the weight vector from C++ as you desired from C. All with error
checking / exception handling and what have in under 60 lines of (IMHO more
readable) code -- see below.
Dirk
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
//
// Another simple example inspired by an r-devel mail by Abhijit Bera
//
// Copyright (C) 2009 Dirk Eddelbuettel and GPL'ed
#include "RInside.h" // for the embedded R via RInside
#include "Rcpp.h" // for the R / Cpp interface used for transfer
#include <iomanip>
int main(int argc, char *argv[]) {
try {
RInside R(argc, argv); // create an embedded R instance
SEXP ans;
std::string txt = "suppressMessages(library(fPortfolio))";
if (R.parseEvalQ(txt)) // load library, no return value
throw std::runtime_error("R cannot evaluate '" + txt + "'");
txt = "lppData <- 100 * LPP2005.RET[, 1:6]; "
"ewSpec <- portfolioSpec(); "
"nAssets <- ncol(lppData); ";
if (R.parseEval(txt, ans)) // prepare problem
throw std::runtime_error("R cannot evaluate '" + txt + "'");
const double dvec[6] = { 0.1, 0.1, 0.1, 0.1, 0.3, 0.3 }; // choose any weights you want
const std::vector<double> w(dvec, &dvec[6]);
R.assign( w, "weightsvec"); // assign STL vector to R's 'weightsvec' variable
txt = "setWeights(ewSpec) <- weightsvec";
if (R.parseEvalQ(txt)) // evaluate assignment
throw std::runtime_error("R cannot evaluate '" + txt + "'");
txt = "ewPortfolio <- feasiblePortfolio(data = lppData, spec = ewSpec, constraints = \"LongOnly\"); "
"print(ewPortfolio); "
"vec <- getCovRiskBudgets(ewPortfolio at portfolio)";
if (R.parseEval(txt, ans)) // assign covRiskBudget weights to ans
throw std::runtime_error("R cannot evaluate '" + txt + "'");
RcppVector<double> V(ans); // convert SEXP variable to an RcppMatrix
R.parseEval("names(vec)", ans); // assign columns names to ans
RcppStringVector names(ans);
for (int i=0; i<names.size(); i++) {
std::cout << std::setw(16) << names(i) << "\t"
<< std::setw(11) << V(i) << "\n";
}
} catch(std::exception& ex) {
std::cerr << "Exception caught: " << ex.what() << std::endl;
} catch(...) {
std::cerr << "Unknown exception caught" << std::endl;
}
exit(0);
}
--
Three out of two people have difficulties with fractions.
More information about the R-devel
mailing list