OpenMS
HashGrid.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2023.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Lars Nilse $
32 // $Authors: Bastian Blank $
33 // --------------------------------------------------------------------------
34 
35 #include <OpenMS/CONCEPT/Types.h>
37 #include <boost/array.hpp>
38 #include <boost/functional/hash.hpp>
39 #include <boost/unordered/unordered_map.hpp>
40 #include <cmath>
41 #include <iterator>
42 #include <limits>
43 
44 #ifndef OPENMS_COMPARISON_CLUSTERING_HASHGRID_H
45  #define OPENMS_COMPARISON_CLUSTERING_HASHGRID_H
46 
47 namespace OpenMS
48 {
59  template<typename Cluster>
60  class HashGrid
61  {
62  public:
66  // XXX: Check is there is another type handy in OpenMS already
68 
73 
77  typedef typename boost::unordered_multimap<ClusterCenter, Cluster> CellContent;
78 
82  typedef boost::unordered_map<CellIndex, CellContent> Grid;
83 
84  typedef typename CellContent::key_type key_type;
85  typedef typename CellContent::mapped_type mapped_type;
86  typedef typename CellContent::value_type value_type;
87 
88  private:
92  class Iterator
93  {
94  private:
95  friend class HashGrid;
96 
97  typedef typename Grid::iterator grid_iterator;
98  typedef typename CellContent::iterator cell_iterator;
99 
104  using iterator_category = std::input_iterator_tag;
110  using pointer = value_type*;
112  using difference_type = std::ptrdiff_t;
114 
115 
119 
120  // Search for next non-empty cell
122  {
123  while (cell_it_ == grid_it_->second.end())
124  {
125  grid_it_++;
126 
127  // If we are at the last cell, set cell iterator to something well-known
128  if (grid_it_ == grid_.end())
129  {
131  return;
132  }
133 
134  cell_it_ = grid_it_->second.begin();
135  }
136  }
137 
138  public:
139  explicit Iterator(Grid& grid) : grid_(grid), grid_it_(grid.end())
140  {
141  }
142 
143  Iterator(Grid& grid, grid_iterator grid_it, cell_iterator cell_it) : grid_(grid), grid_it_(grid_it), cell_it_(cell_it)
144  {
145  searchNextCell_();
146  }
147 
149  {
150  ++cell_it_;
151  searchNextCell_();
152  return *this;
153  }
154 
155  const Iterator operator++(int)
156  {
157  Iterator ret(*this);
158  operator++();
159  return ret;
160  }
161 
162  bool operator==(const Iterator& rhs) const
163  {
164  return grid_it_ == rhs.grid_it_ && cell_it_ == rhs.cell_it_;
165  }
166 
167  bool operator!=(const Iterator& rhs) const
168  {
169  return !(*this == rhs);
170  }
171 
173  {
174  return *cell_it_;
175  }
176 
178  {
179  return &*cell_it_;
180  }
181 
182  const CellIndex index() const
183  {
184  return grid_it_->first;
185  }
186  };
187 
192  {
193  private:
194  friend class HashGrid;
195 
196  typedef typename Grid::const_iterator grid_iterator;
197  typedef typename CellContent::const_iterator cell_iterator;
198 
203  using iterator_category = std::input_iterator_tag;
209  using pointer = value_type*;
211  using difference_type = std::ptrdiff_t;
213 
214  const Grid& grid_;
217 
218  // Search for next non-empty cell
220  {
221  while (cell_it_ == grid_it_->second.end())
222  {
223  grid_it_++;
224 
225  // If we are at the last cell, set cell iterator to something well-known
226  if (grid_it_ == grid_.end())
227  {
229  return;
230  }
231 
232  cell_it_ = grid_it_->second.begin();
233  }
234  }
235 
236  public:
237  ConstIterator(const Grid& grid) : grid_(grid), grid_it_(grid.end())
238  {
239  }
240 
241  ConstIterator(const Grid& grid, grid_iterator grid_it, cell_iterator cell_it) : grid_(grid), grid_it_(grid_it), cell_it_(cell_it)
242  {
243  searchNextCell_();
244  }
245 
247  {
248  }
249 
251  {
252  ++cell_it_;
253  searchNextCell_();
254  return *this;
255  }
256 
258  {
259  ConstIterator ret(*this);
260  operator++();
261  return ret;
262  }
263 
264  bool operator==(const ConstIterator& rhs) const
265  {
266  return grid_it_ == rhs.grid_it_ && cell_it_ == rhs.cell_it_;
267  }
268 
269  bool operator!=(const ConstIterator& rhs) const
270  {
271  return !(*this == rhs);
272  }
273 
274  const value_type& operator*() const
275  {
276  return *cell_it_;
277  }
278 
279  const value_type* operator->() const
280  {
281  return &*cell_it_;
282  }
283 
284  const CellIndex index() const
285  {
286  return grid_it_->first;
287  }
288  };
289 
290  public:
293  typedef typename Grid::const_iterator const_grid_iterator;
294  typedef typename Grid::iterator grid_iterator;
295  typedef typename CellContent::const_iterator const_cell_iterator;
296  typedef typename CellContent::iterator cell_iterator;
297  typedef typename CellContent::size_type size_type;
298 
299  private:
302 
303  public:
308 
313 
314  public:
315  explicit HashGrid(const ClusterCenter& c_dimension) : cells_(), grid_dimension_(), cell_dimension(c_dimension), grid_dimension(grid_dimension_)
316  {
317  }
318 
325  {
326  const CellIndex cellkey = cellindexAtClustercenter_(v.first);
327  CellContent& cell = cells_[cellkey];
328  updateGridDimension_(cellkey);
329  return cell.insert(v);
330  }
331 
335  void erase(iterator pos)
336  {
337  CellContent& cell = pos.grid_it_->second;
338  cell.erase(pos.cell_it_);
339  }
340 
347  {
348  const CellIndex cellkey = cellindexAtClustercenter_(key);
349  auto cell = cells_.find(cellkey);
350  if (cell == cells_.end())
351  return 0;
352  return cell->second.erase(key);
353  }
354 
358  void clear()
359  {
360  cells_.clear();
361  }
362 
367  {
368  grid_iterator grid_it = cells_.begin();
369  if (grid_it == cells_.end())
370  return end();
371 
372  cell_iterator cell_it = grid_it->second.begin();
373  return iterator(cells_, grid_it, cell_it);
374  }
375 
380  {
381  const_grid_iterator grid_it = cells_.begin();
382  if (grid_it == cells_.end())
383  return end();
384 
385  const_cell_iterator cell_it = grid_it->second.begin();
386  return const_iterator(cells_, grid_it, cell_it);
387  }
388 
393  {
394  return iterator(cells_);
395  }
396 
401  {
402  return const_iterator(cells_);
403  }
404 
408  bool empty() const
409  {
410  return size() == 0;
411  }
412 
416  size_type size() const
417  {
418  size_type ret = 0;
419 
420  for (const_grid_iterator it = grid_begin(); it != grid_end(); ++it)
421  {
422  ret += it->second.size();
423  }
424 
425  return ret;
426  }
427 
432  {
433  return cells_.begin();
434  }
435 
440  {
441  return cells_.end();
442  }
443 
447  const typename Grid::mapped_type& grid_at(const CellIndex& x) const
448  {
449  return cells_.at(x);
450  }
451 
455  typename Grid::mapped_type& grid_at(const CellIndex& x)
456  {
457  return cells_.at(x);
458  }
459 
464  {
465  return cells_.find(x);
466  }
467 
472  {
473  return cells_.find(x);
474  }
475 
476 
481  {
482  return cells_.begin();
483  }
488  {
489  return cells_.end();
490  }
491 
492  private:
493  // XXX: Replace with proper operator
495  {
496  CellIndex ret;
497  typename CellIndex::iterator it = ret.begin();
498  typename ClusterCenter::const_iterator lit = key.begin(), rit = cell_dimension.begin();
499  for (; it != ret.end(); ++it, ++lit, ++rit)
500  {
501  double t = std::floor(*lit / *rit);
502  if (t < std::numeric_limits<Int64>::min() || t > std::numeric_limits<Int64>::max())
503  throw Exception::OutOfRange(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION);
504  *it = static_cast<Int64>(t);
505  }
506  return ret;
507  }
508 
510  {
511  typename CellIndex::const_iterator it_new = d.begin();
512  typename CellIndex::iterator it_cur = grid_dimension_.begin();
513  for (; it_new != d.end(); ++it_new, ++it_cur)
514  {
515  if (*it_cur < *it_new)
516  *it_cur = *it_new;
517  }
518  }
519  };
520 
522  template<UInt N, typename T>
523  std::size_t hash_value(const DPosition<N, T>& b)
524  {
525  boost::hash<T> hasher;
526  std::size_t hash = 0;
527  for (typename DPosition<N, T>::const_iterator it = b.begin(); it != b.end(); ++it)
528  hash ^= hasher(*it);
529  return hash;
530  }
531 
532 } // namespace OpenMS
533 
534 #endif /* OPENMS_COMPARISON_CLUSTERING_HASHGRID_H */
Representation of a coordinate in D-dimensional space.
Definition: DPosition.h:55
ConstIterator end() const
Non-mutable end iterator.
Definition: DPosition.h:412
CoordinateType * iterator
Definition: DPosition.h:76
const CoordinateType * const_iterator
Definition: DPosition.h:77
ConstIterator begin() const
Non-mutable begin iterator.
Definition: DPosition.h:406
Out of range exception.
Definition: Exception.h:313
Constant element iterator for the hash grid.
Definition: HashGrid.h:192
ConstIterator(const Grid &grid, grid_iterator grid_it, cell_iterator cell_it)
Definition: HashGrid.h:241
const ConstIterator operator++(int)
Definition: HashGrid.h:257
bool operator!=(const ConstIterator &rhs) const
Definition: HashGrid.h:269
value_type * pointer
The pointer type as returned by operator->()
Definition: HashGrid.h:209
const Grid & grid_
Definition: HashGrid.h:214
const CellIndex index() const
Definition: HashGrid.h:284
grid_iterator grid_it_
Definition: HashGrid.h:215
HashGrid::value_type value_type
The iterator's value type.
Definition: HashGrid.h:205
bool operator==(const ConstIterator &rhs) const
Definition: HashGrid.h:264
value_type & reference
The reference type as returned by operator*()
Definition: HashGrid.h:207
Grid::const_iterator grid_iterator
Definition: HashGrid.h:196
ConstIterator & operator++()
Definition: HashGrid.h:250
const value_type * operator->() const
Definition: HashGrid.h:279
cell_iterator cell_it_
Definition: HashGrid.h:216
ConstIterator(const Iterator &it)
Definition: HashGrid.h:246
const value_type & operator*() const
Definition: HashGrid.h:274
ConstIterator(const Grid &grid)
Definition: HashGrid.h:237
std::input_iterator_tag iterator_category
The iterator's category type.
Definition: HashGrid.h:203
CellContent::const_iterator cell_iterator
Definition: HashGrid.h:197
std::ptrdiff_t difference_type
The difference type.
Definition: HashGrid.h:211
void searchNextCell_()
Definition: HashGrid.h:219
Element iterator for the hash grid.
Definition: HashGrid.h:93
value_type & operator*() const
Definition: HashGrid.h:172
CellContent::iterator cell_iterator
Definition: HashGrid.h:98
value_type * pointer
The pointer type as returned by operator->()
Definition: HashGrid.h:110
const CellIndex index() const
Definition: HashGrid.h:182
grid_iterator grid_it_
Definition: HashGrid.h:117
HashGrid::value_type value_type
The iterator's value type.
Definition: HashGrid.h:106
value_type & reference
The reference type as returned by operator*()
Definition: HashGrid.h:108
Grid::iterator grid_iterator
Definition: HashGrid.h:97
bool operator==(const Iterator &rhs) const
Definition: HashGrid.h:162
cell_iterator cell_it_
Definition: HashGrid.h:118
Iterator(Grid &grid, grid_iterator grid_it, cell_iterator cell_it)
Definition: HashGrid.h:143
Grid & grid_
Definition: HashGrid.h:116
std::input_iterator_tag iterator_category
The iterator's category type.
Definition: HashGrid.h:104
Iterator(Grid &grid)
Definition: HashGrid.h:139
std::ptrdiff_t difference_type
The difference type.
Definition: HashGrid.h:112
bool operator!=(const Iterator &rhs) const
Definition: HashGrid.h:167
void searchNextCell_()
Definition: HashGrid.h:121
const Iterator operator++(int)
Definition: HashGrid.h:155
Iterator & operator++()
Definition: HashGrid.h:148
value_type * operator->() const
Definition: HashGrid.h:177
Container for (2-dimensional coordinate, value) pairs.
Definition: HashGrid.h:61
CellContent::const_iterator const_cell_iterator
Definition: HashGrid.h:295
grid_iterator grid_end()
Definition: HashGrid.h:487
CellIndex cellindexAtClustercenter_(const ClusterCenter &key)
Definition: HashGrid.h:494
boost::unordered_multimap< ClusterCenter, Cluster > CellContent
Contents of a cell.
Definition: HashGrid.h:77
const CellIndex & grid_dimension
Upper-right corner of key space for cells.
Definition: HashGrid.h:312
Grid::const_iterator const_grid_iterator
Definition: HashGrid.h:293
CellIndex grid_dimension_
Definition: HashGrid.h:301
Iterator iterator
Definition: HashGrid.h:292
const_iterator begin() const
Returns iterator to first element.
Definition: HashGrid.h:379
CellContent::iterator cell_iterator
Definition: HashGrid.h:296
const_grid_iterator grid_find(const CellIndex &x) const
Returns the grid cell at given index if present, otherwise the grid_end iterator.
Definition: HashGrid.h:463
const_grid_iterator grid_end() const
Returns iterator to on after last grid cell.
Definition: HashGrid.h:439
DPosition< 2, Int64 > CellIndex
Index for cells.
Definition: HashGrid.h:72
DPosition< 2, double > ClusterCenter
Coordinate for stored pairs.
Definition: HashGrid.h:67
boost::unordered_map< CellIndex, CellContent > Grid
Map of (cell-index, cell-content).
Definition: HashGrid.h:82
cell_iterator insert(const value_type &v)
Inserts a (2-dimensional coordinate, value) pair.
Definition: HashGrid.h:324
ConstIterator const_iterator
Definition: HashGrid.h:291
size_type size() const
Return number of elements.
Definition: HashGrid.h:416
CellContent::value_type value_type
Definition: HashGrid.h:86
bool empty() const
Return true if HashGrid is empty.
Definition: HashGrid.h:408
Grid cells_
Definition: HashGrid.h:300
CellContent::size_type size_type
Definition: HashGrid.h:297
Grid::iterator grid_iterator
Definition: HashGrid.h:294
HashGrid(const ClusterCenter &c_dimension)
Definition: HashGrid.h:315
grid_iterator grid_find(const CellIndex &x)
Returns the grid cell at given index if present, otherwise the grid_end iterator.
Definition: HashGrid.h:471
CellContent::key_type key_type
Definition: HashGrid.h:84
void updateGridDimension_(const CellIndex &d)
Definition: HashGrid.h:509
grid_iterator grid_begin()
Definition: HashGrid.h:480
void clear()
Clears the map.
Definition: HashGrid.h:358
const Grid::mapped_type & grid_at(const CellIndex &x) const
Returns the grid cell at given index.
Definition: HashGrid.h:447
iterator end()
Returns iterator to first element.
Definition: HashGrid.h:392
const_iterator end() const
Returns iterator to first element.
Definition: HashGrid.h:400
void erase(iterator pos)
Erases element on given iterator.
Definition: HashGrid.h:335
const ClusterCenter cell_dimension
Dimension of cells.
Definition: HashGrid.h:307
Grid::mapped_type & grid_at(const CellIndex &x)
Definition: HashGrid.h:455
iterator begin()
Returns iterator to first element.
Definition: HashGrid.h:366
const_grid_iterator grid_begin() const
Returns iterator to first grid cell.
Definition: HashGrid.h:431
size_type erase(const key_type &key)
Erases elements matching the 2-dimensional coordinate.
Definition: HashGrid.h:346
CellContent::mapped_type mapped_type
Definition: HashGrid.h:85
OPENMS_INT64_TYPE Int64
Signed integer type (64bit)
Definition: Types.h:70
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:48
std::size_t hash_value(const DPosition< N, T > &b)
Definition: HashGrid.h:523