LAPACKE_zheevx() 无法收敛——如何在 C++ 中使用 2*DLAMCH('S') 增加 ABSTOL?

LAPACKE_zheevx() failed to converge -- how to increase ABSTOL with 2*DLAMCH('S') in C++?

这是一个关于在 C++ 中使用 LAPACKE_zheevx() 函数设置适当容差 ("abstol") 以收敛特征值计算的问题。

当LAPACKE_zheev()在使用默认值"abstol"(即abstol=-1)计算eigenvalues/eigenvectors时无法收敛时,LAPACK手册说设置abstol=2 *DLAMCH('S')。但是,DLAMCH 是 Fortran 函数,我使用的 C++ 无法将其识别为有效的 C++ 函数。谁能帮我在使用 C++ 的 LAPACK 时(即使用 LAPACKE 时)如何正确设置 "abstol=2*DLAMCH('S')"?

非常感谢!!

背景: LAPACKE 是 LAPACK(用于数值代数的 Fortran 库)的 C++ 接口。 LAPACKE_zheevx() 是 LAPACKE 的 ZHEEVX() 函数的 C++ 接口。

关键词: LAPACK、LAPACKE、C++、ABSTOL、DLAMCH、收敛、特征值、特征向量

我对这些库一无所知,但谷歌搜索显示有相应的 LAPACKE_dlamch() 函数:

double LAPACKE_dlamch(char cmach)

因此您应该能够将 LAPACKE_dlamch('S') 作为 LAPACKE_zheevx()abstol(第 12 个)参数传递:

lapack_int LAPACKE_zheevx (
    int matrix_layout,
    char jobz,
    char range,
    char uplo,
    lapack_int n,
    lapack_complex_double *a,
    lapack_int lda,
    double vl,
    double vu,
    lapack_int il,
    lapack_int iu,
    double abstol,
//  ^^^^^^^^^^^^^
    lapack_int *m,
    double *w,
    lapack_complex_double *z,
    lapack_int ldz,
    lapack_int *ifail
)

除了 Jon Purdy 的回答(这实际上是要走的路):

Here is the definition of dlamch.f in Fortran. Going through that function, and getting the Lapack-intrinsic functions from here,可以看到对于输入 's',转换为 C++ 的函数变为:

auto dlamch_s()
{
    auto one = 1.0;
    auto rnd = one;
    auto eps = (one == rnd ? 0.5 : 1.0) * std::numeric_limits<double>::epsilon();
    auto sfmin = std::numeric_limits<double>::min();
    auto small = one / std::numeric_limits<double>::max();
    if(small>=sfmin)
    {
        sfmin = small*(one + eps);
    }
    return sfmin;
}

但是,不要问我为什么需要 one == rnd 步骤。