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

发布于 2025-01-27 20:33:16 字数 1832 浏览 1 评论 0原文

问题摘要

我想计算矩阵的最小特征值(代数值)。矩阵来自我使用 pynastran 库的OP4文件。以下这些指令,我正在尝试使用最小的eigevanlue计算最小scipy.sparse.linalg.eigsh具有换挡模式的功能。为了检查计算是否正确,我将eigsh的结果与numpy.linalg.eigvals的结果进行了比较。我观察到的很令人困惑:如果我简单地将eigsh应用于矩阵,则计算出的特征值是错误的,如果我将矩阵保存到CSV文件,然后将其加载到numpy中数组特征值正确。更令人困惑的是,当我比较两个矩阵时,numpy.Array_equal返回trueeigsh如何返回同一矩阵的两个不同结果?

Code

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)

This returns the following:

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

Please find the kllrh.op4 file

Problem summary

I want to calculate the smallest eigenvalue (algebraic value) of a matrix. The matrix comes from an op4 file that I read using the pyNastran library. Following these instructions, I am trying to calculate the smallest eigevanlue using the scipy.sparse.linalg.eigsh function with shift-invert mode. In order to check that the computation is correct, I compare the result of eigsh with the result of numpy.linalg.eigvals. What I observe is quite puzzling: if I simply apply eigsh to the matrix, the calculated eigenvalue is wrong, if I save the matrix to a csv file and then I load it back into a numpy array the eigenvalue is correct. What is even more baffling is that numpy.array_equal returns True when I compare the two matrices. How is it possible that eigsh returns two different results for the same matrix?

Code

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)

This returns the following:

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

Please find the kllrh.op4 file here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

好菇凉咱不稀罕他 2025-02-03 20:33:16

虽然np.array_equalkllrh_matrixkllrh_matrix_reloaded是相等的,它们具有不同的dtype s(s(> ) float32 vs float64)。

如果您执行

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)。

Although np.array_equal says that kllrh_matrix and kllrh_matrix_reloaded are equal, they are of different dtypes (float32 vs float64).

If you do

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

everything is correct:

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

As a better alternative, you can specify the precision when reading the op4 file:

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

which will give you slightly other results:

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

The default precision comes from the op4 file: in the example the matrix type is 1 (fourth number on first line of the file) which results in single precision (float32).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文