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