Bridge++  Ver. 2.0.2
sorter_alt.h
Go to the documentation of this file.
1 
14 #ifndef SORTER_INCLUDED
15 #define SORTER_INCLUDED
16 
17 #include <cmath>
18 #include <algorithm>
19 #include <cassert>
20 #include <vector>
21 #include <string>
22 
23 #include "bridge_complex.h"
24 
26 // sort utility class.
27 //
28 // usage:
29 // Sorter sorter(sort_type);
30 // sort_type =
31 // abs_ascending : absolute ascending order |v_0| <= |v_1| <= ...
32 // abs_descending : absolute descending order |v_0| >= |v_1| >= ...
33 // ascending : arithmetic ascending order v_0 <= v_1 <= ...
34 // descending : arithmetic descending order v_0 >= v_1 >= ...
35 // sorter.sort(vec); to sort vec : vector<double>. destructive.
36 // sorter.sort_index(vec); returns index of vec in sorted order.
37 // sorter.comp(a, b); compare two values a, b with the sort condition.
38 //
39 // 2022.02.15: I.Kanamori
40 // added fcomplex
41 
42 template<typename T>
43 class Sorter
44 {
45  public:
46 
47  Sorter(const std::string& type);
48 
49  virtual ~Sorter();
50 
52  void sort(std::vector<T>& v);
53 
55  void sort(std::vector<T>& v, const size_t nelem);
56 
58  std::vector<int> sort_index(std::vector<T>& v);
59 
61  std::vector<int> sort_index(std::vector<T>& v, const size_t nelem);
62 
64  bool comp(const T& lhs, const T& rhs);
65 
66  private:
67 
68  // sort order
69  struct by_abs_ascend;
70  struct by_abs_descend;
71  struct by_ascend;
72  struct by_descend;
73 
74  struct by_order;
75  struct proxy;
76 
77  typedef std::pair<int, T> pair_t;
78 
79  by_order *m_order;
80 
81  // non-copyable
82  Sorter(const Sorter&);
83  Sorter& operator=(const Sorter&);
84 };
85 
86 //====================================================================
88 template<typename T>
89 struct Sorter<T>::by_order
90 {
91  virtual ~by_order() {}
92 
93  virtual
94  bool operator()(const T& lhs, const T& rhs) const = 0;
95 
96  bool operator()(const pair_t& lhs, const pair_t& rhs) const
97  {
98  return operator()(lhs.second, rhs.second);
99  }
100 };
101 
102 //====================================================================
104 // i.e. |v_0| <= |v_1| <= ... <= |v_{n-1}|
105 template<typename T>
106 struct Sorter<T>::by_abs_ascend : public Sorter::by_order
107 {
108  bool operator()(const T& lhs, const T& rhs) const
109  { return abs(lhs) < abs(rhs); }
110 };
111 
112 //====================================================================
114 // i.e. |v_0| >= |v_1| >= ... >= |v_{n-1}|
115 template<typename T>
116 struct Sorter<T>::by_abs_descend : public Sorter::by_order
117 {
118  bool operator()(const T& lhs, const T& rhs) const
119  {
120  return abs(lhs) > abs(rhs);
121  }
122 };
123 
124 //====================================================================
126 // i.e. v_0 <= v_1 <= ... <= v_{n-1}
127 template<typename T>
128 struct Sorter<T>::by_ascend : public Sorter::by_order
129 {
130  virtual
131  bool operator()(const T& lhs, const T& rhs) const
132  {
133  return lhs < rhs;
134  }
135 };
136 
137 //====================================================================
139 // i.e. v_0 >= v_1 >= ... >= v_{n-1}
140 template<typename T>
141 struct Sorter<T>::by_descend : public Sorter::by_order
142 {
143  virtual
144  bool operator()(const T& lhs, const T& rhs) const
145  {
146  return rhs < lhs;
147  }
148 };
149 
150 //====================================================================
152 template<typename T>
153 struct Sorter<T>::proxy
154 {
155  private:
156  const Sorter::by_order& m_order;
157 
158  public:
159  proxy(const Sorter::by_order& order) : m_order(order) {}
160 
161  bool operator()(const T& lhs, const T& rhs) const
162  {
163  return m_order(lhs, rhs);
164  }
165 
166  bool operator()(const pair_t& lhs, const pair_t& rhs) const
167  {
168  return m_order(lhs, rhs);
169  }
170 };
171 
172 //====================================================================
174 template<typename T>
175 Sorter<T>::Sorter(const std::string& type) : m_order(0)
176 {
177  if (type == "abs_ascending") m_order = new by_abs_ascend;
178  if (type == "abs_descending") m_order = new by_abs_descend;
179  if (type == "ascending") m_order = new by_ascend;
180  if (type == "descending") m_order = new by_descend;
181 }
182 
183 
184 //====================================================================
186 template<typename T>
188 {
189  if (m_order) delete m_order;
190 }
191 
192 
193 //====================================================================
195 template<typename T>
196 void Sorter<T>::sort(std::vector<T>& v)
197 {
198  assert(m_order != NULL);
199 
200  return std::sort(v.begin(), v.end(), proxy(*m_order));
201 }
202 
203 
204 //====================================================================
206 template<typename T>
207 void Sorter<T>::sort(std::vector<T>& v, const size_t nelem)
208 {
209  assert(m_order != NULL);
210 
211  return std::sort(v.begin(), v.begin() + nelem, proxy(*m_order));
212 }
213 
214 
215 //====================================================================
217 template<typename T>
218 std::vector<int> Sorter<T>::sort_index(std::vector<T>& v)
219 {
220  assert(m_order != NULL);
221 
222  std::vector<pair_t> w(v.size());
223 
224  for (size_t i = 0, n = v.size(); i < n; ++i) {
225  w[i].first = i;
226  w[i].second = v[i];
227  }
228 
229  std::sort(w.begin(), w.end(), proxy(*m_order));
230 
231  std::vector<int> idx(v.size());
232 
233  for (size_t i = 0, n = v.size(); i < n; ++i) {
234  idx[i] = w[i].first;
235  v[i] = w[i].second;
236  }
237 
238  return idx;
239 }
240 
241 
242 //====================================================================
244 template<typename T>
245 std::vector<int> Sorter<T>::sort_index(std::vector<T>& v, const size_t nelem)
246 {
247  assert(m_order != NULL);
248 
249  std::vector<pair_t> w(v.size());
250 
251  for (size_t i = 0, n = v.size(); i < n; ++i) {
252  w[i].first = i;
253  w[i].second = v[i];
254  }
255 
256  std::sort(w.begin(), w.begin() + nelem, proxy(*m_order));
257 
258  std::vector<int> idx(v.size());
259 
260  for (size_t i = 0, n = v.size(); i < n; ++i) {
261  idx[i] = w[i].first;
262  v[i] = w[i].second;
263  }
264 
265  return idx;
266 }
267 
268 
269 //====================================================================
271 template<typename T>
272 bool Sorter<T>::comp(const T& lhs, const T& rhs)
273 {
274  assert(m_order != NULL);
275  return m_order->operator()(lhs, rhs);
276 }
277 
278 
279 //====================================================================
281 // i.e. v_0 <= v_1 <= ... <= v_{n-1}
282 template<>
283 struct Sorter<dcomplex>::by_ascend : public Sorter::by_order
284 {
285  virtual
286  bool operator()(const dcomplex& lhs, const dcomplex& rhs) const
287  {
288  vout.crucial("by_ascend: unsupported ordering\n");
289  exit(EXIT_FAILURE);
290  return false;
291  }
292 };
293 
294 //====================================================================
296 // i.e. v_0 >= v_1 >= ... >= v_{n-1}
297 template<>
298 struct Sorter<dcomplex>::by_descend : public Sorter::by_order
299 {
300  virtual
301  bool operator()(const dcomplex& lhs, const dcomplex& rhs) const
302  {
303  vout.crucial("by_ascend: unsupported ordering\n");
304  exit(EXIT_FAILURE);
305  return false;
306  }
307 };
308 
309 
310 //====================================================================
312 // i.e. v_0 <= v_1 <= ... <= v_{n-1}
313 template<>
314 struct Sorter<fcomplex>::by_ascend : public Sorter::by_order
315 {
316  virtual
317  bool operator()(const fcomplex& lhs, const fcomplex& rhs) const
318  {
319  vout.crucial("by_ascend: unsupported ordering\n");
320  exit(EXIT_FAILURE);
321  return false;
322  }
323 };
324 
325 //====================================================================
327 // i.e. v_0 >= v_1 >= ... >= v_{n-1}
328 template<>
329 struct Sorter<fcomplex>::by_descend : public Sorter::by_order
330 {
331  virtual
332  bool operator()(const fcomplex& lhs, const fcomplex& rhs) const
333  {
334  vout.crucial("by_ascend: unsupported ordering\n");
335  exit(EXIT_FAILURE);
336  return false;
337  }
338 };
339 
340 
341 //==========================================================
342 #endif /* SORTER_INCLUDED */
343 //==================================================END=====
Sorter::proxy::operator()
bool operator()(const pair_t &lhs, const pair_t &rhs) const
Definition: sorter_alt.h:166
Sorter::by_order
base class for sort ordering
Definition: sorter.cpp:18
Sorter::by_descend::operator()
virtual bool operator()(const T &lhs, const T &rhs) const
Definition: sorter_alt.h:144
Sorter::by_order::~by_order
virtual ~by_order()
Definition: sorter_alt.h:91
Sorter::pair_t
std::pair< int, T > pair_t
Definition: sorter_alt.h:75
Sorter::by_descend::operator()
virtual bool operator()(const dcomplex &lhs, const dcomplex &rhs) const
Definition: sorter_alt.h:301
Sorter::proxy::m_order
const Sorter::by_order & m_order
Definition: sorter.cpp:80
Sorter::Sorter
Sorter(const std::string &type)
constructor with sort ordering as a string arg
Definition: sorter.cpp:98
Sorter::pair_t
std::pair< int, double > pair_t
Definition: sorter.h:70
Sorter::by_ascend::operator()
virtual bool operator()(const dcomplex &lhs, const dcomplex &rhs) const
Definition: sorter_alt.h:286
Sorter::sort_index
std::vector< int > sort_index(std::vector< double > &v)
sort an array and return list of index; v is sorted on exit.
Definition: sorter.cpp:137
bridge_complex.h
Sorter::proxy::proxy
proxy(const Sorter::by_order &order)
Definition: sorter_alt.h:159
AIndex_eo_qxs::idx
int idx(const int in, const int Nin, const int ist, const int Nx2, const int Ny, const int leo, const int Nvol2, const int ex)
Definition: aindex_eo.h:27
Sorter::comp
bool comp(const double lhs, const double rhs)
call sort condition.
Definition: sorter.cpp:189
Sorter::by_ascend::operator()
virtual bool operator()(const fcomplex &lhs, const fcomplex &rhs) const
Definition: sorter_alt.h:317
Sorter::by_descend::operator()
virtual bool operator()(const fcomplex &lhs, const fcomplex &rhs) const
Definition: sorter_alt.h:332
Sorter::m_order
by_order * m_order
Definition: sorter.h:74
Sorter::sort
void sort(std::vector< double > &v)
sort an array of values; v is sorted on exit.
Definition: sorter.cpp:117
Sorter::operator=
Sorter & operator=(const Sorter &)
Sorter::by_abs_descend::operator()
bool operator()(const T &lhs, const T &rhs) const
Definition: sorter_alt.h:118
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:180
Sorter::proxy::operator()
bool operator()(const T &lhs, const T &rhs) const
Definition: sorter_alt.h:161
Sorter::by_abs_ascend::operator()
bool operator()(const T &lhs, const T &rhs) const
Definition: sorter_alt.h:108
Sorter
Definition: sorter.h:38
Sorter::by_ascend::operator()
virtual bool operator()(const T &lhs, const T &rhs) const
Definition: sorter_alt.h:131
Sorter::~Sorter
virtual ~Sorter()
destructor
Definition: sorter.cpp:109
Sorter::by_order::operator()
bool operator()(const pair_t &lhs, const pair_t &rhs) const
Definition: sorter_alt.h:96
Element_type::type
type
Definition: bridge_defs.h:41
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512