R中的randu:无for循环的填充矩阵
采用以下方法实现坏的伪随机数生成器(PRNG): 我想替换for循环。这里的问题是,在每个迭代步骤中生成的整行的条目对于后续的迭代步骤是必需的。我的想法是应用一个函数来填充空矩阵的行。因此,我正在尝试熟悉R中的randu:无for循环的填充矩阵,r,R,采用以下方法实现坏的伪随机数生成器(PRNG): 我想替换for循环。这里的问题是,在每个迭代步骤中生成的整行的条目对于后续的迭代步骤是必需的。我的想法是应用一个函数来填充空矩阵的行。因此,我正在尝试熟悉apply函数,我已经做到了这一点: n = 100000 randu = matrix(NA, ncol=3, nrow=n) randu[1,3] <- 1 # seed randu.fct <- function() { randu[,1] <- (65539 * r
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)
n=100000
randu=矩阵(NA,ncol=3,nrow=n)
randu[1,3]您可以通过复制替换(隐藏)循环:
n = 100000
x = 1
matrix(replicate(3*n, {x <<- (65539*x) %% 2^31})/2^31, ncol = 3, byrow = 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
f1谢谢!我喜欢内联C++,这非常有用。我仍然对apply
函数的功能感兴趣,关于这样的矩阵运算,但我想我会先检查一下
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