1

This is a question about setting proper tolerance ("abstol") for convergence of eigenvalue calculation with LAPACKE_zheevx() function in C++.

When LAPACKE_zheev() fails to converge when calculating eigenvalues/eigenvectors with the default value of "abstol" (i.e. abstol=-1), the LAPACK manual says to set abstol=2*DLAMCH('S'). However, DLAMCH is Fortran function and I use C++ which does not recognize it as a valid C++ function. Could anyone please help me how to properly set "abstol=2*DLAMCH('S')" when using LAPACK with C++ (i.e. when using LAPACKE)?

Thanks very much in advance!!

Background: LAPACKE is C++ interface for LAPACK (Fortran library for numerical algebra). LAPACKE_zheevx() is LAPACKE's C++ interface for LAPACK's ZHEEVX() function.

Keywords: LAPACK, LAPACKE, C++, ABSTOL, DLAMCH, CONVERGENCE, EIGENVALUES, EIGENVECTORS

4

2 回答 2

2

我对这些库一无所知,但谷歌搜索了一下发现有一个相应的LAPACKE_dlamch()功能:

double LAPACKE_dlamch(char cmach)

因此,您应该能够LAPACKE_dlamch('S')作为abstol(12th) 参数传递LAPACKE_zheevx()

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
)
于 2016-08-17T20:52:59.303 回答
2

除了乔恩·珀迪(Jon Purdy)的回答(这实际上是要走的路):

dlamch.fFortran 中的定义。通过该函数,并从此处获取 Lapack 固有函数,可以看到对于输入'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需要这个步骤。

于 2016-08-17T21:09:30.570 回答