如何用Java实现这个EigenVector Python代码

问题描述 投票:0回答:1

我找到了算法的正确结果。我可以用 Java 实现这段代码吗?

import numpy as np
from scipy.linalg import eig 
transition_mat = np.matrix([
    [0.8,  0.15,0.05 ],\
    [0.075,0.85,0.075],\
    [0.05, 0.15,0.8  ]])

S, U = eig(transition_mat.T)
stationary = np.array(U[:np.where(np.abs(S - 1.) < 1e-8)[0][0]].flat)
print stationary
print np.sum(stationary)
stationary = stationary / np.sum(stationary)

print stationary

我用Java实现了这段代码,但结果是错误的

Matrix A = new Matrix(transition);
        A = A.transpose();
        Matrix x = new Matrix(N, 1, 1.0 / N); // initial guess for eigenvector
        for (int i = 0; i < 50; i++) {
            x = A.times(x);
            x = x.times(1.0 / x.norm1());       // rescale
        }
        
        // compute by finding eigenvector corresponding to eigenvalue = 1
        EigenvalueDecomposition eig = new EigenvalueDecomposition(A);
        Matrix V = eig.getV();
        double[] real = eig.getRealEigenvalues();
        for (int i = 0; i < N; i++) {
            if (Math.abs(real[i] - 1.0) < 1E-8) {
                x = V.getMatrix(0, N-1, i, i);
                x = x.times(1.0 / x.norm1());
                System.out.println("Stationary distribution using eigenvector:");
                x.print(9, 6);
            }
        }
java eigenvalue markov-chains
1个回答
0
投票

快速浏览一下代码似乎是正确的,前提是

  1. 你的矩阵
    transition
    与Python示例中的相同。从你的结果我假设
  2. 方法
    Matrix.times
    进行向量乘法而不是逐项乘法
  3. 对于这个例子来说,50 次迭代应该足够了。如果你的第二个特征值也接近 1,这个数字将会大得多
  4. 函数
  5. EigenvalueDecomposition.getV
     以您期望的方向(行/列)返回特征向量 
请注意,有效的

转移矩阵(跳跃概率矩阵)的行或列总和为 1(定义问题),因为停留或切换的机会必须为 100%。这意味着特征向量为 1 的存在。根据您对矩阵初始转置的使用,我假设您需要行总和为一。

由于您的特征值似乎不为 1,因此最符合逻辑的错误是矩阵中的拼写错误。

© www.soinside.com 2019 - 2024. All rights reserved.