Algorithm 计算吸收马尔可夫链基本矩阵的最佳迭代方法?

Algorithm 计算吸收马尔可夫链基本矩阵的最佳迭代方法?,algorithm,math,sparse-matrix,markov-chains,Algorithm,Math,Sparse Matrix,Markov Chains,我有一个非常大的吸收马尔可夫链。我想得到这个链的基本矩阵来计算。从这里我知道这可以用这个方程来计算 (I-Q)t=1 可通过使用以下python代码获得: def expected_steps_fast(Q): I = numpy.identity(Q.shape[0]) o = numpy.ones(Q.shape[0]) numpy.linalg.solve(I-Q, o) 但是,我想使用某种迭代方法来计算它,类似于用于计算结果的幂迭代法。此方法允许我计算类似map

我有一个非常大的吸收马尔可夫链。我想得到这个链的基本矩阵来计算。从这里我知道这可以用这个方程来计算

(I-Q)t=1

可通过使用以下python代码获得:

def expected_steps_fast(Q):
    I = numpy.identity(Q.shape[0])
    o = numpy.ones(Q.shape[0])
    numpy.linalg.solve(I-Q, o)
但是,我想使用某种迭代方法来计算它,类似于用于计算结果的幂迭代法。此方法允许我计算类似mapreduce系统中吸收前的预期步数近似值


是否存在类似的情况?

如果有稀疏矩阵,请检查是否有效。没有关于数值稳健性的保证,但至少对于琐碎的例子,它比用密集矩阵求解要快得多

import networkx as nx
import numpy as np
import scipy.sparse as sp
import scipy.sparse.linalg as spla

def example(n):
    """Generate a very simple transition matrix from a directed graph
    """
    g = nx.DiGraph()
    for i in xrange(n-1):
        g.add_edge(i+1, i)
        g.add_edge(i, i+1)
    g.add_edge(n-1, n)
    g.add_edge(n, n)
    m = nx.to_numpy_matrix(g)
    # normalize rows to ensure m is a valid right stochastic matrix
    m = m / np.sum(m, axis=1)
    return m

A = sp.csr_matrix(example(2000)[:-1,:-1])
Ad = np.array(A.todense())

def sp_solve(Q):
    I = sp.identity(Q.shape[0], format='csr')
    o = np.ones(Q.shape[0])
    return spla.spsolve(I-Q, o)

def dense_solve(Q):
    I = numpy.identity(Q.shape[0])
    o = numpy.ones(Q.shape[0])
    return numpy.linalg.solve(I-Q, o)
稀疏解决方案的计时:

%timeit sparse_solve(A)
1000 loops, best of 3: 1.08 ms per loop
%timeit dense_solve(Ad)
1 loops, best of 3: 216 ms per loop
浓溶液的时间安排:

%timeit sparse_solve(A)
1000 loops, best of 3: 1.08 ms per loop
%timeit dense_solve(Ad)
1 loops, best of 3: 216 ms per loop

正如Tobias在评论中提到的那样,我本以为其他解算器的性能会优于通用解算器,而且它们可能适用于非常大的系统。对于这个玩具示例,通用的解决方案似乎足够有效。

多亏@tobias ribizel建议使用。如果我们从以下等式中分离:

使用Neumann系列:

如果我们将序列的每个项乘以向量1,我们可以对矩阵Q的每一行分别进行运算,并依次用以下公式进行近似:

这是我用来计算的python代码:

def expected_steps_iterative(Q, n=10):
    N = Q.shape[0]
    acc = np.ones(N)
    r_k_1 = np.ones(N)
    for k in range(1, n):
        r_k = np.zeros(N)
        for i in range(N):
            for j in range(N):
                r_k[i] += r_k_1[j] * Q[i, j]
        if np.allclose(acc, acc+r_k, rtol=1e-8):
            acc += r_k
            break
        acc += r_k
        r_k_1 = r_k
    return acc
这是使用Spark的代码。这段代码期望Q是一个RDD,其中每一行都是一个元组(row_id,dict为矩阵中该行的权重)


你看过像GMRES这样的线性方程组的迭代求解器吗?它们提供了一些错误估计来检查需要多少次迭代。Python提供了它们啊对不起,我误解了你的问题!你看过基本矩阵的基本原理了吗?可能只需要使用power SeriesHanks中有限数量的summands来近似求逆,以供您的评论@TobiasRibizel。我认为Neumann级数不是我要搜索的,因为它意味着要将矩阵乘以几次。但是,如果我正确理解GMRES算法,此解决方案可能会在每个组件的基础上并行化。感谢您的回答,Andrew,但是我正在寻找一种可以并行计算解决方案所有元素的方法。遵循Tobias提出的GMRES方法,我找到了其他迭代方法,如可以满足我需求的。