Hi Simon/Martin

I have updated the code. I think I may be doing mistakes with PROTECT and
UNPROTECT but the code works fine, no errors or warnings so far. Please
suggest any improvements/changes.

#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;
    const char *x,*y;

    Rf_initEmbeddedR(argc, argv);

    // loading fPortfolio library

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

    // This is a demo to print out the SWX.RET built-in object

    // Converting SWX.RET into a matrix

    PROTECT(e = lang2(install("as.matrix"),install("SWX.RET")));
    PROTECT(t1 = (R_tryEval(e, NULL, &errorOccurred)));

    v=REAL(t1);

    // Finding the dimensions of the matrix
    PROTECT(t2=getAttrib(t1,R_DimSymbol));

    nx=INTEGER(t2)[0];
    ny=INTEGER(t2)[1];

    // Obtaining a pointer to the dimnames list of the matrix
    PROTECT(t2=getAttrib(t1,R_DimNamesSymbol));


    // The matrix is stored in column major order so
    // we print it in this manner.

    // Printing column headings
    // This contains the index names of the SWX.RET object
    for(j=0;j<ny;j++)
        printf("%s ",(CHAR(STRING_ELT(VECTOR_ELT(t2,1),j))));

    printf("\n");

    for(i=0;i<nx;i++,j++) {

        // Printing the rows of the matrix
        // This contains the date/time values of the SWX.RET object
        printf("%s ",(CHAR(STRING_ELT(VECTOR_ELT(t2,0),i))));

        for(j=0;j<ny;j++)
         printf("%f ",v[i+(j*ny)]);

        printf("\n");

    }

    UNPROTECT(3);

    return 0;

}

Regards

Abhijit Bera

On Fri, Aug 28, 2009 at 7:12 PM, Abhijit Bera <abhib...@gmail.com> wrote:

> Hi Simon
>
> Thanks. All the confusion between CHAR and STRING. First I read this :
>
> http://www1.cuni.cz/~obo/r_surprises.html<http://www1.cuni.cz/%7Eobo/r_surprises.html>
>
> In the meantime I got your reply. Then I read the documentation and it made
> sense!
>
> Regards
>
> Abhijit Bera
>
>
> On Fri, Aug 28, 2009 at 6:49 PM, Simon Urbanek <
> simon.urba...@r-project.org> wrote:
>
>>
>> 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
>>>
>>>
>>>
>>
>

        [[alternative HTML version deleted]]

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

Reply via email to