scipy.sparse.linalg.eigsh返回同一矩阵的不同特征值

vi4fp9gy  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(183)

问题摘要

我想计算最小的特征值(代数值)。该矩阵来自我使用pyNastran库读取的op 4文件。在these instructions之后,我尝试使用scipy.sparse.linalg.eigsh函数和移位-反转模式来计算最小特征值。为了检查计算是否正确,我将eigsh的结果与numpy.linalg.eigvals的结果进行了比较,我观察到的结果令人费解:如果我简单地将eigsh应用于矩阵,计算出的特征值是错误的,如果我将矩阵保存到csv文件,然后将其加载回numpy数组,特征值是正确的。更令人困惑的是,当我比较两个矩阵时,numpy.array_equal返回Trueeigsh怎么可能对同一个矩阵返回两个不同的结果?

代码

from pyNastran.op4.op4 import read_op4
from scipy.sparse.linalg import eigsh
import numpy as np
op4 = read_op4('kllrh.op4')
matrix_name = 'KLLRH'
kllrh_matrix = op4[matrix_name][1][-1]
reference_max_eigenvalue = np.max(np.linalg.eigvals(kllrh_matrix))
reference_min_eigenvalue = np.min(np.linalg.eigvals(kllrh_matrix))
eigsh_min_eigenvalue = eigsh(kllrh_matrix, 1, sigma=0, which='LM', return_eigenvectors=False)
np.savetxt('kllrh.csv', kllrh_matrix, delimiter=',')
kllrh_matrix_reloaded = np.loadtxt('kllrh.csv', delimiter=",")
reloaded_eigsh_min_eigenvalue = eigsh(kllrh_matrix_reloaded, 1, sigma=0, which='LM', return_eigenvectors=False)
print(reference_min_eigenvalue)
print(eigsh_min_eigenvalue)
print(reloaded_eigsh_min_eigenvalue)
print(np.array_equal(kllrh_matrix, kllrh_matrix_reloaded))
print(type(kllrh_matrix))
print(type(kllrh_matrix_reloaded))
print(reference_max_eigenvalue)

这将返回以下内容:

-0.0028387385
[0.05363945]
[-0.00283876]
True
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
6502976000.0

请找到kllrh.op4文件here

xbp102n0

xbp102n01#

虽然np.array_equal表示kllrh_matrixkllrh_matrix_reloaded相等,但它们属于不同的dtypefloat32float64)。
如果你这样做

kllrh_matrix = op4[matrix_name][1][-1].astype('float64')

一切都是正确:

-0.0028387384680708
[-0.00283876]
[-0.00283876]
True
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
6502976138.583383

作为一种更好的替代方法,您可以在阅读op4文件时指定precision

op4 = read_op4('kllrh.op4', precision='double')

这会给予你一些其他的结果:

0.004395871268066287
[0.00439589]
[0.00439589]
True
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
6502976180.582107

默认精度来自op4文件:在该示例中,矩阵类型是1(文件第一行上的第四个数字),其产生单精度(float32)。

相关问题