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
步骤。
这是一个关于在 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
步骤。