iterative-solver 0.0
util.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_UTIL_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_UTIL_H
3#include <limits>
4#include <molpro/linalg/itsolv/ArrayHandlers.h>
5#include <molpro/linalg/itsolv/subspace/Matrix.h>
6#include <molpro/linalg/itsolv/wrap.h>
7
9namespace detail {
10
12template <typename T1, typename T2, typename... Ts>
13struct is_one_of {
14 static constexpr bool value = std::is_same<T1, T2>::value || is_one_of<T1, Ts...>::value;
15};
16
17template <typename T1, typename T2>
18struct is_one_of<T1, T2> {
19 static constexpr bool value = std::is_same<T1, T2>::value;
20};
21
22template <class R, class Q, class Z, class W, bool = is_one_of<Z, R, Q>::value&& is_one_of<W, R, Q>::value,
23 bool = std::is_same<R, Z>::value, bool = std::is_same<W, Q>::value>
24struct Overlap {};
25
26template <class R, class Q, class Z, class W>
27struct Overlap<R, Q, Z, W, true, true, true> {
29 static Matrix<value_type> _(const CVecRef<R>& left, const CVecRef<Q>& right, array::ArrayHandler<Z, W>& handler) {
30 return handler.gemm_inner(left, right);
31 }
32};
33
34template <class R, class Q, class Z, class W>
35struct Overlap<R, Q, Z, W, true, false, false> {
37 static Matrix<value_type> _(const CVecRef<R>& left, const CVecRef<Q>& right, array::ArrayHandler<Z, W>& handler) {
38 auto mat = handler.gemm_inner(right, left);
39 auto m = Matrix<value_type>({left.size(), right.size()});
40 transpose_copy(m, mat);
41 return m;
42 }
43};
44
45template <class R, class Q, class Z, class W>
47} // namespace detail
48
50template <class R, class Q, class Z, class W>
51auto overlap(const CVecRef<R>& left, const CVecRef<Q>& right, array::ArrayHandler<Z, W>& handler)
52 -> std::enable_if_t<detail::Z_and_W_are_one_of_R_and_Q<R, Q, Z, W>,
54 return detail::Overlap<R, Q, Z, W>::_(left, right, handler);
55}
56
58template <class R>
61 auto m = Matrix<typename array::ArrayHandler<R, R>::value_type>({params.size(), params.size()});
62 for (size_t i = 0; i < m.rows(); ++i)
63 for (size_t j = 0; j <= i; ++j)
64 m(i, j) = m(j, i) = handler.dot(params[i], params[j]);
65 return m;
66}
67
68template <typename T>
70 assert(mat.rows() == mat.cols() && "must be a square matrix");
71 for (size_t i = 0; i < mat.rows(); ++i)
72 for (size_t j = 0; j < i; ++j)
73 mat(i, j) = mat(j, i) = T(0.5) * (mat(i, j) + mat(j, i));
74}
75
77template <typename T>
78typename Matrix<T>::coord_type max_element_index(const std::list<size_t>& rows, const std::list<size_t>& cols,
79 const Matrix<T>& mat) {
80 auto max_el = std::numeric_limits<T>::lowest();
81 auto ind = typename Matrix<T>::coord_type{0, 0};
82 for (auto i : rows) {
83 for (auto j : cols) {
84 if (mat(i, j) > max_el) {
85 max_el = mat(i, j);
86 ind = {i, j};
87 }
88 }
89 }
90 return ind;
91}
92
106template <typename Slice>
107std::vector<size_t> eye_order(const Slice& mat) {
108 auto dim = mat.dimensions();
109 auto rows = std::list<size_t>{};
110 auto cols = std::list<size_t>{};
111 for (size_t i = 0; i < dim.first; ++i) {
112 rows.emplace_back(i);
113 cols.emplace_back(i);
114 }
115 auto order = std::vector<size_t>(dim.first);
116 size_t i, j;
117 while (!rows.empty() && !cols.empty()) {
118 std::tie(i, j) = max_element_index(rows, cols, mat);
119 order.at(j) = i;
120 auto it_row = std::find(begin(rows), end(rows), i);
121 auto it_col = std::find(begin(cols), end(cols), j);
122 rows.erase(it_row);
123 cols.erase(it_col);
124 }
125 return order;
126}
127
128} // namespace molpro::linalg::itsolv::subspace::util
129
130#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_SUBSPACE_UTIL_H
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
decltype(value_type_L{} *value_type_R{}) value_type
Definition: ArrayHandler.h:181
virtual Matrix< value_type > gemm_inner(const CVecRef< AL > &xx, const CVecRef< AR > &yy)=0
std::pair< size_t, size_t > coord_type
Definition: Matrix.h:38
index_type rows() const
Definition: Matrix.h:167
index_type cols() const
Definition: Matrix.h:168
constexpr bool Z_and_W_are_one_of_R_and_Q
Definition: util.h:46
Definition: gram_schmidt.h:8
Matrix< T >::coord_type max_element_index(const std::list< size_t > &rows, const std::list< size_t > &cols, const Matrix< T > &mat)
Return maximum element in a matrix along specified rows and columns.
Definition: util.h:78
std::vector< size_t > eye_order(const Slice &mat)
Returns order of rows in a matrix slice that brings it closest to identity.
Definition: util.h:107
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 matrix_symmetrize(Matrix< T > &mat)
Definition: util.h:69
void transpose_copy(ML &&ml, const MR &mr)
Definition: Matrix.h:283
std::vector< std::reference_wrapper< const A > > CVecRef
Definition: wrap.h:14
typename array::ArrayHandler< Z, W >::value_type value_type
Definition: util.h:28
static Matrix< value_type > _(const CVecRef< R > &left, const CVecRef< Q > &right, array::ArrayHandler< Z, W > &handler)
Definition: util.h:29
typename array::ArrayHandler< Z, W >::value_type value_type
Definition: util.h:36
static Matrix< value_type > _(const CVecRef< R > &left, const CVecRef< Q > &right, array::ArrayHandler< Z, W > &handler)
Definition: util.h:37
Checks that type T1 is same as one of T2, Ts ...
Definition: util.h:13
static constexpr bool value
Definition: util.h:14