Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab使用闭包降低性能_Matlab_Closures_Anonymous Function_Finite Element Analysis - Fatal编程技术网

Matlab使用闭包降低性能

Matlab使用闭包降低性能,matlab,closures,anonymous-function,finite-element-analysis,Matlab,Closures,Anonymous Function,Finite Element Analysis,我正在用有限元编写二维矩形上泊松方程的解。为了简化代码,我将基函数的句柄存储在数组中,然后在这些基函数上循环以创建矩阵和右侧。这样做的问题是,即使对于非常粗糙的网格,速度也非常慢。对于9x9网格(使用Dirichlet BC,需要求解49个节点),大约需要20秒。使用这个概要文件,我注意到大约有一半的时间花在访问(而不是执行)我的基函数上 分析器显示matrix_assembly>@(x,y)双线性基函数(x,y,xc(k-1),xc(k+1),yc(j-1),yc(j),yc(j),yc(j+

我正在用有限元编写二维矩形上泊松方程的解。为了简化代码,我将基函数的句柄存储在数组中,然后在这些基函数上循环以创建矩阵和右侧。这样做的问题是,即使对于非常粗糙的网格,速度也非常慢。对于9x9网格(使用Dirichlet BC,需要求解49个节点),大约需要20秒。使用这个概要文件,我注意到大约有一半的时间花在访问(而不是执行)我的基函数上

分析器显示
matrix_assembly>@(x,y)双线性基函数(x,y,xc(k-1),xc(k+1),yc(j-1),yc(j),yc(j),yc(j+1))(156800次调用,11.558秒)
,自时间(不执行双线性基代码)超过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

尝试将
basisFunctions
从单元格数组更改为常规数组


您还可以尝试在jBF循环中内联直接调用
bilinearBasisFunction
,而不是使用
basisFunctions
。在Matlab中创建和以后使用匿名函数总是比直接使用目标函数慢。这样代码可能会稍微冗长一些,但会更快。

首先,您在双
For
循环中调用该行156800次(创建了那么多匿名函数),每次都使用索引更改参数值!您是否确定
nu
等于
(长度(xc)-2)*(长度(yc)-2)
以避免在单元格
基本函数数组中重新分配?是否有任何理由使用156800个函数而不是一个参数为
(jBF,qx(iE),qy(iE))
,每个都有稍微不同的参数。当然,还有其他方法可以做到这一点,但我在这里做的方式具有可读性强的优势,我不明白为什么它会慢得多。那么,做156800次又是什么呢?
matrix\u assembly
bilinearBasisFunction
中的一个子函数的名称吗?@horcler:是的,我经常调用它,但这是不可避免的,我确实需要经常评估我的基函数。我还调用了bilinearBasisFunction 156800次,但根据分析器,这只需要2秒钟。