iterative-solver 0.0
select.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ARRAY_UTIL_SELECT_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ARRAY_UTIL_SELECT_H
3#include <cmath>
4#include <complex>
5#include <cstdlib>
6#include <queue>
7
9// virtual std::map<size_t, value_type_abs> select(size_t n, const AL &x, bool max = false, bool abs = false) = 0;
22template <class X, typename value_type,
23 typename std::enable_if<std::is_compound<value_type>::value, value_type>::type* = nullptr>
24auto select(size_t n, const X& x, bool max = false, bool ignore_sign = false) {
25 throw std::logic_error("select not implemented for complex types");
26 return std::map<size_t, value_type>();
27}
28template <class X, typename value_type,
29 typename std::enable_if<!std::is_compound<value_type>::value, value_type>::type* = nullptr>
30auto select(size_t n, const X& x, bool max = false, bool ignore_sign = false) {
31 using std::abs;
32 using std::begin;
33 using std::end;
34 using std::greater;
35 using select_pair = std::pair<value_type, size_t>; // value and index
36 auto selection = std::priority_queue<select_pair, std::vector<select_pair>, greater<select_pair>>();
37 auto ix = begin(x);
38 for (size_t i = 0; i < n; ++i, ++ix) {
39 selection.emplace(max ? (ignore_sign ? abs((*ix)) : (*ix)) : (ignore_sign ? -abs((*ix)) : -(*ix)), i);
40 }
41 for (size_t i = n; i < x.size(); ++i, ++ix) {
42 selection.emplace(max ? (ignore_sign ? abs((*ix)) : (*ix)) : (ignore_sign ? -abs((*ix)) : -(*ix)), i);
43 selection.pop();
44 }
45 auto selection_map = std::map<size_t, value_type>();
46 auto m = selection.size();
47 for (size_t i = 0; i < m; ++i) {
48 selection_map.emplace(selection.top().second, selection.top().first);
49 selection.pop();
50 }
51 if (not max)
52 for (auto& e : selection_map)
53 e.second = -e.second;
54 return selection_map;
55}
56
68// template <class X, typename value_type>
69// auto select_iter_sparse(size_t n, const X& x, bool max = false, bool ignore_sign = false) {
70// return select<X,value_type>(n, x, max, ignore_sign);
71// using std::abs;
72// using std::begin;
73// using std::end;
74// using std::greater;
75// using select_pair = std::pair<value_type, size_t>; // value and index
76// auto selection = std::priority_queue<select_pair, std::vector<select_pair>, greater<select_pair>>();
77// auto ix = begin(x);
78// for (size_t i = 0; i < n; ++i, ++ix) {
79// if (ix->first < x.size())
80// selection.emplace(max ? (ignore_sign ? abs((ix->second)) : (ix->second)) : (ignore_sign ? -abs((ix->second)) :
81// -(ix->second)), ix->first);
82// }
83// for (auto jx = ix; jx != end(x); ++jx) {
84// if (jx->first < x.size()) {
85// selection.emplace(max ? (ignore_sign ? abs((ix->second)) : (ix->second)) : (ignore_sign ? -abs((ix->second)) :
86// -(ix->second)), jx->first); selection.pop();
87// }
88// }
89// auto selection_map = std::map<size_t, value_type>();
90// auto m = selection.size();
91// for (size_t i = 0; i < m; ++i) {
92// selection_map.emplace(selection.top().second, selection.top().first);
93// selection.pop();
94// }
95// return selection_map;
96//}
97
110template <class X, typename value_type>
111auto select_sparse(size_t n, const X& x, bool max = false, bool ignore_sign = false) {
112 using std::abs;
113 using std::begin;
114 using std::end;
115 using std::greater;
116 using select_pair = std::pair<value_type, size_t>; // value and index
117 auto selection = std::priority_queue<select_pair, std::vector<select_pair>, greater<select_pair>>();
118 auto ix = begin(x);
119 while (selection.size() < n && ix != end(x)) {
120 selection.emplace(max ? (ignore_sign ? abs((ix->second)) : (ix->second))
121 : (ignore_sign ? -abs((ix->second)) : -(ix->second)),
122 ix->first);
123 ++ix;
124 }
125 while (ix != end(x)) {
126 selection.emplace(max ? (ignore_sign ? abs((ix->second)) : (ix->second))
127 : (ignore_sign ? -abs((ix->second)) : -(ix->second)),
128 ix->first);
129 selection.pop();
130 ++ix;
131 }
132 auto selection_map = std::map<size_t, value_type>();
133 auto m = selection.size();
134 for (size_t i = 0; i < m; ++i) {
135 selection_map.emplace(selection.top().second, selection.top().first);
136 selection.pop();
137 }
138 if (not max)
139 for (auto& e : selection_map)
140 e.second = -e.second;
141 return selection_map;
142}
143} // namespace molpro::linalg::array::util
144
145#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ARRAY_UTIL_SELECT_H
auto begin(Span< T > &x)
Definition: Span.h:84
auto end(Span< T > &x)
Definition: Span.h:94
Definition: ArrayHandler.h:23
auto select(size_t n, const X &x, bool max=false, bool ignore_sign=false)
Select n indices with largest (or smallest) actual (or absolute) value.
Definition: select.h:24
auto select_sparse(size_t n, const X &x, bool max=false, bool ignore_sign=false)
Select n indices with largest (or smallest) actual (or absolute) value.
Definition: select.h:111