IterationPack: General framework for building iterative algorithms  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
IterationPack_AlgorithmState.cpp
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 
46 #include "IterationPack_AlgorithmState.hpp"
47 #include "Teuchos_Assert.hpp"
48 
49 namespace {
50 namespace {
51 template< class T >
52 inline
53 T my_max( const T& v1, const T& v2 ) { return v1 > v2 ? v1 : v2; }
54 } // end namespace
55 inline void output_spaces(std::ostream& out, int spaces)
56 { for(int i = 0; i < spaces; ++i) out << ' '; }
57 }
58 
59 namespace IterationPack {
60 
62  const std::string& iq_name, const IQ_ptr& iq)
63 {
65  iq.get() == NULL, std::invalid_argument
66  ,"AlgorithmState::set_iter_quant(...) : The iteration quantity witht the name = \'" << iq_name
67  << "\' being inserted has iq.get() == NULL!" );
68  iq_id_type new_id = iq_.size();
69  std::pair<iq_name_to_id_t::iterator,bool>
70  r = iq_name_to_id_.insert(iq_name_to_id_t::value_type(iq_name,new_id));
72  !r.second // an insert did not take place, key = iq_name already existed.
74  ,"AlgorithmState::set_iter_quant(...) : An iteration quantity with the name \""
75  << iq_name << "\" already exists with the iq_id = " << (*r.first).second );
76  iq_.push_back(iq);
77  return new_id;
78 }
79 
80 void AlgorithmState::erase_iter_quant(const std::string& iq_name) {
81  iq_name_to_id_t::iterator itr = find_and_assert(iq_name);
82  const iq_id_type iq_id = (*itr).second;
83  iq_[iq_id] = Teuchos::null; // set the pointer to null
84  iq_name_to_id_.erase( itr );
85 }
86 
88  bool exists = true;
89  try {
90  IQ_ptr &_iq = iq_.at(iq_id);
91  if( _iq.get() )
92  return *_iq;
93  else
94  exists = false;
95  }
96  catch(const std::out_of_range& excpt) { // Thrown by MS VC++ 6.0
97  exists = false;
98  }
99  catch(const std::range_error& excpt) { // Thrown by libstdc++ v3 in g++ 2.95.2
100  exists = false;
101  }
103  !exists, DoesNotExist
104  ,"AlgorithmState::iter_quant(iq_id) : Error, the iteration quantity iq_id = "
105  << iq_id << " does not exist. "
106  << ( iq_id < iq_.size()
107  ? "This iteration quantity was set and then erased."
108  : "This iteration quantity was never set by the client." ) );
109  return *iq_.at(0); // Will never be executed.
110 }
111 
113  return const_cast<AlgorithmState*>(this)->iter_quant(iq_id);
114 }
115 
117  if(incr_k) this->incr_k();
118  for(iq_t::iterator itr = iq_.begin(); itr != iq_.end(); ++itr)
119  if(itr->get()) (*itr)->next_iteration();
120 }
121 
122 void AlgorithmState::dump_iter_quant(std::ostream& out) const {
123  using std::setw;
124  using std::endl;
125 
126  // Find the maximum length of an iteration quantity name
127  int name_w_max = 0;
128  {for( iq_name_to_id_t::const_iterator itr = iq_name_to_id_.begin();
129  itr != iq_name_to_id_.end(); ++itr )
130  {
131  name_w_max = my_max( (int)name_w_max, (int)(*itr).first.length() );
132  }}
133 
134  const int name_w = name_w_max + 4, id_w = 6;
135  const char gap[] = " ";
136 
137  out << "\n\n"
138  << std::left << setw(name_w) << "iq_name"
139  << std::right << setw(id_w) << "iq_id"
140  << gap << std::left << "concrete type of iq / concrete type of object\n";
141 
142  out << std::left << setw(name_w) << "-----"
143  << std::right << setw(id_w) << "------"
144  << gap << std::left << "---------------------------------------------\n";
145 
146  {for( iq_name_to_id_t::const_iterator itr = iq_name_to_id_.begin();
147  itr != iq_name_to_id_.end(); ++itr )
148  {
149  out << std::left << setw(name_w) << (*itr).first
150  << std::right << setw(id_w) << (*itr).second
151  << gap << std::left << typeName(*iq_[(*itr).second]) << endl
152  << std::left << setw(name_w) << ""
153  << std::right << setw(id_w) << ""
154  << gap << std::left;
155  iq_[(*itr).second]->print_concrete_type(out);
156  out << endl;
157  }}
158 }
159 
160 // private
161 
162 AlgorithmState::iq_name_to_id_t::iterator AlgorithmState::find_and_assert(
163  const std::string& iq_name)
164 {
165  iq_name_to_id_t::iterator itr = iq_name_to_id_.find(iq_name);
166  if(itr == iq_name_to_id_.end())
168  true, DoesNotExist
169  ,"AlgorithmState::find_and_assert(iq_name) : The iteration "
170  "quantity with the name \"" << iq_name << "\" does not exist" );
171  return itr;
172 }
173 
174 AlgorithmState::iq_name_to_id_t::const_iterator AlgorithmState::find_and_assert(
175  const std::string& iq_name) const
176 {
177  iq_name_to_id_t::const_iterator itr = iq_name_to_id_.find(iq_name);
178  if(itr == iq_name_to_id_.end())
180  true, DoesNotExist
181  ,"AlgorithmState::find_and_assert(iq_name) : The iteration "
182  "quantity with the name \"" << iq_name << "\" does not exist" );
183  return itr;
184 }
185 
186 } // end namespace IterationPack
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
T * get() const
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.
Iterface for information about Iteration Quantities.
virtual IterQuantity & iter_quant(const std::string &iq_name)
Iteration quantity encapsulation object access with via iq_name.
Abstacts a set of iteration quantities for an iterative algorithm.
virtual void next_iteration(bool incr_k=true)
iteration quantity forwarding.
std::string typeName(const T &t)