Anasazi  Version of the Day
AnasaziStatusTestCombo.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, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
25 //
26 // ***********************************************************************
27 // @HEADER
28 //
29 
30 #ifndef ANASAZI_STATUS_TEST_COMBO_HPP
31 #define ANASAZI_STATUS_TEST_COMBO_HPP
32 
39 #include "AnasaziTypes.hpp"
40 #include "AnasaziStatusTest.hpp"
41 #include "Teuchos_Array.hpp"
42 namespace Anasazi {
43 
44 
61 template <class ScalarType, class MV, class OP>
62 class StatusTestCombo : public StatusTest<ScalarType,MV,OP> {
63 
64  private:
65  typedef Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > STPArray;
66 
67  public:
68 
70  enum ComboType
71  {
72  OR,
73  AND,
76  };
77 
78 
79 #ifndef DOXYGEN_SHOULD_SKIP_THIS
80 
81  typedef Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > t_arr;
82  typedef std::vector< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > st_vector;
83  typedef typename st_vector::iterator iterator;
84  typedef typename st_vector::const_iterator const_iterator;
85 
86 #endif // DOXYGEN_SHOULD_SKIP_THIS
87 
89 
90 
93  StatusTestCombo() : state_(Undefined) {}
94 
97  StatusTestCombo(ComboType type, Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > tests) :
98  state_(Undefined),
99  type_(type)
100  {
101  setTests(tests);
102  };
103 
105  virtual ~StatusTestCombo() {};
107 
109 
110 
115 
118  return state_;
119  }
120 
122 
129  std::vector<int> whichVecs() const {
130  return ind_;
131  }
132 
134  //
135  // See whichVecs()
136  int howMany() const {
137  return ind_.size();
138  }
139 
141 
143 
144 
148  void setComboType(ComboType type) {
149  type_ = type;
150  state_ = Undefined;
151  }
152 
154  ComboType getComboType() const {return type_;}
155 
159  void setTests(Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tests) {
160  tests_ = tests;
161  state_ = Undefined;
162  }
163 
165  Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > getTests() const {return tests_;}
166 
171  void addTest(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test) {
172  tests_.push_back(test);
173  state_ = Undefined;
174  }
175 
180  void removeTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &test);
181 
183 
185 
186 
190  void reset();
191 
193 
198  void clearStatus();
199 
201 
203 
204 
206  std::ostream& print(std::ostream& os, int indent = 0) const;
207 
209  private:
210 
212  TestStatus evalAND(Eigensolver<ScalarType,MV,OP>* solver);
213  TestStatus evalSEQOR(Eigensolver<ScalarType,MV,OP>* solver);
214  TestStatus evalSEQAND(Eigensolver<ScalarType,MV,OP>* solver);
215 
216  TestStatus state_;
217  ComboType type_;
218  STPArray tests_;
219  std::vector<int> ind_;
220 
221 };
222 
223 
224 template <class ScalarType, class MV, class OP>
226 {
227  typename STPArray::iterator iter1;
228  iter1 = std::find(tests_.begin(),tests_.end(),test);
229  if (iter1 != tests_.end()) {
230  tests_.erase(iter1);
231  state_ = Undefined;
232  }
233 }
234 
235 
236 template <class ScalarType, class MV, class OP>
238  clearStatus();
239  switch (type_) {
240  case OR:
241  state_ = evalOR(solver);
242  break;
243  case AND:
244  state_ = evalAND(solver);
245  break;
246  case SEQOR:
247  state_ = evalSEQOR(solver);
248  break;
249  case SEQAND:
250  state_ = evalSEQAND(solver);
251  break;
252  }
253  return state_;
254 }
255 
256 
257 template <class ScalarType, class MV, class OP>
259  ind_.resize(0);
260  state_ = Undefined;
261  typedef typename STPArray::iterator iter;
262  for (iter i=tests_.begin(); i != tests_.end(); i++) {
263  (*i)->reset();
264  }
265 }
266 
267 template <class ScalarType, class MV, class OP>
269  ind_.resize(0);
270  state_ = Undefined;
271  typedef typename STPArray::iterator iter;
272  for (iter i=tests_.begin(); i != tests_.end(); i++) {
273  (*i)->clearStatus();
274  }
275 }
276 
277 template <class ScalarType, class MV, class OP>
278 std::ostream& StatusTestCombo<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
279  std::string ind(indent,' ');
280  os << ind << "- StatusTestCombo: ";
281  switch (state_) {
282  case Passed:
283  os << "Passed" << std::endl;
284  break;
285  case Failed:
286  os << "Failed" << std::endl;
287  break;
288  case Undefined:
289  os << "Undefined" << std::endl;
290  break;
291  }
292  // print children, with extra indention
293  typedef typename STPArray::const_iterator const_iter;
294  for (const_iter i=tests_.begin(); i != tests_.end(); i++) {
295  (*i)->print(os,indent+2);
296  }
297  return os;
298 }
299 
300 template <class ScalarType, class MV, class OP>
302  state_ = Failed;
303  typedef typename STPArray::iterator iter;
304  for (iter i=tests_.begin(); i != tests_.end(); i++) {
305  TestStatus r = (*i)->checkStatus(solver);
306  if (i == tests_.begin()) {
307  ind_ = (*i)->whichVecs();
308  // sort ind_ for use below
309  std::sort(ind_.begin(),ind_.end());
310  }
311  else {
312  // to use set_union, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
313  // also, ind and iwv must be in ascending order; only ind_ is
314  // lastly, the return from set_union points to the last element in the union, which tells us how big the union is
315  std::vector<int> iwv = (*i)->whichVecs();
316  std::sort(iwv.begin(),iwv.end());
317  std::vector<int> tmp(ind_.size() + iwv.size());
318  std::vector<int>::iterator end;
319  end = std::set_union(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
320  tmp.resize(end - tmp.begin());
321  // ind_ will be sorted coming from set_union
322  ind_ = tmp;
323  }
324  if (r == Passed) {
325  state_ = Passed;
326  }
327  else {
328  TEUCHOS_TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
329  "Anasazi::StatusTestCombo::evalOR(): child test gave invalid return");
330  }
331  }
332  return state_;
333 }
334 
335 template <class ScalarType, class MV, class OP>
337  state_ = Failed;
338  typedef typename STPArray::iterator iter;
339  for (iter i=tests_.begin(); i != tests_.end(); i++) {
340  TestStatus r = (*i)->checkStatus(solver);
341  if (i == tests_.begin()) {
342  ind_ = (*i)->whichVecs();
343  // sort ind_ for use below
344  std::sort(ind_.begin(),ind_.end());
345  }
346  else {
347  // to use set_union, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
348  // also, ind and iwv must be in ascending order; only ind_ is
349  // lastly, the return from set_union points to the last element in the union, which tells us how big the union is
350  std::vector<int> iwv = (*i)->whichVecs();
351  std::sort(iwv.begin(),iwv.end());
352  std::vector<int> tmp(ind_.size() + iwv.size());
353  std::vector<int>::iterator end;
354  end = std::set_union(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
355  tmp.resize(end - tmp.begin());
356  // ind_ will be sorted coming from set_union
357  ind_ = tmp;
358  }
359  if (r == Passed) {
360  state_ = Passed;
361  break;
362  }
363  else {
364  TEUCHOS_TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
365  "Anasazi::StatusTestCombo::evalSEQOR(): child test gave invalid return");
366  }
367  }
368  return state_;
369 }
370 
371 template <class ScalarType, class MV, class OP>
373  state_ = Passed;
374  typedef typename STPArray::iterator iter;
375  for (iter i=tests_.begin(); i != tests_.end(); i++) {
376  TestStatus r = (*i)->checkStatus(solver);
377  if (i == tests_.begin()) {
378  ind_ = (*i)->whichVecs();
379  // sort ind_ for use below
380  std::sort(ind_.begin(),ind_.end());
381  }
382  else {
383  // to use set_intersection, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
384  // also, ind and iwv must be in ascending order; only ind_ is
385  // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
386  std::vector<int> iwv = (*i)->whichVecs();
387  std::sort(iwv.begin(),iwv.end());
388  std::vector<int> tmp(ind_.size() + iwv.size());
389  std::vector<int>::iterator end;
390  end = std::set_intersection(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
391  tmp.resize(end - tmp.begin());
392  // ind_ will be sorted coming from set_intersection
393  ind_ = tmp;
394  }
395  if (r == Failed) {
396  state_ = Failed;
397  }
398  else {
399  TEUCHOS_TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
400  "Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
401  }
402  }
403  return state_;
404 }
405 
406 template <class ScalarType, class MV, class OP>
408  state_ = Passed;
409  typedef typename STPArray::iterator iter;
410  for (iter i=tests_.begin(); i != tests_.end(); i++) {
411  TestStatus r = (*i)->checkStatus(solver);
412  if (i == tests_.begin()) {
413  ind_ = (*i)->whichVecs();
414  // sort ind_ for use below
415  std::sort(ind_.begin(),ind_.end());
416  }
417  else {
418  // to use set_intersection, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
419  // also, ind and iwv must be in ascending order; only ind_ is
420  // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
421  std::vector<int> iwv = (*i)->whichVecs();
422  std::sort(iwv.begin(),iwv.end());
423  std::vector<int> tmp(ind_.size() + iwv.size());
424  std::vector<int>::iterator end;
425  end = std::set_intersection(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
426  tmp.resize(end - tmp.begin());
427  // ind_ will be sorted coming from set_intersection
428  ind_ = tmp;
429  }
430  if (r == Failed) {
431  state_ = Failed;
432  break;
433  }
434  else {
435  TEUCHOS_TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
436  "Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
437  }
438  }
439  return state_;
440 }
441 
442 
443 
444 } // end of Anasazi namespace
445 
446 #endif /* ANASAZI_STATUS_TEST_COMBO_HPP */
void clearStatus()
Clears the results of the last status test.
void setTests(Teuchos::Array< Teuchos::RCP< StatusTest< ScalarType, MV, OP > > > tests)
Set the tests This also resets the test status to Undefined.
StatusTestCombo(ComboType type, Teuchos::Array< Teuchos::RCP< StatusTest< ScalarType, MV, OP > > > tests)
Constructor specifying the StatusTestCombo::ComboType and the tests.
Status test for forming logical combinations of other status tests.
virtual ~StatusTestCombo()
Destructor.
std::vector< int > whichVecs() const
Get the indices for the vectors that passed the test.
Exception thrown to signal error in a status test during Anasazi::StatusTest::checkStatus().
void reset()
Informs the status test that it should reset its internal configuration to the uninitialized state...
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...
std::ostream & print(std::ostream &os, int indent=0) const
Output formatted description of stopping test to output stream.
TestStatus checkStatus(Eigensolver< ScalarType, MV, OP > *solver)
Teuchos::Array< Teuchos::RCP< StatusTest< ScalarType, MV, OP > > > getTests() const
Get the tests.
void removeTest(const Teuchos::RCP< StatusTest< ScalarType, MV, OP > > &test)
Removes a test from the combination, if it exists in the tester.
int howMany() const
Get the number of vectors that passed the test.
ComboType getComboType() const
Get the maximum number of iterations.
void setComboType(ComboType type)
Set the maximum number of iterations. This also resets the test status to Undefined.
Types and exceptions used within Anasazi solvers and interfaces.
ComboType
Enumerated type to list the types of StatusTestCombo combo types.
Common interface of stopping criteria for Anasazi&#39;s solvers.
void addTest(Teuchos::RCP< StatusTest< ScalarType, MV, OP > > test)
Add a test to the combination.
The Eigensolver is a templated virtual base class that defines the basic interface that any eigensolv...
StatusTestCombo()
Default constructor has no tests and initializes to StatusTestCombo::ComboType StatusTestCombo::OR.
Declaration and definition of Anasazi::StatusTest.
TestStatus getStatus() const
Return the result of the most recent checkStatus call.