如何在给定特征值1的情况下找到特征向量,从而最小化内存使用

时间:2014-04-09 14:17:12

标签: memory optimization octave eigenvector

如果有人能帮我找到一种有效的方法(可能是低内存算法)来解决以下问题,我将不胜感激。

我需要找到转换矩阵x的固定分布P。转移矩阵是一个非常大的极稀疏矩阵,其构造使得所有列总和为1.由于静态分布由等式Px = x给出,因此x只是{{1}的特征向量。 1}}与特征值1相关联。

我目前正在使用GNU Octave生成转换矩阵,找到静态分布,并绘制结果。我正在使用函数P来计算特征值和特征向量,并且可以只返回一个特征向量,其中特征值为1(实际上我必须指定1.1,以防止出错)。转换矩阵的构造(使用稀疏矩阵)相当快,但随着我增加大小,找到特征向量变得越来越慢,并且在我检查甚至中等大小的问题之前我的内存已经用完了。

我目前的代码是

eigs()

鉴于我知道1是特征值,我想知道是否有更好的方法来计算特征向量,或者是一种使更有效地使用内存的方法,因为我不需要中间的大密集矩阵。我天真地试过

[v l] = eigs(P, 1, 1.01);
x = v / sum(v);

失败,因为Q是单数(根据定义)。

如果有人对我如何处理这个问题有任何想法,我将非常感激,因为这是我必须执行很多次的计算,并且如果可能的话我想尝试更大更复杂的模型

作为这个问题的背景,我正在解决随机SIR模型中牛群中感染数量的均衡分布。不幸的是,即使是中等规模的畜群,过渡矩阵也非常大。例如:在平均20个人的SIR模型中(95%的人口在12到28个人之间),n = size(P,1); % number of states Q = P - speye(n,n); x = Q\zeros(n,1); % solve (P-I)x = 0 是21169乘21169,其中20340非零值(即0.0005%密集)并且耗尽321 Kb(该大小的完整矩阵将是3.3 Gb),而对于大约50个人P使用3 Mb。 P本身应该很小。我怀疑x在某个地方有一个密集的矩阵,这导致我的内存不足,所以如果我可以避免使用完整的矩阵,我应该没问题。

3 个答案:

答案 0 :(得分:2)

功率迭代是找到矩阵的主要特征值的标准方法。你选择一个随机向量v,然后反复用P点击它,直到你看到它变化很大。您希望定期将v除以sqrt(v^T v)以对其进行标准化。

此处的收敛速度与最大特征值和第二大特征值之间的间隔成比例。每次迭代只需几次矩阵乘法。

有很多方法可以做到这一点(" PageRank"在这里搜索是一件好事)可以提高真正巨大的稀疏矩阵的速度,但我不知道他们&# 39;在这里必要或有用。

答案 1 :(得分:1)

你的方法似乎很好。但是,你所谓的x是Q的零空间。如果null(Q)支持稀疏矩阵,它将起作用,但事实并非如此。网上有很多东西可以找到稀疏矩阵的零空间。例如:

http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/249467

http://www.mathworks.com/matlabcentral/fileexchange/42922-null-space-for-sparse-matrix/content/nulls.m

http://www.mathworks.com/matlabcentral/fileexchange/11120-null-space-of-a-sparse-matrix

答案 2 :(得分:1)

似乎最好的解决方案是按照tmyklebu的建议使用功率迭代方法

该方法是迭代x = Px; x /= sum(x),直到x收敛。如果连续迭代之间的d1范数小于1e-5,我假设收敛,因为这似乎给出了良好的结果。

收敛可能需要一段时间,因为最大的两个特征值相当接近(收敛所需的迭代次数可能会有很大差异,从大约200到2000,取决于所使用的模型和种群大小,但最终到达那里)。但是,内存要求很低,而且很容易实现。