4

なぜこのようなものが遅いのかわかりません:

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#では数秒になります。

4

3 に答える 3

4

R は特定の操作をベクトル化できます。あなたの場合、次の変更を行うことで外側のループを取り除くことができます。

for(i in 2:(steps + 1))
{
    at[i,] = at[(i - 1),] + sigma * sqrt(.0008) * rnorm(samples)
}

system.time元のバージョンによると、 samples = 10006.83 秒かかりますが、変更されたバージョンでは 0.09 秒かかります。

于 2013-02-13T21:49:29.257 に答える
4

どうですか:

at <- s_0 + t(apply(matrix(rnorm(samples*(steps+1),sd=sigma*sqrt(8e-4)),
                   ncol=samples),
                    2,
                    cumsum))

(これはまだ注意深くテストしていませんが、正しく、はるかに高速であると思います。)

于 2013-02-13T21:56:52.753 に答える
1

高速な R コードを作成するには、関数の作成方法を再考する必要があります。一度に 1 つの観測値だけでなく、ベクトル全体を操作する必要があります。

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 との間でデータをマップする方法を学習することを検討してください。

于 2013-02-14T00:51:10.163 に答える