旋转门谜语 - Matlab时间有效的稀疏矩阵使用

时间:2017-07-22 06:41:49

标签: matlab performance matrix sparse-matrix coding-efficiency

我正在运行使用大型稀疏矩阵进行多次迭代的代码。我的代码中有三行占用了大约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

您可以跳过以下两段

这是一个让这个例子更生动的故事。一位老人正在不同医院探望病人。有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)。所以老人现在可以神奇地在医院之间移动。我们需要相应地改变S矩阵。这相当于两件事,增加了在医院indj(i)中移动到房间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
    
  3. 这让我有点希望有一种方法可以让计算更快......

    非常感谢您的帮助!

0 个答案:

没有答案