2016-03-11 25 views
0

我目前正嘗試使用parfor掃描ode45求解的一組微分方程的一系列初始條件。該代碼工作正常使用兩個嵌套for循環,但我希望parfor可以使該過程更有效率。不幸的是,我遇到了一個問題,求解器能夠解決表示初始條件在一系列變量中的組合之一的問題,但其他的似乎將它們的初始值都設置爲0,而不是指定的值由最初的條件。這可能與我需要創建結果將被寫入的零點矩陣('P')可能覆蓋初始條件(?)的任何幫助將不勝感激。使用parfor掃描一組ODE的初始條件

感謝, 凱爾

function help(C, R) 

A = 0.01; 
B = 0.00; 
C = [0.001,0.01]; 
D = 0.00; 
R = [1e-10,1e-9]; 

[CGrid,RGrid] = meshgrid(C,R); 

parfor ij = 1 : numel(CGrid) 
     c2 = [A; B; CGrid(ij); D; RGrid(ij)]; 
     [t,c] = ode45('ode_sys',[0:1:300],c2); 
     for k=1:length([0:1:300]) 
      for l=1:length(c2) 
       if c(k,l)<0 
        c(k,l)=0; 
       end 
      end 
     end 

    P = zeros(301,5,numel(R),numel(C)); 
    temp = zeros(301,5);  
    temp(:,1) = c(:,1); 
    temp(:,2) = c(:,2); 
    temp(:,3) = c(:,3); 
    temp(:,4) = c(:,4); 
    temp(:,5) = c(:,5); 
    P(:,:,ij)=temp; 

    parsave('data.mat', P); 
    end 
end 

回答

0

你有一個錯誤,並簡化代碼的機會很少。

parfor循環中,您有這條線P = zeros(301,5,numel(R),numel(C));,它覆蓋了P,每次迭代時全部爲零。把這個放在parfor循環之前。

第一個雙 - for循環使c的負值元素爲零可以使用max(c,0)來完成,這應該更有效。您也可以直接執行P(:,:,ij)=c(:,1:5)

所以,你可以用

P = zeros(301,5,numel(R),numel(C)); 
for ij = 1 : numel(CGrid) 
    c2 = [A; B; CGrid(ij); D; RGrid(ij)]; 
    [t,c] = ode45('ode_sys',0:300,c2); 
    c = max(c,0); 
    P(:,:,ij) = c(:,1:5); 
    parsave('data.mat',P); 
end 
+0

感謝您的幫助更換您的parfor循環!不幸的是,我需要使用parfor才能在合理的時間尺度上解決我的方程組。此外,似乎matlab需要將P =零(...代碼放置在parfor循環中,似乎迫使我試圖解決的變量初始條件的覆蓋 – ksm

+0

在這種情況下,嘗試'P =零(301 ,5,numel(R)* numel(C));'帶'parfor'。 – David