[Rcpp-devel] RNGScope, importing function, and if-else statement
Dirk Eddelbuettel
edd at debian.org
Mon Apr 16 21:38:26 CEST 2012
On 16 April 2012 at 12:43, Marie Auger-Methe wrote:
| Hi Dirk and list,
|
| As suggested by Dirk I have re-written the function rvm in Rcpp (see
| below) and it now gives the same results as the rvm function in R. So my
Super!
| problem is fixed (although it would nice if you could just import an R
| RNG function in Rcpp... maybe a future development ;) ).
| I'm still not sure what was the problem with my original method, my only
| clue is that the function rvm itself randomly generates multiple numbers
| using runif?
I am still travelling and have not had a chance to look at this, but I
suspect that maybe something odd happen with PutRNGState / GetRNGState on the
side of rvm (and RNGScope deals with this for us). There is no reason why it
shouldn't work, maybe we can work out a fix to be passed to CircStats. Else
we can always provide a suitable rvm in Rcpp too I suppose...
Dirk
| Thanks for all the help,
|
| Marie
|
| suppressMessages(library(CircStats))
| suppressMessages(library(inline))
| suppressMessages(library(sugaR))
|
| rvmscr <- '
| // Inputs
| int nc = as<int>(n);
| double meanc = as<double>(mean);
| double kc = as<double>(k);
|
| // Assign memory
| Rcpp::NumericVector vm(nc);
| double U1;
| double U2;
| double U3;
| double z;
| double f;
| double c;
|
| double a = 1 + pow((1 + 4 * pow(kc,2)),0.5);
| double b = (a - pow(2*a,0.5))/(2*kc);
| double r = (1 + pow(b,2))/(2 * b);
|
| int obs = 0;
|
| RNGScope scope;
|
| while(obs < nc){
| U1 = as<double>(runif(1, 0, 1));
| z = cos(PI * U1);
| f = (1 + r * z)/(r + z);
| c = kc * (r - f);
| U2 = as<double>(runif(1, 0, 1));
| if(c * (2 - c) - U2 > 0){
| U3 = as<double>(runif(1, 0, 1));
| if(U3 < 0.5){
| vm[obs] = 2 * PI - acos(f) + meanc;
| }else{
| vm[obs] = acos(f) + meanc;
| }
| vm[obs] = fmod(vm[obs], 2*PI);
| obs += 1;
| }else{
| if(log(c/U2) + 1 - c >= 0){
| U3 = as<double>(runif(1, 0, 1));
| if(U3 < 0.5){
| vm[obs] = 2 * PI - acos(f) + meanc;
| }else{
| vm[obs] = acos(f) + meanc;
| }
| vm[obs] = fmod(vm[obs], 2*PI);
| obs += 1;
| }
| }
| }
|
| return vm;
| '
|
| rvmc <- cxxfunction(signature(n ="integer", mean = "numeric", k =
| "numeric"),
| body = rvmscr, plugin = "Rcpp")
|
| n <- 1000
| mu <- 0
| k <- 3
| set.seed(89)
| r1 <- rvmc(n,mu,k)
| set.seed(89)
| r2 <- rvm(n,mu,k)
|
| max(r1 - r2)
| cbind(r1[1:20],r2[1:20])
|
| On 16/04/2012 10:29 AM, Dirk Eddelbuettel wrote:
| > Marie,
| >
| > On 16 April 2012 at 08:56, Marie Auger-Methe wrote:
| > | Hi Dirk,
| > |
| > | Thank you for the prompt reply!
| > | By reimplement rvm using Rcpp sugar functions, do you mean re-write the
| > | rvm function using sugar functions?
| >
| > Yes.
| >
| > (But as I said I have not yet looked at the code for rvm at all...)
| >
| > Dirk
| >
|
--
R/Finance 2012 Conference on May 11 and 12, 2012 at UIC in Chicago, IL
See agenda, registration details and more at http://www.RinFinance.com
More information about the Rcpp-devel
mailing list