如何加速这个for循环代码(对于大矩阵`H_sparse`)?

时间:2016-10-21 23:31:25

标签: matlab performance matrix-multiplication large-data

H_sparse是一个大型矩阵,大小为20,000 x 5,000。以下代码中的矩阵向​​量乘积dk = A * Del_H;非常耗时。我怎样才能加快这段代码的速度?

此代码是获取MATLAB中内置函数pinv(H_Sparse)的等效结果的另一种方法。我认为MATLAB在bsxfun中使用mex文件和pinv,所以它很快。

理论上以下算法更快:

function PINV_H_Spp = Recur_Pinv_Comp( H_Sparse ) 
         L           = 1;
         H_candidate = H_Sparse(:,L); 
         A           = pinv( H_candidate );
         for L = 1:size( H_Sparse, 2 ) - 1
             L = L + 1; 
             Del_H = H_Sparse(:,L);
             dk    = A * Del_H;
             Ck    =     Del_H - H_candidate * dk; 
             Gk    = pinv( Ck ); 
             A     = A - dk * Gk; 
             A(end+1,:) = Gk; 
             H_candidate(:,end+1) = Del_H;
         end
         PINV_H_Spp = A;

可以使用pinv(H_Sparse)作为样本数据,将代码与H_Sparse = rand(20000, 5000)进行比较。

1 个答案:

答案 0 :(得分:1)

有几点改进:

  • 您可以将循环索引更改为2:size(H_Sparse, 2)并删除行L = L + 1;
  • 不需要创建单独的变量H_candidate,因为它只是H_Sparse的分区。相反,只需index H_sparse,您就可以节省内存。
  • 您可以preallocate逐行构建矩阵A,而不是使用indexing更新矩阵A。这通常会提供一些加速。
  • 返回function A = Recur_Pinv_Comp(H_Sparse) [nRows, nCols] = size(H_Sparse); A = [pinv(H_Sparse(:, 1)); zeros(nRows-1, nCols)]; for L = 2:nCols Del_H = H_Sparse(:, L); dk = A(1:L-1, :)*Del_H; Ck = Del_H - H_Sparse(:, 1:L-1)*dk; Gk = pinv(Ck); A(1:L-1, :) = A(1:L-1, :) - dk*Gk; A(L, :) = Gk; end end 作为输出。无需将其放在另一个变量中。

以下是包含上述改进的新版代码:

Gk  = Ck.'./(Ck.'*Ck);

此外,您对pinv的调用似乎只对列向量进行操作,因此您可以使用简单的array transpose替换它们,并按照广场的平方和进行缩放。矢量(这可能会加快一点):

{{1}}