2015-11-03 106 views
1

我試圖通過使用parfor加速我的MATLAB代碼,但是,我做的不正確。我的代碼相當簡單,我使用MATLAB的內置函數mle函數對一些數據進行擬合,方法是對平均值(mm)和方差(vv)使用不同的初始猜測。 onestagepdf2是我的概率密度函數。並行MATLAB for循環來計算MLE

這裏是代碼片段:

mm=linspace(.1, 1, 2); % mean 
vv=linspace(.1, 2, 2); % variance 
N=length(mm); 
n=length(vv); 

pd=zeros(n*N,2); 
ld = NaN*ones(n*N,1); 

options = statset('MaxIter',10000, 'MaxFunEvals',10000); 

parfor i=1:N % pick a mean 
    m=mm(i); 
    parfor j=1:n % pick a variance 
     v=vv(j); 
     x0=[m,v]; 
     [p,conf1]=mle(data,'pdf',@onestagepdf2,'start',x0, 'upperbound', [Inf Inf],'lowerbound',[0 0],'options',options) 
     pd(n*(i-1)+j,:)=p; % store parameter values from mle 
     l=onestagepdf2(data,p(1),p(2)); % evaluate pdf with parameter values 
     ld(n*(i-1)+j)=sum(log(l)); % store likelihood value 

    end 
end 

我接收是錯誤: '在不能被歸類一個PARFOR可變PD'

回答

2
pd = zeros(n, N, 2); %initialise culprits 
ld= zeros(n,N); 
parfor ii=1:N % pick a mean 
    m=mm(ii); 
    for jj=1:n % Parallellise the second parfor 
     v=vv(jj); 
     x0=[m,v]; 
     [p,conf1]=mle(data,'pdf',@onestagepdf2,'start',x0, 'upperbound', [Inf Inf],'lowerbound',[0 0],'options',options) 
     pd(ii, jj, :) = p;=p; % store parameter values from mle 
     l=onestagepdf2(data,p(1),p(2)); % evaluate pdf with parameter values 
     ld(ii,jj)=sum(log(l)); % store likelihood value 

    end 
end 

pd的確是罪魁禍首,因爲@Trilarion說,你得到了錯誤。可能ld也不是太好,語法相同,所以初始化也是如此。發生這種情況是因爲parfor想要在執行之前知道循環內所有變量的大小是。這是一個固定的最大尺寸對MATLAB來說是未知的,因爲你正在使用循環變量來「改變」尺寸。

也許您在運行此作爲for環說,有這兩條線下面的「橙色晃」(如拼寫檢查錯誤)「PD出現在大小每次迭代越來越大。請考慮預先分配的速度」。這是需要parfor,因爲迭代順序不是順序的,所以不可能用這種方式增長數組。

其次,你不能嵌套parfor循環。你可以使用像parfor這樣的函數,並在parfor內運行,但是由於你已經在使用所有的工人,所以這不會讓你加速。

有關parfor的更多一般信息,請參閱Saving time and memory using parfor in Matlab?,尤其是關於速度。

+0

我需要在'parfor'循環內部初始化'pd'和'ld'而不是外部? – user3603290

+0

哼,不。確實,你需要在外面初始化它們,我的不好,我會更新這篇文章。 – Adriaan

+0

這裏'n *(i-1)+ j'不大於'n * N',所以變量的大小沒有增長。只是Matlab不確定它。 – Trilarion

1

你想要一個切片,輸出變量,但Matlab是沒有足夠的智慧來檢測n*(i-1)+j實際上是合理的,不會與異步干擾評價。

只要做到這一點作爲單獨的尺寸

pd = zeros(n, N, 2); 
... 
    % in the loop 
    pd(i, j, :) = p; 

,將工作。

請注意,Matlab不允許嵌套parfors。但是,如果N大於工人數量,您也不需要它們。另見documentation

+0

ld也是如此。 – Trilarion

+0

@Adriaan說4-8名工人,N可能大於此數,提問者無論如何都不需要第二個參數。但是他仍然需要擴展pd和ld的維度以便讓外部表達式起作用。 – Trilarion

+0

似乎解決了這個問題。我有一個後續問題:當我打印'max(ld)'時,它會打印兩次最大值,即'-746.8349 -746.8349'。你能解釋爲什麼嗎? – user3603290