Anasazi Version of the Day
AnasaziStatusTestWithOrdering.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_ORDEREDRESNORM_HPP
00031 #define ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP
00032 
00040 #include "AnasaziStatusTest.hpp"
00041 #include "Teuchos_ScalarTraits.hpp"
00042 #include "Teuchos_LAPACK.hpp"
00043 
00067 namespace Anasazi {
00068 
00069 
00070 template <class ScalarType, class MV, class OP>
00071 class StatusTestWithOrdering : public StatusTest<ScalarType,MV,OP> {
00072 
00073  private:
00074   typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00075   typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00076 
00077  public:
00078 
00080 
00081 
00083   StatusTestWithOrdering(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test, Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sorter, int quorum = -1);
00084 
00086   virtual ~StatusTestWithOrdering() {};
00088 
00090 
00091 
00095   TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
00096 
00098   TestStatus getStatus() const { return state_; }
00099 
00101 
00106   std::vector<int> whichVecs() const {
00107     return ind_;
00108   }
00109 
00111   int howMany() const {
00112     return ind_.size();
00113   }
00114 
00116 
00118 
00119 
00125   void setQuorum(int quorum) {
00126     state_ = Undefined;
00127     quorum_ = quorum;
00128   }
00129 
00132   int getQuorum() const {
00133     return quorum_;
00134   }
00135 
00137 
00139 
00140 
00141 
00146   void reset() { 
00147     ind_.resize(0);
00148     state_ = Undefined;
00149     test_->reset();
00150   }
00151 
00153 
00158   void clearStatus() {
00159     ind_.resize(0);
00160     state_ = Undefined;
00161     test_->clearStatus();
00162   }
00163 
00168   void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &vals) {
00169     rvals_ = vals;
00170     ivals_.resize(rvals_.size(),MT::zero());
00171     state_ = Undefined;
00172   }
00173 
00178   void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &rvals, const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &ivals) {
00179     rvals_ = rvals;
00180     ivals_ = ivals;
00181     state_ = Undefined;
00182   }
00183 
00188   void getAuxVals(std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &rvals, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &ivals) const {
00189     rvals = rvals_;
00190     ivals = ivals_;
00191   }
00192 
00194 
00196 
00197   
00199   std::ostream& print(std::ostream& os, int indent = 0) const;
00200  
00202   private:
00203     TestStatus state_;
00204     std::vector<int> ind_;
00205     int quorum_;
00206     std::vector<MagnitudeType> rvals_, ivals_;
00207     Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sorter_;
00208     Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test_;
00209 };
00210 
00211 
00212 template <class ScalarType, class MV, class OP>
00213 StatusTestWithOrdering<ScalarType,MV,OP>::StatusTestWithOrdering(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test, Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sorter, int quorum)
00214   : state_(Undefined), ind_(0), quorum_(quorum), rvals_(0), ivals_(0), sorter_(sorter), test_(test)
00215 {
00216   TEST_FOR_EXCEPTION(sorter_ == Teuchos::null, StatusTestError, "StatusTestWithOrdering::constructor() was passed null pointer for constituent SortManager.");
00217   TEST_FOR_EXCEPTION(test_ == Teuchos::null, StatusTestError, "StatusTestWithOrdering::constructor() was passed null pointer for constituent StatusTest.");
00218 }
00219 
00220 template <class ScalarType, class MV, class OP>
00221 TestStatus StatusTestWithOrdering<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
00222 
00223   // Algorithm
00224   // we PASS iff the "most signficant" values of "all values" PASS
00225   // "most significant" is measured by sorter
00226   // auxilliary values are automatically PASSED
00227   // constituent status test determines who else passes
00228   // "all values" mean {auxilliary values} UNION {solver's ritz values}
00229   //
00230   // test_->checkStatus()                   calls the constituent status test
00231   // cwhch = test_->whichVecs()             gets the passing indices from the constituent test
00232   // solval = solver->getRitzValues()       gets the solver's ritz values
00233   // allval = {solval auxval}               contains all values
00234   // sorter_->sort(allval,perm)             sort all values (we just need the perm vector)
00235   //
00236   // allpass = {cwhch numsolval+1 ... numsolval+numAux}
00237   // mostsig = {perm[1] ... perm[quorum]}
00238   // whichVecs = mostsig INTERSECT allpass
00239   // if size(whichVecs) >= quorum,
00240   //    PASS
00241   // else
00242   //    FAIL
00243   // 
00244   // finish: this needs to be better tested and revisited for efficiency.
00245 
00246   // call the constituent solver manager
00247   test_->checkStatus(solver);
00248   std::vector<int> cwhch( test_->whichVecs() );
00249 
00250   // get the ritzvalues from solver
00251   std::vector<Value<ScalarType> > solval = solver->getRitzValues();
00252   int numsolval = solval.size();
00253   int numauxval = rvals_.size();
00254   int numallval = numsolval + numauxval;
00255 
00256   if (numallval == 0) {
00257     ind_.resize(0);
00258     return Failed;
00259   }
00260 
00261   // make space for all values, real and imaginary parts
00262   std::vector<MagnitudeType> allvalr(numallval), allvali(numallval);
00263   // separate the real and imaginary parts of solver ritz values
00264   for (int i=0; i<numsolval; ++i) {
00265     allvalr[i] = solval[i].realpart;
00266     allvali[i] = solval[i].imagpart;
00267   }
00268   // put the auxiliary values at the end of the solver ritz values
00269   std::copy(rvals_.begin(),rvals_.end(),allvalr.begin()+numsolval);
00270   std::copy(ivals_.begin(),ivals_.end(),allvali.begin()+numsolval);
00271 
00272   // sort all values
00273   std::vector<int> perm(numallval);
00274   sorter_->sort(allvalr,allvali,Teuchos::rcpFromRef(perm),numallval);
00275 
00276   // make the set of passing values: allpass = {cwhch -1 ... -numauxval}
00277   std::vector<int> allpass(cwhch.size() + numauxval);
00278   std::copy(cwhch.begin(),cwhch.end(),allpass.begin());
00279   for (int i=0; i<numauxval; i++) {
00280     allpass[cwhch.size()+i] = -(i+1);
00281   }
00282 
00283   // make list, with length quorum, of most significant values, if there are that many
00284   //  int numsig = quorum_ < numallval ? quorum_ : numallval;
00285   int numsig = cwhch.size() + numauxval;
00286   std::vector<int> mostsig(numsig);
00287   for (int i=0; i<numsig; ++i) {
00288     mostsig[i] = perm[i];
00289     // if perm[i] >= numsolval, then it corresponds to the perm[i]-numsolval aux val
00290     // the first aux val gets index -numauxval, the seonc -numauxval+1, and so forth
00291     if (mostsig[i] >= numsolval) {
00292       mostsig[i] = mostsig[i]-numsolval-numauxval;
00293     }
00294   }
00295 
00296   // who passed?
00297   // to use set_intersection, ind_ must have room for the result, which will have size() <= min( allpass.size(), mostsig.size() )
00298   // also, allpass and mostsig must be in ascending order; neither are
00299   // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
00300   ind_.resize(numsig);
00301   std::vector<int>::iterator end;
00302   std::sort(mostsig.begin(),mostsig.end());
00303   std::sort(allpass.begin(),allpass.end());
00304   end = std::set_intersection(mostsig.begin(),mostsig.end(),allpass.begin(),allpass.end(),ind_.begin());
00305   ind_.resize(end - ind_.begin());
00306 
00307   // did we pass, overall
00308   if (ind_.size() >= (unsigned int)quorum_) {
00309     state_ = Passed;
00310   }
00311   else {
00312     state_ = Failed;
00313   }
00314   return state_;
00315 }
00316 
00317 
00318 template <class ScalarType, class MV, class OP>
00319 std::ostream& StatusTestWithOrdering<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
00320   // build indent string
00321   std::string ind(indent,' ');
00322   // print header
00323   os << ind << "- StatusTestWithOrdering: ";
00324   switch (state_) {
00325   case Passed:
00326     os << "Passed" << std::endl;
00327     break;
00328   case Failed:
00329     os << "Failed" << std::endl;
00330     break;
00331   case Undefined:
00332     os << "Undefined" << std::endl;
00333     break;
00334   }
00335   // print parameters, namely, quorum
00336   os << ind << "  Quorum: " << quorum_ << std::endl;
00337   // print any auxilliary values
00338   os << ind << "  Auxiliary values: ";
00339   if (rvals_.size() > 0) {
00340     for (unsigned int i=0; i<rvals_.size(); i++) {
00341       os << "(" << rvals_[i] << ", " << ivals_[i] << ")  ";
00342     }
00343     os << std::endl;
00344   }
00345   else {
00346     os << "[empty]" << std::endl;
00347   }
00348   // print which vectors have passed
00349   if (state_ != Undefined) {
00350     os << ind << "  Which vectors: ";
00351     if (ind_.size() > 0) {
00352       for (unsigned int i=0; i<ind_.size(); i++) os << ind_[i] << " ";
00353       os << std::endl;
00354     }
00355     else {
00356       os << "[empty]" << std::endl;
00357     }
00358   }
00359   // print constituent test
00360   test_->print(os,indent+2);
00361   return os;
00362 }
00363 
00364 
00365 } // end of Anasazi namespace
00366 
00367 #endif /* ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends