ug4
boxsort2.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3  * Author: Martin Rupp
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 
34 #ifndef __H__UG__LIB_DISC__AMG_SOLVER__BoxPriorityQueue2_H__
35 #define __H__UG__LIB_DISC__AMG_SOLVER__BoxPriorityQueue2_H__
36 
37 #include <vector>
38 
39 namespace ug{
40 
41 /*#ifdef UGASSERT
42 #define MYASSERT(a, b) UGASSERT(a, b)
43 #else
44 #define MYASSERT(a, b) assert(a && ##b)
45 #endif
46 
47 template<typename T>
48 inline size_t get_val(const T &t)
49 {
50  return t.get_val();
51 }
52 
53 inline size_t get_val(size_t i)
54 {
55  return i;
56 }*/
57 
60 
77 template<typename T>
79 {
80 private:
82 
83 public:
85  {
86 
87  }
92  BoxPriorityQueue2(size_t n, const T *arr_) : m_size(0), m_height(0)
93  {
94  create(n, arr_);
95  }
96 
97  BoxPriorityQueue2(const std::vector<T> &v) : m_size(0), m_height(0)
98  {
99  create(v.size(), &v[0]);
100  }
103  {
104  }
105 
109  void create(size_t n, const T *arr_)
110  {
111  if(n != m_size)
112  {
113  m_values.resize(n);
114  m_prev.resize(n);
115  m_next.resize(n);
116  m_size = n;
117  }
118  m_size = n;
119 
120  arr = arr_;
121 
122  reset();
123  }
124 
125  void create(const std::vector<T> &v)
126  {
127  create(v.size(), &v[0]);
128  }
129 
130  void reset()
131  {
132  m_height = 0;
133  m_box.resize(0);
134  for(size_t i=0; i<m_prev.size(); i++)
135  m_prev[i] = -2;
136  }
137 
141  void insert_item(size_t i)
142  {
143  UG_ASSERT(is_in(i), "item is already in");
144  size_check(i);
145  size_t val = get_val(arr[i]);
146  UG_ASSERT(val < (size_t)BOXPRIORITYQUEUE2_MAXIMAL_VALUE, "T::get_val() has to be < " << BOXPRIORITYQUEUE_MAXIMAL_VALUE << " but is " << val);
147  if(m_box.size() < val+1)
148  {
149  m_boxBegin.resize(val+1, -1);
150  m_boxEnd.resize(val+1, -1);
151  }
152 
153  if(m_boxBegin[val] == -1)
154  {
155  m_prev[i] = -1;
156  m_next[i] = -1;
157  m_boxBegin[val] = m_boxEnd[val] = i;
158  }
159  else
160  {
161  m_prev[i] = m_boxEnd[val];
162  m_next[i] = -1;
163  m_boxEnd[val] = i;
164  }
165  m_values[i] = val;
166  m_height++;
167  }
168 
169  // remove
171  void remove(size_t i)
172  {
173  size_check(i);
174  UG_ASSERT(is_in(i), "item is not in");
175 
176  size_t val = m_values[i];
177  if(m_prev[i] == -1) m_boxBegin[val] = m_next[i];
178  else m_next[m_prev[i]] = m_next[i];
179  if(m_next[i] == -1) m_boxEnd[val] = m_prev[i];
180  else m_prev[m_next[i]] = m_prev[i];
181 
182  m_prev[i] = -2;
183  m_height--;
184  while(m_boxBegin.size() && m_boxBegin.back() == -1)
185  {
186  m_boxBegin.pop_back();
187  m_boxEnd.pop_back();
188  }
189  }
190 
191  // removeMax
193  size_t remove_max()
194  {
195  UG_ASSERT(m_height > 0 && m_box.size() > 0, "queue empty! (height = " << m_height << ", boxsize = " << m_box.size() << ").");
196 
197  int i = m_boxBegin.back();
198  remove(i);
199  return i;
200  }
201 
202  // get_max
204  size_t get_max() const
205  {
206  UG_ASSERT(m_height > 0 || m_box.size() <= 0, "queue empty! (height = " << m_height << ", boxsize = " << m_box.size() << ").");
207  return m_boxBegin.back();
208  }
209 
212  void update(size_t i)
213  {
214  if(is_in(i) && m_values[i] != get_val(arr[i]))
215  {
216  remove(i);
217  insert_item(i);
218  }
219  }
220 
221  bool is_in(size_t i)
222  {
223  return m_prev[i] != -2;
224  }
225 
227  size_t arr_size() const
228  {
229  return m_size;
230  }
231 
233  size_t height() const
234  {
235  return m_height;
236  }
237 
240  /*void print()
241  {
242 
243  for(int i=0; i<m_size; i++)
244  {
245  cout << "Element " << i;
246  if(m_posInBox[i] < 0) cout << " not in box." << endl;
247  else cout << " val = " << m_values[i] << " get_val = " << arr[i].get_val() << " m_posInBox= " << m_posInBox[i] << endl;
248  }
249 
250  cout << m_box.size() << " boxs. content:" << endl;
251  for(int i=0; i<m_box.size(); i++)
252  {
253  cout << "m_box[" << i << "]: ";
254  for(int j=0; j<m_box[i].size(); j++)
255  {
256  cout << " " << m_box[i][j];
257  if(m_values[m_box[i][j]] != i) cout << " <-err ";
258  if( m_posInBox[m_box[i][j]] != j) cout << " <-err2 ";
259  }
260  cout << endl;
261  }
262  cout.flush();
263  }*/
264 
265 private:
266  inline void size_check(size_t i)
267  {
268  UG_ASSERT(i < arr_size(), "accessing element " << i << ", but size of the array is only " << arr_size());
269  }
270  const T *arr; //< pointer to array with elements of type T
271 
273 
275  stdvector<size_t> m_values; //< m_values[i] is the value used for sorting of element i
276  size_t m_size; //< maximal size of the PQ = size of array arr
277  size_t m_height;
278 };
279 
280 } // namespace ug
281 
282 #endif
updateable priority queue class. this priority queue works on an external array of elements T.
Definition: boxsort2.h:79
void update(size_t i)
Definition: boxsort2.h:212
stdvector< int > m_boxEnd
Definition: boxsort2.h:274
size_t height() const
returns nr of elements in the heap.
Definition: boxsort2.h:233
BoxPriorityQueue2(size_t n, const T *arr_)
Definition: boxsort2.h:92
size_t m_height
Definition: boxsort2.h:277
stdvector< size_t > m_values
Definition: boxsort2.h:275
stdvector< int > m_prev
Definition: boxsort2.h:274
stdvector< int > m_boxBegin
Definition: boxsort2.h:274
~BoxPriorityQueue2()
deconstructor
Definition: boxsort2.h:102
BoxPriorityQueue2(const BoxPriorityQueue2< T > &other)
void create(const std::vector< T > &v)
Definition: boxsort2.h:125
stdvector< stdvector< size_t > > m_box
Definition: boxsort2.h:272
void remove(size_t i)
removes index i in arr
Definition: boxsort2.h:171
BoxPriorityQueue2()
Definition: boxsort2.h:84
void insert_item(size_t i)
Definition: boxsort2.h:141
size_t remove_max()
returns the index in arr of maximal element of the heap
Definition: boxsort2.h:193
void size_check(size_t i)
Definition: boxsort2.h:266
size_t get_max() const
returns the index in m_arr of maximal element of the heap
Definition: boxsort2.h:204
bool is_in(size_t i)
Definition: boxsort2.h:221
void create(size_t n, const T *arr_)
creates the queue on a external array arr_[0]..arr_[n-1]
Definition: boxsort2.h:109
void reset()
Definition: boxsort2.h:130
stdvector< int > m_next
Definition: boxsort2.h:274
BoxPriorityQueue2(const std::vector< T > &v)
Definition: boxsort2.h:97
size_t arr_size() const
returns size of external array
Definition: boxsort2.h:227
const T * arr
Definition: boxsort2.h:270
size_t m_size
Definition: boxsort2.h:276
Definition: stl_debug.h:45
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
the ug namespace
size_t get_val(const T &t)
Definition: boxsort.h:48
const int BOXPRIORITYQUEUE_MAXIMAL_VALUE
maximal value for T::get_val(). Keep in mind that memory requirements are O(max get_val()).
Definition: boxsort.h:59
const int BOXPRIORITYQUEUE2_MAXIMAL_VALUE
maximal value for T::get_val(). Keep in mind that memory requirements are O(max get_val()).
Definition: boxsort2.h:59