|
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_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 TEUCHOS_TEST_FOR_EXCEPTION(sorter_ == Teuchos::null, StatusTestError, "StatusTestWithOrdering::constructor() was passed null pointer for constituent SortManager."); 00217 TEUCHOS_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 second -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 */
1.7.6.1