Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <cmath>
00036 #include <iterator>
00037 #include <limits>
00038
00039 #include <boost/array.hpp>
00040 #include <boost/functional/hash.hpp>
00041 #include <boost/unordered/unordered_map.hpp>
00042
00043 #include <OpenMS/CONCEPT/Types.h>
00044 #include <OpenMS/DATASTRUCTURES/DPosition.h>
00045
00046 #ifndef OPENMS_COMPARISON_CLUSTERING_HASHGRID_H
00047 #define OPENMS_COMPARISON_CLUSTERING_HASHGRID_H
00048
00049 namespace OpenMS
00050 {
00061 template <typename Cluster>
00062 class HashGrid
00063 {
00064 public:
00068
00069 typedef DPosition<2, DoubleReal> ClusterCenter;
00070
00074 typedef DPosition<2, Int64> CellIndex;
00075
00079 typedef typename boost::unordered_multimap<ClusterCenter, Cluster> CellContent;
00080
00084 typedef boost::unordered_map<CellIndex, CellContent> Grid;
00085
00086 typedef typename CellContent::key_type key_type;
00087 typedef typename CellContent::mapped_type mapped_type;
00088 typedef typename CellContent::value_type value_type;
00089
00090 private:
00094 class Iterator :
00095 public std::iterator<std::input_iterator_tag, value_type>
00096 {
00097 private:
00098 friend class HashGrid;
00099
00100 typedef typename Grid::iterator grid_iterator;
00101 typedef typename CellContent::iterator cell_iterator;
00102
00103 Grid & grid_;
00104 grid_iterator grid_it_;
00105 cell_iterator cell_it_;
00106
00107
00108 void searchNextCell_()
00109 {
00110 while (cell_it_ == grid_it_->second.end())
00111 {
00112 grid_it_++;
00113
00114
00115 if (grid_it_ == grid_.end())
00116 {
00117 cell_it_ = cell_iterator();
00118 return;
00119 }
00120
00121 cell_it_ = grid_it_->second.begin();
00122 }
00123 }
00124
00125 public:
00126 Iterator(Grid & grid) :
00127 grid_(grid), grid_it_(grid.end())
00128 {}
00129
00130 Iterator(Grid & grid, grid_iterator grid_it, cell_iterator cell_it) :
00131 grid_(grid), grid_it_(grid_it), cell_it_(cell_it)
00132 {
00133 searchNextCell_();
00134 }
00135
00136 Iterator & operator++()
00137 {
00138 ++cell_it_;
00139 searchNextCell_();
00140 return *this;
00141 }
00142
00143 Iterator operator++(int)
00144 {
00145 Iterator ret(*this);
00146 operator++();
00147 return ret;
00148 }
00149
00150 bool operator==(const Iterator & rhs) const
00151 { return grid_it_ == rhs.grid_it_ && cell_it_ == rhs.cell_it_; }
00152
00153 bool operator!=(const Iterator & rhs) const
00154 { return !(*this == rhs); }
00155
00156 value_type & operator*() const
00157 { return *cell_it_; }
00158
00159 value_type * operator->() const
00160 { return &*cell_it_; }
00161
00162 const CellIndex index() const
00163 {
00164 return grid_it_->first;
00165 }
00166
00167 };
00168
00172 class ConstIterator :
00173 public std::iterator<std::input_iterator_tag, const value_type>
00174 {
00175 private:
00176 friend class HashGrid;
00177
00178 typedef typename Grid::const_iterator grid_iterator;
00179 typedef typename CellContent::const_iterator cell_iterator;
00180
00181 const Grid & grid_;
00182 grid_iterator grid_it_;
00183 cell_iterator cell_it_;
00184
00185
00186 void searchNextCell_()
00187 {
00188 while (cell_it_ == grid_it_->second.end())
00189 {
00190 grid_it_++;
00191
00192
00193 if (grid_it_ == grid_.end())
00194 {
00195 cell_it_ = cell_iterator();
00196 return;
00197 }
00198
00199 cell_it_ = grid_it_->second.begin();
00200 }
00201 }
00202
00203 public:
00204 ConstIterator(const Grid & grid) :
00205 grid_(grid), grid_it_(grid.end())
00206 {}
00207
00208 ConstIterator(const Grid & grid, grid_iterator grid_it, cell_iterator cell_it) :
00209 grid_(grid), grid_it_(grid_it), cell_it_(cell_it)
00210 {
00211 searchNextCell_();
00212 }
00213
00214 ConstIterator(const Iterator & it) :
00215 grid_(it.grid_), grid_it_(it.grid_it_), cell_it_(it.cell_it_)
00216 {}
00217
00218 ConstIterator & operator++()
00219 {
00220 ++cell_it_;
00221 searchNextCell_();
00222 return *this;
00223 }
00224
00225 ConstIterator operator++(int)
00226 {
00227 ConstIterator ret(*this);
00228 operator++();
00229 return ret;
00230 }
00231
00232 bool operator==(const ConstIterator & rhs) const
00233 { return grid_it_ == rhs.grid_it_ && cell_it_ == rhs.cell_it_; }
00234
00235 bool operator!=(const ConstIterator & rhs) const
00236 { return !(*this == rhs); }
00237
00238 const value_type & operator*() const
00239 { return *cell_it_; }
00240
00241 const value_type * operator->() const
00242 { return &*cell_it_; }
00243
00244 const CellIndex index() const
00245 {
00246 return grid_it_->first;
00247 }
00248
00249 };
00250
00251 public:
00252 typedef ConstIterator const_iterator;
00253 typedef Iterator iterator;
00254 typedef typename Grid::const_iterator const_grid_iterator;
00255 typedef typename Grid::iterator grid_iterator;
00256 typedef typename CellContent::const_iterator const_cell_iterator;
00257 typedef typename CellContent::iterator cell_iterator;
00258 typedef typename CellContent::size_type size_type;
00259
00260 private:
00261 Grid cells_;
00262 CellIndex grid_dimension_;
00263
00264 public:
00268 const ClusterCenter cell_dimension;
00272 const CellIndex & grid_dimension;
00273
00274 public:
00275 HashGrid(const ClusterCenter & cell_dimension) :
00276 cell_dimension(cell_dimension), grid_dimension(grid_dimension_)
00277 {}
00278
00284 cell_iterator insert(const value_type & v)
00285 {
00286 const CellIndex cellkey = cellindexAtClustercenter_(v.first);
00287 CellContent & cell = cells_[cellkey];
00288 updateGridDimension_(cellkey);
00289 return cell.insert(v);
00290 }
00291
00295 void erase(iterator pos)
00296 {
00297 CellContent & cell = pos.grid_it_->second;
00298 cell.erase(pos.cell_it_);
00299 }
00300
00306 size_type erase(const key_type & key)
00307 {
00308 const CellIndex cellkey = cellindexAtClustercenter_(key);
00309 try
00310 {
00311 CellContent & cell = cells_.at(cellkey);
00312 return cell.erase(key);
00313 }
00314 catch (std::out_of_range &) {}
00315 return 0;
00316 }
00317
00321 void clear() { cells_.clear(); }
00322
00326 iterator begin()
00327 {
00328 grid_iterator grid_it = cells_.begin();
00329 if (grid_it == cells_.end()) return end();
00330
00331 cell_iterator cell_it = grid_it->second.begin();
00332 return iterator(cells_, grid_it, cell_it);
00333 }
00334
00338 const_iterator begin() const
00339 {
00340 const_grid_iterator grid_it = cells_.begin();
00341 if (grid_it == cells_.end()) return end();
00342
00343 const_cell_iterator cell_it = grid_it->second.begin();
00344 return const_iterator(cells_, grid_it, cell_it);
00345 }
00346
00350 iterator end()
00351 {
00352 return iterator(cells_);
00353 }
00354
00358 const_iterator end() const
00359 {
00360 return const_iterator(cells_);
00361 }
00362
00366 bool empty() const
00367 {
00368 return size() == 0;
00369 }
00370
00374 size_type size() const
00375 {
00376 size_type ret = 0;
00377
00378 for (const_grid_iterator it = grid_begin(); it != grid_end(); ++it)
00379 {
00380 ret += it->second.size();
00381 }
00382
00383 return ret;
00384 }
00385
00389 const_grid_iterator grid_begin() const { return cells_.begin(); }
00390
00394 const_grid_iterator grid_end() const { return cells_.end(); }
00395
00399 const typename Grid::mapped_type & grid_at(const CellIndex & x) const { return cells_.at(x); }
00400
00404 grid_iterator grid_begin() { return cells_.begin(); }
00408 grid_iterator grid_end() { return cells_.end(); }
00412 typename Grid::mapped_type & grid_at(const CellIndex & x) { return cells_.at(x); }
00413
00414 private:
00415
00416 CellIndex cellindexAtClustercenter_(const ClusterCenter & key)
00417 {
00418 CellIndex ret;
00419 typename CellIndex::iterator it = ret.begin();
00420 typename ClusterCenter::const_iterator lit = key.begin(), rit = cell_dimension.begin();
00421 for (; it != ret.end(); ++it, ++lit, ++rit)
00422 {
00423 DoubleReal t = std::floor(*lit / *rit);
00424 if (t < std::numeric_limits<Int64>::min() || t > std::numeric_limits<Int64>::max()) throw Exception::OutOfRange(__FILE__, __LINE__, __PRETTY_FUNCTION__);
00425 *it = static_cast<Int64>(t);
00426 }
00427 return ret;
00428 }
00429
00430 void updateGridDimension_(const CellIndex & d)
00431 {
00432 typename CellIndex::const_iterator it_new = d.begin();
00433 typename CellIndex::iterator it_cur = grid_dimension_.begin();
00434 for (; it_new != d.end(); ++it_new, ++it_cur)
00435 {
00436 if (*it_cur < *it_new)
00437 *it_cur = *it_new;
00438 }
00439 }
00440
00441 };
00442
00444 template <UInt N, typename T>
00445 std::size_t hash_value(const DPosition<N, T> & b)
00446 {
00447 boost::hash<T> hasher;
00448 std::size_t hash = 0;
00449 for (typename DPosition<N, T>::const_iterator it = b.begin(); it != b.end(); ++it)
00450 hash ^= hasher(*it);
00451 return hash;
00452 }
00453
00454 }
00455
00456 #endif