采用错误伪随机数生成器(PRNG)randu的以下实现:
n = 100000
randu = matrix(NA, ncol=3, nrow=n)
new_z = 1
for(i in 1:n) {
new_x = (65539*new_z) %% 2^31
new_y = (65539*new_x) %% 2^31
new_z = (65539*new_y) %% 2^31
randu[i,] = c(x=new_x/2^31, y=new_y/2^31,z=new_z/2^31)
}
我想替换for循环。这里的问题是随后的迭代步骤需要用每个迭代步骤生成的整行的条目。我的想法是应用一个函数来填充空矩阵的行。所以我试图熟悉apply
函数,我做到了这一点:
n = 100000
randu = matrix(NA, ncol=3, nrow=n)
randu[1,3] <- 1 # seed
randu.fct <- function() {
randu[,1] <- (65539 * randu[,3]) %% 2 ^ 31
randu[,2] <- (65539 * randu[,1]) %% 2 ^ 31
randu[,3] <- (65539 * randu[,2]) %% 2 ^ 31
}
apply(randu[,1:3],1,randu.fct)
..这不是很多。我无法理解如何迭代行的每个元素以及如何生成例如100000行。
答案 0 :(得分:2)
您可以按replicate
:
n = 100000
x = 1
matrix(replicate(3*n, {x <<- (65539*x) %% 2^31})/2^31, ncol = 3, byrow = TRUE)
如果你需要速度,你应该看看Rcpp
,下面是一个简单的实现:
library(inline)
library(Rcpp)
cppFunction(
'NumericMatrix randU(int n) {
NumericMatrix X(n, 3);
int x = 1;
unsigned int d = 2147483648;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 3; ++j) {
x = (65539*x) % d;
X(i,j) = x / double(d);
}
}
return X;
}'
)
> all.equal(randu, randU(100000))
[1] TRUE
小速度比较:
f1 <- function(){
n = 100000
randu = matrix(NA, ncol=3, nrow=n)
new_z = 1
for(i in 1:n) {
new_x = (65539*new_z) %% 2^31
new_y = (65539*new_x) %% 2^31
new_z = (65539*new_y) %% 2^31
randu[i,] = c(x=new_x/2^31, y=new_y/2^31,z=new_z/2^31)
}
randu
}
f2 <- function(){
n = 100000
x = 1
matrix(replicate(3*n, {x <<- (65539*x) %% 2^31})/2^31, ncol = 3, byrow = TRUE)
}
f3 <- function(){
randU(100000)
}
Unit: milliseconds
expr min lq mean median uq max neval
f1() 1170.166889 1245.987545 1331.918328 1320.593903 1356.121828 1593.0860 10
f2() 1194.103998 1449.195295 1499.362126 1514.794140 1562.868296 1798.1218 10
f3() 2.041235 2.055671 3.386515 2.207969 2.676895 13.1357 10