Memory 如何找到给定特征值1的特征向量,最大限度地减少内存使用

Memory 如何找到给定特征值1的特征向量,最大限度地减少内存使用,memory,optimization,octave,eigenvector,Memory,Optimization,Octave,Eigenvector,如果人们能帮助我找到一种有效的方法(可能是低内存算法)来解决以下问题,我将不胜感激 我需要找到转移矩阵p的平稳分布x。转移矩阵是一个非常大、非常稀疏的矩阵,其构造使得所有列的总和为1。由于平稳分布由方程Px=x给出,因此x只是与特征值1相关的P的特征向量 我目前正在使用GNU倍频程来生成转换矩阵,找到平稳分布,并绘制结果。我正在使用函数eigs(),它同时计算特征值和特征向量,并且可以只返回一个特征向量,其中特征值为1(实际上我必须指定1.1,以防止出现错误)。转换矩阵的构造(使用稀疏矩阵)相当

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

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

我目前正在使用GNU倍频程来生成转换矩阵,找到平稳分布,并绘制结果。我正在使用函数
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%),并使用321KB(该大小的完整矩阵为3.3GB),而对于大约50个个体
P
则使用3MB
x
本身应该非常小。我怀疑
eigs()
的某个地方有一个密集的矩阵,这会导致我的内存不足,所以如果我可以避免使用完整的矩阵,我应该没问题。

幂迭代是找到矩阵主特征值的标准方法。你选择一个随机向量
v
,然后用
P
反复点击它,直到你不再看到它有很大的变化。您希望定期将v除以
sqrt(v^tv)
以使其正常化

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


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

幂迭代是找到矩阵主特征值的标准方法。你选择一个随机向量
v
,然后用
P
反复点击它,直到你不再看到它有很大的变化。您希望定期将v除以
sqrt(v^tv)
以使其正常化

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


有一些更为奇特的方法(“PageRank”是这里搜索的一个好方法)可以提高巨大稀疏矩阵的速度,但我不知道它们在这里是必要的还是有用的。

您的方法似乎不错。但是,您所调用的
x
,是Q的null空间。如果null(Q)支持稀疏矩阵,则它可以工作,但它不支持。网络上有很多东西可以用来寻找稀疏矩阵的零空间。例如:


你的方法似乎不错。但是,您所调用的
x
,是Q的null空间。如果null(Q)支持稀疏矩阵,则它可以工作,但它不支持。网络上有很多东西可以用来寻找稀疏矩阵的零空间。例如:


似乎最好的解决方案是使用tmyklebu建议的幂迭代法

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


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

似乎最好的解决方案是使用tmyklebu建议的幂迭代法

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


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

谢谢,我现在正在尝试(忽略我之前的评论,我意识到即使我已经阅读过,它仍然可能有用)