From edd at debian.org  Tue Sep 29 20:55:49 2009
From: edd at debian.org (Dirk Eddelbuettel)
Date: Tue, 29 Sep 2009 13:55:49 -0500
Subject: [Rd] How do I access class slots from C?
In-Reply-To: <fc212e850909290728j1f3a305bkf82db6dfcd42d8a9@mail.gmail.com>
References: <fc212e850909290728j1f3a305bkf82db6dfcd42d8a9@mail.gmail.com>
Message-ID: <19138.22581.659836.39730@ron.nulle.part>


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.



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