FEI Version of the Day
fei_TemplateUtils.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 _fei_TemplateUtils_hpp_
00044 #define _fei_TemplateUtils_hpp_
00045 
00046 
00047 #include <fei_iosfwd.hpp>
00048 #include <fei_SparseRowGraph.hpp>
00049 #include <snl_fei_RaggedTable.hpp>
00050 #include <snl_fei_Utils.hpp>
00051 
00052 #include <fei_ErrMacros.hpp>
00053 
00054 #include <set>
00055 #include <vector>
00056 #include <map>
00057 
00058 namespace fei {
00059 
00060   //------------------------------------------------------------------------
00064   template<typename SET_TYPE>
00065     void copySetToArray(const SET_TYPE& set_obj,
00066       int lenList,
00067       int* list)
00068     {
00069       int setsize = set_obj.size();
00070       int len = setsize > lenList ? lenList : setsize;
00071 
00072       typename SET_TYPE::const_iterator
00073         s_iter = set_obj.begin(),
00074                s_end = set_obj.end();
00075       for(int i=0; i<len; ++i, ++s_iter) {
00076         list[i] = *s_iter;
00077       }
00078     }
00079 
00082   template<typename T>
00083     void copySetToVector(const std::set<T>& set_obj, std::vector<T>& vec)
00084     {
00085       vec.clear();
00086       vec.reserve(set_obj.size());
00087 
00088       typename std::set<T>::const_iterator
00089         s_iter = set_obj.begin(), s_end = set_obj.end();
00090       for(; s_iter != s_end; ++s_iter) {
00091         vec.push_back(*s_iter);
00092       }
00093     }
00094 
00098   template<typename MAP_TYPE>
00099     void copyKeysToArray(const MAP_TYPE& map_obj,
00100        unsigned lenList,
00101        int* list)
00102     {
00103       unsigned i = 0;
00104       typename MAP_TYPE::const_iterator
00105         iter = map_obj.begin(), iter_end = map_obj.end();
00106 
00107       for(; iter != iter_end; ++iter) {
00108         if (i == lenList) break;
00109         list[i++] = iter->first;
00110       }
00111     }
00112 
00116   template<typename MAP_TYPE>
00117     void copyKeysToVector(const MAP_TYPE& map_obj,
00118                           std::vector<int>& keyvector)
00119     {
00120       keyvector.resize(map_obj.size());
00121       if (map_obj.empty()) return;
00122       copyKeysToArray<MAP_TYPE>(map_obj, map_obj.size(), &keyvector[0]);
00123     }
00124 
00125   template<typename T, typename U>
00126     void copyMapOfSetsToVectorOfVectors(const std::map<T,std::set<U> >& mapset,
00127                                      std::vector<T>& keys,
00128                                      std::vector<std::vector<U> >& values)
00129     {
00130       typedef std::map<T,std::set<U> > mapsettype;
00131       keys.resize(mapset.size());
00132       values.resize(mapset.size());
00133       typename mapsettype::const_iterator
00134        ms_iter = mapset.begin(), ms_end = mapset.end();
00135       for(size_t i=0; ms_iter!=ms_end; ++ms_iter, ++i) {
00136         keys[i] = ms_iter->first;
00137         typename std::set<U>::const_iterator
00138           s_iter = ms_iter->second.begin(), s_end = ms_iter->second.end();
00139         values[i].resize(ms_iter->second.size());
00140         for(size_t j=0; s_iter!=s_end; ++s_iter, ++j) {
00141           values[i][j] = *s_iter;
00142         }
00143       }
00144     }
00145 
00150   template<typename MAP_TYPE>
00151     void copyToArrays(MAP_TYPE& map_obj,
00152           int lenList,
00153           int* keylist,
00154           int* vallist)
00155     {
00156       int i = 0;
00157       typename MAP_TYPE::iterator
00158         iter = map_obj.begin(),
00159              iter_end = map_obj.end();
00160 
00161       for(; iter != iter_end; ++iter) {
00162         if (i == lenList) break;
00163         keylist[i] = (*iter).first;
00164         vallist[i++] = (*iter).second;
00165       }
00166     }
00167 
00169   template<typename MAP_TYPE>
00170     void destroyValues(MAP_TYPE& map_obj)
00171     {
00172       typename MAP_TYPE::iterator
00173         m_iter = map_obj.begin(),
00174       m_end  = map_obj.end();
00175 
00176       for(; m_iter != m_end; ++m_iter) {
00177         delete (*m_iter).second;
00178       }
00179     }
00180 
00182   template<typename MAP_TYPE, typename SET_TYPE>
00183   void writeToStream(snl_fei::RaggedTable<MAP_TYPE,SET_TYPE>& table,
00184          FEI_OSTREAM& os,
00185          const char* lineprefix=NULL)
00186   {
00187     MAP_TYPE& map_obj = table.getMap();
00188     typename MAP_TYPE::iterator
00189       m_iter = map_obj.begin(),
00190       m_end = map_obj.end();
00191 
00192     for(; m_iter != m_end; ++m_iter) {
00193       if (lineprefix != NULL) {
00194         os << lineprefix;
00195       }
00196 
00197       os << " row "<<(*m_iter).first<<": ";
00198 
00199       typename SET_TYPE::const_iterator
00200         s_iter = (*m_iter).second->begin(),
00201                s_end = (*m_iter).second->end();
00202 
00203       for(; s_iter != s_end; ++s_iter) {
00204         os << *s_iter << " ";
00205       }
00206 
00207       os << FEI_ENDL;
00208     }
00209   }
00210 
00211   template<typename MAP_TYPE, typename SET_TYPE>
00212     void packRaggedTable(snl_fei::RaggedTable<MAP_TYPE,SET_TYPE>& table,
00213                        std::vector<int>& intdata)
00214     {
00215       MAP_TYPE& map_obj = table.getMap();
00216       int numRows = map_obj.size();
00217 
00218       typename MAP_TYPE::iterator
00219         m_iter = map_obj.begin(),
00220         m_end  = map_obj.end();
00221 
00222       int nnz = 0;
00223 
00224       for(; m_iter != m_end; ++m_iter) {
00225         typename MAP_TYPE::value_type m_pair = *m_iter;
00226 
00227         int rowLen = m_pair.second->size();
00228         nnz += rowLen;
00229       }
00230 
00231       intdata.resize(1+2*numRows+nnz);
00232       intdata[0] = numRows;
00233       int* rowNumbers = &intdata[1];
00234       int* rowLengths = rowNumbers+numRows;
00235       int* packedCols = rowLengths+numRows;
00236 
00237       m_iter = map_obj.begin();
00238       unsigned offset = 0;
00239       for(unsigned i=0; m_iter != m_end; ++m_iter, ++i) {
00240         typename MAP_TYPE::value_type m_pair = *m_iter;
00241         rowNumbers[i] = m_pair.first;
00242         rowLengths[i] = m_pair.second->size();
00243 
00244         int* colInds = &packedCols[offset];
00245         copySetToArray(*(m_pair.second), rowLengths[i], colInds);
00246         offset += rowLengths[i];
00247       }
00248     }
00249 
00252   template<typename MAP_TYPE, typename SET_TYPE>
00253   fei::SharedPtr<fei::SparseRowGraph> createSparseRowGraph(const std::vector<snl_fei::RaggedTable<MAP_TYPE,SET_TYPE>* >& tables)
00254     {
00255       int numRows = 0;
00256       int nnz = 0;
00257       fei::SharedPtr<fei::SparseRowGraph> srg(new fei::SparseRowGraph);
00258 
00259       for(unsigned i=0; i<tables.size(); ++i) {
00260         MAP_TYPE& map_obj = tables[i]->getMap();
00261         numRows += map_obj.size();
00262 
00263         typename MAP_TYPE::iterator
00264           m_iter = map_obj.begin(),
00265           m_end  = map_obj.end();
00266         for(; m_iter != m_end; ++m_iter) {
00267           typename MAP_TYPE::value_type m_pair = *m_iter;
00268           nnz += m_pair.second->size();
00269         }
00270       }
00271 
00272       srg->rowNumbers.resize(numRows);
00273       srg->rowOffsets.resize(numRows+1);
00274       srg->packedColumnIndices.resize(nnz);
00275 
00276       unsigned offset1 = 0;
00277       unsigned rowOffset = 0;
00278       for(unsigned i=0; i<tables.size(); ++i) {
00279         MAP_TYPE& map_obj = tables[i]->getMap();
00280 
00281         typename MAP_TYPE::iterator
00282           m_iter = map_obj.begin(),
00283           m_end  = map_obj.end();
00284         for(; m_iter != m_end; ++m_iter) {
00285           typename MAP_TYPE::value_type m_pair = *m_iter;
00286           srg->rowNumbers[offset1] = m_pair.first;
00287           int rowLen = m_pair.second->size();
00288           srg->rowOffsets[offset1++] = rowOffset;
00289           int* cols = &srg->packedColumnIndices[rowOffset];
00290           copySetToArray(*(m_pair.second), rowLen, cols);
00291           rowOffset += rowLen;
00292         }
00293       }
00294 
00295       srg->rowOffsets[offset1] = rowOffset;
00296 
00297       return(srg);
00298     }
00299 
00301   template<typename MAP_TYPE, typename SET_TYPE>
00302   void copyToSparseRowGraph(snl_fei::RaggedTable<MAP_TYPE,SET_TYPE>& table,
00303                             fei::SparseRowGraph& srg)
00304     {
00305       MAP_TYPE& map_obj = table.getMap();
00306       int numRows = map_obj.size();
00307 
00308       srg.rowNumbers.resize(numRows);
00309       srg.rowOffsets.resize(numRows+1);
00310 
00311       int* rowNumPtr = &(srg.rowNumbers[0]);
00312       int* rowOffsPtr = &(srg.rowOffsets[0]);
00313 
00314       typename MAP_TYPE::iterator
00315         m_iter = map_obj.begin(),
00316         m_end  = map_obj.end();
00317 
00318       int offset = 0;
00319       int nnz = 0;
00320 
00321       for(; m_iter != m_end; ++m_iter) {
00322         typename MAP_TYPE::value_type m_pair = *m_iter;
00323 
00324         rowNumPtr[offset] = m_pair.first;
00325         rowOffsPtr[offset++] = nnz;
00326         int rowLen = m_pair.second->size();
00327         nnz += rowLen;
00328       }
00329       rowOffsPtr[offset] = nnz;
00330 
00331       srg.packedColumnIndices.resize(nnz);
00332       int* colPtr = &(srg.packedColumnIndices[0]);
00333       offset = 0;
00334       m_iter = map_obj.begin();
00335       int i = 0;
00336       for(; m_iter != m_end; ++m_iter, ++i) {
00337         typename MAP_TYPE::value_type m_pair = *m_iter;
00338 
00339         int rowLen = rowOffsPtr[i+1]-rowOffsPtr[i];
00340         int* colInds = &(colPtr[offset]);
00341         copySetToArray(*(m_pair.second), rowLen, colInds);
00342         offset += rowLen;
00343       }
00344     }
00345 
00348   template<typename MAP_TYPE, typename SET_TYPE>
00349   fei::SharedPtr<fei::SparseRowGraph>
00350     createSparseRowGraph(snl_fei::RaggedTable<MAP_TYPE,SET_TYPE>& table)
00351     {
00352       fei::SharedPtr<fei::SparseRowGraph> srg(new fei::SparseRowGraph);
00353 
00354       copyToSparseRowGraph<MAP_TYPE, SET_TYPE>(table, *srg);
00355 
00356       return( srg );
00357     }
00358 
00360   template<typename MAP_TYPE, typename SET_TYPE>
00361   int countNonzeros(snl_fei::RaggedTable<MAP_TYPE,SET_TYPE>& table)
00362     {
00363       int nnz = 0;
00364       MAP_TYPE& map_obj = table.getMap();
00365       typename MAP_TYPE::iterator
00366         m_iter = map_obj.begin(),
00367                m_end = map_obj.end();
00368 
00369       for(; m_iter != m_end; ++m_iter) {
00370         nnz += (*m_iter).second->size();
00371       }
00372 
00373       return(nnz);
00374     }
00375 
00376 } //namespace fei
00377 
00378 #endif // _fei_TemplateUtils_hpp_
00379 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends