iterative-solver 0.0
 
Loading...
Searching...
No Matches
helper-dispatch.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITERATIVESOLVER_HELPER_DISPATCH_H_
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITERATIVESOLVER_HELPER_DISPATCH_H_
3
19#include <Eigen/Dense>
20
21#include <molpro/lapacke.h>
22#include <molpro/linalg/itsolv/helper.h>
23
24#include <algorithm>
25#include <cfenv>
26#include <complex>
27#include <cstddef>
28#include <list>
29#include <span>
30#include <stdexcept>
31#include <string>
32#include <type_traits>
33#include <vector>
34
35#ifdef MOLPRO
36extern "C" int dsyev_c(char, char, int, double*, int, double*);
37#endif
38
39namespace molpro::linalg::itsolv {
40
48template <typename T>
49struct has_lapack_kernel : std::false_type {};
50#if defined(HAVE_LAPACKE) || defined(MOLPRO)
51template <>
52struct has_lapack_kernel<double> : std::true_type {};
53#endif
54#ifdef HAVE_LAPACKE
55template <>
56struct has_lapack_kernel<float> : std::true_type {};
57template <>
58struct has_lapack_kernel<std::complex<float>> : std::true_type {};
59template <>
60struct has_lapack_kernel<std::complex<double>> : std::true_type {};
61#endif
62template <typename T>
64
65#ifdef HAVE_LAPACKE
72namespace lapack {
73
76inline lapack_int heev(int matrix_layout, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* w) {
78}
79inline lapack_int heev(int matrix_layout, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* w) {
81}
82inline lapack_int heev(int matrix_layout, char jobz, char uplo, lapack_int n, std::complex<float>* a, lapack_int lda,
83 float* w) {
84 return LAPACKE_cheevd(matrix_layout, jobz, uplo, n, reinterpret_cast<lapack_complex_float*>(a), lda, w);
85}
86inline lapack_int heev(int matrix_layout, char jobz, char uplo, lapack_int n, std::complex<double>* a, lapack_int lda,
87 double* w) {
88 return LAPACKE_zheevd(matrix_layout, jobz, uplo, n, reinterpret_cast<lapack_complex_double*>(a), lda, w);
89}
90
94 lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz) {
95 return LAPACKE_ssyevr(matrix_layout, 'V', 'I', uplo, n, a, lda, 0, 0, 1, iu, 0, m, w, z, ldz, isuppz);
96}
98 lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz) {
99 return LAPACKE_dsyevr(matrix_layout, 'V', 'I', uplo, n, a, lda, 0, 0, 1, iu, 0, m, w, z, ldz, isuppz);
100}
101inline lapack_int heevr_lowest(int matrix_layout, char uplo, lapack_int n, std::complex<float>* a, lapack_int lda,
102 lapack_int iu, lapack_int* m, float* w, std::complex<float>* z, lapack_int ldz,
104 return LAPACKE_cheevr(matrix_layout, 'V', 'I', uplo, n, reinterpret_cast<lapack_complex_float*>(a), lda, 0, 0, 1, iu,
105 0, m, w, reinterpret_cast<lapack_complex_float*>(z), ldz, isuppz);
106}
107inline lapack_int heevr_lowest(int matrix_layout, char uplo, lapack_int n, std::complex<double>* a, lapack_int lda,
108 lapack_int iu, lapack_int* m, double* w, std::complex<double>* z, lapack_int ldz,
110 return LAPACKE_zheevr(matrix_layout, 'V', 'I', uplo, n, reinterpret_cast<lapack_complex_double*>(a), lda, 0, 0, 1, iu,
111 0, m, w, reinterpret_cast<lapack_complex_double*>(z), ldz, isuppz);
112}
113
116inline lapack_int hegvx_lowest(int matrix_layout, char uplo, lapack_int n, float* a, lapack_int lda, float* b,
117 lapack_int ldb, lapack_int iu, lapack_int* m, float* w, float* z, lapack_int ldz,
118 lapack_int* ifail) {
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);
120}
121inline lapack_int hegvx_lowest(int matrix_layout, char uplo, lapack_int n, double* a, lapack_int lda, double* b,
122 lapack_int ldb, lapack_int iu, lapack_int* m, double* w, double* z, lapack_int ldz,
123 lapack_int* 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);
125}
126inline lapack_int hegvx_lowest(int matrix_layout, char uplo, lapack_int n, std::complex<float>* a, lapack_int lda,
127 std::complex<float>* b, lapack_int ldb, lapack_int iu, lapack_int* m, float* w,
128 std::complex<float>* z, lapack_int ldz, lapack_int* ifail) {
129 return LAPACKE_chegvx(matrix_layout, 1, 'V', 'I', uplo, n, reinterpret_cast<lapack_complex_float*>(a), lda,
130 reinterpret_cast<lapack_complex_float*>(b), ldb, 0, 0, 1, iu, 0, m, w,
131 reinterpret_cast<lapack_complex_float*>(z), ldz, ifail);
132}
133inline lapack_int hegvx_lowest(int matrix_layout, char uplo, lapack_int n, std::complex<double>* a, lapack_int lda,
134 std::complex<double>* b, lapack_int ldb, lapack_int iu, lapack_int* m, double* w,
135 std::complex<double>* z, lapack_int ldz, lapack_int* ifail) {
136 return LAPACKE_zhegvx(matrix_layout, 1, 'V', 'I', uplo, n, reinterpret_cast<lapack_complex_double*>(a), lda,
137 reinterpret_cast<lapack_complex_double*>(b), ldb, 0, 0, 1, iu, 0, m, w,
138 reinterpret_cast<lapack_complex_double*>(z), ldz, ifail);
139}
140
142inline lapack_int potrf(int matrix_layout, char uplo, lapack_int n, float* a, lapack_int lda) {
144}
145inline lapack_int potrf(int matrix_layout, char uplo, lapack_int n, double* a, lapack_int lda) {
147}
148inline lapack_int potrf(int matrix_layout, char uplo, lapack_int n, std::complex<float>* a, lapack_int lda) {
149 return LAPACKE_cpotrf(matrix_layout, uplo, n, reinterpret_cast<lapack_complex_float*>(a), lda);
150}
151inline lapack_int potrf(int matrix_layout, char uplo, lapack_int n, std::complex<double>* a, lapack_int lda) {
152 return LAPACKE_zpotrf(matrix_layout, uplo, n, reinterpret_cast<lapack_complex_double*>(a), lda);
153}
154
156inline lapack_int pocon(int matrix_layout, char uplo, lapack_int n, const float* a, lapack_int lda, float anorm,
157 float* rcond) {
159}
160inline lapack_int pocon(int matrix_layout, char uplo, lapack_int n, const double* a, lapack_int lda, double anorm,
161 double* rcond) {
163}
164inline lapack_int pocon(int matrix_layout, char uplo, lapack_int n, const std::complex<float>* a, lapack_int lda,
165 float anorm, float* rcond) {
166 return LAPACKE_cpocon(matrix_layout, uplo, n, reinterpret_cast<const lapack_complex_float*>(a), lda, anorm, rcond);
167}
168inline lapack_int pocon(int matrix_layout, char uplo, lapack_int n, const std::complex<double>* a, lapack_int lda,
169 double anorm, double* rcond) {
170 return LAPACKE_zpocon(matrix_layout, uplo, n, reinterpret_cast<const lapack_complex_double*>(a), lda, anorm, rcond);
171}
172
174inline lapack_int gesdd(int matrix_layout, char jobz, lapack_int m, lapack_int n, float* a, lapack_int lda, float* s,
175 float* u, lapack_int ldu, float* vt, lapack_int ldvt) {
176 return LAPACKE_sgesdd(matrix_layout, jobz, m, n, a, lda, s, u, ldu, vt, ldvt);
177}
178inline lapack_int gesdd(int matrix_layout, char jobz, lapack_int m, lapack_int n, double* a, lapack_int lda, double* s,
179 double* u, lapack_int ldu, double* vt, lapack_int ldvt) {
180 return LAPACKE_dgesdd(matrix_layout, jobz, m, n, a, lda, s, u, ldu, vt, ldvt);
181}
182inline lapack_int gesdd(int matrix_layout, char jobz, lapack_int m, lapack_int n, std::complex<float>* a,
183 lapack_int lda, float* s, std::complex<float>* u, lapack_int ldu, std::complex<float>* vt,
185 return LAPACKE_cgesdd(matrix_layout, jobz, m, n, reinterpret_cast<lapack_complex_float*>(a), lda, s,
186 reinterpret_cast<lapack_complex_float*>(u), ldu, reinterpret_cast<lapack_complex_float*>(vt),
187 ldvt);
188}
189inline lapack_int gesdd(int matrix_layout, char jobz, lapack_int m, lapack_int n, std::complex<double>* a,
190 lapack_int lda, double* s, std::complex<double>* u, lapack_int ldu, std::complex<double>* vt,
192 return LAPACKE_zgesdd(matrix_layout, jobz, m, n, reinterpret_cast<lapack_complex_double*>(a), lda, s,
193 reinterpret_cast<lapack_complex_double*>(u), ldu, reinterpret_cast<lapack_complex_double*>(vt),
194 ldvt);
195}
196
198inline lapack_int gesvd(int matrix_layout, char jobu, char jobvt, lapack_int m, lapack_int n, float* a, lapack_int lda,
199 float* s, float* u, lapack_int ldu, float* vt, lapack_int ldvt, float* superb) {
200 return LAPACKE_sgesvd(matrix_layout, jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, superb);
201}
202inline lapack_int gesvd(int matrix_layout, char jobu, char jobvt, lapack_int m, lapack_int n, double* a, lapack_int lda,
203 double* s, double* u, lapack_int ldu, double* vt, lapack_int ldvt, double* superb) {
204 return LAPACKE_dgesvd(matrix_layout, jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, superb);
205}
206inline lapack_int gesvd(int matrix_layout, char jobu, char jobvt, lapack_int m, lapack_int n, std::complex<float>* a,
207 lapack_int lda, float* s, std::complex<float>* u, lapack_int ldu, std::complex<float>* vt,
208 lapack_int ldvt, float* superb) {
209 return LAPACKE_cgesvd(matrix_layout, jobu, jobvt, m, n, reinterpret_cast<lapack_complex_float*>(a), lda, s,
210 reinterpret_cast<lapack_complex_float*>(u), ldu, reinterpret_cast<lapack_complex_float*>(vt),
211 ldvt, superb);
212}
213inline lapack_int gesvd(int matrix_layout, char jobu, char jobvt, lapack_int m, lapack_int n, std::complex<double>* a,
214 lapack_int lda, double* s, std::complex<double>* u, lapack_int ldu, std::complex<double>* vt,
215 lapack_int ldvt, double* superb) {
216 return LAPACKE_zgesvd(matrix_layout, jobu, jobvt, m, n, reinterpret_cast<lapack_complex_double*>(a), lda, s,
217 reinterpret_cast<lapack_complex_double*>(u), ldu, reinterpret_cast<lapack_complex_double*>(vt),
218 ldvt, superb);
219}
220
221} // namespace lapack
222#endif // HAVE_LAPACKE
223
224namespace detail {
225
235template <typename value_type>
236int eigensolver_hermitian_kernel(std::false_type /*use_lapack*/, std::span<value_type> a,
237 std::span<real_type_t<value_type>> w, size_t dimension) {
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);
241 // Eigen, like ?syev with uplo='L', references only the lower triangle and returns ascending eigenvalues
242 Eigen::SelfAdjointEigenSolver<matrix_type> solver(A, Eigen::ComputeEigenvectors);
243 if (solver.info() != Eigen::Success)
244 return 1;
245 Eigen::Map<real_vector_type>(w.data(), dimension) = solver.eigenvalues();
246 A = solver.eigenvectors();
247 return 0;
248}
249
250#if defined(HAVE_LAPACKE) || defined(MOLPRO)
252template <typename value_type>
253int eigensolver_hermitian_kernel(std::true_type /*use_lapack*/, std::span<value_type> a,
254 std::span<real_type_t<value_type>> w, size_t dimension) {
255 constexpr char compute_eigenvalues_eigenvectors = 'V';
256 constexpr char store_lower_triangle = 'L';
257#ifdef MOLPRO
258 if constexpr (std::is_same_v<value_type, double>) {
259 return dsyev_c(compute_eigenvalues_eigenvectors, store_lower_triangle, int(dimension), a.data(), int(dimension),
260 w.data());
261 }
262#endif
263#ifdef HAVE_LAPACKE
265 lapack_int(dimension), a.data(), lapack_int(dimension), w.data()));
266#else
267 throw std::logic_error("no LAPACK kernel available for this scalar type");
268#endif
269}
270#endif
271
280template <typename value_type>
281int eigensolver_hermitian_lowest_kernel(std::false_type /*use_lapack*/, std::span<value_type> a,
282 std::span<value_type> z, std::span<real_type_t<value_type>> w,
283 size_t dimension, size_t nroots) {
284 std::vector<real_type_t<value_type>> all(dimension);
285 const int info = eigensolver_hermitian_kernel<value_type>(std::false_type{}, a, all, dimension);
286 std::copy_n(all.begin(), nroots, w.begin());
287 std::copy_n(a.begin(), dimension * nroots, z.begin());
288 return info;
289}
290
294public:
295 ScopedFpeSuspend() { m_suspended = std::feholdexcept(&m_env) == 0; }
297 if (m_suspended)
298 std::fesetenv(&m_env);
299 }
302
303private:
304 std::fenv_t m_env;
305 bool m_suspended;
306};
307
308#if defined(HAVE_LAPACKE) || defined(MOLPRO)
310template <typename value_type>
311int eigensolver_hermitian_lowest_kernel(std::true_type /*use_lapack*/, std::span<value_type> a,
312 std::span<value_type> z, std::span<real_type_t<value_type>> w,
313 size_t dimension, size_t nroots) {
314#ifdef HAVE_LAPACKE
315 constexpr char store_lower_triangle = 'L';
316 lapack_int found = 0;
317 std::vector<lapack_int> support(2 * std::max<size_t>(nroots, 1));
318 // ?syevr/?heevr need room for all dimension eigenvalues, though only the first nroots are returned
319 std::vector<real_type_t<value_type>> all(dimension);
321 const auto info = lapack::heevr_lowest(LAPACK_COL_MAJOR, store_lower_triangle, lapack_int(dimension), a.data(),
322 lapack_int(dimension), lapack_int(nroots), &found, all.data(), z.data(),
323 lapack_int(dimension), support.data());
324 std::copy_n(all.begin(), nroots, w.begin());
325 return info != 0 ? int(info) : (size_t(found) == nroots ? 0 : 1);
326#else
327 // MOLPRO's own ?syev has no partial counterpart
328 std::vector<real_type_t<value_type>> all(dimension);
329 const int info = eigensolver_hermitian_kernel<value_type>(std::true_type{}, a, all, dimension);
330 std::copy_n(all.begin(), nroots, w.begin());
331 std::copy_n(a.begin(), dimension * nroots, z.begin());
332 return info;
333#endif
334}
335#endif
336
337} // namespace detail
338
354template <typename value_type>
355int eigensolver_hermitian_lowest(std::span<const value_type> matrix, std::span<value_type> eigenvectors,
356 std::span<real_type_t<value_type>> eigenvalues, const size_t dimension,
357 const size_t nroots) {
358 if (matrix.size() != dimension * dimension || eigenvectors.size() != dimension * nroots ||
359 eigenvalues.size() != nroots || nroots > dimension) {
360 throw std::runtime_error("Sizes of matrix/eigenvectors/eigenvalues do not match dimension and nroots!");
361 }
362 if (nroots == 0)
363 return 0;
364 // the decomposition overwrites its input
365 std::vector<value_type> a(matrix.begin(), matrix.end());
366 return detail::eigensolver_hermitian_lowest_kernel<value_type>(has_lapack_kernel<value_type>{}, a, eigenvectors,
367 eigenvalues, dimension, nroots);
368}
369
370namespace detail {
372template <typename value_type>
373real_type_t<value_type> one_norm(std::span<const value_type> a, size_t dimension) {
374 using std::abs;
376 for (size_t j = 0; j < dimension; ++j) {
378 for (size_t i = 0; i < dimension; ++i)
379 column += abs(a[i + j * dimension]);
380 norm = std::max(norm, column);
381 }
382 return norm;
383}
384} // namespace detail
385
397template <typename value_type>
398bool eigenvalues_certainly_above(std::span<const value_type> matrix, size_t dimension,
400#ifdef HAVE_LAPACKE
401 if constexpr (has_lapack_kernel_v<value_type>) {
402 using real_t = real_type_t<value_type>;
403 if (dimension == 0)
404 return false;
405 constexpr char store_lower_triangle = 'L';
406 const auto n = lapack_int(dimension);
407 const real_t anorm = detail::one_norm<value_type>(matrix, dimension);
408 std::vector<value_type> factor(matrix.begin(), matrix.end());
409 if (lapack::potrf(LAPACK_COL_MAJOR, store_lower_triangle, n, factor.data(), n) != 0)
410 return false;
411 real_t rcond = 0;
412 if (lapack::pocon(LAPACK_COL_MAJOR, store_lower_triangle, n, factor.data(), n, anorm, &rcond) != 0)
413 return false;
414 // margin >= 1, so dividing by it cannot overflow, unlike margin * threshold for a threshold as large as
415 // numeric_limits::max(), which callers pass to ask for every eigenpair
416 return rcond * anorm / margin > threshold;
417 }
418#endif
419 return false;
420}
421
436template <typename value_type>
437bool generalized_eigensolver_hermitian_lowest(std::span<const value_type> matrix, std::span<const value_type> metric,
438 std::span<value_type> eigenvectors,
439 std::span<real_type_t<value_type>> eigenvalues, size_t dimension,
441#ifdef HAVE_LAPACKE
442 if constexpr (has_lapack_kernel_v<value_type>) {
443 using real_t = real_type_t<value_type>;
444 if (nroots == 0 || nroots > dimension)
445 return false;
446 constexpr char store_lower_triangle = 'L';
447 const auto n = lapack_int(dimension);
448 const real_t anorm = detail::one_norm<value_type>(metric, dimension);
449 // the reduction overwrites both matrices, and leaves the Cholesky factor of S in place of S
450 std::vector<value_type> a(matrix.begin(), matrix.end()), b(metric.begin(), metric.end());
451 std::vector<lapack_int> ifail(dimension);
452 // ?sygvx/?hegvx need room for all dimension eigenvalues, though only the first nroots are returned
453 std::vector<real_t> all(dimension);
454 lapack_int found = 0;
455 if (lapack::hegvx_lowest(LAPACK_COL_MAJOR, store_lower_triangle, n, a.data(), n, b.data(), n, lapack_int(nroots),
456 &found, all.data(), eigenvectors.data(), n, ifail.data()) != 0 ||
457 size_t(found) != nroots)
458 return false;
459 std::copy_n(all.begin(), nroots, eigenvalues.begin());
460 real_t rcond = 0;
461 if (lapack::pocon(LAPACK_COL_MAJOR, store_lower_triangle, n, b.data(), n, anorm, &rcond) != 0)
462 return false;
463 return rcond >= min_rcond;
464 }
465#endif
466 return false;
467}
468
484template <typename value_type>
485int eigensolver_hermitian(std::span<const value_type> matrix, std::span<value_type> eigenvectors,
486 std::span<real_type_t<value_type>> eigenvalues, const size_t dimension) {
487 // validate input
488 if (eigenvectors.size() != matrix.size()) {
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()) + ")");
491 }
492
493 if (eigenvectors.size() != dimension * dimension || eigenvalues.size() != dimension) {
494 throw std::runtime_error("Size of eigenvectors/eigenvalues do not match dimension!");
495 }
496
497 // copy input matrix, since the decomposition overwrites it in place
498 std::copy(matrix.begin(), matrix.end(), eigenvectors.begin());
499 if (dimension == 0)
500 return 0;
501
502 return detail::eigensolver_hermitian_kernel<value_type>(has_lapack_kernel<value_type>{}, eigenvectors, eigenvalues,
503 dimension);
504}
505
515template <typename value_type>
516std::list<SVD<value_type>> eigensolver_hermitian(size_t dimension, std::span<const value_type> matrix) {
517 using real_t = real_type_t<value_type>;
518 std::vector<value_type> eigvecs(dimension * dimension);
519 std::vector<real_t> eigvals(dimension);
520
521 const int success = eigensolver_hermitian<value_type>(matrix, eigvecs, eigvals, dimension);
522 if (success < 0) {
523 throw std::invalid_argument("Invalid argument of eigensolver_hermitian: " + std::to_string(-success));
524 }
525 if (success > 0) {
526 throw std::runtime_error("Hermitian eigensolver failed to converge. "
527 " elements of an intermediate tridiagonal form did not converge to zero.");
528 }
529
530 auto eigensystem = std::list<SVD<value_type>>{};
531
532 // populate eigensystem
533 for (int i = int(dimension) - 1; i >= 0;
534 i--) { // note: flipping this axis gives parity with results of eigen::jacobiSVD
537 for (size_t j = 0; j < dimension; j++) {
538 temp_eigenproblem.v.emplace_back(eigvecs[j + (dimension * i)]);
539 }
540 eigensystem.emplace_back(temp_eigenproblem);
541 }
542
543 return eigensystem;
544}
545
546} // namespace molpro::linalg::itsolv
547
548#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITERATIVESOLVER_HELPER_DISPATCH_H_
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