FEI Version of the Day
snl_fei_RaggedTable.hpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 #ifndef _snl_fei_RaggedTable_hpp_
00044 #define _snl_fei_RaggedTable_hpp_
00045 
00046 
00047 #include <fei_macros.hpp>
00048 
00049 #include <snl_fei_SetTraits_specialize.hpp>
00050 #include <snl_fei_MapTraits_specialize.hpp>
00051 
00052 #include <fei_IndexTable.hpp>
00053 #include <fei_Pool_alloc.hpp>
00054 
00055 namespace snl_fei {
00056 
00063 template<typename MAP_TYPE, typename SET_TYPE>
00064 class RaggedTable : public fei::IndexTable {
00065  public:
00067   RaggedTable(int firstKey,
00068         int lastKey);
00069 
00071   RaggedTable(const RaggedTable<MAP_TYPE,SET_TYPE>& src);
00072 
00073   virtual ~RaggedTable();
00074 
00076   typedef MAP_TYPE map_type;
00077 
00079   typedef SET_TYPE row_type;
00080 
00082   void addDiagonals(int numIndices,
00083         const int* indices);
00084 
00086   void addIndices(int row,
00087                   int numIndices,
00088                   const int* indices);
00089 
00091   void addIndices(int numRows,
00092                   const int* rows,
00093                   int numIndices,
00094                   const int* indices);
00095 
00097   MAP_TYPE& getMap();
00098 
00100   const MAP_TYPE& getMap() const;
00101 
00103   SET_TYPE* getRow(int row);
00104 
00107   typedef typename MAP_TYPE::iterator iterator;
00108 
00110   iterator begin();
00111 
00113   iterator end();
00114 
00116   bool equal(const RaggedTable<MAP_TYPE,SET_TYPE>& rhs, bool quiet=true) const;
00117 
00118  private:
00119   MAP_TYPE map_;
00120   fei_Pool_alloc<SET_TYPE> poolAllocatorSet_;
00121   SET_TYPE dummy;
00122 }; //class RaggedTable
00123 
00124 template<typename MAP_TYPE, typename SET_TYPE>
00125 inline RaggedTable<MAP_TYPE,SET_TYPE>::RaggedTable(int firstKey,
00126                                           int lastKey)
00127   : map_(),
00128   poolAllocatorSet_(),
00129   dummy()
00130 {
00131 }
00132 
00133 template<typename MAP_TYPE, typename SET_TYPE>
00134 inline RaggedTable<MAP_TYPE,SET_TYPE>::RaggedTable(const RaggedTable<MAP_TYPE,SET_TYPE>& src)
00135   : map_(src.map_),
00136     poolAllocatorSet_()
00137 {
00138 }
00139 
00140 template<typename MAP_TYPE, typename SET_TYPE>
00141 RaggedTable<MAP_TYPE,SET_TYPE>::~RaggedTable()
00142 {
00143   iterator it = begin();
00144   iterator it_end = end();
00145   for(; it!=it_end; ++it) {
00146     poolAllocatorSet_.destroy( it->second );
00147     poolAllocatorSet_.deallocate( it->second, 1 );
00148   }
00149 }
00150 
00151 template<typename MAP_TYPE, typename SET_TYPE>
00152 inline void RaggedTable<MAP_TYPE,SET_TYPE>::addIndices(int row,
00153                                               int numIndices,
00154                                               const int* indices)
00155 {
00156   iterator m_end = map_.end();
00157   iterator m_iter = MapTraits<MAP_TYPE>::lower_bound(map_, row);
00158 
00159   SET_TYPE* mapped_indices = NULL;
00160 
00161   bool found_row = false;
00162   if (m_iter != m_end) {
00163     if ((*m_iter).first == row) {
00164       mapped_indices = (*m_iter).second;
00165       found_row = true;
00166     }
00167   }
00168 
00169   if (!found_row) {
00170     mapped_indices = poolAllocatorSet_.allocate(1);
00171     poolAllocatorSet_.construct(mapped_indices, dummy);
00172     typename MAP_TYPE::value_type val(row, mapped_indices);
00173     MapTraits<MAP_TYPE>::insert(map_, m_iter, val);
00174   }
00175 
00176   for(int i=0; i<numIndices; ++i) {
00177     SetTraits<SET_TYPE>::insert(mapped_indices, indices[i]);
00178   }
00179 }
00180 
00181 template<typename MAP_TYPE, typename SET_TYPE>
00182 inline void RaggedTable<MAP_TYPE,SET_TYPE>::addIndices(int numRows,
00183                              const int* rows,
00184                              int numIndices,
00185                              const int* indices)
00186 {
00187   iterator m_end = map_.end();
00188   iterator m_iter;
00189   SET_TYPE* mapped_indices = NULL;
00190 
00191   for(int i=0; i<numRows; ++i) {
00192     int row = rows[i];
00193     m_iter = MapTraits<MAP_TYPE>::lower_bound(map_, row);
00194 
00195     bool found_row = false;
00196     if (m_iter != m_end) {
00197       const typename MAP_TYPE::value_type& m_pair = *m_iter;
00198       if (m_pair.first == row) {
00199         mapped_indices = m_pair.second;
00200         found_row = true;
00201       }
00202     }
00203 
00204     if (!found_row) {
00205       mapped_indices = poolAllocatorSet_.allocate(1);
00206       poolAllocatorSet_.construct(mapped_indices, dummy);
00207       typename MAP_TYPE::value_type val(row, mapped_indices);
00208       MapTraits<MAP_TYPE>::insert(map_, m_iter, val);
00209     }
00210 
00211     for(int j=0; j<numIndices; ++j) {
00212       SetTraits<SET_TYPE>::insert(mapped_indices, indices[j]);
00213     }
00214   }
00215 }
00216 
00217 template<typename MAP_TYPE, typename SET_TYPE>
00218 inline MAP_TYPE& RaggedTable<MAP_TYPE,SET_TYPE>::getMap()
00219 {
00220   return(map_);
00221 }
00222 
00223 template<typename MAP_TYPE, typename SET_TYPE>
00224 inline const MAP_TYPE& RaggedTable<MAP_TYPE,SET_TYPE>::getMap() const
00225 {
00226   return(map_);
00227 }
00228 
00229 template<typename MAP_TYPE, typename SET_TYPE>
00230 inline typename RaggedTable<MAP_TYPE,SET_TYPE>::row_type*
00231 RaggedTable<MAP_TYPE,SET_TYPE>::getRow(int row)
00232 {
00233   iterator m_end = map_.end();
00234   iterator m_iter = map_.find(row);
00235   return( m_end == m_iter ? NULL : (*m_iter).second );
00236 }
00237 
00238 template<typename MAP_TYPE, typename SET_TYPE>
00239 inline typename RaggedTable<MAP_TYPE,SET_TYPE>::iterator
00240 RaggedTable<MAP_TYPE,SET_TYPE>::begin()
00241 {
00242   return(map_.begin());
00243 }
00244 
00245 template<typename MAP_TYPE, typename SET_TYPE>
00246 inline typename RaggedTable<MAP_TYPE,SET_TYPE>::iterator
00247 RaggedTable<MAP_TYPE,SET_TYPE>::end()
00248 {
00249   return(map_.end());
00250 }
00251 
00252 template<typename MAP_TYPE, typename SET_TYPE>
00253 inline void RaggedTable<MAP_TYPE,SET_TYPE>::addDiagonals(int numIndices,
00254                                                 const int* indices)
00255 {
00256   for(int i=0; i<numIndices; ++i) {
00257     int ind = indices[i];
00258     addIndices(ind, 1, &ind);
00259   }
00260 }
00261 
00262 template<typename MAP_TYPE, typename SET_TYPE>
00263 bool RaggedTable<MAP_TYPE,SET_TYPE>::equal(const RaggedTable<MAP_TYPE,SET_TYPE>& rhs, bool quiet) const
00264 {
00265   if (map_.size() != rhs.getMap().size()) {
00266     if (!quiet) {
00267       FEI_COUT << "RaggedTable::equal sizes don't match." << FEI_ENDL;
00268     }
00269     return(false);
00270   }
00271 
00272   typename map_type::const_iterator
00273    m_iter = map_.begin(),
00274    m_end  = map_.end();
00275 
00276   typename map_type::const_iterator
00277    rhs_iter = rhs.getMap().begin(),
00278    rhs_end  = rhs.getMap().end();
00279 
00280   for(; m_iter != m_end; ++m_iter, ++rhs_iter) {
00281     if (rhs_iter->first != m_iter->first) {
00282       if (!quiet) {
00283         FEI_COUT << "RaggedTable::equal keys don't match." << FEI_ENDL;
00284       }
00285       return(false);
00286     }
00287 
00288     if (*(rhs_iter->second) != *(m_iter->second)) {
00289       if (!quiet) {
00290         FEI_COUT << "RaggedTable::equal row-values don't match." << FEI_ENDL;
00291       }
00292       return(false);
00293     }
00294   }
00295 
00296   return(true);
00297 }
00298 
00299 }//namespace snl_fei
00300 
00301 #endif
00302 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends