MArtin,

On Sep 29, 2009, at 12:17 , Martin Morgan wrote:

Simon Urbanek wrote:
Abhijit,
as for your subject - it's GET_SLOT,
but why don't you just use ParseVector and eval instead of hand- crafting C code that calls the evaluator? That latter is way more error prone and the error-handling is a nightmare (your current code is inefficient anyway so you don't gain anything).

My 2 cents: constructing language calls seems much more appropriate than parsing expressions when the values to be used are from programming variables, as is likely the case in most real applications?

Yes, but not in this case - it's all just replication of a script that could be evaluated with one call, there are no native objects involved. As soon as you start using more than one eval in the C code, it is very likely not the right way to go. I do agree that constructed expressions are useful if you have a) a very short call that cannot be easily done at C level or b) it involves unassigned objects generated in the C code -- but neither it the case here.


And accessing slots with GET_SLOT seems to break the (hard-won) abstraction layer of S4, so better to call the R accessors (even when this is inefficient computationally) especially when using objects from packates whose internals you do not control.


Agreed, again something that could be prevented with parse + eval ;).


One particular part of the code below

PROTECT (e =lang4(install("c"),mkString("SBI"),mkString("SPI"),mkString("SII")));

could be re-written as

 SEXP x = PROTECT(NEW_CHARACTER(3));
 SET_STRING_ELT(x, 0, mkChar("SBI"));
 etc

In the original, although the outer PROTECT is unnecessary, I wonder about the mString()... calls, which are not guaranteed to be evaluated in order and produce unprotected CHARSXPs (prior to being protected inside lang4). I'm not really sure about the mkChar() in the above, either, and whether there is an opportunity for garbage collection in SET_VECTOR_ELT.


CHARSXPs are always protected by enclosing STRSXP and SET_STRING_ELT(x, i, mkChar()) is always safe. And yes, the lang4 "c" construct is a bad idea.

Cheers,
Simon




As for setWeights, you got the code wrong - if you want to mimic the R code then it's a call to the assignment "<-" - have a look at the parse result of
"setWeights(ewSpec) <- rep(1/nAssets, times = nAssets)":
 @d58774 06 LANGSXP g0c0 []
   @809008 01 SYMSXP g1c0 [MARK,gp=0x4000] "<-"
   @d59540 06 LANGSXP g0c0 []
     @1a1af34 01 SYMSXP g0c0 [] "setWeights"
     @d59498 01 SYMSXP g0c0 [] "ewSpec"
   @d58720 06 LANGSXP g0c0 []
     @814ac4 01 SYMSXP g1c0 [MARK,gp=0x4000] "rep"
     @d595b0 06 LANGSXP g0c0 []
   @80ae44 01 SYMSXP g1c0 [MARK,gp=0x4000] "/"
   @1bf8ce8 14 REALSXP g0c1 [] (len=1, tl=0) 1
   @1dbf1ac 01 SYMSXP g0c0 [MARK] "nAssets"
     TAG: @9450fc 01 SYMSXP g1c0 [MARK] "times"
     @1dbf1ac 01 SYMSXP g0c0 [MARK] "nAssets"
Again, I think you would be far better off just using parse instead...
Cheers,
Simon
PS: Your PROTECTs are way off-balance, and you don't need almost any of them - langX and listX protect all arguments
On Sep 29, 2009, at 10:28 , Abhijit Bera wrote:
Hi

I'm trying to implement something similar to the following R snippet using
C. I seem to have hit the wall on accessing class slots using C.

library(fPortfolio)

lppData <- 100 * LPP2005.RET[, 1:6]
ewSpec <- portfolioSpec()
nAssets <- ncol(lppData)
setWeights(ewSpec) <- rep(1/nAssets, times = nAssets)

ewPortfolio <- feasiblePortfolio(
 data = lppData,
 spec = ewSpec,
 constraints = "LongOnly")

