如何在Matlab中加速稀疏矩阵索引操作?

时间:2014-03-13 14:11:38

标签: matlab matrix sparse-matrix

我需要创建带有可变元素的备用矩阵。不幸的是,稀疏矩阵索引操作非常慢。

有没有办法加快这个过程?也许有一些我不知道的技巧?

这是一个最小的工作示例:

N = 400;
A = eye(7)+  [ zeros(3,3) eye(3)     zeros(3,1) ;
               zeros(3,3) zeros(3,3) zeros(3,1) ;
               zeros(1,3) zeros(1,3) zeros(1,1) ] ;
B = [ zeros(3,3) zeros(3,1) ;
      eye(3)     zeros(3,1) ;
      zeros(1,3) -2     ] ;

Su = sparse(7*N, 4*N);

for i=1:N
    for j=0:i-1
        Su(((i)*7 + 1) : ((i+1) * 7), (j*4 + 1) : ...
            ((j+1) * 4)) = A^(i-j-1) * B;
    end
end

Sx = sparse(N*7, N*7);

for i=0:N
    Sx((1 + i*7 : (i+1)*7), (1 + i*7 : (i+1)*7)) =  A^i;
end

SuSx是由AB的(产品)划分的矩阵。

1 个答案:

答案 0 :(得分:1)

MATLABs代码分析器已经提到这种分配稀疏矩阵的方法非常慢,因为非零模式被改变,这会产生很大的开销。放弃稀疏矩阵并仅使用Su = zeros(..使函数在合理的时间内执行,即使之后将矩阵转换为稀疏矩阵。

如果使用的内存有任何问题,您可以考虑将zeros矩阵定义为不同的类型,例如int16,因为所有值似乎都是小于400的有符号整数。

否则,如果您可以预测稀疏矩阵中的非零模式,则可以在前面正确定义它,并且不会遇到性能问题。您不需要知道确切的值,只需要知道值是否为非零值。从MATLAB的代码分析器中获取以下内容:

  

说明

     

代码分析器检测可能很慢的稀疏数组的索引模式。更改稀疏数组的非零模式的赋值可能会导致此错误,因为此类分配会导致相当大的开销。

     

建议行动

     

如果可能,使用稀疏构建稀疏数组,如下所示,并且不使用索引赋值(例如C(4)= B)来构建它们:

     
      
  1. 创建单独的索引和值数组。
  2.   
  3. 调用sparse来组装索引和值数组。
  4.         

    如果必须使用索引赋值来构建稀疏数组,则可以通过首先使用spalloc预分配稀疏数组来优化性能。

         

    如果代码只更改已经非零的数组元素,那么开销是合理的。按照调整代码分析器消息指示符和消息中的描述禁止此消息。   有关更多信息,请参阅“构造稀疏矩阵”。

因此,如果您可以创建包含非零值的索引数组,则可以调用sparse(i,j,s[,m,n,nzmax])来预定义非零模式。如果您只知道非零值的数量,而不知道它们的模式,则使用spalloc也可以提高您的效果。