2016-08-30 10 views
1

私は1,000,000回のアーウィンホール分布をシミュレートしていますが、各反復は100個の均一なランダム変数の合計です。私はこのプログラムを作成しましたが、その権利はあると思いますが、MATLABは一晩中実行されていて、完了していないので、何か(明らかに)間違っていますが、ここに私のプログラムがあります、誰かがこの問題を見るかもしれないことを願っています。ループが長い時間を費やしている

n=100; % Nb of samples 
N=1000000; %Nb of replicates 

for jj=1:N 
    for ii=1:n 
     x(ii)=rand(); 
    end 
    s(jj)=sum(x); 
    mu=mean(s); 
    sigma2=var(s); 
    sigma=std(s); 
    S(jj)=1-normcdf((70-mu)/sigma); 
    if mod(jj, 100000)==0 
     jj 
    end 
end 

histogram(S) 
+3

あなたの部門のスペースは/ s igma本当にありますか?また、 'x = rand(100,1);だけでなく、 – Bernhard

+2

百万回の反復で、多くの時間が必要です!また、 'x'、' s'、 'S'のためのメモリーを[pre-allocating](http://www.mathworks.com/help/matlab/matlab_prog/preallocating-arrays.html)と考えてください。 –

+0

/s igmaは修正されましたが、問題は残っています:( – Orongo

答えて

5
n=1e2; % Nb of samples 
N=1e6; % Nb of replicates 
s = zeros(1,N); % INITIALISE, INITIALISE, INITIALISE 
S = zeros(1,N); % INITIALISE, INITIALISE, INITIALISE 

for jj=1:N 
    x=rand(n,1); % Remove redundant inner loop 
    s(1,jj)=sum(x); 
    tmp = s(1,1:jj); % Create temporary storage for convenience 
    mu=mean(tmp); 
    sigma=std(sigma2); % You don't need the variance at all 
    S(1,jj)=1-normcdf((70-mu)/sigma); 
    if mod(jj, 1e5)==0 
     disp('We are at iteration %i',jj); % Proper display command 
    end 
end 

histogram(S) 

このコードは、私のi5-750プロセッサー上N=1e4を使用して半分に秒を走りました。

最も重要なことは、jjのようなコンソールには印刷しないことです。まったく印刷しないでください。または明確にするためにdispコマンドを使用してください。コンソールへの印刷には多くの時間がかかります。また、initialise your variables。ループ内で変数を大きくするには、非常に時間がかかります。変数の長さを100万倍に増やすたびに、MATLABは最初に最初の長さが+ 1の変数を作成し、その内容をコピーしてから古い変数を削除します。それはおそらくあなたのコードを長く取っているでしょう。

また、一時的な変数tmpを使用して、コードの変換をやや簡単にしました。

+0

素敵なスピード! - 原則として、私はvarに基づいてstdを計算します(データに基づくのではなく)。 –

+0

@DennisJaheruddin元のコードに唯一の 'jj'があることに私は驚いていました。私は彼が何らかの進歩率測定器を持っていたいと思うので、それは私が彼のために適切に 'disp 'を呼び出して得たものです。 – Adriaan

+0

私はこれをなぜ置いたのか理解していますが、この呼び出しはうまくいかないようです。 –

2

変数Sを事前に割り当て、コードの一部をベクトル化しました。

tic; 

n=100; % Nb of samples 
N=1000000; %Nb of replicates 

x = rand(n,N); % x(ii) = rand(); 
s = sum(x); % s = sum(x); 
mu = cumsum(s)./(1:N); % mu = mean(s); 

S = zeros(N,1); 
for jj=1:N 
    sigma=std(s(1:jj)); 
    S(jj)=1-normcdf((70-mu(jj))/sigma); 
    if ~mod(jj,100000) 
     fprintf('%d %.2f\n',jj,toc); 
    end 
end 

toc 

histogram(S) 

私はi5-6200Uプロセッサと8ギガバイトDDR3 RAMと

N  orginal modified 
---------------------------- 
1e+05  54.07  31.9 
2e+05 246.37  173.6 
3e+05 621.06 450.91 
4e+05 1161.2 835.03 
5e+05 1837.5 1329.4 
6e+05 2661.4 1930.3 

を取得します。

jjが大きいほど計算が重くなるため、N = 10^6のコードを実行するとかなり時間がかかります。

変数をあらかじめ割り当てていないため、Nを大きく設定すると、その差は大きくなります。

MATLABは可変サイズの変更を処理できますが、MATLAB は、で事前にメモリを割り当てることをお勧めします。 MATLABが変数の境界に達するたびに、MATLABはメモリを再割り当てしようとしますが、時間がかかります。正確なメモリサイズを計算できない場合でも、いくつかの変数を大まかな推測で事前に割り当てて、ループの後で未使用の部分を消去する方が良いです。

+0

それは本当に知っていると便利で便利になるでしょう。実行には6時間かかり、結果とコードは今質問の行にあります。これは学習の練習であるため、私は結果に少し驚いています。私は結果とランタイムが両方とも普通であることに驚いています。 – Orongo

関連する問題