From mtmorgan at fhcrc.org  Wed Aug 26 18:55:42 2009
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Wed, 26 Aug 2009 09:55:42 -0700
Subject: [Rd] Clarifications please.
In-Reply-To: <fc212e850908260715u749f0c3dtfd8599477cb7c805@mail.gmail.com>
References: <fc212e850908250541i16b1918h58187248193b4cbf@mail.gmail.com>	
	<6phd46km2gl.fsf@gopher4.fhcrc.org>	
	<fc212e850908260007w616bc806wccfe5e89d33b3466@mail.gmail.com>
	<fc212e850908260715u749f0c3dtfd8599477cb7c805@mail.gmail.com>
Message-ID: <4A95690E.1070806@fhcrc.org>

Hi Abhijit --

Abhijit Bera wrote:
> Hi Martin
> 
> Thanks. I think I got it! Read the R extensions documentation again. I
> don't even need to convert to a list. This is what I did (just a demo):
> 
> #include <R.h>
> #include <Rinternals.h>
> #include <Rdefines.h>
> #include <Rembedded.h>
> 
> int main (int argc, char** argv)  {
>    
>     SEXP e,t1,t2,val;
>     int errorOccurred,nx,ny,i,j;
>     double *v;
> 
>     Rf_initEmbeddedR(argc, argv);
>    
>     PROTECT(e = lang2(install("library"), mkString("fPortfolio")));
>     R_tryEval(e, R_GlobalEnv, NULL);
>     UNPROTECT(1);
>    
>     /* We try to evaluate the R expression:
>     *  round(cov(100 * SWX.RET), digits = 4)
>     *  we shall split it as:
>     *  t1<-100*SWX.RET
>     *  t2<-cov(t1)
>     *  val<-round(t2,4)
>     */
>    
>     PROTECT(e = lang3(install("*"),ScalarInteger(100), install("SWX.RET")));
>     PROTECT(t1 = (R_tryEval(e, NULL, &errorOccurred)));

For what it's worth, and realizing that this is sloppiness in my
original code, ScalarInteger(100) (and mkString("fPortfolio")) returns
an unprotected SEXP, so it could in principle be garbage collected while
lang3 is being evaluated...

>    
>     PROTECT(e = lang2(install("cov"),t1));
>     PROTECT(t2 = (R_tryEval(e, NULL, &errorOccurred)));
>    
>     PROTECT(e = lang3(install("round"),t2, ScalarInteger(4)));
>     PROTECT(val = (R_tryEval(e, NULL, &errorOccurred)));
>    
>     Rf_PrintValue(val);
>    
>    /* This isn't required, is extraneous.
>     PROTECT(e = lang2(install("as.list"),val));
>     PROTECT(t2 = (R_tryEval(e, NULL, &errorOccurred)));
>    
>     Rf_PrintValue(t2);*/

the reason I recommended using as.list (for example) was to respect the
implied abstraction between the object (of class 'timeSeries') and it's
representation. Apparently there is a method as.list.timeSeries, and a
list is something that I am allowed to know about. Your code below
works, but doesn't respect the (R-level) abstraction the class author
wants. I don't know whether this is regular practice in the R community,
but it seems like the right thing to do.

Martin

>    
>     v=REAL(val);
>    
>     PROTECT(t2=getAttrib(val,R_DimSymbol));
>    
>     nx=INTEGER(t2)[0];
>     ny=INTEGER(t2)[1];
>    
>     /* Just printing out the matrix
>    *  To understand how I can convert
>    *  data types b/w R and C
>    */
> 
>     printf("Matrix:\n");
>    
>     for(i=0,j=0;i<(nx*ny);i++,j++) {
>        
>         printf("%.4f ",v[i]);
>        
>         if(j==ny-1) {
>             printf("\n");
>             j=0;
>         }
>        
>     }
>    
>     UNPROTECT(6);
>    
>     return 0;
>    
> }
> 
> Regards
> 
> Abhijit Bera
> 
> 
> On Wed, Aug 26, 2009 at 12:37 PM, Abhijit Bera <abhibera at gmail.com
> <mailto:abhibera at gmail.com>> wrote:
> 
>     Hi Martin
> 
>     Thanks. I think I got the hang of it. I will try it out and post any
>     more queries I have regarding handling data types onto the mailing list.
> 
>     Regards
> 
>     Abhijit Bera
> 
> 
>     On Tue, Aug 25, 2009 at 7:15 PM, Martin Morgan <mtmorgan at fhcrc.org
>     <mailto:mtmorgan at fhcrc.org>> wrote:
> 
>         Abhijit Bera <abhibera at gmail.com <mailto:abhibera at gmail.com>>
>         writes:
> 
>         > Hi
>         >
>         > I think I have asked these questions earlier, but I been able
>         to find
>         > answers from the documentation (which I found poorly written
>         in several
>         > places). Will someone be kind enough to give me answers and
>         enlighten me?
>         > (as in explain with CODE?)
>         >
>         > I want to embed R in my application and use the fPortfolio
>         package for
>         > carrying out risk management computations. Right now I'm
>         reading the
>         > Rmetrics Ebook and trying to convert the various examples into
>         embedded C
>         > code.
>         >
>         > Coming from a strictly C background, I have slight difficulty in
>         > comprehending a functional language like R and it gets worse
>         when I try to
>         > embed R into a procedural language like C. So here is a list
>         of my doubts:
>         >
>         > 1) I am very confused on how the lang 1 2 3 4 ... set of
>         functions work. I
>         > haven't found any relevant documentation explaining it
>         clearly. I have a
>         > vague idea but still I cannot understand how I would evaluate an R
>         > expression like Covariance <- round(cov(100 * SWX.RET), digits
>         = 4) using
>         > lang, install and R_tryEval.
> 
>         unroll this as
> 
>          tmp0 <- 100 * SWX.RET
>          tmp1 <- cov(tmp0)
>          result <- round(tmp2, 4L)
> 
>         so (untested)
> 
>          PROTECT(expr =
>            lang3(install("*"), scalarNumeric(100), install("SWX.RET")));
>          PROTECT(tmp0 = tryEval(expr, R_GlobalEnv, &errorOccurred));
>          if (errorOccurred)
>            exit(1);
> 
>          PROTECT(expr = lang2(install("cov"), tmp0));
>          PROTECT(tmp1 = tryEval(expr, R_GlobalEnv, &errorOccurred));
>          if (errorOccurred)
>            exit(1);
> 
>          PROTECT(expr = lang3(install("round"), tmp1, scalarInteger(4)));
>          PROTECT(result = tryEval(expr, R_GlobalEnv, &errorOccurred));
>          if (errorOccurred)
>            exit(1);
> 
>          Rf_PrintValue(result);
>          UNPROTECT(6);
> 
> 
> 
>         > 2) What exactly does install do?
> 
>         creates or locates a symbol in the global symbol table. Every unique
>         symbol is recorded and stored in the 'global symbol table'. An
>         environment is then a mapping between a symbol from this table,
>         and a
>         value unique to the environment. The symbols are being reused across
>         environments.
> 
>         In R
> 
>          x <- 10
> 
>         creates a symbol x in the global symbol table, and in the global
>         environment associates the value 10 with that symbol.
> 
>          env = new.env()
>          env$x <- 20
> 
>         uses the same symbol 'x' from the same global symbol table, but
>         associates the value 20 with it in the environment 'env'.
> 
>         In C
> 
>          install("foo");
> 
>         creates a symbol and returns the appropriate SEXP. And then
> 
>          install("foo")
> 
>         again finds the already-defined symbol and returns the same SEXP.
> 
>         > 3) I wrote the following code:
>         >
>         > #include <Rinternals.h>
>         > #include <Rembedded.h>
>         >
>         > int main (int argc, char** argv) {
>         >
>         >     SEXP e,val;
>         >     int errorOccurred;
>         >
>         >     Rf_initEmbeddedR(argc, argv);
>         >
>         >     // library("fPortfolio")
>         >     PROTECT(e = lang2(install("library"),
>         mkString("fPortfolio")));
>         >     R_tryEval(e, R_GlobalEnv, NULL);
>         >     UNPROTECT(1);
>         >
>         >    // colMeans(SWX.RET)
>         >     PROTECT(e = lang2(install("colMeans"), install("SWX.RET")));
>         >     val = (R_tryEval(e, NULL, &errorOccurred));
>         >
>         >     Rf_PrintValue(val);
>         >
>         >     return 0;
>         >
>         > }
>         >
>         > When I tried :
>         >
>         >>mean(SWX.RET)
>         >
>         > in the R prompt I got the following output:
>         >
>         >          SBI          SPI          SII         LP25         LP40
>         > LP60
>         > 4.660521e-06 2.153198e-04 2.033869e-04 1.388886e-04 1.349041e-04
>         > 1.226859e-04
>         >
>         >
>         > However when I replaced colMeans with mean in the C code above
>         I got a mean
>         > of the means (0.0001366410) of all the columns when
>         Rf_PrintValue was
>         > called. Using colMeans gave me the output as shown above. Why
>         does this
>         > happen? How do I get the above output using mean?
> 
>         Guessing a little; I don't know what class SWX.RET is, but perhaps
>         there is a method mean.class_of_SWX.RET defined in a package that is
>         loaded in your R session, but not your C session. In a new R I see
> 
>         > library(fPortfolio)
>         > mean(SWX.RET)
>         [1] 0.0001366410
> 
>         > 4) From the above code segment, how can I deal with the
>         SEXPREC val which is
>         > returned by R_tryEval in the above code and convert it to my
>         own local
>         > vector datatype? How do I access the values of val? val will
>         now be a
>         > timeseries so how do i convert it?
> 
>         Convert it to a 'standard' R object using appropriate R
>         functions and
>         access it using C, e.g.,
> 
>         > lst <- as.list(SWX.RET)
>         > str(lst)
>         List of 6
>         $ SBI : num [1:1916] -0.002088 -0.000105 -0.00136 0.000419 0 ...
>         $ SPI : num [1:1916] -0.03439 -0.01041 0.01212 0.02246 0.00211 ...
>         $ SII : num [1:1916] 1.37e-05 -4.96e-03 3.81e-03 -6.16e-04
>         2.38e-03 ...
>         $ LP25: num [1:1916] -0.01199 -0.00366 -0.00132 0.00771 0.00303 ...
>         $ LP40: num [1:1916] -0.01801 -0.00584 -0.00164 0.01166 0.00457 ...
>         $ LP60: num [1:1916] -0.02616 -0.00901 -0.0024 0.01706 0.00695 ...
> 
>         so in C, once I have lst, I could
> 
>          sbi = VECTOR_ELT(lst, 0);
>          double *vals = NUMERIC(sbi);
>          printf("%f", vals[0]); # -002088
> 
>         Hope that helps, and is not too misleading, I didn't have time to
>         check carefully.
> 
>         Martin
> 
>         > Thanks
>         >
>         > Abhijit Bera
>         >
>         >       [[alternative HTML version deleted]]
>         >
>         > ______________________________________________
>         > R-devel at r-project.org <mailto:R-devel at 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
> 
> 
>



[Rd] Clarifications please.
Martin Morgan