Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
AnasaziStatusTestResNorm.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 //
00029 
00030 #ifndef ANASAZI_STATUS_TEST_RESNORM_HPP
00031 #define ANASAZI_STATUS_TEST_RESNORM_HPP
00032 
00038 #include "AnasaziTypes.hpp"
00039 #include "AnasaziStatusTest.hpp"
00040 #include "Teuchos_ScalarTraits.hpp"
00041 
00042 namespace Anasazi {
00043 
00045 
00046 
00055   class ResNormNaNError : public AnasaziError {public:
00056     ResNormNaNError(const std::string& what_arg) : AnasaziError(what_arg)
00057     {}};
00058 
00060 
00077   template <class ScalarType, class MV, class OP>
00078   class StatusTestResNorm : public StatusTest<ScalarType,MV,OP> {
00079 
00080     typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00081 
00082     public:
00083 
00085 
00086 
00088     StatusTestResNorm(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum = -1, ResType whichNorm = RES_ORTH, bool scaled = true, bool throwExceptionOnNaN = true);
00089 
00091     virtual ~StatusTestResNorm() {};
00093 
00095 
00096 
00100     TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
00101 
00103     TestStatus getStatus() const { return state_; }
00104 
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 
00139     void setTolerance(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol) {
00140       state_ = Undefined;
00141       tol_ = tol;
00142     }
00143 
00145     typename Teuchos::ScalarTraits<ScalarType>::magnitudeType getTolerance() {return tol_;}
00146 
00151     void setWhichNorm(ResType whichNorm) {
00152       state_ = Undefined;
00153       whichNorm_ = whichNorm;
00154     }
00155 
00157     ResType getWhichNorm() {return whichNorm_;}
00158 
00162     void setScale(bool relscale) {
00163       state_ = Undefined;
00164       scaled_ = relscale;
00165     }
00166 
00168     bool getScale() {return scaled_;}
00170 
00172 
00173 
00174 
00179     void reset() { 
00180       ind_.resize(0);
00181       state_ = Undefined;
00182     }
00183 
00185 
00190     void clearStatus() {
00191       ind_.resize(0);
00192       state_ = Undefined;
00193     }
00194 
00196 
00198 
00199 
00201     std::ostream& print(std::ostream& os, int indent = 0) const;
00202 
00204     private:
00205     TestStatus state_;
00206     MagnitudeType tol_;
00207     std::vector<int> ind_;
00208     int quorum_;
00209     bool scaled_;
00210     enum ResType whichNorm_;
00211     bool throwExceptionOnNaN_;
00212   };
00213 
00214 
00215   template <class ScalarType, class MV, class OP>
00216   StatusTestResNorm<ScalarType,MV,OP>::StatusTestResNorm(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum, ResType whichNorm, bool scaled, bool throwExceptionOnNaN)
00217   : state_(Undefined), tol_(tol), quorum_(quorum), scaled_(scaled), whichNorm_(whichNorm), throwExceptionOnNaN_(throwExceptionOnNaN)
00218   {}
00219 
00220   template <class ScalarType, class MV, class OP>
00221   TestStatus StatusTestResNorm<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) 
00222   {
00223     typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00224 
00225     std::vector<MagnitudeType> res;
00226 
00227     // get the eigenvector/ritz residuals norms (using the appropriate norm)
00228     // get the eigenvalues/ritzvalues and ritz index as well
00229     std::vector<Value<ScalarType> > vals = solver->getRitzValues();
00230     switch (whichNorm_) {
00231       case RES_2NORM:
00232         res = solver->getRes2Norms();
00233         // we want only the ritz values corresponding to our eigenvector residuals
00234         vals.resize(res.size());
00235         break;
00236       case RES_ORTH:
00237         res = solver->getResNorms();
00238         // we want only the ritz values corresponding to our eigenvector residuals
00239         vals.resize(res.size());
00240         break;
00241       case RITZRES_2NORM:
00242         res = solver->getRitzRes2Norms();
00243         break;
00244     }
00245 
00246     // if appropriate, scale the norms by the magnitude of the eigenvalue estimate
00247     if (scaled_) {
00248       Teuchos::LAPACK<int,MagnitudeType> lapack;
00249 
00250       for (unsigned int i=0; i<res.size(); i++) {
00251         MagnitudeType tmp = lapack.LAPY2(vals[i].realpart,vals[i].imagpart);
00252         // scale by the newly computed magnitude of the ritz values
00253         if ( tmp != MT::zero() ) {
00254           res[i] /= tmp;
00255         }
00256       }
00257     }
00258 
00259     // test the norms
00260     int have = 0;
00261     ind_.resize(res.size());
00262     for (unsigned int i=0; i<res.size(); i++) {
00263       TEUCHOS_TEST_FOR_EXCEPTION( MT::isnaninf(res[i]), ResNormNaNError, 
00264           "StatusTestResNorm::checkStatus(): residual norm is nan or inf" );
00265       if (res[i] < tol_) {
00266         ind_[have] = i;
00267         have++;
00268       }
00269     }
00270     ind_.resize(have);
00271     int need = (quorum_ == -1) ? res.size() : quorum_;
00272     state_ = (have >= need) ? Passed : Failed;
00273     return state_;
00274   }
00275 
00276 
00277   template <class ScalarType, class MV, class OP>
00278   std::ostream& StatusTestResNorm<ScalarType,MV,OP>::print(std::ostream& os, int indent) const 
00279   {
00280     std::string ind(indent,' ');
00281     os << ind << "- StatusTestResNorm: ";
00282     switch (state_) {
00283       case Passed:
00284         os << "Passed" << std::endl;
00285         break;
00286       case Failed:
00287         os << "Failed" << std::endl;
00288         break;
00289       case Undefined:
00290         os << "Undefined" << std::endl;
00291         break;
00292     }
00293     os << ind << "  (Tolerance,WhichNorm,Scaled,Quorum): " 
00294       << "(" << tol_;
00295     switch (whichNorm_) {
00296       case RES_ORTH:
00297         os << ",RES_ORTH";
00298         break;
00299       case RES_2NORM:
00300         os << ",RES_2NORM";
00301         break;
00302       case RITZRES_2NORM:
00303         os << ",RITZRES_2NORM";
00304         break;
00305     }
00306     os        << "," << (scaled_   ? "true" : "false")
00307       << "," << quorum_ 
00308       << ")" << std::endl;
00309 
00310     if (state_ != Undefined) {
00311       os << ind << "  Which vectors: ";
00312       if (ind_.size() > 0) {
00313         for (unsigned int i=0; i<ind_.size(); i++) os << ind_[i] << " ";
00314         os << std::endl;
00315       }
00316       else {
00317         os << "[empty]" << std::endl;
00318       }
00319     }
00320     return os;
00321   }
00322 
00323 
00324 } // end of Anasazi namespace
00325 
00326 #endif /* ANASAZI_STATUS_TEST_RESNORM_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends