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>
35extern "C" int dsyev_c(
char,
char,
int,
double*,
int,
double*);
49#if defined(HAVE_LAPACKE) || defined(MOLPRO)
55struct has_lapack_kernel<
float> : std::true_type {};
57struct has_lapack_kernel<std::
complex<float>> : std::true_type {};
59struct has_lapack_kernel<std::
complex<double>> : std::true_type {};
92 return LAPACKE_sgesdd(
matrix_layout,
jobz,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt);
96 return LAPACKE_dgesdd(
matrix_layout,
jobz,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt);
116 return LAPACKE_sgesvd(
matrix_layout,
jobu,
jobvt,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt,
superb);
120 return LAPACKE_dgesvd(
matrix_layout,
jobu,
jobvt,
m,
n,
a,
lda,
s, u,
ldu,
vt,
ldvt,
superb);
151template <
typename value_type>
154 using matrix_type = Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
155 using real_vector_type = Eigen::Vector<real_type_t<value_type>, Eigen::Dynamic>;
156 Eigen::Map<matrix_type>
A(
a.data(), dimension, dimension);
158 Eigen::SelfAdjointEigenSolver<matrix_type> solver(
A, Eigen::ComputeEigenvectors);
159 if (solver.info() != Eigen::Success)
161 Eigen::Map<real_vector_type>(
w.data(), dimension) = solver.eigenvalues();
162 A = solver.eigenvectors();
166#if defined(HAVE_LAPACKE) || defined(MOLPRO)
168template <
typename value_type>
174 if constexpr (std::is_same_v<value_type, double>) {
183 throw std::logic_error(
"no LAPACK kernel available for this scalar type");
205template <
typename value_type>
210 throw std::runtime_error(
"Matrix of eigenvectors and input matrix are not the same size! (" +
211 std::to_string(
eigenvectors.size()) +
" vs. " + std::to_string(matrix.size()) +
")");
214 if (
eigenvectors.size() != dimension * dimension || eigenvalues.size() != dimension) {
215 throw std::runtime_error(
"Size of eigenvectors/eigenvalues do not match dimension!");
219 std::copy(matrix.begin(), matrix.end(),
eigenvectors.begin());
236template <
typename value_type>
239 std::vector<value_type>
eigvecs(dimension * dimension);
240 std::vector<real_t>
eigvals(dimension);
244 throw std::invalid_argument(
"Invalid argument of eigensolver_hermitian: " + std::to_string(-
success));
247 throw std::runtime_error(
"Hermitian eigensolver failed to converge. "
248 " elements of an intermediate tridiagonal form did not converge to zero.");
254 for (
int i =
int(dimension) - 1;
i >= 0;
258 for (
size_t j = 0;
j < dimension;
j++) {
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:152
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:206
constexpr bool has_lapack_kernel_v
Definition helper-dispatch.h:62
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
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:48