1

我需要你的帮助来加快我的 MATLAB 代码。17 号线是最昂贵的部分。这是因为两个嵌套循环。我需要帮助来删除循环并将其重写为一个矩阵乘法表达式。请注意,我将 dKdx 作为一个单元格,这会导致用简单的矩阵乘法项替换嵌套循环时出现问题。有任何想法吗?下面是一个简化的代码。可能 dKdx 不需要是一个单元格?单元格背后的想法是能够存储大量大小为 [2*(nelx+1) (nely+1),2 (nelx+1)*(nely+1)] 的矩阵。

    clc
    nelx = 16; nely = 8;
    dKdx = cell(2*(nelx+1)*(nely+1),1);
    Hess = zeros(nelx*nely,nelx*nely);
    U = rand(2*(nelx+1)*(nely+1),1);
    dUdx = rand(2*(nelx+1)*(nely+1),nelx*nely);

    for elx = 1:nelx
        for ely = 1:nely
            elm = nely*(elx-1)+ely;               
            dKdx{elm,1} = rand(2*(nelx+1)*(nely+1),2*(nelx+1)*(nely+1));
        end
    end

    for i = 1:nelx*nely    
        for j = i:nelx*nely
            Hess(i,j) = U'*dKdx{j,1}*dUdx(:,i);
            if i ~= j
                Hess(j,i) = Hess(i,j);
            end
        end
    end
4

2 回答 2

3

这是获得它的一种方法:

  B = reshape(U'*cell2mat(dKdx'),[size(U,1) nelx*nely]);
  C = B'*dUdx;
  Hess=tril(C)+triu(C',1);

在我的机器中,这段代码的运行速度比 for 循环快 6-7 倍。我想知道是否还有其他更快的方法...

于 2012-10-18T00:41:05.887 回答
2

粗麻布是瓶颈可能并不奇怪。您必须计算 O(n^2) 矩阵元素,并且每个矩阵元素都在做 O(n^3) 工作,所以这是 O(n^5),这比反转矩阵更糟糕(除非我误解了你的代码)。

话虽如此,您似乎应该能够将内部循环中的dKdx{j,1}*dUdx(:,i)矩阵/向量乘法替换为外部循环中的单个矩阵/矩阵乘法dKdx{j,1}*dUdx,然后只需在内部循环中拉出您需要的特定列(您也需要j先)。我现在没有时间亲自尝试这个,但也许它会对你有所帮助。

另一个想法:你确定你的矩阵中没有一些结构可以用来减少矩阵乘法的数量吗?

更新

在尝试实现我的想法的过程中,我想出了以下几点:

Hess2 = zeros(nelx*nely,nelx*nely);
for j=1:nelx*nely
    Hess2(j,:) = U'*dKdx{j,1}*dUdx;
end
Hess2 = tril(Hess2)+triu(Hess2',1);

在我的机器上,这快了 25 倍,但 Nate 的机器快了 80 倍,所以他打败了我!

于 2012-10-17T23:19:36.117 回答