Skip to content

[Rcpp-devel] Cast for output of Rcpp Sugar runif()

6 messages · Dirk Eddelbuettel, Cedric Ginestet, Douglas Bates

#
Hi guys,

I want to produce discrete uniform variates within C++ from the runif() 
function available through Rcpp Sugar. However, I don't seem to be able 
to find the appropriate cast in order to return an IntegerVector as 
opposed to a numeric one. I have naively used int(), but this is clearly 
not sufficient.

Any help would be greatly appreciated,
Ced

##########################################
#### Discrete uniform variate.
src <- '
   using namespace Rcpp ;
   RNGScope scope;
   int n = as<int>(xn);
   int a = as<int>(xa);
   int b = as<int>(xb);
   IntegerVector vec(n);
   for(int i=0; i<n; ++i) vec[i] = (int)floor(runif(i,a,b));
return vec;'
cxxfun <- 
cxxfunction(sig=signature(xn="numeric",xa="numeric",xb="numeric"),body=src,plugin="Rcpp",verbose=TRUE)
cxxfun(10,0,10);

##########################
Error in compileCode(f, code, language = language, verbose = verbose) :
   Compilation ERROR, function(s)/method(s) not created! 
file52d217df.cpp: In function 'SEXPREC* file52d217df(SEXPREC*, SEXPREC*, 
SEXPREC*)':
file52d217df.cpp:37: error: invalid cast from type 
'Rcpp::sugar::SugarMath_1<true, double, double, Rcpp::Vector<14>, double 
(*)(double)>' to type 'int' make: *** [file52d217df.o] Error 1
##################################################
#
On 13 April 2011 at 12:19, Cedric Ginestet wrote:
| Hi guys,
| 
| I want to produce discrete uniform variates within C++ from the runif()
| function available through Rcpp Sugar. However, I don't seem to be able to find
| the appropriate cast in order to return an IntegerVector as opposed to a
| numeric one. I have naively used int(), but this is clearly not sufficient.
| 
| Any help would be greatly appreciated,
| Ced
| 
| ##########################################
| #### Discrete uniform variate.
| src <- '
|   using namespace Rcpp ;
|   RNGScope scope;
|   int n = as<int>(xn);
|   int a = as<int>(xa);
|   int b = as<int>(xb);
|   IntegerVector vec(n);
|   for(int i=0; i<n; ++i) vec[i] = (int)floor(runif(i,a,b));
| return vec;'
| cxxfun <- cxxfunction(sig=signature(xn="numeric",xa="numeric",xb=
| "numeric"),body=src,plugin="Rcpp",verbose=TRUE)
| cxxfun(10,0,10);
| 
| ##########################
| Error in compileCode(f, code, language = language, verbose = verbose) :
|   Compilation ERROR, function(s)/method(s) not created! file52d217df.cpp: In
| function ?SEXPREC* file52d217df(SEXPREC*, SEXPREC*, SEXPREC*)?:
| file52d217df.cpp:37: error: invalid cast from type ?Rcpp::sugar::SugarMath_1
| <true, double, double, Rcpp::Vector<14>, double (*)(double)>? to type ?int?
| make: *** [file52d217df.o] Error 1
| ##################################################

Well as a start maybe try this as your loop:

   for (int i=0; i<n; ++i) {
       double tmp = runif(1,a,b));  	// why where you using i here?
       vec[i] = static_cast<int>(tmp);  // C++ static cast 
   }

But you do of course understand that 

    a) Rcpp sugar can draw an entire vector at once and

    b) Rcpp sugar also has a vectorised floor() function

right?   So with that try

R> src <- '
+    RNGScope scope;
+    int n = as<int>(xn);
+    int a = as<int>(xa);
+    int b = as<int>(xb);
+    IntegerVector vec(n);
+    vec = floor(runif(n,a,b));
+    return vec;'
R> cxxfun <- cxxfunction(sig=signature(xn="numeric",xa="numeric",xb="numeric"),
+                       body=src,plugin="Rcpp")
R> cxxfun(10,0,10);
 [1] 8 5 1 7 0 0 6 9 8 1
R> 


Hth, Dirk
 
| --
| Cedric Ginestet
| Centre for Neuroimaging Sciences (L3.04)
| NIHR Biomedical Research Centre
| Department of Neuroimaging
| Institute of Psychiatry, Box P089
| King's College London
| De Crespigny Park
| London
| SE5 8AF
| 
| ----------------------------------------------------------------------
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
#
Brilliant, Dirk. Thanks for that.
Next time, I'll read the Rcpp Sugar .pdf more carefully.
Cheers,
On 13/04/11 12:43, Dirk Eddelbuettel wrote:
#
On Wed, Apr 13, 2011 at 6:50 AM, Cedric Ginestet
<c.ginestet05 at googlemail.com> wrote:
Be aware that in both versions you will never return a vector
containing b, which might be confusing.  That is, the argument b
should be 1 greater than the maximum value in the range from which you
are drawing.

I would design it so that the upper end point in the runif range was b
+ 1, which means the arguments a and b are the minimum and maximum
values in the range from which you wish to draw.

Also you forgot to create an instance of the RNGScope class which
causes the random number generator state to be saved and restored
properly.

Sorry for being so picky.
#
Thanks Douglas for being picky!
I have indeed noted that I needed to use b+1 in my codes to produce 
discrete uniform variates. However, I am not too sure that I understand 
how to use RNGScope properly. I originally referred to the Rcpp Sugar 
codes provided in the Rcpp-introduction .pdf document:

########################
RNGScope scope;
return rnorm(10, 0, 100);
########################

Shall I use anything else?
Cheers,
On 13/04/11 13:59, Douglas Bates wrote:
#
As Dirk pointed out to me off-list, I shouldn't reply to email before
coffee.  It was my mistake - you had indeed used RNGscope properly.

On Wed, Apr 13, 2011 at 8:27 AM, Cedric Ginestet
<c.ginestet05 at googlemail.com> wrote: