财富算法特征求解

Fortune algorithm eigensolve

提问人:Ragon 提问时间:8/14/2023 更新时间:8/15/2023 访问量:57

问:

是否存在财富特征求解算法的实现?

目前,我正在尝试将其移植到 python,但到目前为止它没有提供正确的结果。 我唯一找到的是他在这里描述算法的论文,我不明白我的算法哪里出了问题。

import numpy as np
from sympy import Poly, symbols
lamda = symbols('lamda')

#Creates generalized companion matrix
def gen_companion(p,S):
    #create lagrange coeffs
    L_i = []
    for i in range(len(S)):
        den_s = 1
        for j in range(len(S)):
            if (not (i == j)):
                den_s *= p(S[i]-S[j])
        p_s = p(S[i])/den_s
        L_i.append(p_s)
    #create lagrange matrix L 
    dim = S.shape[0]
    L = np.zeros((dim,dim),np.complex64)
    for i in range(dim):
        for j in range(dim):
            L[j,i] = np.abs(L_i[i])
    B = np.zeros((dim,dim),np.complex64)
    #Create Matrix S
    for i in range(dim):
        B[i,i] = S[i]
    return B-L
    


def eigensolve(p,n_iterations):
    A = np.polynomial.polynomial.polycompanion(coeffs).astype(np.complex64)
    S = qr_algorithm(A,n_iterations)
    for _ in range(n_iterations):
        L = gen_companion(p,S)
        S = qr_algorithm(L,n_iterations)
    return S[0]


def qr_algorithm(A,n_iterations):
    for _ in range(n_iterations):
        Q,R = np.linalg.qr(A)
        A = R @ Q
    return np.array([A[i,i] for i in range(A.shape[0])])

p = Poly((lamda - 10)*(lamda-20)*(lamda-4)*(lamda-5),lamda)
coeffs = np.array(list(reversed(p.all_coeffs())))


n_iterations = 10
v = eigensolve(p,n_iterations)
print("")

我只得到了我在算法的第二部分输入的相同特征值:

(20.153511+0j)
(20.153511+0j)
(20.153511+0j)
(20.153511+0j)
(20.153511+0j)
Python 数学 线性代数 特征值

评论

0赞 Lutz Lehmann 8/14/2023
您能再描述一下这种方法吗?预期的算法和代码之间似乎存在差异。该算法似乎从多项式和近似根集开始,就像在 Durand-Kerner 中一样,无论近似有多糟糕。预期的输出似乎是改进的根集近似值。我猜,算法本身旨在计算拉格朗日多项式基础上算子的伴随矩阵。在此基础上应用了原始的 QR 算法(Francis QR 已经带有移位和通货紧缩)。V to (XV(X) mod P(X))

答:

2赞 Lutz Lehmann 8/14/2023 #1

论文中的公式是

    l[i] = P(s[i]) / Q_S'(s[i])  =  P(s[i]) / prod( (s[i]-s[j]) for i!=j)

这可以实现为

Q = np.poly(S)
dQ = np.polyder(Q)
l = np.polyval(P,S)/np.polyval(dQ,S)

请注意,论文中的垂直线是错误的,或者至少不应该表示绝对值。

正如我在评论中指出的那样,QR 算法的这种变体是 pre-alpha 版本。即使是弗朗西斯推荐的第一个变体,也使用移位来加速最小特征值的收敛,从而加速矩阵的分裂,缩减到与最小特征空间正交的子空间。

如果人们不太关心计算时间,则可以只使用这个原始变体。它将收敛为允许读取特征值的正常形式。这种正态形式将具有按绝对值降序排列的特征值。特别是在寻根器的后期阶段,伴随矩阵已经接近对角线。如果对角线条目的顺序不正确,QR 算法将使用小旋转来交换它们,从而进行大量旋转。这种开销对根/特征值的精度没有贡献,因此应避免。您的实现会自动执行。

我想将您的注意力引向函数和具有常量元素的列表。然后,伴随矩阵可以构造为np.diag

np.diag(S) - np.array(len(S)*[l])

进行这些更改并始终返回完整结果,作为预期值的返回值eigensolve

[20.      +0.j 10.000002+0.j  5.000003+0.j  4.000001+0.j]

评论

0赞 Ragon 8/15/2023
你好卢茨。您能解释一下第二行代码块中QS的含义吗?另外,我不理解您在第一个代码块中描述的 100% 不完全是我实现的吗?
1赞 Lutz Lehmann 8/15/2023
Q_S,我第一次到处都有QS,但在上下文中感觉太长了......
1赞 Lutz Lehmann 8/15/2023
我不确定哪个更好,产品版本或衍生版本在 Weierstrass 更新的分母中。使用类似FFT的方案进行多点评估时,导数版本更快,但可能不太精确。在任何情况下,产品评估都会与衍生品评估存在不同的误差。由于多项式根对扰动的敏感性,这可能会产生明显的影响。