我不知道为什么这样的事情应该很慢:
steps=500
samples=100000
s_0=2.1
r=.02
sigma=.2
k=1.9
at<-matrix(nrow=(steps+1),ncol=samples)
at[1,]=s_0
for(j in 1:samples)
{
for(i in 2:(steps+1))
{
at[i,j]=at[(i-1),j] + sigma*sqrt(.0008)*rnorm(1)
}
}
我尝试使用sapply重写它,但从性能的角度来看仍然很糟糕。
我在这里遗漏了什么吗?这可能是c ++中的秒数,甚至是膨胀的c#。
答案 0 :(得分:4)
R可以对某些操作进行矢量化。在您的情况下,您可以通过执行以下更改来摆脱外部循环。
for(i in 2:(steps + 1))
{
at[i,] = at[(i - 1),] + sigma * sqrt(.0008) * rnorm(samples)
}
根据system.time
samples = 1000
的原始版本需要6.83秒,而修改后的版本需要0.09秒。
答案 1 :(得分:4)
怎么样:
at <- s_0 + t(apply(matrix(rnorm(samples*(steps+1),sd=sigma*sqrt(8e-4)),
ncol=samples),
2,
cumsum))
(尚未仔细测试过,但我认为它应该是正确的,而且要快得多。)
答案 2 :(得分:1)
要编写快速R代码,您真的需要重新思考如何编写函数。您希望对整个向量进行操作,而不是一次只进行一次观察。
如果你在编写C风格的循环时真的很遗憾,你也可以尝试一下Rcpp。如果你已经习惯了C ++并且更喜欢用这种方式编写函数,那么可能很方便。
library(Rcpp)
do_stuff <- cppFunction('NumericMatrix do_stuff(
int steps,
int samples,
double s_0,
double r,
double sigma,
double k ) {
// Ensure RNG scope set
RNGScope scope;
// allocate the output matrix
NumericMatrix at( steps+1, samples );
// fill the first row
for( int i=0; i < at.ncol(); i++ ) {
at(0, i) = s_0;
}
// loop over the matrix and do stuff
for( int j=0; j < samples; j++ ) {
for( int i=1; i < steps+1; i++ ) {
at(i, j) = at(i-1, j) + sigma * sqrt(0.0008) * R::rnorm(0, 1);
}
}
return at;
}')
system.time( out <- do_stuff(500, 100000, 2.1, 0.02, 0.2, 1.9) )
给了我
user system elapsed
3.205 0.092 3.297
因此,如果你已经有了一些C ++背景知识,请考虑学习如何使用Rcpp将数据映射到R和从R映射数据。