【问题标题】:How to find an eigenvector given eigenvalue 1, minimising memory use如何找到给定特征值 1 的特征向量,最小化内存使用
【发布时间】:2014-04-09 14:17:11
【问题描述】:

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

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

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

我当前的代码是

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

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

n = size(P,1);       % number of states
Q = P - speye(n,n);
x = Q\zeros(n,1);    % solve (P-I)x = 0

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

如果有人对我应该如何处理这个问题有任何想法,我将不胜感激,因为这是一个我必须执行很多次的计算,如果可能的话,我想在更大、更复杂的模型上进行尝试.

作为这个问题的背景,我正在求解随机 SIR 模型中牛群中感染者数量的平衡分布。不幸的是,即使是中等规模的牛群,转换矩阵也非常大。例如:在一个平均有 20 个人的 SIR 模型中(95% 的时间人口在 12 到 28 个人之间),P 是 21169 乘以 21169,有 20340 个非零值(即 0.0005% 密集),以及使用了 321 Kb(该大小的完整矩阵将是 3.3 Gb),而对于大约 50 个人P 使用 3 Mb。 x 本身应该很小。我怀疑eigs() 在某处有一个密集矩阵,这导致我内存不足,所以如果我可以避免使用完整矩阵,我应该没问题。

【问题讨论】:

    标签: memory optimization octave eigenvector


    【解决方案1】:

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

    这里的收敛速度与最大特征值和第二大特征值之间的距离成正比。每次迭代只需要几个矩阵乘法。

    有一些更高级的方法可以做到这一点(“PageRank”是在这里搜索的一件好事)可以提高非常大的稀疏矩阵的速度,但我不知道它们在这里是否必要或有用。

    【讨论】:

    • 谢谢,我现在正在尝试(忽略我之前的评论,我意识到即使我已经得到了特征值,它仍然很有用,因为我很确定最大的特征值已经是 1)。现在我开始我的初始xones(n,1)/n(其中P 是n 乘n),并反复乘以P,所以内存需求不会膨胀(如果我尝试@987654329 他们会膨胀@ 到某种程度,因为非零元素的数量迅速增加)。如果它比以前效果更好,我会报告。
    • 当然,对于小情况,最大的几个特征值是 1、.9927、.9818、.9676,...所以收敛可能需要一段时间。
    • 最大特征值必须为 1(除数值误差外),否则平衡分布将爆炸到无穷大或消失为零。见本文“收敛速度”部分:en.wikipedia.org/wiki/Markov_chain
    • 你的方法是对的。 0.007 的差距足够大,足以在几千次迭代中合理收敛——即在现代硬件上有一两秒钟。如果差距变得太小(比如1e-6 或更糟),功率迭代将变得异常缓慢。当然,寻找主导特征向量变得越来越病态,我不知道你为什么会太在意答案。
    • @tmyklebu:另一个问题,你让'x_{n+1} = P^T P x_{n}'。你能说说你为什么使用转置吗?经过测试,它确实提高了收敛速度,但导致了不同的最终结果。
    【解决方案2】:

    您的方法似乎不错。但是,您所称的 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

    【讨论】:

    • 谢谢,我会看看那些。现在我正在尝试另一个建议,但这对于长期解决方案可能会更好(并且可以为我的线性代数技能提供有用的除尘!)。
    【解决方案3】:

    按照 tmyklebu 的建议,似乎最好的解决方案是使用 Power Iteration 方法

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

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

    【讨论】:

      猜你喜欢
      • 2013-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-07-29
      • 1970-01-01
      相关资源
      最近更新 更多