iterative-solver 0.0
QSpace.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_QSPACE_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_QSPACE_H
3#include <array>
4#include <cassert>
5#include <list>
6
7#include <molpro/linalg/itsolv/ArrayHandlers.h>
8#include <molpro/linalg/itsolv/Logger.h>
9#include <molpro/linalg/itsolv/subspace/Dimensions.h>
10#include <molpro/linalg/itsolv/subspace/PSpace.h>
11#include <molpro/linalg/itsolv/wrap.h>
12
14
15namespace qspace {
19template <class Q>
20struct QParam {
21 std::unique_ptr<Q> param;
22 std::unique_ptr<Q> action;
23 size_t id;
24};
25
27template <class Q, class ForwardIt>
28auto cwrap_params(ForwardIt begin, ForwardIt end) {
29 auto param_action = std::array<CVecRef<Q>, 2>{};
30 for (auto it = begin; it != end; ++it) {
31 param_action[0].emplace_back(*it->param);
32 param_action[1].emplace_back(*it->action);
33 }
34 return param_action;
35}
36
37template <class Q, class ForwardIt>
38auto wrap_params(ForwardIt begin, ForwardIt end) {
39 auto param_action = std::array<VecRef<Q>, 2>{};
40 for (auto it = begin; it != end; ++it) {
41 param_action[0].emplace_back(*it->param);
42 param_action[1].emplace_back(*it->action);
43 }
44 return param_action;
45}
46} // namespace qspace
47
55template <class Rt, class Qt, class Pt>
56struct QSpace {
57 using R = Rt;
58 using Q = Qt;
59 using P = Pt;
62
63 explicit QSpace(std::shared_ptr<ArrayHandlers<R, Q, P>> handlers, std::shared_ptr<Logger> logger)
64 : m_handlers(std::move(handlers)), m_logger(std::move(logger)) {}
65
76 void update(const CVecRef<R>& params, const CVecRef<R>& actions, const SubspaceData& qq, const SubspaceData& qx,
77 const SubspaceData& xq, const Dimensions& dims, SubspaceData& old_data) {
78 m_logger->msg("QSpace::update", Logger::Trace);
79 auto it_begin = m_params.begin();
80 for (size_t i = 0; i < params.size(); ++i) {
81 m_params.emplace(it_begin,
82 qspace::QParam<Q>{std::make_unique<Q>(m_handlers->qr().copy(params.at(i))),
83 std::make_unique<Q>(m_handlers->qr().copy(actions.at(i))), m_unique_id++});
84 }
85 const size_t nQnew = params.size();
86 const auto nXnew = dims.nX + nQnew;
87 auto data = old_data;
88 for (auto d : {EqnData::H, EqnData::S}) {
89 data[d].resize({dims.nX + nQnew, dims.nX + nQnew});
90 data[d].slice({dims.oQ + nQnew, dims.oQ + nQnew}, {data[d].rows(), data[d].cols()}) =
91 old_data[d].slice({dims.oQ, dims.oQ}, {dims.nX, dims.nX});
92 data[d].slice({dims.oQ, dims.oQ}, {dims.oQ + nQnew, dims.oQ + nQnew}) = qq.at(d);
93 data[d].slice({dims.oQ, 0}, {dims.oQ + nQnew, dims.oQ}) = qx.at(d).slice({0, 0}, {nQnew, dims.oQ});
94 data[d].slice({dims.oQ, dims.oQ + nQnew}, {dims.oQ + nQnew, nXnew}) =
95 qx.at(d).slice({0, dims.oQ}, {nQnew, dims.nX});
96 data[d].slice({0, dims.oQ}, {dims.oQ, dims.oQ + nQnew}) = xq.at(d).slice({0, 0}, {dims.oQ, nQnew});
97 data[d].slice({dims.oQ + nQnew, dims.oQ}, {nXnew, dims.oQ + nQnew}) =
98 xq.at(d).slice({dims.oQ, 0}, {dims.nX, nQnew});
99 data[d].slice({0, 0}, {dims.oQ, dims.oQ}) = old_data[d].slice({0, 0}, {dims.oQ, dims.oQ});
100 data[d].slice({0, dims.oQ + nQnew}, {dims.oQ, nXnew}) = old_data[d].slice({0, dims.oQ}, {dims.oQ, dims.nX});
101 data[d].slice({dims.oQ + nQnew, 0}, {nXnew, dims.oQ}) = old_data[d].slice({dims.oQ, 0}, {dims.nX, dims.oQ});
102 old_data[d] = data[d];
103 }
104 if (!qq.at(EqnData::rhs).empty()) {
105 data[EqnData::rhs].resize({dims.nX + nQnew, dims.nRHS});
106 data[EqnData::rhs].slice({dims.oQ, 0}, {dims.oQ + nQnew, dims.nRHS}) = qq.at(EqnData::rhs).slice();
107 data[EqnData::rhs].slice({dims.oQ + nQnew, 0}, {dims.nX + nQnew, dims.nRHS}) =
108 old_data[EqnData::rhs].slice({dims.oQ, 0}, {dims.nX, dims.nRHS});
109 old_data[EqnData::rhs] = data[EqnData::rhs];
110 }
111 if (m_logger->data_dump) {
112 m_logger->msg("S = " + as_string(data.at(EqnData::S)), Logger::Info);
113 m_logger->msg("H = " + as_string(data.at(EqnData::H)), Logger::Info);
114 m_logger->msg("rhs = " + as_string(data.at(EqnData::rhs)), Logger::Info);
115 }
116 }
117
118 void clear() { m_params.clear(); }
119
121 void erase(size_t i) {
122 assert(m_params.size() > i);
123 auto it = std::next(begin(m_params), i);
124 m_params.erase(it);
125 }
126
127 size_t size() const { return m_params.size(); }
128
130 auto qparams = qspace::wrap_params<Q>(m_params.begin(), m_params.end());
131 return qparams[0];
132 }
133
135 auto qparams = qspace::cwrap_params<Q>(m_params.begin(), m_params.end());
136 return qparams[0];
137 }
138
139 CVecRef<Q> cparams() const { return params(); }
140
142 auto qparams = qspace::wrap_params<Q>(m_params.begin(), m_params.end());
143 return qparams[1];
144 }
145
147 auto qparams = qspace::cwrap_params<Q>(m_params.begin(), m_params.end());
148 return qparams[1];
149 }
150
151 CVecRef<Q> cactions() const { return actions(); }
152
153protected:
154 std::shared_ptr<ArrayHandlers<R, Q, P>> m_handlers;
155 std::shared_ptr<Logger> m_logger;
156 size_t m_unique_id{0};
157 std::list<qspace::QParam<Q>> m_params;
158};
159
160} // namespace molpro::linalg::itsolv::subspace
161
162#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_QSPACE_H
decltype(value_type_L{} *value_type_R{}) value_type
Definition: ArrayHandler.h:181
decltype(check_abs< value_type >()) value_type_abs
Definition: ArrayHandler.h:182
Class, containing a collection of array handlers used in IterativeSolver Provides a Builder sub-class...
Definition: ArrayHandlers.h:25
auto wrap_params(ForwardIt begin, ForwardIt end)
Definition: QSpace.h:38
auto cwrap_params(ForwardIt begin, ForwardIt end)
Generates vector of reference wrappers to param and action in a range of QParam objects.
Definition: QSpace.h:28
Definition: PSpace.h:7
std::map< EqnData, Matrix< double > > SubspaceData
Definition: SubspaceData.h:9
std::string as_string(const Mat &m, int precision=6)
Definition: Matrix.h:289
std::vector< std::reference_wrapper< const A > > CVecRef
Definition: wrap.h:14
std::vector< std::reference_wrapper< A > > VecRef
Definition: wrap.h:11
@ Info
Definition: Logger.h:49
@ Trace
Definition: Logger.h:49
Stores partitioning of XSpace into P, Q and R blocks with sizes and offsets for each one.
Definition: Dimensions.h:5
size_t oQ
Definition: Dimensions.h:13
size_t nX
Definition: Dimensions.h:11
size_t nRHS
number of rigt-hand-side vectors in the system of linear equations
Definition: Dimensions.h:15
Container storing the Q space parameters.
Definition: QSpace.h:56
typename array::ArrayHandler< R, R >::value_type_abs value_type_abs
Definition: QSpace.h:61
std::shared_ptr< ArrayHandlers< R, Q, P > > m_handlers
Definition: QSpace.h:154
void update(const CVecRef< R > &params, const CVecRef< R > &actions, const SubspaceData &qq, const SubspaceData &qx, const SubspaceData &xq, const Dimensions &dims, SubspaceData &old_data)
Prepends parameters to the start of Q space.
Definition: QSpace.h:76
VecRef< Q > params()
Definition: QSpace.h:129
typename array::ArrayHandler< R, R >::value_type value_type
Definition: QSpace.h:60
CVecRef< Q > cactions() const
Definition: QSpace.h:151
size_t size() const
Definition: QSpace.h:127
void clear()
Definition: QSpace.h:118
CVecRef< Q > cparams() const
Definition: QSpace.h:139
size_t m_unique_id
unique id for any new parameter set
Definition: QSpace.h:156
void erase(size_t i)
Erases q parameter i.
Definition: QSpace.h:121
std::list< qspace::QParam< Q > > m_params
q parameter sets with new parameters first
Definition: QSpace.h:157
std::shared_ptr< Logger > m_logger
Definition: QSpace.h:155
VecRef< Q > actions()
Definition: QSpace.h:141
QSpace(std::shared_ptr< ArrayHandlers< R, Q, P > > handlers, std::shared_ptr< Logger > logger)
Definition: QSpace.h:63
CVecRef< Q > params() const
Definition: QSpace.h:134
CVecRef< Q > actions() const
Definition: QSpace.h:146
Parameter in the Q space.
Definition: QSpace.h:20
std::unique_ptr< Q > param
parameter
Definition: QSpace.h:21
std::unique_ptr< Q > action
corresponding action
Definition: QSpace.h:22
size_t id
unique id
Definition: QSpace.h:23