mathematica如何快速准确地进行局部对角化
mathematica吧
全部回复
仅看楼主
level 4
轰天雷sss 楼主
如何计算一个较大的非厄米矩阵(1000*1000以上)的某个本征值附近的20个本征值,计算结果要准确,尽可能快,在小时的量级还能接受。目前我问了AI,采用的精度和算法是
precision = 100;
mat = N[Rationalize[H, 0], precision];
{vals, vecs} =
Eigensystem[mat, 20,
Method -> {"Arnoldi", "Shift" -> E0, "MaxIterations" -> 5000}];
valsSorted = SortBy[vals, Abs[# - E0] &];
这样计算很快,但却很不准,找到的本征值接近的我要的E0在10^-15量级,而且显示有很多其他点,实际上我全部对角化:
Eigensystem[mat, Method -> {"Direct"}],计算出来的结果在这个精度下是准确的,真实的最接近E0的本征值距离有10^-2量级,也就是说上面局部对角化算出来有很大的数值问题。但矩阵太大全部对角化就算得非常慢,可能要一天以上,而且我只关心E0附近的几个本征值,所以希望有一个准确的局部对角化算法,时间成本也没那么大,非常感谢
2026年07月02日 09点07分 1
吧务
level 15
特征值问题我的经验比较有限,此外你这代码不完整所以我也没法试。我能说的只有:Direct方法比Arnoldi方法更准这个现象确实是存在的,参看SE帖子《NDEigensystem for structural vibration》(编号125713)下面user21的回答;Arnoldi可用的子选项还有几个,参看Eigensystem文档的Method一节,你适当排列组合一下可能会有效。
2026年07月02日 11点07分 2
看了一下这个帖子,原来Direct计算更准时间更长,学习到了[真棒],但局部对角化似乎只能用Arnoldi方法,我也把子选项都试了一遍,没什么效果,算出来还都是及其靠近E0的假值。我用matlab的这个算法去算,就是正确的(用了高精度包,但子空间数量opts.p也必须增大才行),在mathematica里难道没有对应的算法吗[泪],我后面也把完整代码发出来,各位有兴趣可以测试一下 Hmp=mp(H); Nev=20; sigma=E0; opts.tol=mp('1e-40'); opts.maxit=1000; opts.p=max(20*Nev,100); opts.disp=2; [V,D]=eigs(Hmp,Nev,sigma,opts);
2026年07月02日 12点07分
@轰天雷sss 如果MATLAB相同算法能算的话,就有必要考虑bug的可能性了。Arnoldi方法有被发现bug的“前科”,参se帖子《Complex eigenvalues from a sparse Hermitian matrix》(编号186224)——当然了,这是否是同一问题我也说不好。这个建议向官方客服反应一下。
2026年07月02日 12点07分
1