FEI Version of the Day
fei_FillableMat.cpp
00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include <fei_FillableMat.hpp>
00010 #include <fei_EqnBuffer.hpp>
00011 #include <fei_CSVec.hpp>
00012 
00013 namespace fei {
00014 
00015 //-----------------------------------------------------------------
00016 FillableMat::FillableMat()
00017  : matdata_(),
00018    vecpool_()
00019 {
00020 }
00021 
00022 //-----------------------------------------------------------------
00023 FillableMat::FillableMat(EqnBuffer& eqnbuf)
00024  : matdata_(),
00025    vecpool_()
00026 {
00027   std::vector<int>& eqnNums = eqnbuf.eqnNumbers();
00028   int numEqns = eqnNums.size();
00029   std::vector<fei::CSVec*>& eqns = eqnbuf.eqns();
00030 
00031   for(int i=0; i<numEqns; ++i) {
00032     int row = eqnNums[i];
00033     fei::CSVec* row_vec = eqns[i];
00034     int rowlen = row_vec->size();
00035     int* indices = &(row_vec->indices()[0]);
00036     double* coefs = &(row_vec->coefs()[0]);
00037 
00038     for(int j=0; j<rowlen; ++j) {
00039       putCoef(row, indices[j], coefs[j]);
00040     }
00041   }
00042 }
00043 
00044 //-----------------------------------------------------------------
00045 FillableMat::~FillableMat()
00046 {
00047   feipoolmat::iterator
00048     iter = matdata_.begin(), iter_end = matdata_.end();
00049   for(; iter!=iter_end; ++iter) {
00050     vecpool_.destroy(iter->second);
00051     vecpool_.deallocate(iter->second, 1);
00052   }
00053 }
00054 
00055 //-----------------------------------------------------------------
00056 FillableMat&
00057 FillableMat::operator=(const FillableMat& src)
00058 {
00059   clear();
00060 
00061   FillableMat::const_iterator
00062     s_iter = src.begin(),
00063     s_end = src.end();
00064 
00065   for(; s_iter != s_end; ++s_iter) {
00066     int row = s_iter->first;
00067     const CSVec* srow = s_iter->second;
00068     const std::vector<int>& s_ind = srow->indices();
00069     const std::vector<double>& s_coef = srow->coefs();
00070 
00071     for(size_t i=0; i<s_ind.size(); ++i) {
00072       int col = s_ind[i];
00073       double coef = s_coef[i];
00074 
00075       putCoef(row, col, coef);
00076     }
00077   }
00078 
00079   return *this;
00080 }
00081 
00082 //-----------------------------------------------------------------
00083 void
00084 FillableMat::setValues(double value)
00085 {
00086   feipoolmat::iterator
00087     iter = matdata_.begin(), iter_end = matdata_.end();
00088 
00089   for(; iter != iter_end; ++iter) {
00090     set_values(*(iter->second), value);
00091   }
00092 }
00093 
00094 //-----------------------------------------------------------------
00095 void
00096 FillableMat::createPosition(int row, int col)
00097 {
00098   sumInCoef(row, col, 0.0);
00099 }
00100 
00101 //-----------------------------------------------------------------
00102 FillableMat::feipoolmat::iterator
00103 insert_row(FillableMat::feipoolmat& matdata,
00104            FillableMat::feipoolmat::iterator iter,
00105            int row,
00106            fei_Pool_alloc<CSVec>& vecpool)
00107 {
00108   static CSVec dummy;
00109 
00110   CSVec* vptr = vecpool.allocate(1);
00111   vecpool.construct(vptr, dummy);
00112 
00113   if (vptr->indices().capacity() == 0) {
00114     vptr->indices().reserve(16);
00115     vptr->coefs().reserve(16);
00116   }
00117 
00118   return matdata.insert(iter, std::make_pair(row, vptr));
00119 }
00120 
00121 //-----------------------------------------------------------------
00122 void
00123 FillableMat::sumInCoef(int row, int col, double coef)
00124 {
00125   CSVec* rowvec = create_or_getRow(row);
00126 
00127   add_entry(*rowvec, col, coef);
00128 }
00129 
00130 //-----------------------------------------------------------------
00131 void
00132 FillableMat::putCoef(int row, int col, double coef)
00133 {
00134   CSVec* rowvec = create_or_getRow(row);
00135 
00136   put_entry(*rowvec, col, coef);
00137 }
00138 
00139 //-----------------------------------------------------------------
00140 void
00141 FillableMat::sumInRow(int row, const int* cols, const double* coefs,
00142                       unsigned len)
00143 {
00144   CSVec* rowvec = create_or_getRow(row);
00145 
00146   for(unsigned i=0; i<len; ++i) {
00147     add_entry(*rowvec, cols[i], coefs[i]);
00148   }
00149 }
00150 
00151 //-----------------------------------------------------------------
00152 void
00153 FillableMat::putRow(int row, const int* cols, const double* coefs,
00154                     unsigned len)
00155 {
00156   CSVec* rowvec = create_or_getRow(row);
00157 
00158   for(unsigned i=0; i<len; ++i) {
00159     put_entry(*rowvec, cols[i], coefs[i]);
00160   }
00161 }
00162 
00163 //-----------------------------------------------------------------
00164 unsigned
00165 FillableMat::getNumRows() const
00166 {
00167   return matdata_.size();
00168 }
00169 
00170 //-----------------------------------------------------------------
00171 bool
00172 FillableMat::hasRow(int row) const
00173 {
00174   feipoolmat::const_iterator iter = matdata_.find(row);
00175   return iter != matdata_.end();
00176 }
00177 
00178 //-----------------------------------------------------------------
00179 const CSVec*
00180 FillableMat::getRow(int row) const
00181 {
00182   feipoolmat::const_iterator iter = matdata_.lower_bound(row);
00183 
00184   if (iter == matdata_.end() || iter->first != row) {
00185     throw std::runtime_error("fei::FillableMat: row not found.");
00186   }
00187 
00188   return iter->second;
00189 }
00190 
00191 //-----------------------------------------------------------------
00192 CSVec*
00193 FillableMat::create_or_getRow(int row)
00194 {
00195   feipoolmat::iterator iter = matdata_.lower_bound(row);
00196 
00197   if (iter == matdata_.end() || iter->first != row) {
00198     iter = insert_row(matdata_, iter, row, vecpool_);
00199   }
00200 
00201   return iter->second;
00202 }
00203 
00204 //-----------------------------------------------------------------
00205 void
00206 FillableMat::clear()
00207 {
00208   feipoolmat::iterator
00209     iter = matdata_.begin(), iter_end = matdata_.end();
00210   for(; iter!=iter_end; ++iter) {
00211     vecpool_.destroy(iter->second);
00212     vecpool_.deallocate(iter->second, 1);
00213   }
00214 
00215   matdata_.clear();
00216 }
00217 
00218 //-----------------------------------------------------------------
00219 bool
00220 FillableMat::operator==(const FillableMat& rhs) const
00221 {
00222   if (getNumRows() != rhs.getNumRows()) return false;
00223 
00224   FillableMat::const_iterator
00225     this_it = begin(),
00226     this_end = end();
00227 
00228   FillableMat::const_iterator
00229     rhs_it = rhs.begin(),
00230     rhs_end = rhs.end();
00231 
00232   for(; this_it != this_end; ++this_it, ++rhs_it) {
00233     int this_row = this_it->first;
00234     int rhs_row = rhs_it->first;
00235     if (this_row != rhs_row) return false;
00236 
00237     const CSVec* this_row_vec = this_it->second;
00238     const CSVec* rhs_row_vec = rhs_it->second;
00239 
00240     if (*this_row_vec != *rhs_row_vec) return false;
00241   }
00242 
00243   return true;
00244 }
00245 
00246 //-----------------------------------------------------------------
00247 bool
00248 FillableMat::operator!=(const FillableMat& rhs) const
00249 {
00250   return !(*this == rhs);
00251 }
00252 
00253 //-----------------------------------------------------------------
00254 void print(std::ostream& os, const FillableMat& mat)
00255 {
00256   FillableMat::const_iterator
00257     irow = mat.begin(), irowend = mat.end();
00258   for(; irow!=irowend; ++irow) {
00259     int row = irow->first;
00260     const CSVec* vec = irow->second;
00261     const std::vector<int>& v_ind = vec->indices();
00262     const std::vector<double>& v_coef = vec->coefs();
00263     os << "row " << row << ": ";
00264     for(size_t i=0; i<v_ind.size(); ++i) {
00265       os << "("<<v_ind[i]<<","<<v_coef[i]<<") ";
00266     }
00267     os << std::endl;
00268   }
00269 }
00270 
00271 //-----------------------------------------------------------------
00272 int count_nnz(const FillableMat& mat)
00273 {
00274   int nnz = 0;
00275 
00276   FillableMat::const_iterator
00277     r_iter = mat.begin(),
00278     r_end = mat.end();
00279 
00280   for(; r_iter != r_end; ++r_iter) {
00281     CSVec* row = r_iter->second;
00282     nnz += row->size();
00283   }
00284 
00285   return nnz;
00286 }
00287 
00288 //-----------------------------------------------------------------
00289 void get_row_numbers(const FillableMat& mat, std::vector<int>& rows)
00290 {
00291   rows.resize(mat.getNumRows());
00292 
00293   FillableMat::const_iterator
00294     m_iter = mat.begin(),
00295     m_end = mat.end();
00296 
00297   size_t offset = 0;
00298   for(; m_iter!=m_end; ++m_iter) {
00299     rows[offset++] = m_iter->first;
00300   }
00301 }
00302 
00303 }//namespace fei
00304 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends