1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_PROPOSE_RSPACE_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_PROPOSE_RSPACE_H
3#include <molpro/linalg/itsolv/IterativeSolver.h>
4#include <molpro/linalg/itsolv/helper.h>
5#include <molpro/linalg/itsolv/qspace_options.h>
6#include <molpro/linalg/itsolv/rspace_options.h>
7#include <molpro/linalg/itsolv/subspace/Dimensions.h>
8#include <molpro/linalg/itsolv/subspace/ISubspaceSolver.h>
9#include <molpro/linalg/itsolv/subspace/IXSpace.h>
10#include <molpro/linalg/itsolv/subspace/QSpace.h>
11#include <molpro/linalg/itsolv/subspace/gram_schmidt.h>
12#include <molpro/linalg/itsolv/subspace/util.h>
13#include <molpro/linalg/itsolv/util.h>
14#include <molpro/linalg/itsolv/wrap_util.h>
15#include <molpro/profiler/Profiler.h>
32 for (
auto& p : params) {
33 auto dot = handler.
dot(p, p);
34 dot = std::sqrt(std::abs(dot));
36 handler.
scal(1. / dot, p);
38 logger.
warn(
"parameter's length is too small for normalisation, dot = " + std::format(
"{:.2e}",
double(dot)));
52template <
typename value_type>
54 const std::vector<std::size_t>& remove_qspace,
Logger& logger) {
55 logger.
trace(
"construct_projected_solution()");
56 const auto nQd = remove_qspace.size();
57 const auto nSol = solutions.
rows();
59 for (
size_t i = 0; i < nSol; ++i) {
60 for (
size_t j = 0; j < nQd; ++j) {
61 solutions_proj(i, j) = solutions(i, dims.
oQ + remove_qspace[j]);
63 for (
size_t j = 0; j < dims.
nD; ++j) {
64 solutions_proj(i, nQd + j) = solutions(i, dims.
oD + j);
67 logger.
debug(
"nSol, nQd, nD", nSol, nQd, dims.
nD);
68 return solutions_proj;
85template <
typename value_type>
89 const std::vector<std::size_t>& remove_qspace,
Logger& logger) {
90 logger.
trace(
"construct_projected_solution_overlap()");
91 const auto nSol = solutions_proj.
rows();
92 const auto nQd = remove_qspace.size();
94 for (
size_t i = 0; i < nSol; ++i) {
95 for (
size_t ii = 0; ii <= i; ++ii) {
96 for (
size_t j = 0; j < nQd; ++j) {
97 for (
size_t k = 0; k < nQd; ++k) {
98 overlap_proj(i, ii) += solutions_proj(i, j) * solutions_proj(ii, k) *
99 overlap(dims.
oQ + remove_qspace[j], dims.
oQ + remove_qspace[k]);
101 for (
size_t k = 0; k < dims.
nD; ++k) {
102 overlap_proj(i, ii) +=
103 solutions_proj(i, j) * solutions_proj(ii, nQd + k) * overlap(dims.
oQ + remove_qspace[j], dims.
oD + k);
106 for (
size_t j = 0; j < dims.
nD; ++j) {
107 for (
size_t k = 0; k < dims.
nD; ++k) {
108 overlap_proj(i, ii) +=
109 solutions_proj(i, nQd + j) * solutions_proj(ii, nQd + k) * overlap(dims.
oD + j, dims.
oD + k);
111 for (
size_t k = 0; k < nQd; ++k) {
112 overlap_proj(i, ii) +=
113 solutions_proj(i, nQd + j) * solutions_proj(ii, k) * overlap(dims.
oD + j, dims.
oQ + remove_qspace[k]);
116 overlap_proj(ii, i) = overlap_proj(i, ii);
129template <
typename value_type,
typename value_type_abs>
131 const value_type_abs norm_thresh,
Logger& logger) {
132 logger.
trace(
"remove_null_norm_and_normalise()");
133 const auto nSol = parameters.
rows();
134 auto norm_proj = std::vector<value_type_abs>(nSol, 0.);
135 for (
size_t i = 0; i < nSol; ++i)
136 norm_proj[i] = std::sqrt(std::abs(overlap(i, i)));
137 for (
size_t i = 0, j = 0; i < nSol; ++i) {
138 if (norm_proj[i] > norm_thresh) {
139 parameters.
row(j).scal(1. / norm_proj[i]);
140 overlap.col(j).scal(1. / norm_proj[i]);
141 overlap.row(j).scal(1. / norm_proj[i]);
145 overlap.remove_row_col(j, j);
146 std::stringstream ss;
147 ss << std::setprecision(3) <<
"remove projected solution parameter i = " << i <<
", norm = " << norm_proj[i];
148 logger.
info(ss.str());
152 logger.
data_dump(
"parameters after normalisation = ", parameters);
153 logger.
data_dump(
"overlap of parameters = ", overlap);
168template <
typename value_type,
typename value_type_abs>
172 logger.
trace(
"remove_null_projected_solutions()");
173 logger.
debug(
"nS on entry = ", solutions_proj.
rows());
174 value_type* m =
const_cast<std::vector<value_type>&
>(overlap_proj.
data()).data();
176 std::numeric_limits<value_type_abs>::max(),
true);
177 svd_vecs.remove_if([&svd_thresh](
const auto& el) {
return el.value < svd_thresh; });
178 svd_vecs.sort([](
const auto& lt,
const auto& rt) {
return lt.value < rt.value; });
179 const auto nD = svd_vecs.size();
180 const auto nX = solutions_proj.
cols();
182 auto svd = svd_vecs.begin();
183 for (
size_t i = 0; i < nD; ++i, ++svd)
184 for (
size_t j = 0; j < overlap_proj.
cols(); ++j)
185 for (
size_t k = 0; k < nX; ++k)
186 solutions_stable(i, k) += svd->v[j] * solutions_proj(j, k);
187 logger.
debug(
"nS without null space = ", solutions_stable.rows());
188 return solutions_stable;
200template <
typename value_type>
204 const auto nDnew = solutions_proj.
rows();
205 const auto nQd = remove_qspace.size();
206 const auto nQ = dims.
nQ - nQd;
208 for (
size_t i = 0; i < dims.
nD; ++i) {
209 ov.remove_row_col(dims.
oD, dims.
oD);
211 auto is_Qdelete = [&remove_qspace](
size_t i) {
212 return std::find(begin(remove_qspace), end(remove_qspace), i) != end(remove_qspace);
214 for (
size_t i = 0, j = 0; i < dims.
nQ; ++i) {
216 ov.remove_row_col(dims.
oQ + j, dims.
oQ + j);
220 const auto oDnew = dims.
nP + nQ + nR;
221 ov.resize({oDnew + nDnew, oDnew + nDnew});
228 auto accumulate_ov_offdiag = [&](
size_t i,
size_t j,
size_t jj) {
229 for (
size_t k = 0; k < nQd; ++k)
230 ov(oDnew + i, j) += solutions_proj(i, k) * overlap(jj, dims.
oQ + remove_qspace[k]);
231 for (
size_t k = 0; k < dims.
nD; ++k)
232 ov(oDnew + i, j) += solutions_proj(i, nQd + k) * overlap(jj, dims.
oD + k);
233 ov(j, oDnew + i) = ov(oDnew + i, j);
235 for (
size_t i = 0; i < nDnew; ++i) {
236 for (
size_t j = 0; j < dims.
nP; ++j)
237 accumulate_ov_offdiag(i, j, dims.
oP + j);
238 for (
size_t j = 0, jj = 0; j < dims.
nQ; ++j)
240 accumulate_ov_offdiag(i, dims.
nP + jj++, dims.
oQ + j);
241 for (
size_t j = 0; j < nR; ++j)
242 accumulate_ov_offdiag(i, dims.
nP + nQ + j, dims.
nX + j);
244 for (
size_t i = 0; i < nDnew; ++i) {
245 for (
size_t j = 0; j <= i; ++j) {
246 for (
size_t k = 0; k < nQd; ++k) {
247 for (
size_t l = 0; l < nQd; ++l)
248 ov(oDnew + i, oDnew + j) += solutions_proj(i, k) * solutions_proj(j, l) *
249 overlap(dims.
oQ + remove_qspace[k], dims.
oQ + remove_qspace[l]);
250 for (
size_t l = 0; l < dims.
nD; ++l)
251 ov(oDnew + i, oDnew + j) +=
252 solutions_proj(i, k) * solutions_proj(j, nQd + l) * overlap(dims.
oQ + remove_qspace[k], dims.
oD + l);
254 for (
size_t k = 0; k < dims.
nD; ++k) {
255 for (
size_t l = 0; l < nQd; ++l)
256 ov(oDnew + i, oDnew + j) +=
257 solutions_proj(i, nQd + k) * solutions_proj(j, l) * overlap(dims.
oD + k, dims.
oQ + remove_qspace[l]);
258 for (
size_t l = 0; l < dims.
nD; ++l)
259 ov(oDnew + i, oDnew + j) +=
260 solutions_proj(i, nQd + k) * solutions_proj(j, nQd + l) * overlap(dims.
oD + k, dims.
oD + l);
262 ov(oDnew + j, oDnew + i) = ov(oDnew + i, oDnew + j);
281template <
class R,
class Q,
class P,
typename value_type>
285 logger.
trace(
"append_overlap_with_r()");
286 const auto nP = pparams.size(), nQ = qparams.size(), nD = dparams.size(), nN = params.size();
287 const auto nX = nP + nQ + nD + nN;
289 const auto oQ = oP + nP;
290 const auto oD = oQ + nQ;
291 const auto oN = oD + nD;
298 auto copy_upper_to_lower = [&ov, oN, nN](
size_t oX,
size_t nX) {
299 for (
size_t i = 0; i < nX; ++i)
300 for (
size_t j = 0; j < nN; ++j)
301 ov(oX + i, oN + j) = ov(oN + j, oX + i);
303 copy_upper_to_lower(oP, nP);
304 copy_upper_to_lower(oQ, nQ);
305 copy_upper_to_lower(oD, nD);
306 logger.
data_dump(
"full overlap P+Q+D+R = ", ov);
318template <
typename value_type>
321 using value_type_abs =
decltype(std::abs(solutions(0, 0)));
322 using contrib_pair = std::pair<std::size_t, value_type_abs>;
326 logger.
trace(
"limit_qspace_size()");
328 assert(opts.max_size >= opts.min_size);
330 const bool must_trim_size = dims.
nQ > opts.max_size;
331 const bool may_trim_size = dims.
nQ > opts.min_size && opts.contrib_thresh > 0;
333 if (!must_trim_size && !may_trim_size) {
337 const std::size_t min_deletions = must_trim_size ? dims.
nQ - opts.max_size : 0;
338 const std::size_t max_deletions = dims.
nQ - opts.min_size;
340 std::vector<std::size_t> q_delete;
341 q_delete.reserve(min_deletions);
343 const std::size_t nSol = solutions.
rows();
345 std::vector<contrib_pair> max_contrib_to_solution;
346 max_contrib_to_solution.reserve(nSol);
348 for (std::size_t idx : std::ranges::views::iota(std::size_t(0), dims.
nQ)) {
349 max_contrib_to_solution.emplace_back(std::make_pair(idx, value_type_abs(0)));
351 for (
size_t j = 0; j < nSol; ++j) {
352 const value_type_abs current = std::abs(solutions(j, dims.
oQ + idx));
353 max_contrib_to_solution.back().second = std::max(max_contrib_to_solution.back().second, current);
357 std::ranges::sort(max_contrib_to_solution, std::less<>{}, &contrib_pair::second);
359 logger.
trace(
"contribution to solutions =",
360 max_contrib_to_solution | std::ranges::views::transform([](
const contrib_pair& p) {
return p.second; }));
362 for (
auto [idx, contrib] : max_contrib_to_solution) {
363 if (q_delete.size() == max_deletions || (q_delete.size() >= min_deletions && contrib >= opts.contrib_thresh)) {
367 if (opts.contrib_thresh != 0 && contrib >= opts.contrib_thresh) {
368 logger.
warn(
"deleted Q vector with max. contribution = ", contrib);
370 logger.
debug(
"deleted Q vector with max. contribution = ", contrib);
373 q_delete.emplace_back(idx);
390template <
class R,
class Q,
class P,
typename value_type,
typename value_type_abs>
392 const std::vector<std::size_t>& q_delete,
const value_type_abs norm_thresh,
403 auto svd_vecs =
svd_system(overlap_full_subspace.rows(), overlap_full_subspace.cols(),
404 array::Span(&overlap_full_subspace(0, 0), overlap_full_subspace.size()), svd_thresh,
true);
405 assert(svd_vecs.empty() &&
"P+Q+D subspace should be stable by construction");
406 const auto nD = solutions_proj.rows();
407 const auto nQd = q_delete.size();
408 assert(nQd + dims.nD == solutions_proj.cols());
411 std::vector<Q> dparams_new, dactions_new;
414 Q
const* q =
nullptr;
415 if (!qparams.empty())
416 q = &qparams.front().get();
417 else if (!dparams.empty())
418 q = &dparams.front().get();
420 for (
size_t i = 0; i < nD; ++i) {
421 dparams_new.emplace_back(handler.
copy(*q));
422 dactions_new.emplace_back(handler.
copy(*q));
423 handler.
fill(0, dparams_new.back());
424 handler.
fill(0, dactions_new.back());
428 for (
size_t i = 0; i < nD; ++i) {
429 for (
size_t j = 0; j < q_delete.size(); ++j) {
430 handler.
axpy(solutions_proj(i, j), qparams.at(q_delete[j]), dparams_new.at(i));
431 handler.
axpy(solutions_proj(i, j), qactions.at(q_delete[j]), dactions_new.at(i));
433 for (
size_t j = 0; j < dims.nD; ++j) {
434 handler.
axpy(solutions_proj(i, nQd + j), dparams.at(j), dparams_new.at(i));
435 handler.
axpy(solutions_proj(i, nQd + j), dactions.at(j), dactions_new.at(i));
438 for (
size_t i = 0; i < nD; ++i) {
439 auto norm = std::sqrt(std::abs(handler.
dot(dparams_new.at(i), dparams_new.at(i))));
440 if (norm < norm_thresh) {
442 std::format(
"construct_dspace: skipping normalisation of D vector {} with near-zero norm = {:.2e}", i, norm));
445 handler.
scal(1. / norm, dparams_new[i]);
446 handler.
scal(1. / norm, dactions_new[i]);
448 return std::make_tuple(std::move(dparams_new), std::move(dactions_new));
467template <
class R,
class Q,
class P,
typename value_type,
typename value_type_abs>
470 const CVecRef<Q>& dparams,
const value_type_abs norm_thresh,
472 logger.
trace(
"modified_gram_schmidt()");
473 const auto nR = rparams.size(), nP = pparams.size(), nQ = qparams.size(), nD = dparams.size();
475 assert(nP == dims.
nP && nQ == dims.
nQ && nD == dims.
nD);
476 auto orthogonalise = [&overlap, &rparams, nR](
const auto& xparams,
auto& handler,
const size_t oX,
const size_t nX) {
477 for (
size_t i = 0; i < nX; ++i) {
478 auto norm = std::abs(overlap(oX + i, oX + i));
480 auto dot_mat = handler.gemm_inner(
cwrap(rparams),
cwrap_arg(xparams.at(i).get()));
481 std::pair<size_t, size_t> mcoeff_dim = std::make_pair(1, nR);
482 subspace::Matrix<
typename std::decay_t<
decltype(dot_mat)>::value_type> mcoeff(dot_mat.data(), mcoeff_dim);
483 for (
size_t j = 0; j < nR; ++j) {
484 mcoeff(0, j) = -mcoeff(0, j) / norm;
486 handler.gemm_outer(mcoeff,
cwrap_arg(xparams.at(i).get()), rparams);
491 prof->start(
"orthoganalise");
492 orthogonalise(pparams, handlers.
rp(), dims.
oP, nP);
493 orthogonalise(qparams, handlers.
rq(), dims.
oQ, nQ);
494 orthogonalise(dparams, handlers.
rq(), dims.
oD, nD);
496 prof->start(
"get null_params");
497 auto null_params = std::vector<int>{};
498 for (
size_t i = 0; i < nR; ++i) {
499 auto norm = std::sqrt(std::abs(handlers.
rr().dot(rparams[i], rparams[i])));
500 if (norm > norm_thresh) {
501 handlers.
rr().scal(1. / norm, rparams[i]);
502 for (
size_t j = i + 1; j < nR; ++j) {
503 auto ov = handlers.
rr().dot(rparams[i], rparams[j]);
504 handlers.
rr().axpy(-ov, rparams[i], rparams[j]);
507 null_params.push_back(i);
517 auto new_indices =
find_ref(wparams, params);
518 auto new_working_set = std::vector<int>{};
519 for (
auto i : new_indices) {
520 new_working_set.emplace_back(working_set.at(i));
522 return new_working_set;
553template <
class R,
class Q,
class P>
561 logger.
trace(
"itsolv::detail::propose_rspace");
564 profiler.
start(
"itsolv::ISubspaceSolver::solutions");
565 auto solutions = subspace_solver.
solutions();
568 logger.
debug(
"delete Q parameter indices = ", q_delete);
569 if (!q_delete.empty()) {
570 auto prof = profiler.
push(
"construct_dspace");
571 auto [dparams, dactions] =
572 construct_dspace(solutions, xspace, q_delete, r_opts.norm_thresh, r_opts.svd_thresh, handlers.
qq(), logger);
573 std::sort(begin(q_delete), end(q_delete), std::greater<int>());
574 for (
auto iq : q_delete)
576 auto wdparams =
wrap(dparams);
577 auto wdactions =
wrap(dactions);
579 auto eigenvalues_ref = subspace_solver.
eigenvalues();
580 subspace_solver.
solve(xspace, solutions.rows());
581 auto eigval_error = std::vector<double>{};
582 std::transform(std::begin(eigenvalues_ref), std::end(eigenvalues_ref), std::begin(subspace_solver.
eigenvalues()),
583 std::back_inserter(eigval_error), [](
auto& e_ref,
auto& e_new) { return std::abs(e_ref - e_new); });
584 logger.
debug(
"eigenvalue error due to new D space = ", eigval_error);
588 auto wresidual =
wrap(residuals.begin(), residuals.begin() + solver.
working_set().size());
589 profiler.
start(
"normalise");
592 profiler.
start(
"append_overlap_with_r");
593 prof->
start(
"append_overlap_with_r");
594 const auto full_overlap =
599 prof->
start(
"redundant_indices");
600 auto redundant_indices =
603 logger.
debug(
"redundant indices = ", redundant_indices);
605 profiler.
start(
"modified_gram_schmidt");
606 prof->
start(
"modified_gram_schmidt");
607 auto null_param_indices =
609 xspace.
cparamsq(), xspace.
cparamsd(), r_opts.norm_thresh, handlers, logger);
613 logger.
debug(
"null parameters = ", null_param_indices);
616 for (
size_t i = 0; i < wresidual.size(); ++i)
617 handlers.
rr().copy(parameters.at(i), wresidual.at(i));
618 profiler.
start(
"get_new_working_set");
621 return new_working_set;
Enhances various operations between pairs of arrays and allows dynamic code injection with uniform in...
Definition: ArrayHandler.h:162
virtual value_type dot(const AL &x, const AR &y)=0
virtual void scal(value_type alpha, AL &x)=0
virtual AL copy(const AR &source)=0
virtual void axpy(value_type alpha, const AR &x, AL &y)=0
virtual void fill(value_type alpha, AL &x)=0
decltype(check_abs< value_type >()) value_type_abs
Definition: ArrayHandler.h:182
Non-owning container taking a pointer to the data buffer and its size and exposing routines for itera...
Definition: Span.h:31
Class, containing a collection of array handlers used in IterativeSolver Provides a Builder sub-class...
Definition: ArrayHandlers.h:25
auto & qq()
Definition: ArrayHandlers.h:40
auto & rp()
Definition: ArrayHandlers.h:44
auto & rr()
Definition: ArrayHandlers.h:39
auto & rq()
Definition: ArrayHandlers.h:42
Base class defining the interface common to all iterative solvers.
Definition: IterativeSolver.h:209
virtual const std::vector< int > & working_set() const =0
Working set of roots that are not yet converged.
void info(std::string_view message, Ts &&...args) const
Definition: Logger.h:505
void warn(std::string_view message, Ts &&...args) const
Definition: Logger.h:510
void debug(std::string_view message, Ts &&...args) const
Definition: Logger.h:500
void data_dump(std::string_view what, Ts...data) const
Definition: Logger.h:526
void trace(std::string_view message, Ts &&...args) const
Definition: Logger.h:495
SubspaceData< value_type > data
Equation data in the subspace.
Definition: IXSpace.h:28
virtual CVecRef< Q > cparamsq() const =0
virtual CVecRef< P > cparamsp() const =0
virtual CVecRef< Q > cactionsd() const =0
virtual void eraseq(size_t i)=0
Removes parameter i from Q subspace.
virtual CVecRef< Q > cactionsq() const =0
virtual CVecRef< Q > cparamsd() const =0
virtual const Dimensions & dimensions() const =0
virtual void update_dspace(VecRef< Q > ¶ms, VecRef< Q > &actions)=0
Updates D space with the new parameters.
Slice row(size_t i)
Access row slice.
Definition: Matrix.h:120
void remove_row(index_type row)
removes a row from the matrix
Definition: Matrix.h:144
const std::vector< T > & data() const &
Access the underlying data buffer.
Definition: Matrix.h:67
size_t size() const
Definition: Matrix.h:170
index_type rows() const
Definition: Matrix.h:167
index_type cols() const
Definition: Matrix.h:168
Profiler & start(const std::string &name)
Profiler & stop(const std::string &name="")
Proxy push(const std::string &name)
static std::shared_ptr< Profiler > single()
auto construct_projected_solution(const subspace::Matrix< value_type > &solutions, const subspace::Dimensions &dims, const std::vector< std::size_t > &remove_qspace, Logger &logger)
Projects solution from the full subspace on to Q_{delete} and current D space.
Definition: propose_rspace.h:53
auto construct_projected_solutions_overlap(const subspace::Matrix< value_type > &solutions_proj, const subspace::Matrix< value_type > &overlap, const subspace::Dimensions &dims, const std::vector< std::size_t > &remove_qspace, Logger &logger)
Constructs overlap matrix for projected solutions.
Definition: propose_rspace.h:86
auto remove_null_projected_solutions(const subspace::Matrix< value_type > &solutions_proj, const subspace::Matrix< value_type > &overlap_proj, const value_type_abs svd_thresh, Logger &logger)
Transforms to a stable subspace of projected solutions via SVD.
Definition: propose_rspace.h:169
void remove_null_norm_and_normalise(subspace::Matrix< value_type > ¶meters, subspace::Matrix< value_type > &overlap, const value_type_abs norm_thresh, Logger &logger)
Removes parameters with norm less than threshold and normalises the rest.
Definition: propose_rspace.h:130
auto construct_full_subspace_overlap(const subspace::Matrix< value_type > &solutions_proj, const subspace::Dimensions &dims, const std::vector< std::size_t > &remove_qspace, const subspace::Matrix< value_type > &overlap, const size_t nR)
Constructs overlap matrix of P+Q+R+(projected solutions) subspaces, where Q is without removed parame...
Definition: propose_rspace.h:201
Definition: helper-dispatch.h:140
void normalise(const size_t n_roots, const VecRef< R > ¶ms, const VecRef< R > &actions, array::ArrayHandler< R, R > &handler, Logger &logger)
Definition: IterativeSolverTemplate.h:84
auto propose_rspace(IterativeSolver< R, Q, P > &solver, const VecRef< R > ¶meters, const VecRef< R > &residuals, subspace::IXSpace< R, Q, P > &xspace, subspace::ISubspaceSolver< R, Q, P > &subspace_solver, ArrayHandlers< R, Q, P > &handlers, Logger &logger, const RSpaceOptions< typename array::ArrayHandler< R, R >::value_type_abs > &r_opts, const QSpaceOptions &q_opts, molpro::profiler::Profiler &profiler)
Proposes new parameters for the subspace from the preconditioned residuals.
Definition: propose_rspace.h:554
auto construct_dspace(const subspace::Matrix< value_type > &solutions, const subspace::IXSpace< R, Q, P > &xspace, const std::vector< std::size_t > &q_delete, const value_type_abs norm_thresh, const value_type_abs svd_thresh, array::ArrayHandler< Q, Q > &handler, Logger &logger)
Constructs the new D space by projecting the solutions onto Qd+D subspace and ensuring they are well ...
Definition: propose_rspace.h:391
auto get_new_working_set(const std::vector< int > &working_set, const CVecRef< R > ¶ms, const CVecRef< R > &wparams)
Returns new working set based on parameters included in wparams.
Definition: propose_rspace.h:516
auto append_overlap_with_r(const subspace::Matrix< value_type > &overlap, const CVecRef< R > ¶ms, const CVecRef< P > &pparams, const CVecRef< Q > &qparams, const CVecRef< Q > &dparams, ArrayHandlers< R, Q, P > &handlers, Logger &logger)
Constructs overlap of the full subspace by appending overlap with new parameters to the overlap of pr...
Definition: propose_rspace.h:282
std::vector< std::size_t > limit_qspace_size(const subspace::Dimensions &dims, const QSpaceOptions &opts, const subspace::Matrix< value_type > &solutions, Logger &logger)
Ensures that size Q space is within limit by proposing Q parameters for deletion.
Definition: propose_rspace.h:319
auto modified_gram_schmidt(const VecRef< R > &rparams, const subspace::Matrix< value_type > &overlap, const subspace::Dimensions &dims, const CVecRef< P > &pparams, const CVecRef< Q > &qparams, const CVecRef< Q > &dparams, const value_type_abs norm_thresh, ArrayHandlers< R, Q, P > &handlers, Logger &logger)
Orthogonalises R parameters against P+Q+D subspace (and themselves)
Definition: propose_rspace.h:468
auto redundant_parameters(const subspace::Matrix< value_type > &overlap, const size_t oR, const size_t nR, const value_type_abs svd_thresh, Logger &logger)
Deduces a set of parameters that are redundant due to linear dependencies.
Definition: helper-implementation.h:627
auto overlap(const CVecRef< R > &left, const CVecRef< Q > &right, array::ArrayHandler< Z, W > &handler) -> std::enable_if_t< detail::Z_and_W_are_one_of_R_and_Q< R, Q, Z, W >, Matrix< typename array::ArrayHandler< Z, W >::value_type > >
Calculates overlap matrix between left and right vectors.
Definition: util.h:51
void delete_parameters(std::vector< int > indices, Container ¶ms)
Removes parameters.
Definition: util.h:98
auto cwrap(ForwardIt begin, ForwardIt end)
Takes a begin and end iterators and returns a vector of references to each element.
Definition: wrap.h:52
auto cwrap_arg(T &&arg, S &&... args) -> std::enable_if_t< std::conjunction_v< std::is_same< decay_t< T >, decay_t< S > >... >, CVecRef< decay_t< T > > >
Constructs a vector of const reference wrappers with provided arguments.
Definition: wrap.h:149
auto wrap(ForwardIt begin, ForwardIt end)
Takes a begin and end iterators and returns a vector of references to each element.
Definition: wrap.h:32
std::vector< std::reference_wrapper< const A > > CVecRef
Definition: wrap.h:14
std::list< SVD< value_type > > svd_system(size_t nrows, size_t ncols, const array::Span< value_type > &m, real_type_t< value_type > threshold, bool hermitian=false, bool reduce_to_rank=false)
Performs singular value decomposition and returns SVD objects for singular values less than threshold...
Definition: helper-implementation.h:213
std::vector< std::reference_wrapper< A > > VecRef
Definition: wrap.h:11
std::vector< size_t > find_ref(const VecRef< R > &wparams, ForwardIt begin, ForwardIt end)
Given wrapped references in wparams and a range of original parameters [begin, end),...
Definition: wrap_util.h:17
real_type_t< value_type > precision_scaled(double tolerance_for_double)
Rescale a tolerance that was calibrated for IEEE double precision to the working precision.
Definition: scalar_traits.h:54
Stores partitioning of XSpace into P, Q and R blocks with sizes and offsets for each one.
Definition: Dimensions.h:8
size_t oQ
Definition: Dimensions.h:16
size_t nD
Definition: Dimensions.h:13
size_t nX
Definition: Dimensions.h:14
size_t nQ
Definition: Dimensions.h:12
size_t nP
Definition: Dimensions.h:11
size_t oP
Definition: Dimensions.h:15
size_t oD
Definition: Dimensions.h:17
Manages solution of the subspace problem and storage of those solutions.
Definition: ISubspaceSolver.h:21
virtual void solve(IXSpace< R, Q, P > &xspace, size_t nroots_max)=0
Solve the subspace problem.
virtual const std::vector< value_type > & eigenvalues() const =0
Access eigenvalues from the last solve() call.
virtual const Matrix< value_type > & solutions() const =0
Access solutions from the last solve() call.