简体   繁体   English

MATLAB-帮助加快代码

[英]MATLAB - Help speed up the code

I need your help to speed up my MATLAB code. 我需要您的帮助来加速我的MATLAB代码。 Line 17 is the most expensive part. 17号线是最昂贵的部分。 It is because of the two nested loops. 这是因为有两个嵌套循环。 I need help with removing the loops and rewrite it into just one matrix multiplication expression. 我需要删除循环并将其重写为一个矩阵乘法表达式的帮助。 Note that I have taken dKdx as a cell, which is causing problems to replace nested loops with simple matrix multiplication term. 请注意,我已经将dKdx作为一个单元,这导致使用简单的矩阵乘法项替换嵌套循环时会出现问题。 Any ideas? 有任何想法吗? Below if a simplified code. 下面是一个简化的代码。 May be dKdx doesn't need to be an cell? 也许dKdx不必是一个单元格吗? Idea behind cell was to be able to store lot of matrices of size [2*(nelx+1) (nely+1),2 (nelx+1)*(nely+1)]. 单元格背后的想法是能够存储许多大小为[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

Here's one way to get it: 这是获得它的一种方法:

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

In my machine this code runs 6-7 times faster than the for loop one. 在我的机器中,此代码的运行速度比for循环1高6-7倍。 I wonder if there are other even faster ways... 我想知道是否还有其他更快的方法...

It may not be surprising that the hessian is the bottleneck. 粗麻布是瓶颈,这并不奇怪。 You have to calculate O(n^2) matrix elements, and you are doing O(n^3) work per matrix element, so that's O(n^5), which is worse than inverting the matrix (unless I am misunderstanding your code). 您必须计算O(n ^ 2)个矩阵元素,并且每个矩阵元素要进行O(n ^ 3)个工作,所以这是O(n ^ 5),这比求矩阵倒数还差(除非我误解了码)。

Having said that, it seems like you should be able to replace the dKdx{j,1}*dUdx(:,i) matrix/vector multiplication in the inner loop with a single matrix/matrix multiplication dKdx{j,1}*dUdx in the outer loop, then just pull out the particular column that you need in the inner loop (you would need to j first too). 话虽如此,看来您应该可以用单个矩阵/矩阵乘法dKdx{j,1}*dUdx内部循环中的dKdx{j,1}*dUdx(:,i)矩阵/矢量乘法在外部循环中,然后只需在内部循环中拉出所需的特定列即可(您也需要首先使用j )。 I don't have time to try this myself right now, but perhaps it will help you. 我现在没有时间自己尝试该操作,但也许会对您有所帮助。

Another thought: are you sure there isn't some structure in your matrices that you can take advantage of to reduce the number of matrix multiplies? 另一个想法:您确定矩阵中没有可以利用的结构来减少矩阵乘法的数量吗?

Update 更新资料

In the process of trying to make my idea work, I came up with the following: 在尝试使我的想法可行的过程中,我提出了以下建议:

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);

On my machine this is 25 times faster, but Nate's is 80 times faster, so he beats me! 在我的机器上,速度快25倍,但内特的速度快80倍,所以他击败了我!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM