在 MATLAB 中有一个包含转移概率transition_probs
的大矩阵和一个邻接矩阵adj_mat
。我想计算沿列的转移矩阵的累积和,然后元素明智地将它与邻接矩阵相乘,邻接矩阵以这种方式充当掩码:
cumsumTransitionMat = cumsum(transition_probs,2) .* adj_mat;
我收到MEMORY错误,因为cumsum
矩阵的所有条目都是非零的。
我想通过仅在第一个位置存在非零条目的累积和条目来避免此问题。如何在不使用for
循环的情况下完成这项工作?
答案 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)
。