MOOCHO (Single Doxygen Collection) Version of the Day
IterationPack_TestAlgorithm.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) 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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include <ostream>
00043 #include <iomanip>
00044 
00045 #include "IterationPack_TestIterationPack.hpp"
00046 #include "IterationPack_AlgorithmStepTesting.hpp"
00047 #include "IterationPack_AlgorithmTrackTesting.hpp"
00048 #include "IterationPack_Algorithm.hpp"
00049 #include "IterationPack_AlgorithmState.hpp"
00050 
00051 namespace IterationPack {
00052 
00053 // Implement minor loop 1
00054 class MinorLoop1Step : public AlgorithmStepTesting {
00055 public:
00056 
00057   MinorLoop1Step() : called_(false)
00058   {}
00059 
00060   bool do_step(Algorithm& algo, poss_type step_poss, EDoStepType type
00061     , poss_type assoc_step_poss)
00062   {
00063     if(called_) {
00064       algo.terminate(false);
00065       return false;
00066     }
00067     AlgorithmStepTesting::do_step(algo,step_poss,type,assoc_step_poss);
00068     algo.track().journal_out() << "\n* Jump to \"Step_2\"\n";
00069     algo.do_step_next("Step_2");
00070     called_ = true;
00071     return false;
00072   }
00073 
00074 private:
00075   bool called_;
00076 };
00077 
00078 // Implement controled loop 1
00079 class ControledLoop1Step : public AlgorithmStepTesting {
00080 public:
00081 
00082   ControledLoop1Step() : called_(false)
00083   {}
00084 
00085   bool do_step(Algorithm& algo, poss_type step_poss, EDoStepType type
00086     , poss_type assoc_step_poss)
00087   {
00088     if(called_) {
00089       algo.terminate(false);
00090       return false;
00091     }
00092     AlgorithmStepTesting::do_step(algo,step_poss,type,assoc_step_poss);
00093     algo.track().journal_out() << "\n* Do step \"Step_2_p1\" then Jump to \"Step_1\"\n";
00094     algo.get_assoc_step(2,POST_STEP,1)->do_step(algo,2,DO_POST_STEP,1);
00095     algo.do_step_next("Step_1");
00096     called_ = true;
00097     return false;
00098   }
00099 
00100 private:
00101   bool called_;
00102 };
00103 
00104 // Runtime Config change
00105 class RuntimeConfigChangeStep : public AlgorithmStepTesting {
00106 public:
00107 
00108   RuntimeConfigChangeStep() : called_(false)
00109   {}
00110 
00111   bool do_step(Algorithm& algo, poss_type step_poss, EDoStepType type
00112     , poss_type assoc_step_poss)
00113   {
00114     AlgorithmStepTesting::do_step(algo,step_poss,type,assoc_step_poss);
00115     if(!called_) {
00116       algo.track().journal_out() << "\n* Remove step \"Step_1\" then put it back then print steps\n";
00117       algo.begin_config_update();
00118       Algorithm::step_ptr_t step = algo.get_step(1);
00119       algo.remove_step(1);
00120       algo.insert_step(1,"Step_1",step);
00121       algo.end_config_update();
00122       called_ = true;
00123     }
00124     else {
00125       algo.track().journal_out() << "\n* Remove step 1, step_name = "
00126         << algo.get_step_name(1) << " but don't put it back then print steps\n";
00127       algo.begin_config_update();
00128       algo.remove_step(1);
00129       algo.end_config_update();
00130       called_ = true;
00131     }
00132     algo.print_steps(algo.track().journal_out());
00133     return true;
00134   }
00135 
00136 private:
00137   bool called_;
00138 };
00139 
00140 } // end namespace IterationPack
00141 
00142 bool IterationPack::TestingPack::TestAlgorithm(std::ostream* out) {
00143 
00144   using std::endl;
00145   using std::setw;
00146   
00147   std::ostream& _out = *out;
00148   // ToDo: RAB: 7/1/99: Modify for optional output when out == 0;
00149 
00150   try {
00151 
00152   bool success = true;
00153 //  const int w = 15;
00154   _out << std::boolalpha;
00155     
00156   _out  << "\n\n*************************\n"
00157       << "*** Testing Algorithm ***\n"
00158       << "*************************\n";
00159 
00160   Algorithm algo;
00161   
00162   Algorithm::state_ptr_t      state   = Teuchos::rcp(new AlgorithmState);
00163   Algorithm::track_ptr_t      track   = Teuchos::rcp(new AlgorithmTrackTesting(Teuchos::rcp(&_out,false)));
00164 
00165   algo.set_state( state );
00166   algo.set_track( track );
00167 
00168   Algorithm::step_ptr_t     step    = Teuchos::rcp(new AlgorithmStepTesting);
00169   Algorithm::step_ptr_t     assoc_step  = Teuchos::rcp(new AlgorithmStepTesting);
00170 
00171   algo.insert_step( 1, "Step_1", step );
00172 
00173   algo.insert_step( 2, "Step_2", step );
00174 
00175   algo.insert_assoc_step( 2, PRE_STEP, 1, "Step_2_m1", assoc_step );
00176 
00177   algo.insert_assoc_step( 2, POST_STEP, 1, "Step_2_p1", assoc_step );
00178 
00179   algo.insert_step( 3, "Step_3", step );
00180 
00181   algo.insert_step( 4, "Step_4", step );
00182 
00183   algo.insert_assoc_step( 4, PRE_STEP, 1, "Step_4_m2", assoc_step );
00184 
00185   algo.insert_assoc_step( 4, PRE_STEP, 2, "Step_4_m1", assoc_step );
00186 
00187   _out  << "\n\n*** algo.print_algorithm(_out)\n\n";
00188   algo.print_algorithm(_out);
00189 
00190   // Test the major loop
00191 
00192   _out  << "\n\n*** Test the major loop for two iterations ***\n";
00193 
00194   _out  << "\nalgo.set_algo_timing(true); algo.max_iter(2); algo.do_algorithm();\n\n";
00195   algo.set_algo_timing(true);
00196   algo.max_iter(2);
00197   algo.do_algorithm();
00198 
00199   // Test Minor Loop 1
00200 
00201   _out  << "\n\n*** Test Minor Loop 1 ***\n";
00202 
00203   _out  << "\nalgo.remove_assoc_step( 4, PRE_STEP, 2 );\n";
00204   algo.remove_assoc_step( 4, PRE_STEP, 2 );
00205 
00206   _out  << "\nalgo.insert_assoc_step( 4, PRE_STEP, 2, \"Step_4_m1\", new MinorLoop1Step );\n";
00207   algo.insert_assoc_step( 4, PRE_STEP, 2, "Step_4_m1", Teuchos::rcp(new MinorLoop1Step) );
00208 
00209   _out  << "\nalgo.state().k(0);\n";
00210   algo.state().k(0);
00211 
00212   _out  << "\nalgo.max_iter(1);\n";
00213   algo.max_iter(1);
00214 
00215   _out  << "\n\nalgo.print_steps(_out)\n\n";
00216   algo.print_steps(_out);
00217 
00218   _out  << "\nalgo.do_algorithm();\n";
00219   algo.do_algorithm();
00220 
00221   // Test Controlled Loop 1
00222 
00223   _out  << "\n\n*** Test Controlled Loop 1 ***\n";
00224 
00225   _out  << "\nalgo.remove_assoc_step( 4, PRE_STEP, 2 );\n";
00226   algo.remove_assoc_step( 4, PRE_STEP, 2 );
00227 
00228   _out  << "\nalgo.insert_assoc_step( 4, PRE_STEP, 2, \"Step_4_m1\", assoc_step );\n";
00229   algo.insert_assoc_step( 4, PRE_STEP, 2, "Step_4_m1", assoc_step );
00230 
00231   _out  << "\nalgo.remove_assoc_step( 4, PRE_STEP, 1 );\n";
00232   algo.remove_assoc_step( 4, PRE_STEP, 1 );
00233 
00234   _out  << "\nalgo.insert_assoc_step( 4, PRE_STEP, 1 , \"Step_4_m2\", new ControledLoop1Step );\n";
00235   algo.insert_assoc_step( 4, PRE_STEP, 1 , "Step_4_m2", Teuchos::rcp(new ControledLoop1Step) );
00236 
00237   _out  << "\n\nalgo.print_steps(_out)\n\n";
00238   algo.print_steps(_out);
00239 
00240   _out  << "\nalgo.state.k(0);\n";
00241   algo.state().k(0);
00242 
00243   _out  << "\nalgo.do_algorithm();\n";
00244   algo.do_algorithm();
00245 
00246   // Test runtime configuration change.
00247 
00248   _out  << "\n\n*** Test runtime configuration change ***\n";
00249 
00250   _out  << "\nalgo.remove_assoc_step( 4, PRE_STEP, 1 );\n";
00251   algo.remove_assoc_step( 4, PRE_STEP, 1 );
00252 
00253   _out  << "\nalgo.insert_assoc_step( 4, PRE_STEP, 1, \"Step_4_m2\", new  RuntimeConfigChangeStep );\n";
00254   algo.insert_assoc_step( 4, PRE_STEP, 1, "Step_4_m2", Teuchos::rcp(new  RuntimeConfigChangeStep) );
00255 
00256   _out  << "\n\nalgo.print_steps(_out)\n\n";
00257   algo.print_steps(_out);
00258 
00259   _out  << "\nalgo.state.k(0);\n";
00260   algo.state().k(0);
00261 
00262   _out  << "\nalgo.max_iter(5);\n";
00263   algo.max_iter(5);
00264 
00265   try {
00266     _out  << "In the 5th (k= 4) iteration an Algorithm::InvalidConfigChange exception should be thrown.";
00267     _out  << "\nalgo.do_algorithm();\n";
00268     algo.do_algorithm();
00269     success = false;
00270     _out
00271       << "Algorithm threw exception : false\n";
00272   }
00273   catch(Algorithm::InvalidConfigChange& excpt) {
00274     _out << "\nAs expected!  Caught a Algorithm::InvalidConfigChange&: " << excpt.what() << endl
00275        << "Algorithm threw exception : true\n";
00276   }
00277 
00278   _out << "\n*** Congradulations, If you read this the tests for Algorithm"
00279       " seem to have been successful\n";
00280 
00281   return success;
00282 
00283   } // end try
00284   catch(const std::exception& excpt) {
00285     _out << "\nCaught a std::exception: " << excpt.what() << endl;
00286   }
00287   catch(...) {
00288     _out << "\nCaught an unknown exception\n";
00289   }
00290 
00291   _out << "\n*** Oops, If you read this some function throw an unexpected exception and the tests have failed!\n";
00292 
00293   return false;
00294 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines