对于MATLAB中的大型稀疏矩阵,计算非零项的列的累积和?

时间:2013-09-13 07:46:44

标签: matlab memory matrix sparse-matrix adjacency-matrix

MATLAB 中有一个包含转移概率transition_probs的大矩阵和一个邻接矩阵adj_mat。我想计算沿列的转移矩阵的累积和,然后元素明智地将它与邻接矩阵相乘,邻接矩阵以这种方式充当掩码:

cumsumTransitionMat = cumsum(transition_probs,2) .* adj_mat;

我收到MEMORY错误,因为cumsum矩阵的所有条目都是非零的。

我想通过仅在第一个位置存在非零条目的累积和条目来避免此问题。如何在不使用for循环的情况下完成这项工作?

2 个答案:

答案 0 :(得分:2)

您只能对非零元素应用cumsum。这是一些代码:

A = sparse(round(rand(100,1)));        %some sparse data
A_cum = A;                             %instantiate A_cum by copy A

idx_A = find(A);                       %find non-zeros
A_cum(idx_A) = cumsum(A(idx_A)); %cumsum on non-zeros elements only 

您可以使用

检查输出
 B = cumsum(A);


   A_cum   B
     1     1
     0     1
     0     1
     2     2
     3     3
     4     4
     5     5
     0     5
     0     5
     6     6

isequal(A_cum(find(A_cum)), B(find(A_cum)))给出1

答案 1 :(得分:2)

当CUMSUM应用于行时,对于每一行,它将进入并填充从它找到的第一个非零列开始直到最后一列的值,这就是它根据定义所做的事情。

存储方面最糟糕的情况是稀疏矩阵包含第一列的值,最好的情况是所有非零值出现在最后一列。例如:

% worst case
>> M = sparse([ones(5,1) zeros(5,4)]);
>> MM = cumsum(M,2);       % completely dense matrix
>> nnz(MM)
ans =
    25

% best case
>> MM = cumsum(fliplr(M),2);

如果生成的矩阵不适合内存,我不会看到你还能做什么,除了可以在行上使用for循环,并且处理矩阵是小批量...

请注意,在计算累积和之前无法应用屏蔽操作,因为这会改变结果。所以你不能说cumsum(transition_probs .* adj_mat, 2)