3

我正在运行一个使用大型稀疏矩阵进行多次迭代的代码。我的代码中有三行占用了大约 75% 的运行时间,我认为我可以使用稀疏矩阵的特殊结构来减少该时间,但到目前为止我还没有设法做到这一点。我很想得到你的帮助!!

好的,这是我的代码的要点:

I = 70;
J = 1000;
A = rand(I);
A = A./repmat(sum(A, 2), 1, I);
S   = kron(A, speye(J));
indj = randi(J,I,1); 
tic
for i = 1:I
    S(:, (i-1)*J+indj(i)) = sum(S(:, (i-1)*J + (1:indj(i))), 2);
end
toc

您可以跳过以下2段

这里有一个故事,可以让这个例子更生动一点。一位老人正在不同的医院探望病人。有1000(J)家医院,每家医院有70(I)间病房。矩阵 A 是指定老人从医院的一个房间移动到同一医院的另一个房间的概率的转移矩阵。A(i1,i2) 是老人从房间 i1 移动到房间 i2 的概率(因此列总和为 1)。大 S 矩阵是转移概率矩阵,其中从医院 j1 的房间 i1 移动到医院 j2 的房间 i2 由 (J*(i1-1)+j1, J*(i2-1)+j2) 元素给出. 老人不可能从一家医院搬到另一家医院,所以矩阵是稀疏的。

神奇的事情发生了,现在第一家 indj(i) 医院的 i 号房间的所有门都通向同一家医院,indj(i) 医院。所以老人现在可以神奇地在医院之间移动。我们需要相应地改变 S 矩阵。这相当于两件事,增加所有 i 在医院 indj(i) 移动到房间 i 的概率,以及将所有 i 在医院 i 进入所有低于 indj(i) 的房间的概率设置为零。后者我可以非常有效地完成,但第一部分花费了我太长时间。

为什么我认为有机会减少运行时间

  1. 循环。tic 和 toc 之间的部分可以不用循环编写。我已经做到了,但它使它运行得更慢,也许是因为 sub2ind 的长度非常大。
  2. 矩阵结构。请注意,我们不需要整个总和,只需要添加一个元素。这些循环实现了相同的结果(但在这里,显然要慢得多):

    for i = 1:I
    for ii = 1:I
    for j = 1:indj(i)-1
        S((ii-1)*J+j, (i-1)*J+indj(i)) = S((ii-1)*J+j, (i-1)*J+indj(i)) + S((ii-1)*J+j, (i-1)*J+j);
    end
    end
    end
    

这让我有点希望有一种方法可以使计算更快……</p>

非常感谢您的帮助!

4

0 回答 0