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