首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java和Python计算特征向量的差异

用Java和Python计算特征向量的差异
EN

Stack Overflow用户
提问于 2016-11-15 13:06:37
回答 2查看 1.5K关注 0票数 6

作为当前的任务,我需要计算120*120矩阵的特征值和特征向量。首先,我在Java (Apache库)和Python2.7 (Numpy库)的简单2×2矩阵上测试了这些计算。我有一个与特征向量不匹配的问题,如下所示:

代码语言:javascript
复制
//Java
import org.apache.commons.math3.linear.EigenDecomposition;
import org.apache.commons.math3.linear.MatrixUtils;
import org.apache.commons.math3.linear.RealMatrix;

public class TemporaryTest {

  public static void main(String[] args) {

    double[][] testArray = {{2, -1}, {1, 1}};
    RealMatrix testMatrix = MatrixUtils.createRealMatrix(testArray);
    EigenDecomposition decomposition = new EigenDecomposition (testMatrix);
    System.out.println("eigenvector[0] = " + decomposition.getEigenvector(0));
    System.out.println("eigenvector[1] = " + decomposition.getEigenvector(1));
}

特征向量的输出显示为{real_value + imaginary_value;real_value + imaginary_value}:

代码语言:javascript
复制
//Java output
eigenvector[0] = {-0.8660254038; 0}
eigenvector[1] = {0.5; 1}

Python中的代码相同,但使用Numpy库:

代码语言:javascript
复制
# Python
import numpy as np
from numpy import linalg as LA

w, v = LA.eig(np.array([[2, -1], [1, 1]]))
print (v[:, 0])
print (v[:, 1])

Python中特征向量的输出类似于real+imag real+imag

代码语言:javascript
复制
[ 0.35355339+0.61237244j  0.70710678+0.j        ]
[ 0.35355339-0.61237244j  0.70710678-0.j        ]

我关心的是,为什么这些向量是不同的?我遗漏了什么吗?寻求任何帮助或建议

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-17 20:47:08

在Apache 3中,EigenDecomposition接受非对称矩阵,但它使用类RealVectorRealMatrix返回结果。要得到实际的复结果,必须将适当的实结果组合成复共轭对。

在特征向量的情况下,你可以得到:

代码语言:javascript
复制
eigenvector[0] = {-0.8660254038; 0}
eigenvector[1] = {0.5; 1}

这两个向量都与特征值getRealEigenvalue(0) + getImagEigenvalue(0)*igetRealEigenvalue(1) + getImagEigenvalue(1)*i的复共轭对相关联,但这些向量并不是实际的特征向量。实际的特征向量是复共轭对eigenvector[0] + eigenvector[1]*ieigenvector[0] - eigenvector[1]*i

这些向量仍然不匹配numpy返回的结果,但这是因为这两个库没有使用相同的规范化。特征向量不是唯一的,特征向量乘以任何非零标量(包括复标量)仍然是特征向量。Java结果和numpy结果之间唯一的区别是标量乘数。

为了方便起见,我将把浮点值转换成它们的确切值。也就是说,-0.8660254038-sqrt(3)/2的浮点逼近。Java数学库提供了以下特征向量:

代码语言:javascript
复制
 [-sqrt(3)/2 + (1/2)*i]    and    [-sqrt(3)/2 - (1/2)*i]
 [      0    +     1*i]           [      0    -     1*i]

如果你把第一个特征向量乘以- (sqrt(2)/2)*i,第二个特征向量乘以(sqrt(2)/2)*i,你就会得到由numpy返回的特征向量。

这里有一个ipython会话,其中包含了这个计算。v1v2是上面所示的向量。

代码语言:javascript
复制
In [20]: v1 = np.array([-np.sqrt(3)/2 + 0.5j, 1j])

In [21]: v1
Out[21]: array([-0.8660254+0.5j,  0.0000000+1.j ])

In [22]: v2 = np.array([-np.sqrt(3)/2 - 0.5j, -1j])

In [23]: v2
Out[23]: array([-0.8660254-0.5j,  0.0000000-1.j ])

v1乘以-(sqrt(2)/2)*i,得到numpy.linalg.eig返回的第一个特征向量

代码语言:javascript
复制
In [24]: v1*(-np.sqrt(2)/2*1j)
Out[24]: array([ 0.35355339+0.61237244j,  0.70710678-0.j        ])

v2乘以(sqrt(2)/2)*i,得到numpy.linalg.eig返回的第二个特征向量

代码语言:javascript
复制
In [25]: v2*(np.sqrt(2)/2*1j)
Out[25]: array([ 0.35355339-0.61237244j,  0.70710678+0.j        ])

为了方便起见,这里重复了numpy计算。evecs的列是特征向量。

代码语言:javascript
复制
In [28]: evals, evecs = np.linalg.eig(a)

In [29]: evecs
Out[29]: 
array([[ 0.35355339+0.61237244j,  0.35355339-0.61237244j],
       [ 0.70710678+0.j        ,  0.70710678-0.j        ]])
票数 2
EN

Stack Overflow用户

发布于 2016-11-17 19:28:41

我不认为你能成功。原因如下:

从2.0开始,这个类只支持对称矩阵,因此只计算真实的realEigenvalues。这意味着getD()返回的D矩阵总是对角的,返回的虚值getImagEigenvalue(int)和getImagEigenvalues()总是空的。(c) EigenDecomposition JavaDoc

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40610582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档