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

时间:2016-08-17 19:05:38

标签: c++ lapack lapacke

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

当LAPACKE_zheev()在计算默认值为“abstol”(即abstol = -1)的特征值/特征向量时无法收敛,LAPACK手册说要设置abstol = 2 * DLAMCH('S')。但是,DLAMCH是Fortran函数,我使用C ++,它不能将它识别为有效的C ++函数。在使用LAPACK和C ++(即使用LAPACKE时)时,有谁可以帮助我如何正确设置“abstol = 2 * DLAMCH('S')”?

非常感谢!!

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

关键词: LAPACK,LAPACKE,C ++,ABSTOL,DLAMCH,CONVERGENCE,EIGENVALUES,EIGENVECTORS

2 个答案:

答案 0 :(得分:2)

我对这些库一无所知,但谷歌的一点点显示有相应的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
)

答案 1 :(得分:2)

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

Here是Fortran中dlamch.f的定义。通过该函数,并从here获取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步骤。