2012-11-19 12 views
5

したがって、h(x)として定義された関数の曲線下面積を効果的に推定する必要があるこのコードを記述しました。私の問題は、小数点以下6桁までの範囲を見積もることができる必要があることです。しかし、estimateNで定義したアルゴリズムは、私のマシンにとっては重すぎると思われます。本質的に問題は、次のコードをより効率的にする方法です。私はそのループを取り除く方法がありますか?このラインではより効率的なモンテカルロシミュレーションを作成する

count = 0 
k = 1 
while(k <= n){ 
if(ypoints[k]<=h(xpoints[k])) 
    count = count+1 
k = k+1 
} 

h = function(x) { 
    return(1+(x^9)+(x^3)) 
} 
estimateN = function(n) { 
    count = 0 
    k = 1 
    xpoints = runif(n, 0, 1) 
    ypoints = runif(n, 0, 3) 
    while(k <= n){ 
    if(ypoints[k]<=h(xpoints[k])) 
     count = count+1 
    k = k+1 
    } 
    #because of the range that im using for y 
    return(3*(count/n)) 
} 
#uses the fact that err<=1/sqrt(n) to determine size of dataset 
estimate_to = function(i) { 
    n = (10^i)^2 
    print(paste(n, " repetitions: ", estimateN(n))) 
} 

estimate_to(6) 
+1

'estimate_to(6)'少しも貪欲かもしれません:あなたの現在のアルゴリズムはおそらくRが長1E12の数値ベクトルを割り当てるしようとしてメモリ不足になります。 – flodel

+0

実際に1e12シミュレーションが必要な場合は、計算時間とメモリ使用量との間の妥協点を見つけるようにアルゴリズムを書き直す必要があります。 – flodel

+0

Monte Carloの統合(より多くの)をより効率的にする、つまり反復回数を減らして同じ精度を得るための最良の方法は、Metropolis Monte Carloなどの重要度サンプリングを使用することです。あなたのケースでは、「1.0」に近い「x」の点は、「0.0」に近いものよりも積分の値に寄与します。 –

答えて

8

このコードを置き換え

count <- sum(ypoints <= h(xpoints)) 
+1

私はベクトル化の力をかなり雄弁にまとめると思います。 –

1

を、それはあなたがのために努力している、真に効率だ場合、integrateが速く数桁です(言うまでもありませんより多くのメモリ効率)。

integrate(h, 0, 1) 

# 1.35 with absolute error < 1.5e-14 

microbenchmark(integrate(h, 0, 1), estimate_to(3), times=10) 

# Unit: microseconds 
#    expr  min   lq  median   uq  max neval 
# integrate(h, 0, 1)  14.456  17.769  42.918  54.514  83.125 10 
#  estimate_to(3) 151980.781 159830.956 162290.668 167197.742 174881.066 10 
関連する問題