我需要创建带有可变元素的备用矩阵。不幸的是,稀疏矩阵索引操作非常慢。
有没有办法加快这个过程?也许有一些我不知道的技巧?
这是一个最小的工作示例:
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
Su
和Sx
是由A
和B
的(产品)划分的矩阵。
答案 0 :(得分:1)
MATLABs代码分析器已经提到这种分配稀疏矩阵的方法非常慢,因为非零模式被改变,这会产生很大的开销。放弃稀疏矩阵并仅使用Su = zeros(..
使函数在合理的时间内执行,即使之后将矩阵转换为稀疏矩阵。
如果使用的内存有任何问题,您可以考虑将zeros
矩阵定义为不同的类型,例如int16
,因为所有值似乎都是小于400的有符号整数。
否则,如果您可以预测稀疏矩阵中的非零模式,则可以在前面正确定义它,并且不会遇到性能问题。您不需要知道确切的值,只需要知道值是否为非零值。从MATLAB的代码分析器中获取以下内容:
说明
代码分析器检测可能很慢的稀疏数组的索引模式。更改稀疏数组的非零模式的赋值可能会导致此错误,因为此类分配会导致相当大的开销。
建议行动
如果可能,使用稀疏构建稀疏数组,如下所示,并且不使用索引赋值(例如C(4)= B)来构建它们:
- 创建单独的索引和值数组。
- 调用sparse来组装索引和值数组。
醇>如果必须使用索引赋值来构建稀疏数组,则可以通过首先使用spalloc预分配稀疏数组来优化性能。
如果代码只更改已经非零的数组元素,那么开销是合理的。按照调整代码分析器消息指示符和消息中的描述禁止此消息。 有关更多信息,请参阅“构造稀疏矩阵”。
因此,如果您可以创建包含非零值的索引数组,则可以调用sparse(i,j,s[,m,n,nzmax])
来预定义非零模式。如果您只知道非零值的数量,而不知道它们的模式,则使用spalloc
也可以提高您的效果。