Performance MATLAB-帮助加速代码

Performance MATLAB-帮助加速代码,performance,matlab,nested-loops,matrix-multiplication,Performance,Matlab,Nested Loops,Matrix Multiplication,我需要你的帮助来加速我的MATLAB代码。第17行是最昂贵的部分。这是因为有两个嵌套的循环。我需要帮助删除循环并将其重写为一个矩阵乘法表达式。请注意,我将dKdx作为一个单元,这会导致用简单的矩阵乘法项替换嵌套循环的问题。有什么想法吗? 下面是一个简化的代码。可能dKdx不需要是一个单元格?该单元背后的想法是能够存储大量大小为[2*nelx+1nely+1,2nelx+1*nely+1]的矩阵 clc nelx = 16; nely = 8; dKdx = cell(2*

我需要你的帮助来加速我的MATLAB代码。第17行是最昂贵的部分。这是因为有两个嵌套的循环。我需要帮助删除循环并将其重写为一个矩阵乘法表达式。请注意,我将dKdx作为一个单元,这会导致用简单的矩阵乘法项替换嵌套循环的问题。有什么想法吗? 下面是一个简化的代码。可能dKdx不需要是一个单元格?该单元背后的想法是能够存储大量大小为[2*nelx+1nely+1,2nelx+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

黑森河成为瓶颈也许并不奇怪。你必须计算^2个矩阵元素,每个矩阵元素要做^3个工作,所以这是在^5上,这比反转矩阵更糟糕,除非我误解了你的代码

话虽如此,似乎您应该能够用外循环中的单个矩阵/矩阵乘法dKdx{j,1}*dUdx:,i替换内循环中的dKdx{j,1}*dUdx:,i矩阵/向量乘法,然后只需拉出内循环中需要的特定列,您也需要先提取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倍快,但内特的是80倍快,所以他打败了我

黑森河成为瓶颈可能并不奇怪。你必须计算^2个矩阵元素,每个矩阵元素要做^3个工作,所以这是在^5上,这比反转矩阵更糟糕,除非我误解了你的代码

话虽如此,似乎您应该能够用外循环中的单个矩阵/矩阵乘法dKdx{j,1}*dUdx:,i替换内循环中的dKdx{j,1}*dUdx:,i矩阵/向量乘法,然后只需拉出内循环中需要的特定列,您也需要先提取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倍快,但内特的是80倍快,所以他打败了我

这里有一种方法可以得到它:

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

在我的机器上,这个代码比for循环快6-7倍。我想知道是否还有其他更快捷的方法…

这里有一种方法:

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

在我的机器上,这个代码比for循环快6-7倍。我想知道是否还有其他更快的方法…

如果Hess循环是您想要优化的,那么可能更好,如果您可以将代码提取到最基本的部分,并说Hess是一个nxny乘以nxny的矩阵,U是一个2*nx+1ny+1向量,等等,您是对的。我想为我的问题提供一些背景资料。但这一切似乎都是多余的。我将简化代码。如果Hess循环是您想要优化的,可能会更好,如果您可以将代码提取到最基本的部分,并说Hess是一个nxny×nxny矩阵,U是一个2*nx+1ny+1向量,等等,那么会更清晰。您是对的。我想为我的问题提供一些背景资料。但这一切似乎都是多余的。我将简化代码。谢谢,但这是上/下三角形计算,这是昂贵的部分$Hessi,j=-2*U'*dKdx{j,1}*dUdx:,I;$。。静止对角线加法,加下三角形可以忽略不计。你真的在问我一些你自己几秒钟就能回答的问题吗?试试看,你只需要复制粘贴它。我复制粘贴了它!结果是,它对John的原始代码给出了不同的结果,这也是我仍然在使用的代码,但对现在的代码给出了相同的结果。不知道为什么。啊,那是因为他把-2丢在了美国队面前。谢谢你们两个。。这很有帮助。内特,快问。为什么需要第三条线?根据矩阵乘法公式,C不是已经是我需要的黑森函数了吗?我看到你的代码中的Hess比C更接近我的代码中的Hess。你如何证明第三行?谢谢,但这是上/下三角形的计算,这是昂贵的部分$Hessi,j=-2*U'*dKdx{j,1}*dUdx:,I;$。。静止对角线加法,加下三角形可以忽略不计。你真的在问我一些你自己几秒钟就能回答的问题吗?试试看,你只需要复制粘贴它。我复制粘贴了它!结果是,它对John的原始代码给出了不同的结果,这也是我仍然在使用的代码,但对现在的代码给出了相同的结果。不知道为什么。啊,那是因为他把-2丢在了美国队面前。谢谢你们两个。。这 这很有帮助。内特,快问。为什么需要第三条线?根据矩阵乘法公式,C不是已经是我需要的黑森函数了吗?我看到您代码中的Hess比C代码中的Hess更接近。您如何证明第三行的合理性?