11#include <Eigen/SparseCore>
13#include <spdlog/spdlog.h>
16template <
typename Scalar>
18 : float_type(float_type) {}
20template <
typename Scalar>
21template <
typename ScalarLim>
26 int dim = matrix.rows();
32 shift = matrix.diagonal().real().mean();
37 double floating_point_error = 5 * std::numeric_limits<real_lim_t>::epsilon();
39 if (floating_point_error > rtol) {
41 "Because the floating point precision is too low, the eigenvalues cannot be calculated "
42 "accurately. The estimated floating point error ({} * ||H||) is larger than the "
43 "specified tolerance ({} * ||H||). Try to use a 'float_type' with higher precision or "
45 floating_point_error, rtol);
80 return shifted_matrix;
83template <
typename Scalar>
84template <
typename RealLim>
90 eigenvalues.array() += shift;
94template <
typename Scalar>
97 std::optional<real_t> min_eigenvalue,
98 std::optional<real_t> max_eigenvalue,
double rtol)
const {
99 int dim = matrix.rows();
101 auto eigensys = eigh(matrix, rtol);
104 std::lower_bound(eigensys.eigenvalues.data(), eigensys.eigenvalues.data() + dim,
105 min_eigenvalue.value_or(std::numeric_limits<real_t>::lowest() / 2));
107 std::upper_bound(eigensys.eigenvalues.data(), eigensys.eigenvalues.data() + dim,
108 max_eigenvalue.value_or(std::numeric_limits<real_t>::max() / 2));
109 eigensys.eigenvectors = eigensys.eigenvectors
110 .block(0, std::distance(eigensys.eigenvalues.data(), it_begin), dim,
111 std::distance(it_begin, it_end))
113 eigensys.eigenvalues = eigensys.eigenvalues
114 .segment(std::distance(eigensys.eigenvalues.data(), it_begin),
115 std::distance(it_begin, it_end))
130 const Eigen::MatrixX<std::complex<double>> &matrix,
double &shift,
double rtol)
const;
143 const Eigen::MatrixX<std::complex<double>> &matrix,
double &shift,
double rtol)
const;
Eigen::MatrixX< ScalarLim > subtract_mean(const Eigen::MatrixX< Scalar > &matrix, real_t &shift, double rtol) const
typename traits::NumTraits< Scalar >::real_t real_t
virtual EigenSystemH< Scalar > eigh(const Eigen::SparseMatrix< Scalar, Eigen::RowMajor > &matrix, double rtol) const =0
DiagonalizerInterface(FloatType float_type)
Eigen::VectorX< real_t > add_mean(const Eigen::VectorX< RealLim > &eigenvalues, real_t shift) const
Matrix< Type, Dynamic, Dynamic > MatrixX
Matrix< Type, Dynamic, 1 > VectorX