Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages

HashGrid.h

Go to the documentation of this file.
00001 // --------------------------------------------------------------------------
00002 //                   OpenMS -- Open-Source Mass Spectrometry
00003 // --------------------------------------------------------------------------
00004 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
00005 // ETH Zurich, and Freie Universitaet Berlin 2002-2012.
00006 //
00007 // This software is released under a three-clause BSD license:
00008 //  * Redistributions of source code must retain the above copyright
00009 //    notice, this list of conditions and the following disclaimer.
00010 //  * Redistributions in binary form must reproduce the above copyright
00011 //    notice, this list of conditions and the following disclaimer in the
00012 //    documentation and/or other materials provided with the distribution.
00013 //  * Neither the name of any author or any participating institution
00014 //    may be used to endorse or promote products derived from this software
00015 //    without specific prior written permission.
00016 // For a full list of authors, refer to the file AUTHORS.
00017 // --------------------------------------------------------------------------
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
00022 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00024 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00025 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00027 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00028 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 //
00030 // --------------------------------------------------------------------------
00031 // $Maintainer: Lars Nilse $
00032 // $Authors: Bastian Blank $
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     // XXX: Check is there is another type handy in OpenMS already
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       // Search for next non-empty cell
00108       void searchNextCell_()
00109       {
00110         while (cell_it_ == grid_it_->second.end())
00111         {
00112           grid_it_++;
00113 
00114           // If we are at the last cell, set cell iterator to something well-known
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       // Search for next non-empty cell
00186       void searchNextCell_()
00187       {
00188         while (cell_it_ == grid_it_->second.end())
00189         {
00190           grid_it_++;
00191 
00192           // If we are at the last cell, set cell iterator to something well-known
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     // XXX: Replace with proper operator
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 /* OPENMS_COMPARISON_CLUSTERING_HASHGRID_H */

OpenMS / TOPP release 1.10.0 Documentation generated on Thu Mar 7 2013 09:42:40 using doxygen 1.7.1