Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 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_COMBO_HPP
44 #define ANASAZI_STATUS_TEST_COMBO_HPP
45 
52 #include "AnasaziTypes.hpp"
53 #include "AnasaziStatusTest.hpp"
54 #include "Teuchos_Array.hpp"
55 namespace Anasazi {
56 
57 
74 template <class ScalarType, class MV, class OP>
75 class StatusTestCombo : public StatusTest<ScalarType,MV,OP> {
76 
77  private:
79 
80  public:
81 
83  enum ComboType
84  {
85  OR,
86  AND,
89  };
90 
91 
92 #ifndef DOXYGEN_SHOULD_SKIP_THIS
93 
95  typedef std::vector< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > st_vector;
96  typedef typename st_vector::iterator iterator;
97  typedef typename st_vector::const_iterator const_iterator;
98 
99 #endif // DOXYGEN_SHOULD_SKIP_THIS
100 
102 
103 
106  StatusTestCombo() : state_(Undefined) {}
107 
111  state_(Undefined),
112  type_(type)
113  {
114  setTests(tests);
115  };
116 
118  virtual ~StatusTestCombo() {};
120 
122 
123 
128 
131  return state_;
132  }
133 
135 
142  std::vector<int> whichVecs() const {
143  return ind_;
144  }
145 
147  //
148  // See whichVecs()
149  int howMany() const {
150  return ind_.size();
151  }
152 
154 
156 
157 
161  void setComboType(ComboType type) {
162  type_ = type;
163  state_ = Undefined;
164  }
165 
167  ComboType getComboType() const {return type_;}
168 
173  tests_ = tests;
174  state_ = Undefined;
175  }
176 
179 
185  tests_.push_back(test);
186  state_ = Undefined;
187  }
188 
194 
196 
198 
199 
203  void reset();
204 
206 
211  void clearStatus();
212 
214 
216 
217 
219  std::ostream& print(std::ostream& os, int indent = 0) const;
220 
222  private:
223 
225  TestStatus evalAND(Eigensolver<ScalarType,MV,OP>* solver);
226  TestStatus evalSEQOR(Eigensolver<ScalarType,MV,OP>* solver);
227  TestStatus evalSEQAND(Eigensolver<ScalarType,MV,OP>* solver);
228 
229  TestStatus state_;
230  ComboType type_;
231  STPArray tests_;
232  std::vector<int> ind_;
233 
234 };
235 
236 
237 template <class ScalarType, class MV, class OP>
239 {
240  typename STPArray::iterator iter1;
241  iter1 = std::find(tests_.begin(),tests_.end(),test);
242  if (iter1 != tests_.end()) {
243  tests_.erase(iter1);
244  state_ = Undefined;
245  }
246 }
247 
248 
249 template <class ScalarType, class MV, class OP>
251  clearStatus();
252  switch (type_) {
253  case OR:
254  state_ = evalOR(solver);
255  break;
256  case AND:
257  state_ = evalAND(solver);
258  break;
259  case SEQOR:
260  state_ = evalSEQOR(solver);
261  break;
262  case SEQAND:
263  state_ = evalSEQAND(solver);
264  break;
265  }
266  return state_;
267 }
268 
269 
270 template <class ScalarType, class MV, class OP>
272  ind_.resize(0);
273  state_ = Undefined;
274  typedef typename STPArray::iterator iter;
275  for (iter i=tests_.begin(); i != tests_.end(); i++) {
276  (*i)->reset();
277  }
278 }
279 
280 template <class ScalarType, class MV, class OP>
282  ind_.resize(0);
283  state_ = Undefined;
284  typedef typename STPArray::iterator iter;
285  for (iter i=tests_.begin(); i != tests_.end(); i++) {
286  (*i)->clearStatus();
287  }
288 }
289 
290 template <class ScalarType, class MV, class OP>
291 std::ostream& StatusTestCombo<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
292  std::string ind(indent,' ');
293  os << ind << "- StatusTestCombo: ";
294  switch (state_) {
295  case Passed:
296  os << "Passed" << std::endl;
297  break;
298  case Failed:
299  os << "Failed" << std::endl;
300  break;
301  case Undefined:
302  os << "Undefined" << std::endl;
303  break;
304  }
305  // print children, with extra indention
306  typedef typename STPArray::const_iterator const_iter;
307  for (const_iter i=tests_.begin(); i != tests_.end(); i++) {
308  (*i)->print(os,indent+2);
309  }
310  return os;
311 }
312 
313 template <class ScalarType, class MV, class OP>
315  state_ = Failed;
316  typedef typename STPArray::iterator iter;
317  for (iter i=tests_.begin(); i != tests_.end(); i++) {
318  TestStatus r = (*i)->checkStatus(solver);
319  if (i == tests_.begin()) {
320  ind_ = (*i)->whichVecs();
321  // sort ind_ for use below
322  std::sort(ind_.begin(),ind_.end());
323  }
324  else {
325  // to use set_union, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
326  // also, ind and iwv must be in ascending order; only ind_ is
327  // lastly, the return from set_union points to the last element in the union, which tells us how big the union is
328  std::vector<int> iwv = (*i)->whichVecs();
329  std::sort(iwv.begin(),iwv.end());
330  std::vector<int> tmp(ind_.size() + iwv.size());
331  std::vector<int>::iterator end;
332  end = std::set_union(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
333  tmp.resize(end - tmp.begin());
334  // ind_ will be sorted coming from set_union
335  ind_ = tmp;
336  }
337  if (r == Passed) {
338  state_ = Passed;
339  }
340  else {
341  TEUCHOS_TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
342  "Anasazi::StatusTestCombo::evalOR(): child test gave invalid return");
343  }
344  }
345  return state_;
346 }
347 
348 template <class ScalarType, class MV, class OP>
349 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalSEQOR( Eigensolver<ScalarType,MV,OP>* solver ) {
350  state_ = Failed;
351  typedef typename STPArray::iterator iter;
352  for (iter i=tests_.begin(); i != tests_.end(); i++) {
353  TestStatus r = (*i)->checkStatus(solver);
354  if (i == tests_.begin()) {
355  ind_ = (*i)->whichVecs();
356  // sort ind_ for use below
357  std::sort(ind_.begin(),ind_.end());
358  }
359  else {
360  // to use set_union, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
361  // also, ind and iwv must be in ascending order; only ind_ is
362  // lastly, the return from set_union points to the last element in the union, which tells us how big the union is
363  std::vector<int> iwv = (*i)->whichVecs();
364  std::sort(iwv.begin(),iwv.end());
365  std::vector<int> tmp(ind_.size() + iwv.size());
366  std::vector<int>::iterator end;
367  end = std::set_union(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
368  tmp.resize(end - tmp.begin());
369  // ind_ will be sorted coming from set_union
370  ind_ = tmp;
371  }
372  if (r == Passed) {
373  state_ = Passed;
374  break;
375  }
376  else {
377  TEUCHOS_TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
378  "Anasazi::StatusTestCombo::evalSEQOR(): child test gave invalid return");
379  }
380  }
381  return state_;
382 }
383 
384 template <class ScalarType, class MV, class OP>
385 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalAND( Eigensolver<ScalarType,MV,OP>* solver ) {
386  state_ = Passed;
387  typedef typename STPArray::iterator iter;
388  for (iter i=tests_.begin(); i != tests_.end(); i++) {
389  TestStatus r = (*i)->checkStatus(solver);
390  if (i == tests_.begin()) {
391  ind_ = (*i)->whichVecs();
392  // sort ind_ for use below
393  std::sort(ind_.begin(),ind_.end());
394  }
395  else {
396  // to use set_intersection, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
397  // also, ind and iwv must be in ascending order; only ind_ is
398  // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
399  std::vector<int> iwv = (*i)->whichVecs();
400  std::sort(iwv.begin(),iwv.end());
401  std::vector<int> tmp(ind_.size() + iwv.size());
402  std::vector<int>::iterator end;
403  end = std::set_intersection(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
404  tmp.resize(end - tmp.begin());
405  // ind_ will be sorted coming from set_intersection
406  ind_ = tmp;
407  }
408  if (r == Failed) {
409  state_ = Failed;
410  }
411  else {
412  TEUCHOS_TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
413  "Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
414  }
415  }
416  return state_;
417 }
418 
419 template <class ScalarType, class MV, class OP>
420 TestStatus StatusTestCombo<ScalarType,MV,OP>::evalSEQAND( Eigensolver<ScalarType,MV,OP>* solver ) {
421  state_ = Passed;
422  typedef typename STPArray::iterator iter;
423  for (iter i=tests_.begin(); i != tests_.end(); i++) {
424  TestStatus r = (*i)->checkStatus(solver);
425  if (i == tests_.begin()) {
426  ind_ = (*i)->whichVecs();
427  // sort ind_ for use below
428  std::sort(ind_.begin(),ind_.end());
429  }
430  else {
431  // to use set_intersection, ind_ must have room for the result, which will have size() <= end.size() + iwv.size()
432  // also, ind and iwv must be in ascending order; only ind_ is
433  // lastly, the return from set_intersection points to the last element in the intersection, which tells us how big the intersection is
434  std::vector<int> iwv = (*i)->whichVecs();
435  std::sort(iwv.begin(),iwv.end());
436  std::vector<int> tmp(ind_.size() + iwv.size());
437  std::vector<int>::iterator end;
438  end = std::set_intersection(ind_.begin(),ind_.end(),iwv.begin(),iwv.end(),tmp.begin());
439  tmp.resize(end - tmp.begin());
440  // ind_ will be sorted coming from set_intersection
441  ind_ = tmp;
442  }
443  if (r == Failed) {
444  state_ = Failed;
445  break;
446  }
447  else {
448  TEUCHOS_TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
449  "Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
450  }
451  }
452  return state_;
453 }
454 
455 
456 
457 } // end of Anasazi namespace
458 
459 #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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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.
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.
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.
std::vector< Teuchos::RCP< StatusTest< ScalarType, MV, OP > > >::const_iterator const_iterator
void push_back(const value_type &x)
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.
std::vector< Teuchos::RCP< StatusTest< ScalarType, MV, OP > > >::iterator iterator
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.