MATLAB/C++ 中的 Lanczos 求解器实现给出了不同的结果

计算科学 线性代数 软件 本征系统
2021-11-27 22:28:27

在英特尔 MKL 和 MTL4 库的帮助下,我已将用于对称特征值求解器的 MATLAB Lanczos 求解器转移到 C++ 中。我有一些 MKL 例程的包装模板。然而,在迭代过程中,我的 C++ 实现的结果开始偏离 MATLAB 找到的值。在迭代中的某个时间点,差异似乎很小,但在大约 9-10 次迭代后,结果开始出现偏差。

我怀疑这是由于我在 Lanczos 求解器中使用的完全重新正交化。奇怪的是,我在 MATLAB 中使用了简单的 Gram-Schmidt 正交化,但是在 C++ 中使用相同的操作会导致我的问题的 \alpha 和 \beta 系数不同。据我所知,MATLAB 使用双精度,而在 C++ 中,我默认也使用双精度。英特尔 MKL 也使用双精度。然而,中间计算中引入的舍入误差似乎严重影响了 C++ 代码的性能,至少这是我的猜测,除了正交化。有什么想法可以解决这个奇怪的问题吗?

2个回答

我相信这与您最近在此处向 MUMPS 列表提出的问题相同,因此我假设您引用的 C++ 代码是 MUMPS 的包装器。

老实说,只要您使用相同的浮点标准和相同的算法,您计算的语言是无关紧要的。我也不清楚您的最终答案是否发生了重大变化;如果您担心三对角矩阵的变化,请确保您的两个实现之间的每个算法细节都是相同的。

在比较 SciPy/NumPy 和 MATLAB 之间的结果时,我遇到了类似的问题。(我使用 SciPy/NumPy 的结果作为单元测试中的参考结果。)MATLAB 使用自己的 LAPACK 和 BLAS 版本。为了获得逐位协议,您必须使用与 MATLAB 相同的库,特别是因为算法可能会在 LAPACK 的版本之间略有变化(错误修复、排序约定的更改)。

我怀疑这是您面临的确切问题(我的用例是 QR 分解),但它应该解释您看到的细微差异,并且可能不是这些差异的放大,除非您使用完全相同的两种实现中的算法,并且该算法在数值上是稳定的。