Chombo + EB + MF  3.2
InsertionSort.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _INSERTIONSORT_H_
12 #define _INSERTIONSORT_H_
13 
14 
15 /******************************************************************************/
16 /**
17  * \file
18  *
19  * \brief Some support for sorting small arrays
20  *
21  *//***************************************************************************/
22 
23 #include <cstdlib>
24 #include <functional>
25 
26 #include "NamespaceHeader.H"
27 
28 /**
29  * \namespace Sort
30  * \brief Some support for sorting small arrays
31  */
32 
33 namespace Sort
34 {
35 
36 /*--------------------------------------------------------------------*/
37 /// Compares m_a[i] > m_a[j]
38 /** Allows for sorting an index instead of the actual array
39  *//*-----------------------------------------------------------------*/
40 
41 template <typename T>
43 {
44 public:
45  CmpGreaterIndex(const T* const a)
46  :
47  m_a(a)
48  { }
49  bool operator()(const int i, const int j) const
50  {
51  return (m_a[i] > m_a[j]);
52  }
53 private:
54  const T *const m_a;
55 };
56 
57 /*--------------------------------------------------------------------*/
58 /// Insertion sort
59 /** Sorts using Cmp which defaults to std::less<T>(). Use only for
60  * small ~(n < 20) arrays.
61  * \tparam T Type of element
62  * \tparam Cmp Comparison functor. Requires operator()(T&, T&).
63  * \tparam M Type of mask
64  * \param[in] n Number of elements to sort
65  * \param[in] array Array to sort
66  * \param[in] cmp Comparison bool operator()(i, j) to determine
67  * if element array[i] belongs before array[j]
68  * \param[in] mask Only sort elements were mask = true. Unused
69  * if set to null
70  *//*-----------------------------------------------------------------*/
71 
72 template <typename T, typename Cmp, typename M>
73 void insertion(const int n,
74  T* array,
75  const Cmp& cmp,
76  const M *const mask)
77 {
78  if (mask == NULL)
79  {
80  for (int j = 1 ; j != n ; ++j)
81  {
82  T tmp(array[j]);
83  int i = j;
84  while (i-- && cmp(tmp, array[i]))
85  {
86  array[i+1] = array[i];
87  }
88  array[i+1] = tmp;
89  }
90  }
91  else
92  {
93  int s = 0;
94  while (s > n && !mask[s]) ++s;
95  for (int j = s+1 ; j != n ; ++j)
96  {
97  if (mask[j])
98  {
99  T tmp(array[j]);
100  int ip = j;
101  int i = j;
102  while ((i-- > s) && (!mask[i] || cmp(tmp, array[i])))
103  {
104  if (mask[i])
105  {
106  array[ip] = array[i];
107  ip = i;
108  }
109  }
110  array[ip] = tmp;
111  }
112  }
113  }
114 }
115 template <typename T, typename Cmp>
116 void insertion(const int n, T* array, const Cmp& cmp)
117 {
118  insertion<T, Cmp, bool>(n, array, cmp, NULL);
119 }
120 template <typename T>
121 void insertion(const int n, T* array)
122 {
123  insertion<T, std::less<T>, bool>(n, array, std::less<T>(), NULL);
124 }
125 
126 /*--------------------------------------------------------------------*/
127 /// Mover for use with 'rearrangeToIndex'
128 /** Moves elements for 1 array
129  *//*-----------------------------------------------------------------*/
130 
131 template <typename T>
133 {
134 public:
135  Move1Array(T *const array)
136  : m_array(array)
137  { }
138  void copy(const int i, const int j)
139  {
140  m_array[i] = m_array[j];
141  }
142  void save(const int i)
143  {
144  m_tmp = m_array[i];
145  }
146  void restore(const int i)
147  {
148  m_array[i] = m_tmp;
149  }
150 private:
151  T m_tmp;
152  T *const m_array;
153 };
154 
155 /*--------------------------------------------------------------------*/
156 /// Mover for use with 'rearrangeToIndex'
157 /** Moves elements for 2 arrays
158  *//*-----------------------------------------------------------------*/
159 
160 template <typename T1, typename T2>
162 {
163 public:
164  Move2Array(T1 *const array0, T2 *const array1)
165  : m_array0(array0), m_array1(array1)
166  { }
167  void copy(const int i, const int j)
168  {
169  m_array0[i] = m_array0[j];
170  m_array1[i] = m_array1[j];
171  }
172  void save(const int i)
173  {
174  m_tmp0 = m_array0[i];
175  m_tmp1 = m_array1[i];
176  }
177  void restore(const int i)
178  {
179  m_array0[i] = m_tmp0;
180  m_array1[i] = m_tmp1;
181  }
182 private:
183  T1 m_tmp0;
184  T2 m_tmp1;
185  T1 *const m_array0;
186  T2 *const m_array1;
187 };
188 
189 /*--------------------------------------------------------------------*/
190 /// Rearrange arrays to a sorted index
191 /** If an index to an array has been sorted instead of the actual
192  * array, this allows for rearranging other arrays in the exact same
193  * manner that the index was rearranged during sorting.
194  * Note that the index array is reverted to a sequential order
195  * during this process
196  * \tparam Mv Class for moving elements and saving/restoring
197  * elements. Needs members 'copy', 'save', and
198  * 'restore'. See Move1Array for example.
199  * \param[in] n Number of elements to rearrange
200  * \param[in] index Array of indices describing where elements are
201  * to be moved.
202  * \param[out] index index[0] < index[...] < index[n]
203  * \param[in] mv Class for moving elements and saving/restoring
204  * elements.
205  *//*-----------------------------------------------------------------*/
206 
207 template <typename Mv>
208 void rearrangeToIndex(const int n, int *const index, Mv& mv)
209 {
210  for (int i = 0; i != n; ++i)
211  {
212  if (i != index[i])
213  {
214  mv.save(i);
215  int jp = i;
216  for (int j = index[i]; j != i; j = index[j])
217  {
218  index[jp] = jp;
219  mv.copy(jp, j); // Copy j to jp
220  jp = j;
221  }
222  index[jp] = jp;
223  mv.restore(jp);
224  }
225  }
226 }
227 } // End of namespace Sort
228 
229 #include "NamespaceFooter.H"
230 #endif
const T *const m_a
Definition: InsertionSort.H:54
Some support for sorting small arrays.
T1 m_tmp0
Definition: InsertionSort.H:183
void restore(const int i)
Definition: InsertionSort.H:146
void save(const int i)
Definition: InsertionSort.H:142
T1 *const m_array0
Definition: InsertionSort.H:185
Move2Array(T1 *const array0, T2 *const array1)
Definition: InsertionSort.H:164
T2 m_tmp1
Definition: InsertionSort.H:184
Mover for use with &#39;rearrangeToIndex&#39;.
Definition: InsertionSort.H:132
void insertion(const int n, T *array, const Cmp &cmp, const M *const mask)
Insertion sort.
Definition: InsertionSort.H:73
Compares m_a[i] > m_a[j].
Definition: InsertionSort.H:42
T m_tmp
Definition: InsertionSort.H:151
bool operator()(const int i, const int j) const
Definition: InsertionSort.H:49
void rearrangeToIndex(const int n, int *const index, Mv &mv)
Rearrange arrays to a sorted index.
Definition: InsertionSort.H:208
void save(const int i)
Definition: InsertionSort.H:172
void restore(const int i)
Definition: InsertionSort.H:177
T2 *const m_array1
Definition: InsertionSort.H:186
Mover for use with &#39;rearrangeToIndex&#39;.
Definition: InsertionSort.H:161
void const char const int * M
Definition: Lapack.H:83
CmpGreaterIndex(const T *const a)
Definition: InsertionSort.H:45
T *const m_array
Definition: InsertionSort.H:152
void copy(const int i, const int j)
Definition: InsertionSort.H:138
Move1Array(T *const array)
Definition: InsertionSort.H:135
void copy(const int i, const int j)
Definition: InsertionSort.H:167