0

我正在使用有限元素爲2d矩形編寫泊松方程的解。爲了簡化代碼,我將句柄存儲到數組中的基函數中,然後遍歷這些基函數來創建我的矩陣和右側。這個問題在於,即使對於非常粗糙的網格,它的速度也非常慢。對於9x9網格(使用Dirichlet BC,有49個節點可以解決),大約需要20秒。使用配置文件我注意到,大約一半的時間用於訪問(不執行)我的基本功能。Matlab使用閉包的緩慢性能

分析器說matrix_assembly>@(x,y)bilinearBasisFunction(x,y,xc(k-1),xc(k),xc(k+1),yc(j-1),yc(j),yc(j+1)) (156800 calls, 11.558 sec),自身時間(不執行雙線性基本代碼)超過9秒。任何想法,爲什麼這可能會這麼慢?

下面是一些代碼,如果需要,我可以發佈更多:

%% setting up the basis functions, storing them in cell array 
basisFunctions = cell(nu, 1); %nu is #unknowns 
i = 1; 
for j = 2:length(yc) - 1 
for k = 2:length(xc) - 1 
    basisFunctions{i} = @(x,y) bilinearBasisFunction(x,y, xc(k-1), xc(k),... 
     xc(k+1), yc(j-1), yc(j), yc(j+1)); %my code for bilinear basis functions 
    i = i+1; 
end 
end 

%% Assemble matrices and RHS 
M = zeros(nu,nu); 
S = zeros(nu,nu); 
F = zeros(nu, 1); 

for iE = 1:ne 
for iBF = 1:nu 
    [z1, dx1, dy1] = basisFunctions{iBF}(qx(iE), qy(iE)); 

    F(iBF) = F(iBF) + z1*forcing_handle(qx(iE),qy(iE))/ae(iE); 

    for jBF = 1:nu 
     [z2, dx2, dy2] = basisFunctions{jBF}(qx(iE), qy(iE)); 

     %M(iBF,jBF) = M(iBF,jBF) + z1*z2/ae(iE); 
     S(iBF,jBF) = S(iBF, jBF) + (dx1*dx2 + dy1*dy2)/ae(iE); 
    end   
end 
end 
+0

首先,您要在雙'for'循環中調用該行156,800次(創建許多匿名函數),並每次使用索引更改參數值!你確定'nu'等於'(length(xc)-2)*(length(yc)-2)',以避免在cellFunctions數組中重新分配嗎? – horchler

+0

是否有任何理由使用參數'(jBF,qx(iE),qy(iE))'具有156800個函數而不是一個函數? – Daniel

+0

@DanielR:只有49個函數,每個函數的參數略有不同。當然,還有其他的方法可以做到這一點,但我在這裏做的方式具有可讀性強的優點,我不明白爲什麼它會慢得多。 –

回答

0

嘗試basisFunctions從一個電池陣列是規則陣列改變。

你也可以嘗試在你的jBF循環中直接調用bilinearBasisFunction,而不是使用basisFunctions。在Matlab中創建和稍後使用匿名函數總是比直接使用目標函數慢。這種方式的代碼可能稍微冗長些,但速度會更快。