AnasaziStatusTestCombo.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                 Anasazi: Block Eigensolvers Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 //
00029 
00030 #ifndef ANASAZI_STATUS_TEST_COMBO_HPP
00031 #define ANASAZI_STATUS_TEST_COMBO_HPP
00032 
00039 #include "AnasaziTypes.hpp"
00040 #include "AnasaziStatusTest.hpp"
00041 #include "Teuchos_Array.hpp"
00042 namespace Anasazi {
00043 
00044 
00061 template <class ScalarType, class MV, class OP>
00062 class StatusTestCombo : public StatusTest<ScalarType,MV,OP> {
00063 
00064  private:
00065    typedef Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > STPArray;
00066 
00067  public:
00068 
00070  enum ComboType
00071    {
00072      OR,           
00073      AND,          
00074      SEQOR,        
00075      SEQAND        
00076    };
00077 
00078 
00079 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00080 
00081   typedef Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > t_arr;
00082   typedef std::vector< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > st_vector;
00083   typedef typename st_vector::iterator                 iterator;
00084   typedef typename st_vector::const_iterator     const_iterator;
00085 
00086 #endif // DOXYGEN_SHOULD_SKIP_THIS
00087 
00089 
00090 
00093   StatusTestCombo() : state_(Undefined) {}
00094 
00097   StatusTestCombo(ComboType type, Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > tests) :
00098     state_(Undefined), 
00099     type_(type)
00100   {
00101     setTests(tests);
00102   };
00103 
00105   virtual ~StatusTestCombo() {};
00107 
00109 
00110 
00114   TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
00115 
00117   TestStatus getStatus() const {
00118     return state_;
00119   }
00120 
00122 
00129   std::vector<int> whichVecs() const {
00130     return ind_;
00131   }
00132 
00134   //
00135   // See whichVecs()
00136   int howMany() const {
00137     return ind_.size();
00138   }
00139 
00141 
00143 
00144 
00148   void setComboType(ComboType type) {
00149     type_ = type;
00150     state_ = Undefined;
00151   }
00152 
00154   ComboType getComboType() const {return type_;}
00155 
00159   void setTests(Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tests) {
00160     tests_ = tests;
00161     state_ = Undefined;
00162   }
00163 
00165   Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > getTests() const {return tests_;}
00166 
00171   void addTest(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test) {
00172     tests_.push_back(test);
00173     state_ = Undefined;
00174   }
00175 
00180   void removeTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &test);
00181 
00183 
00185 
00186 
00187 
00190   void reset();
00191 
00193 
00198   void clearStatus();
00199 
00201 
00203 
00204   
00206   std::ostream& print(std::ostream& os, int indent = 0) const;
00207  
00209   private:
00210 
00211   TestStatus evalOR(Eigensolver<ScalarType,MV,OP>* solver);
00212   TestStatus evalAND(Eigensolver<ScalarType,MV,OP>* solver);
00213   TestStatus evalSEQOR(Eigensolver<ScalarType,MV,OP>* solver);
00214   TestStatus evalSEQAND(Eigensolver<ScalarType,MV,OP>* solver);
00215 
00216   TestStatus state_;
00217   ComboType type_;
00218   STPArray tests_;
00219   std::vector<int> ind_;
00220 
00221 };
00222 
00223 
00224 template <class ScalarType, class MV, class OP>
00225 void StatusTestCombo<ScalarType,MV,OP>::removeTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &test) 
00226 {
00227   typename STPArray::iterator iter1;
00228   iter1 = std::find(tests_.begin(),tests_.end(),test);
00229   if (iter1 != tests_.end()) {
00230     tests_.erase(iter1);
00231     state_ = Undefined;
00232   }
00233 }
00234 
00235 
00236 template <class ScalarType, class MV, class OP>
00237 TestStatus StatusTestCombo<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
00238   clearStatus();
00239   switch (type_) {
00240     case OR:
00241       state_ = evalOR(solver);
00242       break;
00243     case AND:
00244       state_ = evalAND(solver);
00245       break;
00246     case SEQOR:
00247       state_ = evalSEQOR(solver);
00248       break;
00249     case SEQAND:
00250       state_ = evalSEQAND(solver);
00251       break;
00252   }
00253   return state_;
00254 }
00255 
00256 
00257 template <class ScalarType, class MV, class OP>
00258 void StatusTestCombo<ScalarType,MV,OP>::reset() {
00259   ind_.resize(0);
00260   state_ = Undefined;
00261   typedef typename STPArray::iterator iter;
00262   for (iter i=tests_.begin(); i != tests_.end(); i++) {
00263     (*i)->reset();
00264   }
00265 }
00266 
00267 template <class ScalarType, class MV, class OP>
00268 void StatusTestCombo<ScalarType,MV,OP>::clearStatus() {
00269   ind_.resize(0);
00270   state_ = Undefined;
00271   typedef typename STPArray::iterator iter;
00272   for (iter i=tests_.begin(); i != tests_.end(); i++) {
00273     (*i)->clearStatus();
00274   }
00275 }
00276 
00277 template <class ScalarType, class MV, class OP>
00278 std::ostream& StatusTestCombo<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
00279   std::string ind(indent,' ');
00280   os << ind << "- StatusTestCombo: ";
00281   switch (state_) {
00282   case Passed:
00283     os << "Passed" << std::endl;
00284     break;
00285   case Failed:
00286     os << "Failed" << std::endl;
00287     break;
00288   case Undefined:
00289     os << "Undefined" << std::endl;
00290     break;
00291   }
00292   // print children, with extra indention
00293   typedef typename STPArray::const_iterator const_iter;
00294   for (const_iter i=tests_.begin(); i != tests_.end(); i++) {
00295     (*i)->print(os,indent+2);
00296   }
00297   return os;
00298 }
00299 
00300 template <class ScalarType, class MV, class OP>
00301 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalOR( Eigensolver<ScalarType,MV,OP>* solver ) {
00302   state_ = Failed;
00303   typedef typename STPArray::iterator iter;
00304   for (iter i=tests_.begin(); i != tests_.end(); i++) {
00305     TestStatus r = (*i)->checkStatus(solver);
00306     if (i == tests_.begin()) {
00307       ind_ = (*i)->whichVecs();
00308       // sort ind_ for use below
00309       std::sort(ind_.begin(),ind_.end());
00310     }
00311     else {
00312       // to use set_union, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
00313       // also, ind and iwv must be in ascending order; only ind_ is
00314       // lastly, the return from set_union points to the last element in the union, which tells us how big the union is
00315       std::vector<int> iwv = (*i)->whichVecs();
00316       std::sort(iwv.begin(),iwv.end());
00317       std::vector<int> tmp(ind_.size() + iwv.size());
00318       std::vector<int>::iterator end;
00319       end = std::set_union(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
00320       tmp.resize(end - tmp.begin());
00321       // ind_ will be sorted coming from set_union
00322       ind_ = tmp;
00323     }
00324     if (r == Passed) {
00325       state_ = Passed;
00326     }
00327     else {
00328       TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
00329                          "Anasazi::StatusTestCombo::evalOR(): child test gave invalid return");
00330     }
00331   }
00332   return state_;
00333 }
00334 
00335 template <class ScalarType, class MV, class OP>
00336 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalSEQOR( Eigensolver<ScalarType,MV,OP>* solver ) {
00337   state_ = Failed;
00338   typedef typename STPArray::iterator iter;
00339   for (iter i=tests_.begin(); i != tests_.end(); i++) {
00340     TestStatus r = (*i)->checkStatus(solver);
00341     if (i == tests_.begin()) {
00342       ind_ = (*i)->whichVecs();
00343       // sort ind_ for use below
00344       std::sort(ind_.begin(),ind_.end());
00345     }
00346     else {
00347       // to use set_union, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
00348       // also, ind and iwv must be in ascending order; only ind_ is
00349       // lastly, the return from set_union points to the last element in the union, which tells us how big the union is
00350       std::vector<int> iwv = (*i)->whichVecs();
00351       std::sort(iwv.begin(),iwv.end());
00352       std::vector<int> tmp(ind_.size() + iwv.size());
00353       std::vector<int>::iterator end;
00354       end = std::set_union(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
00355       tmp.resize(end - tmp.begin());
00356       // ind_ will be sorted coming from set_union
00357       ind_ = tmp;
00358     }
00359     if (r == Passed) {
00360       state_ = Passed;
00361       break;
00362     }
00363     else {
00364       TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
00365                          "Anasazi::StatusTestCombo::evalSEQOR(): child test gave invalid return");
00366     }
00367   }
00368   return state_;
00369 }
00370 
00371 template <class ScalarType, class MV, class OP>
00372 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalAND( Eigensolver<ScalarType,MV,OP>* solver ) {
00373   state_ = Passed;
00374   typedef typename STPArray::iterator iter;
00375   for (iter i=tests_.begin(); i != tests_.end(); i++) {
00376     TestStatus r = (*i)->checkStatus(solver);
00377     if (i == tests_.begin()) {
00378       ind_ = (*i)->whichVecs();
00379       // sort ind_ for use below
00380       std::sort(ind_.begin(),ind_.end());
00381     }
00382     else {
00383       // to use set_intersection, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
00384       // also, ind and iwv must be in ascending order; only ind_ is
00385       // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
00386       std::vector<int> iwv = (*i)->whichVecs();
00387       std::sort(iwv.begin(),iwv.end());
00388       std::vector<int> tmp(ind_.size() + iwv.size());
00389       std::vector<int>::iterator end;
00390       end = std::set_intersection(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
00391       tmp.resize(end - tmp.begin());
00392       // ind_ will be sorted coming from set_intersection
00393       ind_ = tmp;
00394     }
00395     if (r == Failed) {
00396       state_ = Failed;
00397     }
00398     else {
00399       TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
00400                          "Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
00401     }
00402   }
00403   return state_;
00404 }
00405 
00406 template <class ScalarType, class MV, class OP>
00407 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalSEQAND( Eigensolver<ScalarType,MV,OP>* solver ) {
00408   state_ = Passed;
00409   typedef typename STPArray::iterator iter;
00410   for (iter i=tests_.begin(); i != tests_.end(); i++) {
00411     TestStatus r = (*i)->checkStatus(solver);
00412     if (i == tests_.begin()) {
00413       ind_ = (*i)->whichVecs();
00414       // sort ind_ for use below
00415       std::sort(ind_.begin(),ind_.end());
00416     }
00417     else {
00418       // to use set_intersection, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
00419       // also, ind and iwv must be in ascending order; only ind_ is
00420       // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
00421       std::vector<int> iwv = (*i)->whichVecs();
00422       std::sort(iwv.begin(),iwv.end());
00423       std::vector<int> tmp(ind_.size() + iwv.size());
00424       std::vector<int>::iterator end;
00425       end = std::set_intersection(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
00426       tmp.resize(end - tmp.begin());
00427       // ind_ will be sorted coming from set_intersection
00428       ind_ = tmp;
00429     }
00430     if (r == Failed) {
00431       state_ = Failed;
00432       break;
00433     }
00434     else {
00435       TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
00436                          "Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
00437     }
00438   }
00439   return state_;
00440 }
00441 
00442 
00443 
00444 } // end of Anasazi namespace
00445 
00446 #endif /* ANASAZI_STATUS_TEST_COMBO_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
Generated on Wed Apr 13 09:56:59 2011 for Anasazi by  doxygen 1.6.3