On Aug 28, 2009, at 7:41 AM, Abhijit Bera wrote:
Hi Martin
Here's the code. I'm stuck at one point. I cannot figure out how to
print
the dimnames. I've commented it in my code:
int main (int argc, char** argv) {
SEXP e,t1,t2,val;
int errorOccurred,nx,ny,i,j;
double *v;
char x[1024],y[1024];
Rf_initEmbeddedR(argc, argv);
PROTECT(e = lang2(install("library"), mkString("fPortfolio")));
R_tryEval(e, R_GlobalEnv, NULL);
UNPROTECT(1);
PROTECT(e = lang2(install("as.matrix"),install("SWX.RET")));
PROTECT(t1 = (R_tryEval(e, NULL, &errorOccurred)));
v=REAL(t1);
PROTECT(t2=getAttrib(t1,R_DimSymbol));
FWIW no need to protect it - t1 is already protected and even more so
you are blowing t2 away two lines later anyway ...
nx=INTEGER(t2)[0];
ny=INTEGER(t2)[1];
PROTECT(t2=getAttrib(t1,R_DimNamesSymbol));
Again, no need to protect - you have protected t1 already ...
// I'm getting stuck here.
// I want to print out the dimnames
// so that I can get the dates for the timeseries object.
strcpy(x,(CHAR(VECTOR_ELT(t2,0))[0]));
Please read docs about character vectors - what you probably meant is
something like
const char *x = CHAR(STRING_ELT(VECTOR_ELT(t2,0), 0));
printf("dim 1 = (%s, ...)\n", x);
Cheers,
Simon
strcpy(y,(CHAR(VECTOR_ELT(t2,1))[0]));
printf("%d * %d\n %s %s \n Matrix:\n",nx,ny,x,y);
// The matrix is stored in column major order so
// we print it in this manner.
// my previous code was incorrect.
for(i=0;i<nx;i++,j++) {
for(j=0;j<ny;j++)
printf("%f ",v[i+(j*ny)]);
printf("\n");
}
//UNPROTECT(3);
return 0;
}
On Wed, Aug 26, 2009 at 10:25 PM, Martin Morgan <mtmor...@fhcrc.org>
wrote:
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 <abhib...@gmail.com
<mailto:abhib...@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
<mtmor...@fhcrc.org
<mailto:mtmor...@fhcrc.org>> wrote:
Abhijit Bera <abhib...@gmail.com <mailto:abhib...@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@r-project.org <mailto: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
[[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