00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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 StatusTestOrderedResNorm : 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
00085 enum ResType {
00086 RES_ORTH,
00087 RES_2NORM,
00088 RITZRES_2NORM
00089 };
00090
00092
00094
00095
00097 StatusTestOrderedResNorm(Teuchos::RCP<SortManager<ScalarType,MV,OP> > sorter, typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum = -1, ResType whichNorm = RES_ORTH, bool scaled = true);
00098
00100 virtual ~StatusTestOrderedResNorm() {};
00102
00104
00105
00108 TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
00109
00111 TestStatus getStatus() const { return state_; }
00113
00115
00116
00120 void setTolerance(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol) {
00121 state_ = Undefined;
00122 tol_ = tol;
00123 }
00124
00126 typename Teuchos::ScalarTraits<ScalarType>::magnitudeType getTolerance() {return tol_;}
00127
00132 void setWhichNorm(ResType whichNorm) {
00133 state_ = Undefined;
00134 whichNorm_ = whichNorm;
00135 }
00136
00138 ResType getWhichNorm() {return whichNorm_;}
00139
00143 void setScale(bool relscale) {
00144 state_ = Undefined;
00145 scaled_ = relscale;
00146 }
00147
00149 bool getScale() {return scaled_;}
00150
00152 std::vector<int> whichVecs() {
00153 return ind_;
00154 }
00155
00157 int howMany() {
00158 return ind_.size();
00159 }
00160
00162
00164
00165
00166
00171 void reset() {
00172 state_ = Undefined;
00173 }
00174
00176
00181 void clearStatus() {
00182 state_ = Undefined;
00183 }
00184
00189 void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &vals) {
00190 rvals_ = vals;
00191 ivals_.resize(rvals_.size(),MT::zero());
00192 state_ = Undefined;
00193 }
00194
00199 void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &rvals, const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &ivals) {
00200 rvals_ = rvals;
00201 ivals_ = ivals;
00202 state_ = Undefined;
00203 }
00204
00206
00208
00209
00211 std::ostream& print(std::ostream& os, int indent = 0) const;
00212
00214 private:
00215 TestStatus state_;
00216 MagnitudeType tol_;
00217 std::vector<int> ind_;
00218 int quorum_;
00219 bool scaled_;
00220 ResType whichNorm_;
00221 std::vector<MagnitudeType> rvals_, ivals_;
00222 Teuchos::RCP<SortManager<ScalarType,MV,OP> > sorter_;
00223 };
00224
00225
00226 template <class ScalarType, class MV, class OP>
00227 StatusTestOrderedResNorm<ScalarType,MV,OP>::StatusTestOrderedResNorm(Teuchos::RCP<SortManager<ScalarType,MV,OP> > sorter, typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum, ResType whichNorm, bool scaled)
00228 : state_(Undefined), quorum_(quorum), scaled_(scaled), whichNorm_(whichNorm), sorter_(sorter)
00229 {
00230 TEST_FOR_EXCEPTION(sorter_ == Teuchos::null, StatusTestError, "StatusTestOrderedResNorm::constructor() was passed null pointer for SortManager.");
00231 setTolerance(tol);
00232 }
00233
00234 template <class ScalarType, class MV, class OP>
00235 TestStatus StatusTestOrderedResNorm<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
00236
00237
00238
00239
00240 std::vector<MagnitudeType> res;
00241 std::vector<Value<ScalarType> > vals = solver->getRitzValues();
00242 switch (whichNorm_) {
00243 case RES_2NORM:
00244 res = solver->getRes2Norms();
00245 vals.resize(res.size());
00246 break;
00247 case RES_ORTH:
00248 res = solver->getResNorms();
00249 vals.resize(res.size());
00250 break;
00251 case RITZRES_2NORM:
00252 res = solver->getRitzRes2Norms();
00253 break;
00254 }
00255
00256 int numaux = rvals_.size();
00257 int bs = res.size();
00258 int num = bs + numaux;
00259
00260 if (num == 0) {
00261 ind_.resize(0);
00262 return Failed;
00263 }
00264
00265
00266 std::vector<MagnitudeType> allrvals(bs), allivals(bs);
00267 for (int i=0; i<bs; i++) {
00268 allrvals[i] = vals[i].realpart;
00269 allivals[i] = vals[i].imagpart;
00270 }
00271
00272
00273 allrvals.insert(allrvals.end(),rvals_.begin(),rvals_.end());
00274 allivals.insert(allivals.end(),ivals_.begin(),ivals_.end());
00275
00276
00277 Teuchos::LAPACK<int,MagnitudeType> lapack;
00278 if (scaled_) {
00279 for (unsigned int i=0; i<res.size(); i++) {
00280 MagnitudeType tmp = lapack.LAPY2(allrvals[i],allivals[i]);
00281 if ( tmp != MT::zero() ) {
00282 res[i] /= tmp;
00283 }
00284 }
00285 }
00286
00287 res.insert(res.end(),numaux,-MT::one());
00288
00289
00290 std::vector<int> perm(num,-1);
00291 sorter_->sort(solver,num,allrvals,allivals,&perm);
00292
00293
00294 std::vector<MagnitudeType> oldres = res;
00295 for (int i=0; i<num; i++) {
00296 res[i] = oldres[perm[i]];
00297 }
00298
00299
00300 ind_.resize(num);
00301
00302
00303 int have = 0;
00304 int need = (quorum_ == -1) ? num : quorum_;
00305 int tocheck = need > num ? num : need;
00306 for (int i=0; i<tocheck; i++) {
00307 TEST_FOR_EXCEPTION( MT::isnaninf(res[i]), StatusTestError, "StatusTestOrderedResNorm::checkStatus(): residual norm is nan or inf" );
00308 if (res[i] < tol_) {
00309 ind_[have] = perm[i];
00310 have++;
00311 }
00312 }
00313 ind_.resize(have);
00314 state_ = (have >= need) ? Passed : Failed;
00315 return state_;
00316 }
00317
00318
00319 template <class ScalarType, class MV, class OP>
00320 std::ostream& StatusTestOrderedResNorm<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
00321 std::string ind(indent,' ');
00322 os << ind << "- StatusTestOrderedResNorm: ";
00323 switch (state_) {
00324 case Passed:
00325 os << "Passed" << std::endl;
00326 break;
00327 case Failed:
00328 os << "Failed" << std::endl;
00329 break;
00330 case Undefined:
00331 os << "Undefined" << std::endl;
00332 break;
00333 }
00334 os << ind << " (Tolerance,WhichNorm,Scaled,Quorum): "
00335 << "(" << tol_;
00336 switch (whichNorm_) {
00337 case RES_ORTH:
00338 os << ",RES_ORTH";
00339 break;
00340 case RES_2NORM:
00341 os << ",RES_2NORM";
00342 break;
00343 case RITZRES_2NORM:
00344 os << ",RITZRES_2NORM";
00345 break;
00346 }
00347 os << "," << (scaled_ ? "true" : "false")
00348 << "," << quorum_
00349 << ")" << std::endl;
00350 os << ind << " Auxiliary values: ";
00351 if (rvals_.size() > 0) {
00352 for (unsigned int i=0; i<rvals_.size(); i++) {
00353 os << "(" << rvals_[i] << ", " << ivals_[i] << ") ";
00354 }
00355 os << std::endl;
00356 }
00357 else {
00358 os << "[empty]" << std::endl;
00359 }
00360
00361 if (state_ != Undefined) {
00362 os << ind << " Which vectors: ";
00363 if (ind_.size() > 0) {
00364 for (unsigned int i=0; i<ind_.size(); i++) os << ind_[i] << " ";
00365 os << std::endl;
00366 }
00367 else {
00368 os << "[empty]" << std::endl;
00369 }
00370 }
00371 return os;
00372 }
00373
00374
00375 }
00376
00377 #endif