Re: [Rcpp-devel] Deriving type information
In addition to what Kevin said, perhaps you are looking for macros from this file: https://github.com/RcppCore/Rcpp/blob/master/inst/include/Rcpp/macros/dispatch.h Le 14 févr. 2014 à 00:34, Søren Højsgaard a écrit : > Dear all, > > Function foo_num below takes a numeric vector and returns a list with the > first element of the vector. (Not very interesting function). I want to > create a templated version of this in function do_foo below, but whether "a" > should be a double, an integer, or a string depends on the RTYPE. > > My question is (and it is embarrasing to ask because I believe Romain has > already answered it; just can't find the answer) how to derive the what type > "a" should have once we know RTYPE?? > > My second question is: Isn't there an easier general way to write the > dispatch function (I have in mind situations where the templated function > takes *more* than one argument!)? I have in mind something like: > > int type = TYPEOF(XX_) ; > return do_foo ( XX_ ) ; > > but that fails because INTSXP, REALSXP etc seems to be defined as const's > (thats my reading of the compiler message). What goes into template parameters is compile time constant. And the type of an R object is dynamic, there is no way to know before runtime, so the compiler can not do this for you. > > Thanks > Søren > > > #include > using namespace Rcpp; > //[[Rcpp::export]] > List foo_num(NumericVector x){ > double a=x[0]; > return List::create( a ); > } > > template > List do_foo( Vector x ){ > double a=x[0]; // WHAT TO DO HERE??? > return List::create( a ); > } > > SEXP foo_any( SEXP& XX_){ > int type = TYPEOF(XX_) ; > switch( type ){ > case INTSXP : return do_foo ( XX_ ) ; > case REALSXP : return do_foo( XX_ ) ; > case STRSXP : return do_foo ( XX_ ) ; > } > return R_NilValue ; > } > ___ > Rcpp-devel mailing list > Rcpp-devel@lists.r-forge.r-project.org > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] Deriving type information
Hi Søren, You want to use Rcpp's traits. I don't think these are explicitly documented anywhere, although there are a few examples on the gallery demonstrating their usage (e.g. http://gallery.rcpp.org/articles/top-elements-from-vectors-using-priority-queue/) In this case, you can use traits::storage_type::type to extract the type. Typically, using a typedef makes it easiest, so I would write something like: typedef typename traits::storage_type::type storage_t; storage_t a = x[0]; Once you understand the general pattern, it's pretty easy to just read and understand the traits available at https://github.com/RcppCore/Rcpp/tree/master/inst/include/Rcpp/traits, but perhaps this would be a good gallery post. For more information, I thought this was a pretty good introductory article on understanding C++ traits: http://accu.org/index.php/journals/442 Cheers, Kevin ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
[Rcpp-devel] Deriving type information
Dear all, Function foo_num below takes a numeric vector and returns a list with the first element of the vector. (Not very interesting function). I want to create a templated version of this in function do_foo below, but whether "a" should be a double, an integer, or a string depends on the RTYPE. My question is (and it is embarrasing to ask because I believe Romain has already answered it; just can't find the answer) how to derive the what type "a" should have once we know RTYPE?? My second question is: Isn't there an easier general way to write the dispatch function (I have in mind situations where the templated function takes *more* than one argument!)? I have in mind something like: int type = TYPEOF(XX_) ; return do_foo ( XX_ ) ; but that fails because INTSXP, REALSXP etc seems to be defined as const's (thats my reading of the compiler message). Thanks Søren #include using namespace Rcpp; //[[Rcpp::export]] List foo_num(NumericVector x){ double a=x[0]; return List::create( a ); } template List do_foo( Vector x ){ double a=x[0]; // WHAT TO DO HERE??? return List::create( a ); } SEXP foo_any( SEXP& XX_){ int type = TYPEOF(XX_) ; switch( type ){ case INTSXP : return do_foo ( XX_ ) ; case REALSXP : return do_foo( XX_ ) ; case STRSXP : return do_foo ( XX_ ) ; } return R_NilValue ; } ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] conditionally created vectors
On 13 February 2014 at 18:26, Hideyoshi Maeda wrote: | So I’m guessing there is no simple export outside of the {} function? Wrong. You can also do this, relying on the Rcpp vector constructor: #include // [[Rcpp::export]] Rcpp::NumericVector f2(std::string typ){ Rcpp::NumericVector xx; if (typ=="nc"){ xx = Rcpp::NumericVector(10); } else { xx = Rcpp::NumericVector(20); } return xx; } This is pretty basic C / C++ so you may want to go back and revisit some of your books. Dirk -- Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] conditionally created vectors
The way around it is to declare 'xx' in the parent scope, and then assign to it directly, e.g. // [[Rcpp::export]] Rcpp::NumericVector f1(String typ){ Rcpp::NumericVector xx; if(typ=="nc"){ xx = Rcpp::NumericVector(10); } else { xx = Rcpp::NumericVector(20); } return xx; } 'Technically', the object 'xx' will be default initialized when declared like that, but the compiler can optimize that away. Cheers, Kevin On Thu, Feb 13, 2014 at 10:26 AM, Hideyoshi Maeda wrote: > So I'm guessing there is no simple export outside of the {} function? > On 13 Feb 2014, at 18:17, Dirk Eddelbuettel wrote: > > > > > On 13 February 2014 at 17:48, Hideyoshi Maeda wrote: > > | Dear Rcpp-Devel list, > > | > > | I am relatively new to Rcpp and am struggling to work out why the > following code does not compile. > > | > > | #include > > | using namespace Rcpp; > > | > > | // [[Rcpp::export]] > > | Rcpp::NumericVector f1(String typ){ > > | if(typ=="nc"){ > > | Rcpp::NumericVector xx(10); > > | } else { > > | Rcpp::NumericVector xx(20); > > | } > > | return xx; > > | } > > > > "Scope". > > > > You create 'xx' inside the { } and it does not exist outside of those. > > > > | Basically the function takes in a string input and if its has the > value "nc" then it returns a zero string of length 10 and if it doesn't > then it should return a zero vector of length 20. I don't quite understand > why the above code works but the below code does. What do I need to do to > make the above code work, so that I can call xx after the if statement is > done? > > | > > | #include > > | using namespace Rcpp; > > | > > | // [[Rcpp::export]] > > | Rcpp::NumericVector f1(String typ){ > > | if(typ=="nc"){ > > | Rcpp::NumericVector xx(10); > > | return xx; > > | } else { > > | Rcpp::NumericVector xx(20); > > | return xx; > > | } > > | } > > > > Try this. It uses RcppArmadillo which has a resize() member function. > > > > > > // [[Rcpp::depends(RcppArmadillo)]] > > > > #include > > > > > > // [[Rcpp::export]] > > arma::colvec f1(std::string typ){ > > arma::colvec xx; > > if (typ=="nc"){ > >xx.resize(10); > > } else { > >xx.resize(20); > > } > > return xx; > > } > > > > Dirk > > > > -- > > Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com > > ___ > Rcpp-devel mailing list > Rcpp-devel@lists.r-forge.r-project.org > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel > ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] conditionally created vectors
So I’m guessing there is no simple export outside of the {} function? On 13 Feb 2014, at 18:17, Dirk Eddelbuettel wrote: > > On 13 February 2014 at 17:48, Hideyoshi Maeda wrote: > | Dear Rcpp-Devel list, > | > | I am relatively new to Rcpp and am struggling to work out why the following > code does not compile. > | > | #include > | using namespace Rcpp; > | > | // [[Rcpp::export]] > | Rcpp::NumericVector f1(String typ){ > | if(typ=="nc"){ > | Rcpp::NumericVector xx(10); > | } else { > | Rcpp::NumericVector xx(20); > | } > | return xx; > | } > > "Scope". > > You create 'xx' inside the { } and it does not exist outside of those. > > | Basically the function takes in a string input and if its has the value > “nc” then it returns a zero string of length 10 and if it doesn’t then it > should return a zero vector of length 20. I don’t quite understand why the > above code works but the below code does. What do I need to do to make the > above code work, so that I can call xx after the if statement is done? > | > | #include > | using namespace Rcpp; > | > | // [[Rcpp::export]] > | Rcpp::NumericVector f1(String typ){ > | if(typ=="nc"){ > | Rcpp::NumericVector xx(10); > | return xx; > | } else { > | Rcpp::NumericVector xx(20); > | return xx; > | } > | } > > Try this. It uses RcppArmadillo which has a resize() member function. > > > // [[Rcpp::depends(RcppArmadillo)]] > > #include > > > // [[Rcpp::export]] > arma::colvec f1(std::string typ){ > arma::colvec xx; > if (typ=="nc"){ >xx.resize(10); > } else { >xx.resize(20); > } > return xx; > } > > Dirk > > -- > Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] conditionally created vectors
On 13 February 2014 at 17:48, Hideyoshi Maeda wrote: | Dear Rcpp-Devel list, | | I am relatively new to Rcpp and am struggling to work out why the following code does not compile. | | #include | using namespace Rcpp; | | // [[Rcpp::export]] | Rcpp::NumericVector f1(String typ){ | if(typ=="nc"){ | Rcpp::NumericVector xx(10); | } else { | Rcpp::NumericVector xx(20); | } | return xx; | } "Scope". You create 'xx' inside the { } and it does not exist outside of those. | Basically the function takes in a string input and if its has the value “nc” then it returns a zero string of length 10 and if it doesn’t then it should return a zero vector of length 20. I don’t quite understand why the above code works but the below code does. What do I need to do to make the above code work, so that I can call xx after the if statement is done? | | #include | using namespace Rcpp; | | // [[Rcpp::export]] | Rcpp::NumericVector f1(String typ){ | if(typ=="nc"){ | Rcpp::NumericVector xx(10); | return xx; | } else { | Rcpp::NumericVector xx(20); | return xx; | } | } Try this. It uses RcppArmadillo which has a resize() member function. // [[Rcpp::depends(RcppArmadillo)]] #include // [[Rcpp::export]] arma::colvec f1(std::string typ){ arma::colvec xx; if (typ=="nc"){ xx.resize(10); } else { xx.resize(20); } return xx; } Dirk -- Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
[Rcpp-devel] conditionally created vectors
Dear Rcpp-Devel list, I am relatively new to Rcpp and am struggling to work out why the following code does not compile. #include using namespace Rcpp; // [[Rcpp::export]] Rcpp::NumericVector f1(String typ){ if(typ=="nc"){ Rcpp::NumericVector xx(10); } else { Rcpp::NumericVector xx(20); } return xx; } Basically the function takes in a string input and if its has the value “nc” then it returns a zero string of length 10 and if it doesn’t then it should return a zero vector of length 20. I don’t quite understand why the above code works but the below code does. What do I need to do to make the above code work, so that I can call xx after the if statement is done? #include using namespace Rcpp; // [[Rcpp::export]] Rcpp::NumericVector f1(String typ){ if(typ=="nc"){ Rcpp::NumericVector xx(10); return xx; } else { Rcpp::NumericVector xx(20); return xx; } } thank HLM ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] Extending Rcpp with a dummy class
On 13 February 2014 at 15:55, Alessandro Mammana wrote: | Suppose that for any reason I want to define my own vector class like this: | | template | struct Vec { | T* ptr; | int len; | }; Conceptually that is about the same as our vectors. | so, without owning memory but just pointing to some (hopefully valid) | area of memory. | How can I extend Rcpp with this class so that I can have R vectors | automatically converted to these vectors? | The obvious answer is "read "extending Rcpp" instead of bothering us", Precisely. :) And look at the working examples, eg on the Rcpp Gallery I have posts doing this for Boost DateTime, and for sparse Armadillo matrices. Look at other packages. The most full-featured are probably RcppArmadillo and RcppEigen. | but the compiler complains and says: | error: 'Vector' is not a member of 'Rcpp' | | this is probably because I still did not import Rcpp.h, but in Correct. | "extending Rcpp" they say to include Rcpp.h only after defining my | classes, so how should I do? Re-read it. You misunderstood that statement. RcppCommon is used for some forward declarations. You use it here to replace Rcpp.h. Won't work. Dirk -- Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
[Rcpp-devel] Extending Rcpp with a dummy class
Dear all, I have another one of my stupid questions. Suppose that for any reason I want to define my own vector class like this: @ template struct Vec { T* ptr; int len; }; @ so, without owning memory but just pointing to some (hopefully valid) area of memory. How can I extend Rcpp with this class so that I can have R vectors automatically converted to these vectors? The obvious answer is "read "extending Rcpp" instead of bothering us", and I did it, and I tried the following: @ #include template struct Vec { T* ptr; int len; Vec(SEXP x){ if (TYPEOF(x) != Rcpp::traits::r_sexptype_traits::rtype) Rcpp::stop("incompatible types"); Rcpp::Vector< Rcpp::traits::r_sexptype_traits::rtype > rcpp_vec(x); ptr = rcpp_vec.begin(); len = rcpp_vec.length(); } }; #include blablabla @ but the compiler complains and says: error: 'Vector' is not a member of 'Rcpp' this is probably because I still did not import Rcpp.h, but in "extending Rcpp" they say to include Rcpp.h only after defining my classes, so how should I do? Thanks in advance! Ale -- Alessandro Mammana, PhD Student Max Planck Institute for Molecular Genetics Ihnestraße 63-73 D-14195 Berlin, Germany ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Re: [Rcpp-devel] filling in blocks of a matrix
On 13 February 2014 at 11:23, Hideyoshi Maeda wrote: | I am looking to see it is possible to fill in a matrix with another matrix. | | I have three matrices, out1 which is a 5x5 zero matrix | | out2 is a 3x3 matrix with each value set as 8 | | and out3 which is a 5x4 matrix with each value set as 9 | | I would like to change part of my out1 matrix by filling it with the values in out2 or out3, is this possible? I would do that in Armadillo via RcppArmadillo -- as Armadillo has a number of sub-matrix views, subsetters and assignments. Dirk -- Dirk Eddelbuettel | e...@debian.org | http://dirk.eddelbuettel.com ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
[Rcpp-devel] filling in blocks of a matrix
Dear Rcpp-List, I am looking to see it is possible to fill in a matrix with another matrix. I have three matrices, out1 which is a 5x5 zero matrix out2 is a 3x3 matrix with each value set as 8 and out3 which is a 5x4 matrix with each value set as 9 I would like to change part of my out1 matrix by filling it with the values in out2 or out3, is this possible? Would I just need to use loops to sequentially fill it in (either row by row or column by column etc)? or could I just assign new values to the bits i want to change? Below is my attempt at doing the later, but it does not compile saying that for this line "out1(Range(0,2),Range(1,3)) = out2;” there is no viable overload ‘=' Perhaps this is rather simple but I am very new to Rcpp, but any help would be much appreciated. Regards HLM #include using namespace Rcpp; // [[Rcpp::export]] Rcpp::NumericMatrix f1(String h){ String h1 = h; NumericMatrix out1(5,5); NumericMatrix out2(3,3); NumericMatrix out3(5,4); std::fill(out2.begin(), out2.end(), 8); std::fill(out3.begin(), out2.end(), 9); if(h1=="nc"){ out1(Range(0,2),Range(1,3)) = out2; } else { out1(_,Range(1,4)) = out3; } return out1; } ___ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel