iterative-solver 0.0
 
Loading...
Searching...
No Matches
XSpace.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_XSPACE_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_XSPACE_H
3#include <Eigen/Dense>
4#include <molpro/linalg/itsolv/helper.h>
5#include <molpro/linalg/itsolv/subspace/DSpace.h>
6#include <molpro/linalg/itsolv/subspace/Dimensions.h>
7#include <molpro/linalg/itsolv/subspace/IXSpace.h>
8#include <molpro/linalg/itsolv/subspace/PSpace.h>
9#include <molpro/linalg/itsolv/subspace/QSpace.h>
10#include <molpro/linalg/itsolv/subspace/util.h>
11
12#include <algorithm>
13#include <cassert>
14#include <functional>
15#include <memory>
16#include <stdexcept>
17#include <vector>
18
20namespace xspace {
22template <typename T>
23struct NewData {
25 NewData(size_t nQnew, size_t nX, size_t nRHS, bool metric = false) {
26 if (metric)
27 for (auto* blocks : {&qq, &qx, &xq})
28 (*blocks)[EqnData::M] = {};
29 for (auto d : square_blocks(qq)) {
30 qq[d].resize({nQnew, nQnew});
31 qx[d].resize({nQnew, nX});
32 xq[d].resize({nX, nQnew});
33 }
34 qq[EqnData::rhs].resize({nQnew, nRHS});
35 }
36
40};
41
49template <class R, class Q, class P>
50auto update_qspace_data(const CVecRef<R>& params, const CVecRef<R>& actions, const CVecRef<P>& pparams,
52 const CVecRef<Q>& dactions, const CVecRef<Q>& rhs, const Dimensions& dims,
53 ArrayHandlers<R, Q, P>& handlers, Logger& logger, bool hermitian = false,
54 bool action_dot_action = false, const CVecRef<R>& metric_actions = {}) {
55 auto nQnew = params.size();
56 const bool metric = !metric_actions.empty();
58 auto& qq = data.qq;
59 auto& qx = data.qx;
60 auto& xq = data.xq;
61 qq[EqnData::S] = util::overlap(params, handlers.rr());
62 // rows nQnew and beyond of the overlaps with the subspace vectors are those of the actions of the metric
63 auto left = params;
64 left.insert(left.end(), metric_actions.begin(), metric_actions.end());
65 auto copy_overlaps = [&](const auto& overlaps, const size_t offset, const size_t size) {
66 qx[EqnData::S].slice({0, offset}, {nQnew, offset + size}) = overlaps.slice({0, 0}, {nQnew, size});
67 if (metric)
68 qx[EqnData::M].slice({0, offset}, {nQnew, offset + size}) = overlaps.slice({nQnew, 0}, {2 * nQnew, size});
69 };
73 qq[EqnData::H] =
74 action_dot_action ? util::overlap(actions, handlers.rr()) : util::overlap(params, actions, handlers.rr());
75 // left-hand vectors of the H matrix elements with existing actions
76 const auto& h_left = action_dot_action ? actions : params;
77 qx[EqnData::H].slice({0, dims.oQ()}, {nQnew, dims.oQ() + dims.nQ}) = util::overlap(h_left, qactions, handlers.rq());
78 qx[EqnData::H].slice({0, dims.oD()}, {nQnew, dims.oD() + dims.nD}) = util::overlap(h_left, dactions, handlers.rq());
79 if (hermitian) {
80 xq[EqnData::H].slice({dims.oP(), 0}, {dims.oP() + dims.nP, nQnew}) = util::overlap(pparams, actions, handlers.rp());
81 // xq[EqnData::H].slice({dims.oQ(), 0}, {dims.oQ() + dims.nQ, nQnew}) = util::overlap(action_dot_action ? qactions :
82 // qparams, actions, handlers.qr());
83 conjugate_transpose_copy(xq[EqnData::H].slice({dims.oQ(), 0}, {dims.oQ() + dims.nQ, nQnew}),
84 qx[EqnData::H].slice({0, dims.oQ()}, {nQnew, dims.oQ() + dims.nQ}));
85 conjugate_transpose_copy(xq[EqnData::H].slice({dims.oD(), 0}, {dims.oD() + dims.nD, nQnew}),
86 qx[EqnData::H].slice({0, dims.oD()}, {nQnew, dims.oD() + dims.nD}));
87 conjugate_transpose_copy(qx[EqnData::H].slice({0, dims.oP()}, {nQnew, dims.oP() + dims.nP}),
88 xq[EqnData::H].slice({dims.oP(), 0}, {dims.oP() + dims.nP, nQnew}));
89 } else {
90 xq[EqnData::H].slice({dims.oQ(), 0}, {dims.oQ() + dims.nQ, nQnew}) = util::overlap(qparams, actions, handlers.rq());
91 xq[EqnData::H].slice({dims.oD(), 0}, {dims.oD() + dims.nD, nQnew}) = util::overlap(dparams, actions, handlers.rq());
92 }
93 if (metric) {
95 conjugate_transpose_copy(xq[EqnData::M].slice(), qx[EqnData::M].slice());
96 }
97 qq[EqnData::rhs] = util::overlap(params, rhs, handlers.rq());
98 conjugate_transpose_copy(xq[EqnData::S].slice({dims.oP(), 0}, {dims.oP() + dims.nP, nQnew}),
99 qx[EqnData::S].slice({0, dims.oP()}, {nQnew, dims.oP() + dims.nP}));
100 conjugate_transpose_copy(xq[EqnData::S].slice({dims.oQ(), 0}, {dims.oQ() + dims.nQ, nQnew}),
101 qx[EqnData::S].slice({0, dims.oQ()}, {nQnew, dims.oQ() + dims.nQ}));
102 conjugate_transpose_copy(xq[EqnData::S].slice({dims.oD(), 0}, {dims.oD() + dims.nD, nQnew}),
103 qx[EqnData::S].slice({0, dims.oD()}, {nQnew, dims.oD() + dims.nD}));
104 logger.data_dump("xspace::update_qspace_data() nQnew = ", nQnew);
105 logger.data_dump("Sqq = ", qq[EqnData::S]);
106 logger.data_dump("Hqq = ", qq[EqnData::H]);
107 logger.data_dump("Sqx = ", qx[EqnData::S]);
108 logger.data_dump("Hqx = ", qx[EqnData::H]);
109 logger.data_dump("Sxq = ", xq[EqnData::S]);
110 logger.data_dump("Hxq = ", xq[EqnData::H]);
111 if (metric) {
112 logger.data_dump("Mqq = ", qq[EqnData::M]);
113 logger.data_dump("Mqx = ", qx[EqnData::M]);
114 }
115 logger.data_dump("rhs_q = ", qq[EqnData::rhs]);
116 return data;
117}
118
120template <class Q, class P>
121auto update_dspace_overlap_data(const CVecRef<P>& pparams, const CVecRef<Q>& qparams, const CVecRef<Q>& dparams,
122 const CVecRef<Q>& rhs, array::ArrayHandler<Q, P>& handler_qp,
123 array::ArrayHandler<Q, Q>& handler_qq, Logger& logger) {
124 const auto nP = pparams.size();
125 const auto nQ = qparams.size();
126 const auto nX = nP + nQ;
127 auto nD = dparams.size();
128 const auto nRHS = rhs.size();
130 data.qq[EqnData::S].slice() = util::overlap(dparams, handler_qq);
131 data.qx[EqnData::S].slice({0, 0}, {nD, nP}) = util::overlap(dparams, pparams, handler_qp);
132 data.qx[EqnData::S].slice({0, nP}, {nD, nX}) = util::overlap(dparams, qparams, handler_qq);
133 data.qq[EqnData::rhs].slice() = util::overlap(dparams, rhs, handler_qq);
134 conjugate_transpose_copy(data.xq[EqnData::S].slice(), data.qx[EqnData::S].slice());
135 logger.data_dump("xspace::update_dspace_overlap_data() nD = ", nD);
136 logger.data_dump("Sdd = ", data.qq[EqnData::S]);
137 logger.data_dump("Sdx = ", data.qx[EqnData::S]);
138 logger.data_dump("rhs_d = ", data.qq[EqnData::rhs]);
139 return data;
140}
141
143template <class Q, class P>
144auto update_dspace_action_data(const CVecRef<P>& pparams, const CVecRef<Q>& qparams, const CVecRef<Q>& qactions,
145 const CVecRef<Q>& dparams, const CVecRef<Q>& dactions,
147 Logger& logger) {
148 const auto nP = pparams.size();
149 const auto nQ = qparams.size();
150 const auto nX = nP + nQ;
151 auto nD = dparams.size();
153 const auto e = EqnData::H;
154 data.qq[e].slice() = util::overlap(dparams, dactions, handler_qq);
155 data.xq[e].slice({0, 0}, {nP, nD}) = util::overlap(pparams, dactions, handler_qp);
156 data.xq[e].slice({nP, 0}, {nX, nD}) = util::overlap(qparams, dactions, handler_qq);
157 data.qx[e].slice({0, nP}, {nD, nX}) = util::overlap(dparams, qactions, handler_qq);
158 conjugate_transpose_copy(data.qx[e].slice({0, 0}, {nD, nP}), data.xq[e].slice({0, 0}, {nP, nD}));
159 logger.data_dump("xspace::update_dspace_action_data() nD = ", nD);
160 logger.data_dump("Hdd = ", data.qq[e]);
161 logger.data_dump("Hdx = ", data.qx[e]);
162 logger.data_dump("Hxd = ", data.xq[e]);
163 return data;
164}
165
175template <typename value_type>
177 const std::vector<std::size_t>& q_delete,
178 const Matrix<value_type>& dcoefficients) {
179 using matrix_type = Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic>;
180 // the kept P and Q vectors, and the deleted Q and old D vectors that the new D vectors are combinations of
181 auto kept = std::vector<size_t>{}, combined = std::vector<size_t>{};
182 for (size_t i = 0; i < dims.nP; ++i)
183 kept.push_back(dims.oP() + i);
184 for (size_t i = 0; i < dims.nQ; ++i)
185 if (std::find(q_delete.begin(), q_delete.end(), i) == q_delete.end())
186 kept.push_back(dims.oQ() + i);
187 for (auto iq : q_delete)
188 combined.push_back(dims.oQ() + iq);
189 for (size_t i = 0; i < dims.nD; ++i)
190 combined.push_back(dims.oD() + i);
191 const auto nK = kept.size(), nB = combined.size(), nDnew = dcoefficients.rows();
192 // only the blocks involving the new D vectors need multiplications, of cost nX * nB * nDnew
193 matrix_type m_kb(nK, nB), m_bb(nB, nB), c(nDnew, nB);
194 for (size_t k = 0; k < nK; ++k)
195 for (size_t j = 0; j < nB; ++j)
196 m_kb(k, j) = metric(kept[k], combined[j]);
197 for (size_t i = 0; i < nB; ++i)
198 for (size_t j = 0; j < nB; ++j)
199 m_bb(i, j) = metric(combined[i], combined[j]);
200 for (size_t i = 0; i < nDnew; ++i)
201 for (size_t j = 0; j < nB; ++j)
202 c(i, j) = dcoefficients(i, j);
203 // <k|M d_i> = sum_j <k|M b_j> c_ij, and <d_i|M d_l> = sum_jm conj(c_ij) <b_j|M b_m> c_lm
204 const matrix_type m_kd = m_kb * c.transpose();
205 const matrix_type m_dd = c.conjugate() * m_bb * c.transpose();
206 const auto nXnew = nK + nDnew;
207 auto m_new = Matrix<value_type>({nXnew, nXnew});
208 for (size_t k = 0; k < nK; ++k)
209 for (size_t l = 0; l < nK; ++l)
210 m_new(k, l) = metric(kept[k], kept[l]);
211 for (size_t k = 0; k < nK; ++k)
212 for (size_t i = 0; i < nDnew; ++i) {
213 m_new(k, nK + i) = m_kd(k, i);
214 m_new(nK + i, k) = conjugate(m_kd(k, i));
215 }
216 for (size_t i = 0; i < nDnew; ++i)
217 for (size_t l = 0; l < nDnew; ++l)
218 m_new(nK + i, nK + l) = m_dd(i, l);
219 return m_new;
220}
221
222template <typename T>
224 const Dimensions& dims) {
225 const auto& dd = new_data.qq.at(e);
226 const auto& dx = new_data.qx.at(e);
227 const auto& xd = new_data.xq.at(e);
228 data[e].slice({dims.oD(), dims.oD()}, {dims.oD() + dims.nD, dims.oD() + dims.nD}) = dd;
229 data[e].slice({dims.oD(), dims.oP()}, {dims.oD() + dims.nD, dims.oP() + dims.nP}) =
230 dx.slice({0, 0}, {dims.nD, dims.nP});
231 data[e].slice({dims.oD(), dims.oQ()}, {dims.oD() + dims.nD, dims.oQ() + dims.nQ}) =
232 dx.slice({0, dims.nP}, {dims.nD, dims.nP + dims.nQ});
233 data[e].slice({dims.oP(), dims.oD()}, {dims.oP() + dims.nP, dims.oD() + dims.nD}) =
234 xd.slice({0, 0}, {dims.nP, dims.nD});
235 data[e].slice({dims.oQ(), dims.oD()}, {dims.oQ() + dims.nQ, dims.oD() + dims.nD}) =
236 xd.slice({dims.nP, 0}, {dims.nP + dims.nQ, dims.nD});
237}
238} // namespace xspace
239
240template <class R, class Q, class P>
241class XSpace : public IXSpace<R, Q, P> {
242public:
243 using typename IXSpace<R, Q, P>::value_type;
245 using IXSpace<R, Q, P>::data;
246 using IXSpace<R, Q, P>::stores_metric_actions;
247
248 explicit XSpace(const std::shared_ptr<ArrayHandlers<R, Q, P>>& handlers, const std::shared_ptr<Logger>& logger)
249 : pspace(), qspace(handlers, logger), dspace(logger), m_handlers(handlers), m_logger(logger) {
250 data = null_data<value_type, EqnData::H, EqnData::S, EqnData::rhs>();
251 };
252
253 void set_metric(MetricKind kind, MetricStorage storage = MetricStorage::Stored) override {
254 if (kind == m_metric_kind && storage == m_metric_storage)
255 return;
256 if (m_dim.nX() != 0)
257 throw std::logic_error("XSpace::set_metric: the metric cannot be changed once the subspace is not empty");
258 m_metric_kind = kind;
259 m_metric_storage = storage;
260 if (metric_kind() != MetricKind::Identity)
261 data[EqnData::M] = {};
262 else
263 data.erase(EqnData::M);
264 }
265
266 MetricKind metric_kind() const override { return m_metric_kind; }
267 MetricStorage metric_storage() const override { return m_metric_storage; }
268
270 void update_qspace(const CVecRef<R>& params, const CVecRef<R>& actions,
271 const CVecRef<R>& metric_actions = {}) override {
272 m_logger->trace("QSpace::update_qspace");
273 if (metric_actions.size() != (metric_kind() != MetricKind::Identity ? params.size() : 0))
274 throw std::invalid_argument(
275 "XSpace::update_qspace: actions of the metric must be given for every parameter exactly when there is a "
276 "metric");
277 auto new_data = xspace::update_qspace_data(params, actions, cparamsp(), cparamsq(), cactionsq(), cparamsd(),
278 cactionsd(), cwrap(m_rhs), m_dim, *m_handlers, *m_logger, m_hermitian,
279 m_action_dot_action, metric_actions);
280 qspace.update(params, actions, new_data.qq, new_data.qx, new_data.xq, m_dim, data,
281 stores_metric_actions() ? metric_actions : CVecRef<R>{});
282 update_dimensions();
283 }
284
286 void update_dspace(VecRef<Q>& params, VecRef<Q>& actions, const VecRef<Q>& metric_actions = {},
287 const std::vector<size_t>& q_delete = {}, const Matrix<value_type>& coefficients = {}) override {
288 if (metric_actions.size() != (stores_metric_actions() ? params.size() : 0))
289 throw std::invalid_argument(
290 "XSpace::update_dspace: actions of the metric must be given exactly when they are stored");
291 if (metric_kind() != MetricKind::Identity && !params.empty() &&
292 (coefficients.rows() != params.size() || coefficients.cols() != q_delete.size() + m_dim.nD))
293 throw std::invalid_argument("XSpace::update_dspace: the coefficients of the new D vectors are needed");
294 // the metric matrix of the new subspace is transformed from the current one, before the subspace changes
295 const auto metric_matrix = metric_kind() != MetricKind::Identity && !params.empty()
296 ? xspace::metric_with_new_dspace(data.at(EqnData::M), m_dim, q_delete, coefficients)
297 : Matrix<value_type>{};
299 std::sort(q_delete_descending.begin(), q_delete_descending.end(), std::greater<>());
300 for (auto iq : q_delete_descending)
301 eraseq(iq);
302 dspace.update(params, actions, metric_actions);
303 update_dimensions();
304 for (auto e : square_blocks(data))
305 data[e].resize({m_dim.nX(), m_dim.nX()});
306 auto new_data = xspace::update_dspace_overlap_data(cparamsp(), cparamsq(), cparamsd(), cwrap(m_rhs),
307 m_handlers->qp(), m_handlers->qq(), *m_logger);
310 cparamsp(), cparamsq(), cactionsq(), cparamsd(), cactionsd(), m_handlers->qp(), m_handlers->qq(), *m_logger);
312 if (metric_kind() != MetricKind::Identity && m_dim.nD > 0)
314 data[EqnData::rhs].resize({m_dim.nX(), m_dim.nRHS});
315 data[EqnData::rhs].slice({m_dim.oD(), 0}, {m_dim.oD() + m_dim.nD, m_dim.nRHS}) = new_data.qq[EqnData::rhs].slice();
316 }
317
318 // FIXME this must be called when XSpace is empty
320 void update_pspace(const CVecRef<P>& params, const array::Span<value_type>& pp_action_matrix,
321 const array::Span<value_type>& pp_metric_matrix = {}) override {
322 assert(m_dim.nX() == 0);
323 if (!m_hermitian)
324 throw std::runtime_error("P space can only be used with hermitian kernels");
325 const size_t nPnew = params.size();
326 if (pp_metric_matrix.size() != (metric_kind() != MetricKind::Identity ? nPnew * nPnew : 0))
327 throw std::invalid_argument("XSpace::update_pspace: the metric matrix in the P space must be given exactly when "
328 "there is a metric");
329 pspace.update(params, m_handlers->pp());
330 update_dimensions();
331 const size_t nP = m_dim.nP;
332 update_rhs_with_pspace();
333 data[EqnData::S].resize({nP, nP});
334 data[EqnData::H].resize({nP, nP});
335 data[EqnData::S].slice() = util::overlap(params, m_handlers->pp());
336 for (size_t i = 0, ij = 0; i < nP; ++i)
337 for (size_t j = 0; j < nP; ++j, ++ij)
338 data[EqnData::H](i, j) = pp_action_matrix[ij];
339 if (metric_kind() != MetricKind::Identity) {
340 data[EqnData::M].resize({nP, nP});
341 for (size_t i = 0, ij = 0; i < nP; ++i)
342 for (size_t j = 0; j < nP; ++j, ++ij)
343 data[EqnData::M](i, j) = pp_metric_matrix[ij];
344 }
345 }
346
349 m_rhs.reserve(m_rhs.size() + rhs.size());
350 for (const auto& r : rhs)
351 m_rhs.emplace_back(this->m_handlers->qr().copy(r));
352 for (const auto& r : rhs) {
353 auto d = std::abs(this->m_handlers->rr().dot(r, r));
354 if (d == 0)
355 throw std::runtime_error("RHS vector cannot be zero");
356 m_rhs_norm.emplace_back(std::sqrt(d));
357 }
358 update_dimensions();
359 update_rhs_with_pspace();
360 }
361
363 CVecRef<Q> rhs() const { return cwrap(m_rhs); }
364
366 const std::vector<value_type_abs>& rhs_norm() const { return m_rhs_norm; }
367
368 const Dimensions& dimensions() const override { return m_dim; }
369
370 void erase(size_t i) override {
371 if (i >= m_dim.oP() && i < m_dim.oP() + m_dim.nP) {
372 erasep(i - m_dim.oP());
373 } else if (i >= m_dim.oQ() && i < m_dim.oQ() + m_dim.nQ) {
374 eraseq(i - m_dim.oQ());
375 } else if (i >= m_dim.oD() && i < m_dim.oD() + m_dim.nD) {
376 erased(i - m_dim.oD());
377 }
378 }
379
380 void eraseq(size_t i) override {
381 qspace.erase(i);
382 remove_data(m_dim.oQ() + i);
383 update_dimensions();
384 }
385
386 void erasep(size_t i) override {
387 pspace.erase(i);
388 remove_data(m_dim.oP() + i);
389 update_dimensions();
390 }
391
392 void erased(size_t i) override {
393 dspace.erase(i);
394 remove_data(m_dim.oD() + i);
395 update_dimensions();
396 }
397
398 VecRef<P> paramsp() override { return pspace.params(); }
399 VecRef<Q> paramsq() override { return qspace.params(); }
400 VecRef<Q> actionsq() override { return qspace.actions(); }
401 VecRef<Q> paramsd() override { return dspace.params(); }
402 VecRef<Q> actionsd() override { return dspace.actions(); }
403
404 CVecRef<P> paramsp() const override { return pspace.params(); }
405 CVecRef<Q> paramsq() const override { return qspace.params(); }
406 CVecRef<Q> actionsq() const override { return qspace.actions(); }
407 CVecRef<Q> paramsd() const override { return dspace.cparams(); }
408 CVecRef<Q> actionsd() const override { return dspace.cactions(); }
409
410 CVecRef<P> cparamsp() const override { return pspace.cparams(); }
411 CVecRef<Q> cparamsq() const override { return qspace.cparams(); }
412 CVecRef<Q> cactionsq() const override { return qspace.cactions(); }
413 CVecRef<Q> cparamsd() const override { return dspace.cparams(); }
414 CVecRef<Q> cactionsd() const override { return dspace.cactions(); }
415
416 CVecRef<Q> cmetric_actionsq() const override { return qspace.cmetric_actions(); }
417 CVecRef<Q> cmetric_actionsd() const override { return dspace.cmetric_actions(); }
418
419 void set_logger(std::shared_ptr<Logger> logger) override {
420 qspace.set_logger(logger);
421 dspace.set_logger(logger);
422 m_logger = std::move(logger);
423 }
424
426 void set_hermiticity(bool hermitian) { m_hermitian = hermitian; }
427 bool get_hermiticity() { return m_hermitian; }
428 void set_action_action() { m_action_dot_action = true; }
429
433
434protected:
436 m_dim = Dimensions(pspace.size(), qspace.size(), dspace.size());
437 m_dim.nRHS = m_rhs.size();
438 }
439
442 data[EqnData::rhs].resize({m_dim.nP, m_dim.nRHS});
443 data[EqnData::rhs].slice() = util::overlap(cparamsp(), rhs(), m_handlers->qp());
444 };
445
446 void remove_data(size_t i) {
447 for (auto d : square_blocks(data))
448 data[d].remove_row_col(i, i);
449 if (data.find(EqnData::rhs) != std::end(data) && !data[EqnData::rhs].empty())
450 data[EqnData::rhs].remove_row(i);
451 if (data.find(EqnData::value) != std::end(data) && !data[EqnData::value].empty())
452 data[EqnData::value].remove_row(i);
453 }
454 std::shared_ptr<ArrayHandlers<R, Q, P>> m_handlers;
455 std::shared_ptr<Logger> m_logger;
457 std::vector<Q> m_rhs;
458 std::vector<value_type_abs> m_rhs_norm;
459 bool m_hermitian = false;
460 bool m_action_dot_action = false;
463};
464
465} // namespace molpro::linalg::itsolv::subspace
466#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_XSPACE_H
Enhances various operations between pairs of arrays and allows dynamic code injection with uniform in...
Definition ArrayHandler.h:163
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
Logger class implementation. Provides (customizable) logging functionalities.
Definition Logger.h:370
void data_dump(std::string_view what, const T &data) const
Dumps data (context log::DataDump<T>, verbosity Trace). Nothing is copied.
Definition Logger.h:496
D space stores complement of P+Q+R subspace that is necessary to reproduce the previous solutions.
Definition DSpace.h:17
size_t size() const
Definition DSpace.h:56
Full subspace.
Definition IXSpace.h:21
typename array::ArrayHandler< R, R >::value_type_abs value_type_abs
Definition IXSpace.h:27
typename array::ArrayHandler< R, R >::value_type value_type
Definition IXSpace.h:26
Matrix container that allows simple data access, slicing, copying and resizing without loosing data.
Definition Matrix.h:32
size_t size() const
Definition Matrix.h:172
index_type rows() const
Definition Matrix.h:169
size_t size() const
Definition PSpace.h:24
CVecRef< Q > cparamsq() const override
Definition XSpace.h:411
bool get_hermiticity()
Definition XSpace.h:427
CVecRef< Q > cactionsq() const override
Definition XSpace.h:412
void remove_data(size_t i)
Definition XSpace.h:446
void update_dimensions()
Definition XSpace.h:435
std::vector< Q > m_rhs
Right hand side vectors.
Definition XSpace.h:457
CVecRef< P > cparamsp() const override
Definition XSpace.h:410
void update_qspace(const CVecRef< R > &params, const CVecRef< R > &actions, const CVecRef< R > &metric_actions={}) override
Update parameters in Q space and corresponding equation data.
Definition XSpace.h:270
CVecRef< Q > cparamsd() const override
Definition XSpace.h:413
void update_dspace(VecRef< Q > &params, VecRef< Q > &actions, const VecRef< Q > &metric_actions={}, const std::vector< size_t > &q_delete={}, const Matrix< value_type > &coefficients={}) override
Replaces the old D space and the Q vectors q_delete by new D vectors, see IXSpace::update_dspace()
Definition XSpace.h:286
void add_rhs_equations(const CVecRef< R > &rhs)
For a system of linear equations Ax=b, adds rhs vectors b.
Definition XSpace.h:348
void erased(size_t i) override
Removes parameter i from D subspace.
Definition XSpace.h:392
CVecRef< Q > cmetric_actionsq() const override
Actions of the metric on the Q space parameters, empty unless there is a metric.
Definition XSpace.h:416
VecRef< Q > actionsd() override
Definition XSpace.h:402
std::vector< value_type_abs > m_rhs_norm
norm of RHS vectors
Definition XSpace.h:458
PSpace< R, P > pspace
Definition XSpace.h:430
CVecRef< Q > rhs() const
Access RHS vectors in linear equations.
Definition XSpace.h:363
CVecRef< Q > paramsq() const override
Definition XSpace.h:405
Dimensions m_dim
Definition XSpace.h:456
CVecRef< Q > actionsq() const override
Definition XSpace.h:406
std::shared_ptr< Logger > m_logger
Definition XSpace.h:455
VecRef< Q > paramsq() override
Definition XSpace.h:399
CVecRef< Q > paramsd() const override
Definition XSpace.h:407
VecRef< P > paramsp() override
Definition XSpace.h:398
VecRef< Q > paramsd() override
Definition XSpace.h:401
const Dimensions & dimensions() const override
Definition XSpace.h:368
CVecRef< Q > cmetric_actionsd() const override
Actions of the metric on the D space parameters, empty unless there is a metric.
Definition XSpace.h:417
VecRef< Q > actionsq() override
Definition XSpace.h:400
void set_metric(MetricKind kind, MetricStorage storage=MetricStorage::Stored) override
Declares the metric of the subspace. Anything other than MetricKind::Identity creates the metric matr...
Definition XSpace.h:253
CVecRef< P > paramsp() const override
Definition XSpace.h:404
std::shared_ptr< ArrayHandlers< R, Q, P > > m_handlers
Definition XSpace.h:454
void eraseq(size_t i) override
Removes parameter i from Q subspace.
Definition XSpace.h:380
const std::vector< value_type_abs > & rhs_norm() const
Norm of RHS vectors.
Definition XSpace.h:366
auto update_rhs_with_pspace()
Update projection of RHS data onto P space.
Definition XSpace.h:441
void erasep(size_t i) override
Removes parameter i from P subspace.
Definition XSpace.h:386
QSpace< R, Q, P > qspace
Definition XSpace.h:431
void set_logger(std::shared_ptr< Logger > logger) override
Definition XSpace.h:419
void set_action_action()
Definition XSpace.h:428
CVecRef< Q > actionsd() const override
Definition XSpace.h:408
CVecRef< Q > cactionsd() const override
Definition XSpace.h:414
void update_pspace(const CVecRef< P > &params, const array::Span< value_type > &pp_action_matrix, const array::Span< value_type > &pp_metric_matrix={}) override
Definition XSpace.h:320
void erase(size_t i) override
Removes parameter i from the full subspace.
Definition XSpace.h:370
DSpace< Q > dspace
Definition XSpace.h:432
XSpace(const std::shared_ptr< ArrayHandlers< R, Q, P > > &handlers, const std::shared_ptr< Logger > &logger)
Definition XSpace.h:248
void set_hermiticity(bool hermitian)
Set Hermiticity of the subspace. P space can only be used with Hermitian problems.
Definition XSpace.h:426
MetricKind metric_kind() const override
The kind of metric declared with set_metric()
Definition XSpace.h:266
MetricStorage metric_storage() const override
How the actions of the metric declared with set_metric() are obtained.
Definition XSpace.h:267
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:57
auto update_qspace_data(const CVecRef< R > &params, const CVecRef< R > &actions, const CVecRef< P > &pparams, const CVecRef< Q > &qparams, const CVecRef< Q > &qactions, const CVecRef< Q > &dparams, const CVecRef< Q > &dactions, const CVecRef< Q > &rhs, const Dimensions &dims, ArrayHandlers< R, Q, P > &handlers, Logger &logger, bool hermitian=false, bool action_dot_action=false, const CVecRef< R > &metric_actions={})
Returns new sections of equation data.
Definition XSpace.h:50
auto update_dspace_action_data(const CVecRef< P > &pparams, const CVecRef< Q > &qparams, const CVecRef< Q > &qactions, const CVecRef< Q > &dparams, const CVecRef< Q > &dactions, array::ArrayHandler< Q, P > &handler_qp, array::ArrayHandler< Q, Q > &handler_qq, Logger &logger)
Calculates action blocks between D space and the rest of the subspace.
Definition XSpace.h:144
void copy_dspace_eqn_data(const NewData< T > &new_data, SubspaceData< T > &data, const subspace::EqnData e, const Dimensions &dims)
Definition XSpace.h:223
Matrix< value_type > metric_with_new_dspace(const Matrix< value_type > &metric, const Dimensions &dims, const std::vector< std::size_t > &q_delete, const Matrix< value_type > &dcoefficients)
The metric matrix of the subspace after the deletion of Q vectors and their replacement,...
Definition XSpace.h:176
auto update_dspace_overlap_data(const CVecRef< P > &pparams, const CVecRef< Q > &qparams, const CVecRef< Q > &dparams, const CVecRef< Q > &rhs, array::ArrayHandler< Q, P > &handler_qp, array::ArrayHandler< Q, Q > &handler_qq, Logger &logger)
Calculates overlap blocks between D space and the rest of the subspace.
Definition XSpace.h:121
EqnData
Kinds of equation data in the subspace.
Definition SubspaceData.h:14
void conjugate_transpose_copy(ML &&ml, const MR &mr)
Copies the conjugate transpose of mr into ml.
Definition Matrix.h:299
std::map< EqnData, Matrix< T > > SubspaceData
Equation data blocks of the subspace, in the scalar type of the problem.
Definition SubspaceData.h:18
std::vector< EqnData > square_blocks(const SubspaceData< T > &data)
The square matrices, H, S and, if present, M, among the equation data.
Definition SubspaceData.h:22
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
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
std::vector< std::reference_wrapper< const A > > CVecRef
Definition wrap.h:14
MetricStorage
How a solver obtains the actions of a metric on its subspace vectors, see IterativeSolver::set_metric...
Definition Metric.h:21
@ Stored
the actions of the metric on all subspace vectors are kept
std::vector< std::reference_wrapper< A > > VecRef
Definition wrap.h:11
MetricKind
The kind of metric M of a generalised problem, such as the eigenproblem A v = lambda M v.
Definition Metric.h:13
@ Identity
M = 1, i.e. no metric.
T conjugate(const T &x)
Complex conjugate, staying within the scalar type; the identity for a real type.
Definition scalar_traits.h:47
size_t oP() const
offset of the P block
Definition Dimensions.h:17
size_t nD
Definition Dimensions.h:14
size_t nQ
Definition Dimensions.h:13
size_t nP
Definition Dimensions.h:12
size_t oQ() const
offset of the Q block
Definition Dimensions.h:18
size_t oD() const
offset of the D block
Definition Dimensions.h:19
Container storing the Q space parameters.
Definition QSpace.h:62
size_t size() const
Definition QSpace.h:170
New sections of equation data.
Definition XSpace.h:23
SubspaceData< T > xq
data block between current X space and new parameters
Definition XSpace.h:39
SubspaceData< T > qx
data block between new parameters and current X space
Definition XSpace.h:38
NewData(size_t nQnew, size_t nX, size_t nRHS, bool metric=false)
Definition XSpace.h:25
SubspaceData< T > qq
data block between new paramters
Definition XSpace.h:37