我尝试使用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
为每个调用包装一个随机数生成器,还是应该将它们设置在代码的开头/结尾?
我知道Rcpp
在R
内调用代码时会更轻松,但我只是尝试直接在C++
中测试独立版本。目的我使用Debian wheezy。
答案 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中的数字相同,可以通过设置种子来预测。