ewSpec is an object of type Portfolio Spec which has the following slots:

model slot
  type = "MV"                  a string value
  optimize = "minRisk"         a string value
  estimator = "covEstimator"   a function name
  tailRisk = list()            a list
  params =
    list(alpha=0.05, a=1, ...) a list
portfolio slot                   a list
  weights = NULL               a numeric vector
  targetReturn = NULL          a numeric value
  targetRisk = NULL            a numeric value
  riskFreeRate = 0             a numeric value
  nFrontierPoints = 50         an integer value
  status = NA)                 a integer value
optim slot                       a list
  solver = "solveRquadprog"    a function names
  objective = NULL             function names
  options = list()             a list with parameters
  control = list()             a list with controls
  trace = FALSE)               a logical
messages slot:                   a list
  list = list()                a list

I want to set the weights so that I can compute a feasiblePortfolio.
Unfortunately I cannot figure out how to do this from C.

Here is what I wrote so far:

#include <stdio.h>
#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>
#include <Rembedded.h>

int main(int argc, char** argv)
{

  SEXP
e ,c ,portSpec ,portData ,portConstr ,portVal,portWeights,tsAssets,tsReturns,nAssets,reciprocal;
  int errorOccurred,nx,ny,i,j;
  double *v;
  const char *x,*y;

  Rf_initEmbeddedR(argc, argv);

  // loading fPortfolio
  PROTECT(e = lang2(install("library"), mkString("fPortfolio")));
  R_tryEval(e, R_GlobalEnv, NULL);
  UNPROTECT(1);


  // creating a default portfolioSpec object
  PROTECT(e=lang1(install("portfolioSpec")));
  PROTECT(portSpec=R_tryEval(e,R_GlobalEnv, NULL));

  // creating a portfolioData object


PROTECT (e = lang4 (install("c"),mkString("SBI"),mkString("SPI"),mkString("SII")));
  PROTECT(tsAssets=R_tryEval(e,R_GlobalEnv,NULL));

PROTECT (e=lang4(install("["),install("SWX.RET"),R_MissingArg,tsAssets));
  PROTECT(tsReturns=R_tryEval(e,R_GlobalEnv,NULL));

  PROTECT(e=lang3(install("*"),ScalarInteger(100),tsReturns));
  PROTECT(tsReturns=R_tryEval(e,R_GlobalEnv,NULL));

  PROTECT(e=lang3(install("portfolioData"),tsReturns,portSpec));
  PROTECT(portData=R_tryEval(e,R_GlobalEnv,NULL));

// Creating a portfolio constraints string
  PROTECT(portConstr=mkString("LongOnly"));

// Setting weights
  PROTECT(e=lang2(install("ncol"),tsReturns));
  PROTECT(nAssets=R_tryEval(e,R_GlobalEnv,NULL));

  PROTECT(e=lang3(install("/"),ScalarInteger(1),nAssets));
  PROTECT(reciprocal=R_tryEval(e,R_GlobalEnv,NULL));

  PROTECT(e=lang3(install("rep"),reciprocal,nAssets));
  PROTECT(portWeights=R_tryEval(e,R_GlobalEnv,NULL));

// Right now the program crashes here. It says: Cannot find function
"setWeights"
// How do I set the weights? It's a standard numeric vector. I'm confused on
access class slots from C.
// Not much is writted on this in the R extensions manual.

  PROTECT(e=lang3(install("setWeights"),portSpec,portWeights));
  PROTECT(portSpec=R_tryEval(e,R_GlobalEnv,NULL));

  PROTECT(e=lang2(install("print"),portSpec));
  R_tryEval(e,R_GlobalEnv,NULL);

  UNPROTECT(3);

  Rf_endEmbeddedR(0);

  return 0;
}

Regards
Abhijit Bera

   [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


--
Martin Morgan
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109

Location: Arnold Building M1 B861
Phone: (206) 667-2793



______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to