1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITERATIVESOLVER_HELPER_DISPATCH_H_
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITERATIVESOLVER_HELPER_DISPATCH_H_
21#include <molpro/lapacke.h>
22#include <molpro/linalg/itsolv/helper.h>
36extern "C" int dsyev_c(
char,
char,
int,
double*,
int,
double*);
50#if defined(HAVE_LAPACKE) || defined(MOLPRO)
56struct has_lapack_kernel<
float> : std::true_type {};
58struct has_lapack_kernel<std::
complex<float>> : std::true_type {};
60struct has_lapack_kernel<std::
complex<double>> : std::true_type {};
95 return LAPACKE_ssyevr(
matrix_layout,
'V',
'I',
uplo,
n,
a,
lda, 0, 0, 1,
iu, 0,
m,
w,
z,
ldz,
isuppz);
99 return LAPACKE_dsyevr(
matrix_layout,
'V',
'I',
uplo,
n,
a,
lda, 0, 0, 1,
iu, 0,
m,
w,
z,
ldz,
isuppz);
104 return LAPACKE_cheevr(
matrix_layout,
'V',
'I',
uplo,
n,
reinterpret_cast<lapack_complex_float*
>(
a),
lda, 0, 0, 1,
iu,
110 return LAPACKE_zheevr(
matrix_layout,
'V',
'I',
uplo,
n,
reinterpret_cast<lapack_complex_double*
>(
a),
lda, 0, 0, 1,
iu,
119 return LAPACKE_ssygvx(
matrix_layout, 1,
'V',
'I',
uplo,
n,
a,
lda,
b,
ldb, 0, 0, 1,
iu, 0,
m,
w,
z,
ldz,
ifail);
124 return LAPACKE_dsygvx(
matrix_layout, 1,
'V',
'I',
uplo,
n,
a,
lda,
b,
ldb, 0, 0, 1,
iu, 0,
m,
w,
z,
ldz,
ifail);
176 return LAPACKE_sgesdd(
matrix_layout,
jobz,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt);
180 return LAPACKE_dgesdd(
matrix_layout,
jobz,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt);
200 return LAPACKE_sgesvd(
matrix_layout,
jobu,
jobvt,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt,
superb);
204 return LAPACKE_dgesvd(
matrix_layout,
jobu,
jobvt,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt,
superb);
235template <
typename value_type>
238 using matrix_type = Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
239 using real_vector_type = Eigen::Vector<real_type_t<value_type>, Eigen::Dynamic>;
240 Eigen::Map<matrix_type>
A(
a.data(), dimension, dimension);
242 Eigen::SelfAdjointEigenSolver<matrix_type> solver(
A, Eigen::ComputeEigenvectors);
243 if (solver.info() != Eigen::Success)
245 Eigen::Map<real_vector_type>(
w.data(), dimension) = solver.eigenvalues();
246 A = solver.eigenvectors();
250#if defined(HAVE_LAPACKE) || defined(MOLPRO)
252template <
typename value_type>
258 if constexpr (std::is_same_v<value_type, double>) {
267 throw std::logic_error(
"no LAPACK kernel available for this scalar type");
280template <
typename value_type>
283 size_t dimension,
size_t nroots) {
284 std::vector<real_type_t<value_type>> all(dimension);
286 std::copy_n(all.begin(),
nroots,
w.begin());
287 std::copy_n(
a.begin(), dimension *
nroots,
z.begin());
298 std::fesetenv(&m_env);
308#if defined(HAVE_LAPACKE) || defined(MOLPRO)
310template <
typename value_type>
313 size_t dimension,
size_t nroots) {
317 std::vector<lapack_int>
support(2 * std::max<size_t>(
nroots, 1));
319 std::vector<real_type_t<value_type>> all(dimension);
324 std::copy_n(all.begin(),
nroots,
w.begin());
328 std::vector<real_type_t<value_type>> all(dimension);
330 std::copy_n(all.begin(),
nroots,
w.begin());
331 std::copy_n(
a.begin(), dimension *
nroots,
z.begin());
354template <
typename value_type>
358 if (matrix.size() != dimension * dimension ||
eigenvectors.size() != dimension *
nroots ||
360 throw std::runtime_error(
"Sizes of matrix/eigenvectors/eigenvalues do not match dimension and nroots!");
365 std::vector<value_type>
a(matrix.begin(), matrix.end());
367 eigenvalues, dimension,
nroots);
372template <
typename value_type>
376 for (
size_t j = 0;
j < dimension; ++
j) {
378 for (
size_t i = 0;
i < dimension; ++
i)
380 norm = std::max(norm,
column);
397template <
typename value_type>
407 const real_t
anorm = detail::one_norm<value_type>(matrix, dimension);
408 std::vector<value_type>
factor(matrix.begin(), matrix.end());
436template <
typename value_type>
448 const real_t
anorm = detail::one_norm<value_type>(
metric, dimension);
450 std::vector<value_type>
a(matrix.begin(), matrix.end()),
b(
metric.begin(),
metric.end());
451 std::vector<lapack_int>
ifail(dimension);
453 std::vector<real_t> all(dimension);
459 std::copy_n(all.begin(),
nroots, eigenvalues.begin());
484template <
typename value_type>
489 throw std::runtime_error(
"Matrix of eigenvectors and input matrix are not the same size! (" +
490 std::to_string(
eigenvectors.size()) +
" vs. " + std::to_string(matrix.size()) +
")");
493 if (
eigenvectors.size() != dimension * dimension || eigenvalues.size() != dimension) {
494 throw std::runtime_error(
"Size of eigenvectors/eigenvalues do not match dimension!");
498 std::copy(matrix.begin(), matrix.end(),
eigenvectors.begin());
515template <
typename value_type>
518 std::vector<value_type>
eigvecs(dimension * dimension);
519 std::vector<real_t>
eigvals(dimension);
523 throw std::invalid_argument(
"Invalid argument of eigensolver_hermitian: " + std::to_string(-
success));
526 throw std::runtime_error(
"Hermitian eigensolver failed to converge. "
527 " elements of an intermediate tridiagonal form did not converge to zero.");
533 for (
int i =
int(dimension) - 1;
i >= 0;
537 for (
size_t j = 0;
j < dimension;
j++) {
Definition helper-dispatch.h:293
ScopedFpeSuspend(const ScopedFpeSuspend &)=delete
~ScopedFpeSuspend()
Definition helper-dispatch.h:296
ScopedFpeSuspend & operator=(const ScopedFpeSuspend &)=delete
ScopedFpeSuspend()
Definition helper-dispatch.h:295
int eigensolver_hermitian_kernel(std::false_type, std::span< value_type > a, std::span< real_type_t< value_type > > w, size_t dimension)
Eigen implementation of the hermitian eigenproblem, used for every scalar type LAPACK does not cover.
Definition helper-dispatch.h:236
int eigensolver_hermitian_lowest_kernel(std::false_type, std::span< value_type > a, std::span< value_type > z, std::span< real_type_t< value_type > > w, size_t dimension, size_t nroots)
The lowest nroots eigenpairs of a hermitian matrix: without a partial kernel, the whole decomposition...
Definition helper-dispatch.h:281
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition helper.h:14
int eigensolver_hermitian(std::span< const value_type > matrix, std::span< value_type > eigenvectors, std::span< real_type_t< value_type > > eigenvalues, const size_t dimension)
Eigen-decomposition of a real symmetric / complex hermitian matrix.
Definition helper-dispatch.h:485
constexpr bool has_lapack_kernel_v
Definition helper-dispatch.h:63
int eigensolver_hermitian_lowest(std::span< const value_type > matrix, std::span< value_type > eigenvectors, std::span< real_type_t< value_type > > eigenvalues, const size_t dimension, const size_t nroots)
The lowest nroots eigenpairs of a real symmetric / complex hermitian matrix.
Definition helper-dispatch.h:355
std::unique_ptr< LinearEigensystem< R, Q, P > > create_LinearEigensystem(const LinearEigensystemOptions &options, const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers=std::make_shared< molpro::linalg::itsolv::ArrayHandlers< R, Q, P > >())
Definition SolverFactory.h:111
bool eigenvalues_certainly_above(std::span< const value_type > matrix, size_t dimension, real_type_t< value_type > threshold, real_type_t< value_type > margin=1e4)
Whether every eigenvalue of a hermitian matrix certainly exceeds threshold, established without its e...
Definition helper-dispatch.h:398
bool generalized_eigensolver_hermitian_lowest(std::span< const value_type > matrix, std::span< const value_type > metric, std::span< value_type > eigenvectors, std::span< real_type_t< value_type > > eigenvalues, size_t dimension, size_t nroots, real_type_t< value_type > min_rcond)
The lowest nroots eigenpairs of the generalized hermitian problem H c = S c e, for a metric S that is...
Definition helper-dispatch.h:437
typename real_type< T >::type real_type_t
The real type underlying T, i.e. T itself for a real type and U for std::complex<U>.
Definition scalar_traits.h:43
Stores a singular value and corresponding left and right singular vectors.
Definition helper.h:27
value_type value
Definition helper.h:29
Whether the dense kernels of this library dispatch T to LAPACK rather than to Eigen.
Definition helper-dispatch.h:49