[Rd] How do I access class slots from C?

Romain Francois romain.francois at dbmail.com
Wed Sep 30 10:12:32 CEST 2009


On 09/30/2009 09:51 AM, Abhijit Bera wrote:
> Hi Romain
>
> I got what ur saying. Good idea. First I convert the data into a
> timeseries and return object using C, then I pass it onto an R function
> which I have written, I call the R function from my C code, it evaluates
> and then I process the values returned by it in my C code. Much simpler
> that way. So, I can do away with all these confusing constructs. :)
>
> What about performance? You think I will see a difference if I follow a
> C only approach of creating all the objects?

Essentially you are not using a C only approach, even in your original 
example, since you call functions from fPortfolio (btw, R has to look 
down the search path each time to find the function, so you can make 
this more efficient, ...)

It might even be faster like this since you only need to parse the R 
functions once, so you pay the (not so expensive btw) price of parsing 
once.

Combine this with an approach that caches the references to the 
functions, so you only pay the price of searching through R search path 
once, and you're set.

Anyway, chances are the code from fPorfolio you call will be what costs 
the most, after all that is what is actually working here. Before 
converting your R script to C, did you do some profiling to identify 
what takes the most time ?

Romain

> Regards
>
> Abhijit
>
> On Wed, Sep 30, 2009 at 12:45 PM, Abhijit Bera <abhibera at gmail.com
> <mailto:abhibera at gmail.com>> wrote:
>
>     Hi
>
>     I'm pulling financial datasets from a DB, converting it to a
>     timeseries object then creating a returns object out of it.
>
>     I plan to embed R into an application, which is why I'm taking this
>     route of using C.
>
>     Regards
>
>     Abhijit
>
>
>     On Wed, Sep 30, 2009 at 12:07 PM, Romain Francois
>     <romain.francois at dbmail.com <mailto:romain.francois at dbmail.com>> wrote:
>
>         On 09/30/2009 08:51 AM, Abhijit Bera wrote:
>
>
>             Hi
>
>             Thanks all of you for your suggestions. I will put up my
>             code shortly based
>             on your suggestions.
>
>             I wonder how the parsing and eval will work when most of my
>             data comes in
>             from an external source like a DB?  Probably it would be
>             more efficient to
>             make an object? Hmmmm... maybe it has to be a mix of parsing
>             and eval?
>
>
>         What's in the database ? Is this the data or the R code ? What's
>         wrong with writing your own set of R functions and evaluate
>         calls to these functions instead of basically replicate this in
>         C or C++ or whatever.
>
>         Dirk's code certainly is nicer, but would you really do it like
>         that in real life ?
>
>         Romain
>
>
>             Yes, the lang4 c idea sucks. mkstring is better.
>
>             Regards
>
>             Abhijit
>
>
>             On Tue, Sep 29, 2009 at 11:55 PM, Dirk
>             Eddelbuettel<edd at debian.org <mailto:edd at debian.org>>  wrote:
>
>
>                 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);
>                 }

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/ztCu : RGG #158:161: examples of package IDPmisc
|- http://tr.im/yw8E : New R package : sos
`- http://tr.im/y8y0 : search the graph gallery from R



More information about the R-devel mailing list