Python Numpy:将可对角化方阵提升到无穷次方

Python Numpy:将可对角化方阵提升到无穷次方,python,numpy,matrix,eigenvalue,markov-models,Python,Numpy,Matrix,Eigenvalue,Markov Models,考虑具有可对角化转移矩阵a的马尔可夫过程,其中a=PDP^-1,其中D是特征值为a的对角矩阵,p是列为a的特征向量的矩阵 为了计算,对于每个状态,在每个吸收状态结束的可能性,我想把转移矩阵提高到n的幂,n接近无穷大: A^n=PD^nP^-1 在努比,哪一种是蟒蛇式的方式?我可以天真地计算A的特征值和特征向量,将特征值提升到无穷大。由于我假设我有一个转移矩阵,我们只有等于1的特征值(保持为1),以及介于0和1之间的特征值,这些特征值将变为零(受以下启发): 将numpy导入为np 来自scipy

考虑具有可对角化转移矩阵a的马尔可夫过程,其中a=PDP^-1,其中D是特征值为a的对角矩阵,p是列为a的特征向量的矩阵

为了计算,对于每个状态,在每个吸收状态结束的可能性,我想把转移矩阵提高到n的幂,n接近无穷大:

A^n=PD^nP^-1

在努比,哪一种是蟒蛇式的方式?我可以天真地计算A的特征值和特征向量,将特征值提升到无穷大。由于我假设我有一个转移矩阵,我们只有等于1的特征值(保持为1),以及介于0和1之间的特征值,这些特征值将变为零(受以下启发):

将numpy导入为np
来自scipy进口公司
#计算左特征值和左特征向量
特征值,左特征向量=linalg.eig(传递矩阵,右=假,左=真)
#对于平稳分布,特征值和向量是实的(达到数值精度)
特征值=特征值.real
leftEigenvectors=leftEigenvectors.real
#创建一个过滤器以收集接近1的特征值
绝对公差=1e-10
掩码=abs(特征值-1)<绝对公差
#将特征值提升到无穷大的幂次方
特征值[掩码]=1
特征值[~mask]=0
D_=np.诊断(特征值)
A_凸起=左特征向量@D_凸起@linalg.inv(左特征向量)

这是推荐的方法吗?即,一种在数值上既稳定又有效的方法?

有效的幂运算(矩阵或其他什么)是一种非常常见的方法,可以在对数时间内完成。我想你可能会问,或者代替我们。这实际上不是一个实现问题。虽然我对张量理论的了解有限,但这似乎是合理的。我唯一要做的改变是
mask=np.isclose(特征值1,atol=1e-10)
,甚至
exhactary=np.isclose(特征值1,atol=1e-10)。aType(int)
@DanielF也加入到混合中。这取决于矩阵的大小。如果可以进行分解,则只使用占主导地位的左特征向量,并将外积取为1的恒定向量(此处检查行-列方向),即矩阵具有相同的行或列。另外,如果使用right=true,则可以得到左矩阵的逆矩阵,而且它应该更快、更稳定。注意,如果多个EV为1,则平稳分布不是唯一的。如果矩阵非常大,则使用幂法获得特征值为1的一个EV的任意良好近似值。
import numpy as np
from scipy import linalg    

# compute left eigenvalues and left eigenvectors
eigenvalues, leftEigenvectors = linalg.eig(transitionMatrix, right=False, left=True)

# for stationary distribution, eigenvalues and vectors are real (up to numerical precision)
eigenvalues = eigenvalues.real
leftEigenvectors = leftEigenvectors.real

# create a filter to collect the eigenvalues close to one
absoluteTolerance = 1e-10
mask = abs(eigenvalues - 1) < absoluteTolerance

# raise eigenvalues to the power of infinity
eigenvalues[mask] = 1
eigenvalues[~mask] = 0

D_raised = np.diag(eigenvalues)

A_raised = leftEigenvectors @ D_raised @ linalg.inv(leftEigenvectors)