MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IterationPack_TestAlgorithmState.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) 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 // 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 Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include <ostream>
43 #include <iomanip>
44 #include <typeinfo>
45 
51 #include "Teuchos_Assert.hpp"
52 
53 // explicit instantiation for testing compilation only
54 //template Teuchos::RCP<double>;
55 //class B {};
56 //class D : public B {};
57 //template IterationPack::IterQuantityAccessDerivedToBase<B,D>;
58 
59 namespace {
60 
61 // Create class hierarchy for derived to base conversion.
62 
63 class B {
64 public:
65  virtual B& operator=(const B&) = 0;
66  virtual void alpha(double) = 0;
67  virtual double alpha() const = 0;
68 }; // end class B
69 
70 class D : public B {
71 public:
72  B& operator=(const B& b) {
73  const D* d = dynamic_cast<const D*>(&b);
74  if(!d)
75  throw std::logic_error("D::operator=(...) : b is not of type D");
76  alpha_ = d->alpha_;
77  return *this;
78  }
79  void alpha(double alpha) {
80  alpha_ = alpha;
81  }
82  double alpha() const {
83  return alpha_;
84  }
85 private:
86  double alpha_;
87 }; // end class D
88 
89 } // end namespace
90 
92 
93  using std::endl;
94  using std::setw;
96 
97  try {
98 
99  bool success = true, result;
100 // const int w = 15;
101  if(out) *out << std::boolalpha;
102 
103  if(out)
104  *out<< "\n\n******************************\n"
105  << "*** Testing AlgorithmState ***\n"
106  << "******************************\n"
107  << "\nWarning: this interface is weakly typed and mistakes"
108  << "can be very bad\n";
109 
110  typedef double alpha_k_t;
111  typedef std::vector<double> x_k_t;
112  typedef B V_k_t;
116 
117  if(out) *out << "\n*** Create state object ...\n";
118  AlgorithmState state(4);
119 
120  // Set three types of iteration quantity access objects.
121 
122  if(out) *out << "\n*** Set three types of iteration quantity access objects.\n";
123 
124  if(out) *out << "set IterQuantityAccessContiguous<double>(2,\"alpha\")\n";
125  state.set_iter_quant( "alpha", Teuchos::rcp(
126  new alpha_t(
127  2,"alpha"
128 #ifdef _MIPS_CXX
131 #endif
132  )) );
133 
134  if(out) *out << "set IterQuantityAccessContiguous<std::vector<double> >(2,\"x\")\n";
135  state.set_iter_quant( "x", Teuchos::rcp(
136  new x_t(
137  2,"x"
138 #ifdef _MIPS_CXX
141 #endif
142  )) );
143 
144  if(out) *out << "set IterQuantityAccessDerivedToBase<B,D>(1,\"V\")\n";
145  state.set_iter_quant(
146  "V"
147  ,Teuchos::rcp(
148  new V_t(
149  1
150  ,"V"
152  )
153  )
154  );
155 
156  // Try to add the same name again.
157 
158  if(out) *out << "\nTry to add \"x\" (should throw execption) : ";
159  try {
160  state.set_iter_quant( "x", Teuchos::rcp(
161  new x_t(
162  2,"x"
163 #ifdef _MIPS_CXX
166 #endif
167  )) );
168  success = false;
169  if(out)
170  *out << "false\n";
171  }
172  catch(const AlgorithmState::AlreadyExists& expt) {
173  if(out) *out << "Caught a AlgorithmState::AlreadyExists execption : " << expt.what() << " : true\n" << endl;
174  }
175 
176  // dump the iteration quantity names, ids, and concrete types.
177 
178  if(out) {
179  *out << "\n*** dump iteration quantitys\n";
180  state.dump_iter_quant(*out);
181  }
182 
183  update_success( result = state.k() == 0, &success );
184  if(out) *out << "\nstate.k() == 0 : " << result << endl;
185 
186  // Set the iteration quantities for the kth iteration and check them
187 
188  if(out) *out << "\n*** Set iteration quantities for the kth iteration\n";
189 
190  if(out) *out << "\nSet alpha_k(0) = 5.0 then get alpha_k(0) == 5.0 : ";
191  alpha_t *alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") );
192  alpha->set_k(0) = 5.0;
193  alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") );
194  update_success( result = alpha->get_k(0) == 5.0, &success );
195  if(out) *out << result << endl;
196 
197  if(out) *out << "\nSet x_k(0)[0] = 2.0 then get x_k(0)[0] == 2.0 : ";
198  x_t *x = dynamic_cast<x_t*>( &state.iter_quant("x") );
199  x->set_k(0).resize(1);
200  x->set_k(0)[0] = 2.0;
201  x = dynamic_cast<x_t*>( &state.iter_quant("x") );
202  update_success( result = x->get_k(0)[0] == 2.0, &success );
203  if(out) *out << result << endl;
204 
205  if(out) *out << "\nSet V_k(0).alpha() = 3.0 then get V_k(0).alpha() == 3.0 : ";
206  V_t *V = dynamic_cast<V_t*>( &state.iter_quant("V") );
207  V->set_k(0).alpha(3.0);
208  V = dynamic_cast<V_t*>( &state.iter_quant("V") );
209  update_success( result = V->get_k(0).alpha() == 3.0, &success );
210  if(out) *out << result << endl;
211 
212  // Use an id to get at an iteration quantity.
213 
214  if(out) *out << "\n*** Use an id to get at an iteration quantity\n";
215 
216  if(out) *out << "\nid for \"x\" is : ";
218  if(out) *out << x_id << endl;
219 
220  if(out) *out << "\nAccess \"x\" using id and x_k(0)[0] == 2.0 : ";
221  x = dynamic_cast<x_t*>( &state.iter_quant(x_id) );
222  update_success( result = x->get_k(0)[0] == 2.0, &success );
223  if(out) *out << result << endl;
224 
225  // use a nonexistant name
226 
227  if(out) *out << "\n*** Use a nonexistant name or id to access iteration quantity\n";
228 
229  if(out) *out << "id for \"X\" is DOES_NOT_EXIST : ";
230  update_success( result = state.get_iter_quant_id("X") == AlgorithmState::DOES_NOT_EXIST
231  , & success );
232  if(out) *out << result << endl;
233 
234  if(out) *out << "\nAccess nonexistant iteration quantity by name \"X\" throws a AlgorithmState::DoesNotExist exception : ";
235  try {
236  state.iter_quant("X");
237  success = false;
238  if(out) *out << false << endl;
239  }
240  catch(const AlgorithmState::DoesNotExist& expt) {
241  if(out) *out << true << endl;
242  }
243 
244  // use a nonexistant id
245 
246  if(out) *out << "\nUse of a nonexistant id = 100 throws a AlgorithmState::DoesNotExist exception : ";
247  try {
248  state.iter_quant(100);
249  success = false;
250  if(out) *out << false << endl;
251  }
252  catch(const AlgorithmState::DoesNotExist& expt) {
253  if(out) *out << true << endl;
254  }
255 
256  // update the iteration
257 
258  if(out) *out << "\n*** Update iteration quantities k+1 = k then check\n";
259 
260  if(out) *out << "alpha_k(+1) = alpha_k(0)...\n";
261  alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") );
262  {
263  alpha_k_t &alpha_k = alpha->get_k(0);
264  alpha->set_k(+1) = alpha_k;
265  }
266 
267  if(out) *out << "x_k(+1) = x_k(0)...\n";
268  x = dynamic_cast<x_t*>( &state.iter_quant("x") );
269  {
270  x_k_t &x_k = x->get_k(0);
271  x->set_k(+1) = x_k;
272  }
273 
274  if(out) *out << "V_k(+1) = V_k(0)...\n";
275  V = dynamic_cast<V_t*>( &state.iter_quant("V") );
276  {
277  V_k_t &V_k = V->get_k(0);
278  V->set_k(+1) = V_k;
279  }
280 
281  if(out) *out << "shift reference from k to k+1...\n";
282  state.next_iteration();
283 
284  if(out) *out << "\nalpha_k(-1) == 5.0 : ";
285  alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") );
286  update_success( result = alpha->get_k(-1) == 5.0, &success );
287  if(out) *out << result << endl;
288  if(out) *out << "alpha_k(0) == 5.0 : ";
289  update_success( result = alpha->get_k(0) == 5.0, &success );
290  if(out) *out << result << endl;
291 
292  if(out) *out << "\nx_k(-1)[0] == 2.0 : ";
293  x = dynamic_cast<x_t*>( &state.iter_quant("x") );
294  update_success( result = x->get_k(-1)[0] == 2.0, &success );
295  if(out) *out << result << endl;
296  if(out) *out << "x_k(0)[0] == 2.0 : ";
297  update_success( result = x->get_k(0)[0] == 2.0, &success );
298  if(out) *out << result << endl;
299 
300  if(out) *out << "\nV_k(0).alpha() == 3.0 : ";
301  V = dynamic_cast<V_t*>( &state.iter_quant("V") );
302  update_success( result = V->get_k(0).alpha() == 3.0, &success );
303  if(out) *out << result << endl;
304 
305  // erase an iteration quantity then try to access it
306 
307  if(out) *out << "\n*** Erasing iteration quantity \"x\" then trying to access it throws"
308  " a AlgorithmState::DoesNotExist exception : ";
309  state.erase_iter_quant("x");
310  try {
311  state.iter_quant(x_id);
312  if(out) *out << false << endl;
313  update_success( false, &success );
314  }
315  catch(const AlgorithmState::DoesNotExist& expt) {
316  if(out) *out << true << endl;
317  }
318 
319  // final printout.
320 
321  if(out) {
322  if(success) {
323  *out << "\n*** Congradulations, all of the tests for AlgorihtmState"
324  " returned the expected results\n";
325  }
326  else {
327  *out << "\n*** Oops, at least one of the above tests for AlgorihtmState"
328  " did not return the expected results ***\n";
329  }
330  }
331 
332  return success;
333 
334  } // end try
335  catch(const std::exception& excpt) {
336  if(out) *out << "\nCaught a std::exception: " << typeName(excpt) << " : " << excpt.what() << endl;
337  }
338  catch(...) {
339  if(out) *out << "\nCaught an unknown exception\n";
340  }
341 
342  if(out) *out << "\n*** Oops, If you read this some function throw an unexpected exception and the tests have failed!\n";
343 
344  return false;
345 }
std::string typeName(const T &t)
virtual void erase_iter_quant(const std::string &iq_name)
Removes the iteration quantity with name iq_name.
virtual void dump_iter_quant(std::ostream &out) const
iteration quantity information dumping.
virtual iq_id_type set_iter_quant(const std::string &iq_name, const IQ_ptr &iq)
Inserts the iteration quantity through a RCP<...> object.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual IterQuantity & iter_quant(const std::string &iq_name)
Iteration quantity encapsulation object access with via iq_name.
std::ostream * out
Abstacts a set of iteration quantities for an iterative algorithm.
virtual iq_id_type get_iter_quant_id(const std::string &iq_name) const
Return the iteration quantity id (iq_id) for the iteration quantity.
Iteration Quanities subclass for contiguous iterations.
bool update_success(bool result_check, bool *success)
Helper function for updating a flag for if an operation returned false.
virtual void next_iteration(bool incr_k=true)
iteration quantity forwarding.