iterative-solver 0.0
 
Loading...
Searching...
No Matches
SubspaceSolverLinEig.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_SUBSPACESOLVERLINEIG_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_SUBSPACESOLVERLINEIG_H
3#include <molpro/linalg/itsolv/subspace/ISubspaceSolver.h>
4#include <molpro/linalg/itsolv/subspace/IXSpace.h>
5#include <molpro/linalg/itsolv/subspace/Matrix.h>
6#include <molpro/linalg/itsolv/Logger.h>
7#include <molpro/linalg/itsolv/helper.h>
8
9#include <map>
10#include <memory>
11#include <optional>
12
14
18template <class RT, class QT, class PT>
19class SubspaceSolverLinEig : public ISubspaceSolver<RT, QT, PT> {
20public:
26
27 explicit SubspaceSolverLinEig(std::shared_ptr<Logger> logger) : m_logger(std::move(logger)) {}
28
29 void solve(IXSpace<R, Q, P>& xspace, const size_t nroots_max) override {
30 m_logger->trace("SubspaceSolverLinEig::solve");
31 if (xspace.data.find(EqnData::rhs) == xspace.data.end() || xspace.data[EqnData::rhs].empty()) {
33 } else {
35 }
36 }
37
38protected:
40 switch (verbosity) {
42 return 3;
44 return 2;
46 return 1;
48 return 0;
49 }
50
51 return 0;
52 }
53
54 void solve_eigenvalue(IXSpace<R, Q, P>& xspace, const size_t nroots_max) {
55 m_logger->trace("SubspaceSolverLinEig::solve_eigenvalue");
56 auto h = xspace.data[EqnData::H];
57 // the metric of a generalised eigenproblem replaces the overlap of the subspace vectors
58 const bool metric = xspace.metric_kind() != MetricKind::Identity;
59 auto s = xspace.data[metric ? EqnData::M : EqnData::S];
60 m_logger->data_dump(metric ? "M = " : "S = ", s);
61 m_logger->data_dump<15>("H = ", h);
62 auto dim = h.rows();
63 auto evec = std::vector<value_type>{};
64 int verbosity = convert_verbosity(m_logger->verbosity());
67 m_complex_partners.clear();
68 for (size_t k = 0; k + 1 < m_imag_eigval_comps.size(); k += 2) {
69 const auto first = m_imag_eigval_comps[k].first;
70 const auto second = m_imag_eigval_comps[k + 1].first;
73 }
74 size_t n_solutions = 0;
75 if (dim)
76 n_solutions = evec.size() / dim;
77 auto full_matrix = Matrix<value_type>{std::move(evec), {n_solutions, dim}};
78 auto nroots = std::min(nroots_max, n_solutions);
80 if (nroots > 0) {
81 // Without its partner the residual of a pair member never vanishes. The partner's coefficients are kept, but not
82 // the partner itself, so that the number of solutions never exceeds the number of roots requested.
83 const auto partner = complex_partner(nroots - 1);
84 if (partner && *partner == nroots) {
86 m_retained_solutions.slice() = full_matrix.slice({0, 0}, {nroots + 1, dim});
87 }
88 }
89 m_eigenvalues.resize(nroots);
90 auto [first, last] = std::ranges::remove_if(
91 m_imag_eigval_comps, [nroots](std::size_t idx) { return idx >= nroots; },
92 &decltype(m_imag_eigval_comps)::value_type::first);
93 if (first != last && (std::ranges::distance(first, last) % 2) != 0) {
94 m_logger->info("Complex eigenvalue pair split up due to truncation to requested number of roots");
95 }
97 std::erase_if(m_complex_partners, [nroots](const auto& entry) { return entry.first >= nroots; });
99 m_solutions.slice() = full_matrix.slice({0, 0}, {nroots, dim});
100 m_errors.assign(size(), std::numeric_limits<value_type_abs>::max());
101 m_logger->data_dump<10>("eigenvalues = ", m_eigenvalues);
102 if (!m_imag_eigval_comps.empty()) {
103 m_logger->info("The following eigenvalues turned out to be complex-valued: ",
105 std::ranges::views::transform([](const auto& pair) { return pair.first + 1; }));
106 m_logger->data_dump("imaginary parts of eigenvalues = ",
107 m_imag_eigval_comps | std::ranges::views::transform([](auto pair) {
108 pair.first += 1;
109 return pair;
110 }));
111 }
112 m_logger->data_dump("eigenvectors = ", m_solutions);
113 }
114
116 m_logger->trace("SubspaceSolverLinEig::solve_linear_equations");
117 auto h = xspace.data[EqnData::H];
118 auto s = xspace.data[EqnData::S];
119 auto rhs = xspace.data[EqnData::rhs];
120 m_logger->data_dump<15>("S = ", s);
121 m_logger->data_dump<15>("H = ", h);
122 m_logger->data_dump<15>("rhs = ", rhs);
123 const auto dim = h.rows();
124 const auto n_solutions = rhs.cols();
125 auto solution = std::vector<value_type>{};
126 m_eigenvalues.assign(n_solutions, 0);
127 m_imag_eigval_comps.clear();
128 m_complex_partners.clear();
130 int verbosity = convert_verbosity(m_logger->verbosity());
131 itsolv::solve_LinearEquations(solution, m_eigenvalues, h.data(), s.data(), rhs.data(), dim, n_solutions,
133 m_solutions = Matrix<value_type>{std::move(solution), {n_solutions, dim}};
134 m_errors.assign(size(), std::numeric_limits<value_type_abs>::max());
135 m_logger->data_dump<10>("eigenvalues = ", m_eigenvalues);
136 m_logger->data_dump("solutions = ", m_solutions);
137 }
138
139public:
141 void set_error(int root, value_type_abs error) override { m_errors.at(root) = error; }
142 void set_error(const std::vector<int>& roots, const std::vector<value_type_abs>& errors) override {
143 for (size_t i = 0; i < roots.size(); ++i)
144 set_error(roots[i], errors[i]);
145 }
146
147 const Matrix<value_type>& solutions() const override { return m_solutions; }
148 const std::vector<value_type>& eigenvalues() const override { return m_eigenvalues; }
149 const std::vector<std::pair<std::size_t, value_type>>& imag_eigval_components() const { return m_imag_eigval_comps; }
154 std::optional<std::size_t> complex_partner(std::size_t root) const {
155 const auto it = m_complex_partners.find(root);
156 if (it == m_complex_partners.end())
157 return std::nullopt;
158 return it->second;
159 }
168 const std::vector<value_type_abs>& errors() const override { return m_errors; }
169
171 size_t size() const override { return m_solutions.rows(); }
172
173 void set_logger(std::shared_ptr<Logger> logger) override { m_logger = std::move(logger); }
174
175 // FIXME What difference does it make?
178 bool get_hermiticity() { return m_hermitian; }
182
183protected:
185 std::vector<value_type> m_eigenvalues;
186 std::vector<std::pair<std::size_t, value_type>> m_imag_eigval_comps;
187 std::map<std::size_t, std::size_t> m_complex_partners;
189 std::vector<value_type_abs> m_errors;
190 std::shared_ptr<Logger> m_logger{};
191
192public:
195protected:
196 bool m_hermitian = false;
199};
200
201} // namespace molpro::linalg::itsolv::subspace
202
203#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_SUBSPACESOLVERLINEIG_H
Full subspace.
Definition IXSpace.h:21
SubspaceData< value_type > data
Equation data in the subspace.
Definition IXSpace.h:30
virtual MetricKind metric_kind() const =0
The kind of metric declared with set_metric()
Matrix container that allows simple data access, slicing, copying and resizing without loosing data.
Definition Matrix.h:32
Slice slice(coord_type upper_left, coord_type bottom_right)
Access a rectangular slice of the matrix.
Definition Matrix.h:101
void clear()
Clears all elements and sets dimensions to 0.
Definition Matrix.h:81
bool empty() const
Returns true if matrix is empty.
Definition Matrix.h:78
void resize(const coord_type &dims)
Resize the matrix. The old data is preserved and any new rows/cols are zeroed.
Definition Matrix.h:130
index_type rows() const
Definition Matrix.h:169
Solves subspace problem for linear eigenvalues and system of linear equations.
Definition SubspaceSolverLinEig.h:19
value_type_abs get_augmented_hessian()
Definition SubspaceSolverLinEig.h:181
value_type_abs m_augmented_hessian
value of augmented hessian parameter. If 0, than augmented Hessian is not used
Definition SubspaceSolverLinEig.h:198
std::vector< value_type_abs > m_errors
errors in subspace solutions
Definition SubspaceSolverLinEig.h:189
std::optional< std::size_t > complex_partner(std::size_t root) const
The other member of the complex conjugate eigenvalue pair that root belongs to, if any.
Definition SubspaceSolverLinEig.h:154
typename ISubspaceSolver< RT, QT, PT >::value_type_abs value_type_abs
Definition SubspaceSolverLinEig.h:22
void set_error(const std::vector< int > &roots, const std::vector< value_type_abs > &errors) override
Update errors for a group of roots.
Definition SubspaceSolverLinEig.h:142
void set_logger(std::shared_ptr< Logger > logger) override
Definition SubspaceSolverLinEig.h:173
void set_error(int root, value_type_abs error) override
Set error value for solution root
Definition SubspaceSolverLinEig.h:141
void solve_eigenvalue(IXSpace< R, Q, P > &xspace, const size_t nroots_max)
Definition SubspaceSolverLinEig.h:54
std::map< std::size_t, std::size_t > m_complex_partners
root -> other member of its complex pair
Definition SubspaceSolverLinEig.h:187
value_type_abs m_svd_solver_threshold
threshold to select null space during SVD in eigenproblem, rescaled from double to the working precis...
Definition SubspaceSolverLinEig.h:194
std::vector< value_type > m_eigenvalues
eigenvalues
Definition SubspaceSolverLinEig.h:185
bool get_hermiticity()
Definition SubspaceSolverLinEig.h:178
typename ISubspaceSolver< RT, QT, PT >::Q Q
Definition SubspaceSolverLinEig.h:24
Matrix< value_type > m_solutions
solution matrix with row vectors
Definition SubspaceSolverLinEig.h:184
std::shared_ptr< Logger > m_logger
Definition SubspaceSolverLinEig.h:190
const std::vector< value_type > & eigenvalues() const override
Access eigenvalues from the last solve() call.
Definition SubspaceSolverLinEig.h:148
std::vector< std::pair< std::size_t, value_type > > m_imag_eigval_comps
eigenvalues
Definition SubspaceSolverLinEig.h:186
void set_augmented_hessian(value_type_abs parameter)
Set value of augmented hessian parameter. If 0, than augmented Hessian is not used.
Definition SubspaceSolverLinEig.h:180
const Matrix< value_type > & retained_solutions() const override
The solutions, followed by the complex partner of the last root if that partner was truncated away.
Definition SubspaceSolverLinEig.h:165
typename ISubspaceSolver< RT, QT, PT >::value_type value_type
Definition SubspaceSolverLinEig.h:21
typename ISubspaceSolver< RT, QT, PT >::P P
Definition SubspaceSolverLinEig.h:25
void solve(IXSpace< R, Q, P > &xspace, const size_t nroots_max) override
Solve the subspace problem.
Definition SubspaceSolverLinEig.h:29
const std::vector< std::pair< std::size_t, value_type > > & imag_eigval_components() const
Definition SubspaceSolverLinEig.h:149
void set_hermiticity(bool hermitian)
Set Hermiticity of the subspace.
Definition SubspaceSolverLinEig.h:177
const std::vector< value_type_abs > & errors() const override
Access errors corresponding to each solution.
Definition SubspaceSolverLinEig.h:168
int convert_verbosity(log::Verbosity verbosity)
Definition SubspaceSolverLinEig.h:39
SubspaceSolverLinEig(std::shared_ptr< Logger > logger)
Definition SubspaceSolverLinEig.h:27
void solve_linear_equations(IXSpace< R, Q, P > &xspace)
Definition SubspaceSolverLinEig.h:115
const Matrix< value_type > & solutions() const override
Access solutions from the last solve() call.
Definition SubspaceSolverLinEig.h:147
Matrix< value_type > m_retained_solutions
solutions and truncated partner of the last root, empty without one
Definition SubspaceSolverLinEig.h:188
typename ISubspaceSolver< RT, QT, PT >::R R
Definition SubspaceSolverLinEig.h:23
bool m_hermitian
Definition SubspaceSolverLinEig.h:196
size_t size() const override
Number of solutions.
Definition SubspaceSolverLinEig.h:171
Verbosity
Different levels of logging.
Definition Logger.h:63
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
void solve_LinearEquations(std::vector< value_type > &solution, std::vector< value_type > &eigenvalues, const std::vector< value_type > &matrix, const std::vector< value_type > &metric, const std::vector< value_type > &rhs, size_t dimension, size_t nroot, real_type_t< value_type > augmented_hessian, real_type_t< value_type > svdThreshold, int verbosity)
Definition helper-implementation.h:844
@ Identity
M = 1, i.e. no metric.
void eigenproblem(std::vector< value_type > &eigenvectors, std::vector< value_type > &eigenvalues, const std::vector< value_type > &matrix, const std::vector< value_type > &metric, size_t dimension, bool hermitian, real_type_t< value_type > svdThreshold, int verbosity, std::vector< std::pair< std::size_t, value_type > > *imag_eval_parts=nullptr, size_t nroots=std::numeric_limits< size_t >::max())
Definition helper-implementation.h:431
Manages solution of the subspace problem and storage of those solutions.
Definition ISubspaceSolver.h:21
typename array::ArrayHandler< R, R >::value_type value_type
Definition ISubspaceSolver.h:25
typename array::ArrayHandler< R, R >::value_type_abs value_type_abs
Definition ISubspaceSolver.h:26
PT P
Definition ISubspaceSolver.h:24
QT Q
Definition ISubspaceSolver.h:23
RT R
Definition ISubspaceSolver.h:22