设置随机种子独立Rmath库

时间:2015-05-15 16:19:53

标签: c++ linux r

我尝试使用C++提供的独立Rmath库在R中生成随机数。

我获得的最好成绩是:

#include <stdio.h>      /* printf, scanf, NULL */
#include <stdlib.h>     /* malloc, free, rand */
#define MATHLIB_STANDALONE
#include <Rmath.h>
#include <time.h>

int main(){
  int i;
  unsigned int SEED1, SEED2;
  double mu, sigma, PHI_X, *X;

  mu = 0;
  sigma = 1;
  SEED1 = time(NULL);
  SEED2 = time(NULL);
  set_seed(SEED1, SEED2);

  //int GetRNGstate();

  X = (double *) malloc(10);
  for(i = 0; i < 10; i++){
    X[i] = rnorm(mu, sigma);
    PHI_X = pnorm(X[i], mu, sigma, 1, 0);
    printf("X: %f, PHI(X): %f\n", X[i], PHI_X);
  }

  //int PutRNGstate();
}

如果我理解正确,GetRNGstate应该初始化随机种子,而不是使用set_seed,但它对我不起作用。如果使用它,我总是生成相同的随机数链。另外,我在网上找到的所有例子都使用GetRNGstate(),而不必声明它,但我不能让它以这种方式工作,不得不将它声明为int,我在做什么错误?另外,我应该使用GetRNGstate()PutRNGState为每个调用包装一个随机数生成器,还是应该将它们设置在代码的开头/结尾?

我知道RcppR内调用代码时会更轻松,但我只是尝试直接在C++中测试独立版本。目的我使用Debian wheezy。

1 个答案:

答案 0 :(得分:1)

我不确定(但)你的程序有什么问题,但这是我几年前为自己写的一个更简单,更短的一个:

// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; \
//         compile-command: "gcc -s -Wall -O3 -I/usr/share/R/include \
//         -o rmath_rnorm rmath_rnorm.c -lRmath -lm" -*-        

// Compare to
//    $ Rscript -e "RNGkind('Marsaglia'); \
//          .Random.seed[2:3] <- c(123L, 456L); rnorm(2)"        
//    [1] -0.2934974 -0.3343770

#include <stdio.h>

#define MATHLIB_STANDALONE 1
#include <Rmath.h>

int main(void) {

    set_seed(123, 456);
    printf("rnorm: %f %f\n", rnorm(0.0, 1.0));
    printf("rnorm: %f %f\n", rnorm(0.0, 1.0));

    return 0;
}

它仍然像宣传的那样工作:

/tmp$ gcc -s -Wall -O3 -I/usr/share/R/include -o rmath_rnorm \
                  rmath_rnorm.c -lRmath -lm
/tmp$ ./rmath_rnorm 
rnorm: -0.293497
rnorm: -0.334377
/tmp$ Rscript  -e 'RNGkind("Marsaglia"); .Random.seed[2:3] <- c(123L, 456L); rnorm(2)'
[1] -0.293497 -0.334377
tmp$ 

与R中的数字相同,可以通过设置种子来预测。