Anasazi  Version of the Day
AnasaziStatusTestWithOrdering.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Anasazi: Block Eigensolvers Package
5 // Copyright 2004 Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 //
42 
43 #ifndef ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP
44 #define ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP
45 
53 #include "AnasaziStatusTest.hpp"
54 #include "Teuchos_ScalarTraits.hpp"
55 #include "Teuchos_LAPACK.hpp"
56 
80 namespace Anasazi {
81 
82 
83 template <class ScalarType, class MV, class OP>
84 class StatusTestWithOrdering : public StatusTest<ScalarType,MV,OP> {
85 
86  private:
87  typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
88  typedef Teuchos::ScalarTraits<MagnitudeType> MT;
89 
90  public:
91 
93 
94 
96  StatusTestWithOrdering(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test, Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sorter, int quorum = -1);
97 
101 
103 
104 
109 
111  TestStatus getStatus() const { return state_; }
112 
114 
119  std::vector<int> whichVecs() const {
120  return ind_;
121  }
122 
124  int howMany() const {
125  return ind_.size();
126  }
127 
129 
131 
132 
138  void setQuorum(int quorum) {
139  state_ = Undefined;
140  quorum_ = quorum;
141  }
142 
145  int getQuorum() const {
146  return quorum_;
147  }
148 
150 
152 
153 
159  void reset() {
160  ind_.resize(0);
161  state_ = Undefined;
162  test_->reset();
163  }
164 
166 
171  void clearStatus() {
172  ind_.resize(0);
173  state_ = Undefined;
174  test_->clearStatus();
175  }
176 
181  void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &vals) {
182  rvals_ = vals;
183  ivals_.resize(rvals_.size(),MT::zero());
184  state_ = Undefined;
185  }
186 
191  void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &rvals, const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &ivals) {
192  rvals_ = rvals;
193  ivals_ = ivals;
194  state_ = Undefined;
195  }
196 
201  void getAuxVals(std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &rvals, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &ivals) const {
202  rvals = rvals_;
203  ivals = ivals_;
204  }
205 
207 
209 
210 
212  std::ostream& print(std::ostream& os, int indent = 0) const;
213 
215  private:
216  TestStatus state_;
217  std::vector<int> ind_;
218  int quorum_;
219  std::vector<MagnitudeType> rvals_, ivals_;
220  Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sorter_;
221  Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test_;
222 };
223 
224 
225 template <class ScalarType, class MV, class OP>
226 StatusTestWithOrdering<ScalarType,MV,OP>::StatusTestWithOrdering(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test, Teuchos::RCP<SortManager<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> > sorter, int quorum)
227  : state_(Undefined), ind_(0), quorum_(quorum), rvals_(0), ivals_(0), sorter_(sorter), test_(test)
228 {
229  TEUCHOS_TEST_FOR_EXCEPTION(sorter_ == Teuchos::null, StatusTestError, "StatusTestWithOrdering::constructor() was passed null pointer for constituent SortManager.");
230  TEUCHOS_TEST_FOR_EXCEPTION(test_ == Teuchos::null, StatusTestError, "StatusTestWithOrdering::constructor() was passed null pointer for constituent StatusTest.");
231 }
232 
233 template <class ScalarType, class MV, class OP>
235 
236  // Algorithm
237  // we PASS iff the "most signficant" values of "all values" PASS
238  // "most significant" is measured by sorter
239  // auxilliary values are automatically PASSED
240  // constituent status test determines who else passes
241  // "all values" mean {auxilliary values} UNION {solver's ritz values}
242  //
243  // test_->checkStatus() calls the constituent status test
244  // cwhch = test_->whichVecs() gets the passing indices from the constituent test
245  // solval = solver->getRitzValues() gets the solver's ritz values
246  // allval = {solval auxval} contains all values
247  // sorter_->sort(allval,perm) sort all values (we just need the perm vector)
248  //
249  // allpass = {cwhch numsolval+1 ... numsolval+numAux}
250  // mostsig = {perm[1] ... perm[quorum]}
251  // whichVecs = mostsig INTERSECT allpass
252  // if size(whichVecs) >= quorum,
253  // PASS
254  // else
255  // FAIL
256  //
257  // finish: this needs to be better tested and revisited for efficiency.
258 
259  // call the constituent solver manager
260  test_->checkStatus(solver);
261  std::vector<int> cwhch( test_->whichVecs() );
262 
263  // get the ritzvalues from solver
264  std::vector<Value<ScalarType> > solval = solver->getRitzValues();
265  int numsolval = solval.size();
266  int numauxval = rvals_.size();
267  int numallval = numsolval + numauxval;
268 
269  if (numallval == 0) {
270  ind_.resize(0);
271  return Failed;
272  }
273 
274  // make space for all values, real and imaginary parts
275  std::vector<MagnitudeType> allvalr(numallval), allvali(numallval);
276  // separate the real and imaginary parts of solver ritz values
277  for (int i=0; i<numsolval; ++i) {
278  allvalr[i] = solval[i].realpart;
279  allvali[i] = solval[i].imagpart;
280  }
281  // put the auxiliary values at the end of the solver ritz values
282  std::copy(rvals_.begin(),rvals_.end(),allvalr.begin()+numsolval);
283  std::copy(ivals_.begin(),ivals_.end(),allvali.begin()+numsolval);
284 
285  // sort all values
286  std::vector<int> perm(numallval);
287  sorter_->sort(allvalr,allvali,Teuchos::rcpFromRef(perm),numallval);
288 
289  // make the set of passing values: allpass = {cwhch -1 ... -numauxval}
290  std::vector<int> allpass(cwhch.size() + numauxval);
291  std::copy(cwhch.begin(),cwhch.end(),allpass.begin());
292  for (int i=0; i<numauxval; i++) {
293  allpass[cwhch.size()+i] = -(i+1);
294  }
295 
296  // make list, with length quorum, of most significant values, if there are that many
297  int numsig = quorum_ < numallval ? quorum_ : numallval;
298  // int numsig = cwhch.size() + numauxval;
299  std::vector<int> mostsig(numsig);
300  for (int i=0; i<numsig; ++i) {
301  mostsig[i] = perm[i];
302  // if perm[i] >= numsolval, then it corresponds to the perm[i]-numsolval aux val
303  // the first aux val gets index -numauxval, the second -numauxval+1, and so forth
304  if (mostsig[i] >= numsolval) {
305  mostsig[i] = mostsig[i]-numsolval-numauxval;
306  }
307  }
308 
309  // who passed?
310  // to use set_intersection, ind_ must have room for the result, which will have size() <= min( allpass.size(), mostsig.size() )
311  // also, allpass and mostsig must be in ascending order; neither are
312  // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
313  ind_.resize(numsig);
314  std::vector<int>::iterator end;
315  std::sort(mostsig.begin(),mostsig.end());
316  std::sort(allpass.begin(),allpass.end());
317  end = std::set_intersection(mostsig.begin(),mostsig.end(),allpass.begin(),allpass.end(),ind_.begin());
318  ind_.resize(end - ind_.begin());
319 
320  // did we pass, overall
321  if (ind_.size() >= (unsigned int)quorum_) {
322  state_ = Passed;
323  }
324  else {
325  state_ = Failed;
326  }
327  return state_;
328 }
329 
330 
331 template <class ScalarType, class MV, class OP>
332 std::ostream& StatusTestWithOrdering<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
333  // build indent string
334  std::string ind(indent,' ');
335  // print header
336  os << ind << "- StatusTestWithOrdering: ";
337  switch (state_) {
338  case Passed:
339  os << "Passed" << std::endl;
340  break;
341  case Failed:
342  os << "Failed" << std::endl;
343  break;
344  case Undefined:
345  os << "Undefined" << std::endl;
346  break;
347  }
348  // print parameters, namely, quorum
349  os << ind << " Quorum: " << quorum_ << std::endl;
350  // print any auxilliary values
351  os << ind << " Auxiliary values: ";
352  if (rvals_.size() > 0) {
353  for (unsigned int i=0; i<rvals_.size(); i++) {
354  os << "(" << rvals_[i] << ", " << ivals_[i] << ") ";
355  }
356  os << std::endl;
357  }
358  else {
359  os << "[empty]" << std::endl;
360  }
361  // print which vectors have passed
362  if (state_ != Undefined) {
363  os << ind << " Which vectors: ";
364  if (ind_.size() > 0) {
365  for (unsigned int i=0; i<ind_.size(); i++) os << ind_[i] << " ";
366  os << std::endl;
367  }
368  else {
369  os << "[empty]" << std::endl;
370  }
371  }
372  // print constituent test
373  test_->print(os,indent+2);
374  return os;
375 }
376 
377 
378 } // end of Anasazi namespace
379 
380 #endif /* ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP */
virtual std::vector< Value< ScalarType > > getRitzValues()=0
Get the Ritz values from the previous iteration.
TestStatus getStatus() const
Return the result of the most recent checkStatus call, or undefined if it has not been run...
std::ostream & print(std::ostream &os, int indent=0) const
Output formatted description of stopping test to output stream.
Exception thrown to signal error in a status test during Anasazi::StatusTest::checkStatus().
TestStatus
Enumerated type used to pass back information from a StatusTest.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package...
TestStatus checkStatus(Eigensolver< ScalarType, MV, OP > *solver)
void getAuxVals(std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &rvals, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &ivals) const
Get the auxiliary eigenvalues.
std::vector< int > whichVecs() const
Get the indices for the vectors that passed the test.
StatusTestWithOrdering(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test, Teuchos::RCP< SortManager< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > > sorter, int quorum=-1)
Constructor.
void setAuxVals(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &rvals, const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &ivals)
Set the auxiliary eigenvalues.
A status test for testing the norm of the eigenvectors residuals along with a set of auxiliary eigenv...
int howMany() const
Get the number of vectors that passed the test.
void reset()
Informs the status test that it should reset its internal configuration to the uninitialized state...
void setAuxVals(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &vals)
Set the auxiliary eigenvalues.
Anasazi&#39;s templated pure virtual class for managing the sorting of approximate eigenvalues computed b...
void clearStatus()
Clears the results of the last status test.
Common interface of stopping criteria for Anasazi&#39;s solvers.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
Declaration and definition of Anasazi::StatusTest.