|
Anasazi
Version of the Day
|
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 */
1.7.6.1