1 // @HEADER 2 // ************************************************************************ 3 // 4 // Rapid Optimization Library (ROL) Package 5 // Copyright (2014) 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 lead developers: 38 // Drew Kouri (dpkouri@sandia.gov) and 39 // Denis Ridzal (dridzal@sandia.gov) 40 // 41 // ************************************************************************ 42 // @HEADER 43 44 #ifndef ROL_ALGORITHM_H 45 #define ROL_ALGORITHM_H 46 47 #include "ROL_Types.hpp" 48 #include "ROL_Step.hpp" 49 #include "ROL_StatusTest.hpp" 50 #include "ROL_Objective.hpp" 51 #include "ROL_BoundConstraint.hpp" 52 #include "ROL_Constraint.hpp" 53 #include "ROL_ValidParameters.hpp" 54 55 /** \class ROL::Algorithm 56 \brief Provides an interface to run optimization algorithms. 57 */ 58 59 60 namespace ROL { 61 62 template <class Real> 63 class Algorithm { 64 private: 65 ROL::Ptr<Step<Real> > step_; 66 ROL::Ptr<StatusTest<Real> > status_; 67 ROL::Ptr<AlgorithmState<Real> > state_; 68 69 bool printHeader_; 70 71 public: 72 ~Algorithm()73 virtual ~Algorithm() {} 74 75 /** \brief Constructor, given a step and a status test. 76 */ Algorithm(const ROL::Ptr<Step<Real>> & step,const ROL::Ptr<StatusTest<Real>> & status,bool printHeader=false)77 Algorithm( const ROL::Ptr<Step<Real> > & step, 78 const ROL::Ptr<StatusTest<Real> > & status, 79 bool printHeader = false ) { 80 step_ = step; 81 status_ = status; 82 state_ = ROL::makePtr<AlgorithmState<Real>>(); 83 printHeader_ = printHeader; 84 } 85 86 /** \brief Constructor, given a step, a status test, and a 87 previously defined algorithm state. 88 */ Algorithm(const ROL::Ptr<Step<Real>> & step,const ROL::Ptr<StatusTest<Real>> & status,const ROL::Ptr<AlgorithmState<Real>> & state,bool printHeader=false)89 Algorithm( const ROL::Ptr<Step<Real> > & step, 90 const ROL::Ptr<StatusTest<Real> > & status, 91 const ROL::Ptr<AlgorithmState<Real> > & state, 92 bool printHeader = false ) { 93 step_ = step; 94 status_ = status; 95 state_ = state; 96 printHeader_ = printHeader; 97 } 98 99 /** \brief Run algorithm on unconstrained problems (Type-U). 100 This is the primary Type-U interface. 101 */ run(Vector<Real> & x,Objective<Real> & obj,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)102 virtual std::vector<std::string> run( Vector<Real> &x, 103 Objective<Real> &obj, 104 bool print = false, 105 std::ostream &outStream = std::cout, 106 bool printVectors = false, 107 std::ostream &vectorStream = std::cout ) { 108 BoundConstraint<Real> bnd; 109 bnd.deactivate(); 110 return run(x,x.dual(),obj,bnd,print,outStream,printVectors,vectorStream); 111 } 112 113 /** \brief Run algorithm on unconstrained problems (Type-U). 114 This general interface supports the use of dual optimization vector spaces, 115 where the user does not define the dual() method. 116 */ run(Vector<Real> & x,const Vector<Real> & g,Objective<Real> & obj,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)117 virtual std::vector<std::string> run( Vector<Real> &x, 118 const Vector<Real> &g, 119 Objective<Real> &obj, 120 bool print = false, 121 std::ostream &outStream = std::cout, 122 bool printVectors = false, 123 std::ostream &vectorStream = std::cout ) { 124 BoundConstraint<Real> bnd; 125 bnd.deactivate(); 126 return run(x,g,obj,bnd,print,outStream,printVectors,vectorStream); 127 } 128 129 /** \brief Run algorithm on bound constrained problems (Type-B). 130 This is the primary Type-B interface. 131 */ run(Vector<Real> & x,Objective<Real> & obj,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)132 virtual std::vector<std::string> run( Vector<Real> &x, 133 Objective<Real> &obj, 134 BoundConstraint<Real> &bnd, 135 bool print = false, 136 std::ostream &outStream = std::cout, 137 bool printVectors = false, 138 std::ostream &vectorStream = std::cout ) { 139 return run(x,x.dual(),obj,bnd,print,outStream,printVectors,vectorStream); 140 } 141 142 /** \brief Run algorithm on bound constrained problems (Type-B). 143 This general interface supports the use of dual optimization vector spaces, 144 where the user does not define the dual() method. 145 */ run(Vector<Real> & x,const Vector<Real> & g,Objective<Real> & obj,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)146 virtual std::vector<std::string> run( Vector<Real> &x, 147 const Vector<Real> &g, 148 Objective<Real> &obj, 149 BoundConstraint<Real> &bnd, 150 bool print = false, 151 std::ostream &outStream = std::cout, 152 bool printVectors = false, 153 std::ostream &vectorStream = std::cout ) { 154 if(printVectors) { 155 x.print(vectorStream); 156 } 157 158 std::vector<std::string> output; 159 160 // Initialize Current Iterate Container 161 if ( state_->iterateVec == ROL::nullPtr ) { 162 state_->iterateVec = x.clone(); 163 } 164 state_->iterateVec->set(x); 165 166 // Initialize Step Container 167 ROL::Ptr<Vector<Real> > s = x.clone(); 168 169 // Initialize Step 170 step_->initialize(x, g, obj, bnd, *state_); 171 output.push_back(step_->print(*state_,true)); 172 if ( print ) { 173 outStream << step_->print(*state_,true); 174 } 175 176 // Initialize Minimum Value and Vector 177 if ( state_->minIterVec == ROL::nullPtr ) { 178 state_->minIterVec = x.clone(); 179 } 180 state_->minIterVec->set(x); 181 state_->minIter = state_->iter; 182 state_->minValue = state_->value; 183 184 // Run Algorithm 185 while (status_->check(*state_)) { 186 step_->compute(*s, x, obj, bnd, *state_); 187 step_->update(x, *s, obj, bnd, *state_); 188 189 if( printVectors ) { 190 x.print(vectorStream); 191 } 192 193 // Store Minimal Value and Vector 194 if ( state_->minValue > state_->value ) { 195 state_->minIterVec->set(*(state_->iterateVec)); 196 state_->minValue = state_->value; 197 state_->minIter = state_->iter; 198 } 199 // Update Output 200 output.push_back(step_->print(*state_,printHeader_)); 201 if ( print ) { 202 outStream << step_->print(*state_,printHeader_); 203 } 204 } 205 std::stringstream hist; 206 hist << "Optimization Terminated with Status: "; 207 hist << EExitStatusToString(state_->statusFlag); 208 hist << "\n"; 209 output.push_back(hist.str()); 210 if ( print ) { 211 outStream << hist.str(); 212 } 213 return output; 214 } 215 216 217 /** \brief Run algorithm on equality constrained problems (Type-E). 218 This is the primary Type-E interface. 219 */ run(Vector<Real> & x,Vector<Real> & l,Objective<Real> & obj,Constraint<Real> & con,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)220 virtual std::vector<std::string> run( Vector<Real> &x, 221 Vector<Real> &l, 222 Objective<Real> &obj, 223 Constraint<Real> &con, 224 bool print = false, 225 std::ostream &outStream = std::cout, 226 bool printVectors = false, 227 std::ostream &vectorStream = std::cout ) { 228 229 return run(x, x.dual(), l, l.dual(), obj, con, print, outStream, printVectors, vectorStream); 230 231 } 232 233 234 /** \brief Run algorithm on equality constrained problems (Type-E). 235 This general interface supports the use of dual optimization and 236 constraint vector spaces, where the user does not define the dual() method. 237 */ run(Vector<Real> & x,const Vector<Real> & g,Vector<Real> & l,const Vector<Real> & c,Objective<Real> & obj,Constraint<Real> & con,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)238 virtual std::vector<std::string> run( Vector<Real> &x, 239 const Vector<Real> &g, 240 Vector<Real> &l, 241 const Vector<Real> &c, 242 Objective<Real> &obj, 243 Constraint<Real> &con, 244 bool print = false, 245 std::ostream &outStream = std::cout, 246 bool printVectors = false, 247 std::ostream &vectorStream = std::cout ) { 248 if( printVectors ) { 249 x.print(vectorStream); 250 } 251 252 std::vector<std::string> output; 253 254 // Initialize Current Iterate Container 255 if ( state_->iterateVec == ROL::nullPtr ) { 256 state_->iterateVec = x.clone(); 257 } 258 state_->iterateVec->set(x); 259 260 // Initialize Current Lagrange Multiplier Container 261 if ( state_->lagmultVec == ROL::nullPtr ) { 262 state_->lagmultVec = l.clone(); 263 } 264 state_->lagmultVec->set(l); 265 266 // Initialize Step Container 267 ROL::Ptr<Vector<Real> > s = x.clone(); 268 269 // Initialize Step 270 step_->initialize(x, g, l, c, obj, con, *state_); 271 output.push_back(step_->print(*state_,true)); 272 if ( print ) { 273 outStream << step_->print(*state_,true); 274 } 275 276 // Initialize Minimum Value and Vector 277 if ( state_->minIterVec == ROL::nullPtr ) { 278 state_->minIterVec = x.clone(); 279 } 280 state_->minIterVec->set(x); 281 state_->minIter = state_->iter; 282 state_->minValue = state_->value; 283 284 // Run Algorithm 285 while (status_->check(*state_)) { 286 step_->compute(*s, x, l, obj, con, *state_); 287 step_->update(x, l, *s, obj, con, *state_); 288 289 if( printVectors ) { 290 x.print(vectorStream); 291 } 292 293 output.push_back(step_->print(*state_,printHeader_)); 294 if ( print ) { 295 outStream << step_->print(*state_,printHeader_); 296 } 297 } 298 std::stringstream hist; 299 hist << "Optimization Terminated with Status: "; 300 hist << EExitStatusToString(state_->statusFlag); 301 hist << "\n"; 302 output.push_back(hist.str()); 303 if ( print ) { 304 outStream << hist.str(); 305 } 306 return output; 307 } 308 309 /** \brief Run algorithm on equality and bound constrained problems (Type-EB). 310 This is the primary Type-EB interface. 311 */ run(Vector<Real> & x,Vector<Real> & l,Objective<Real> & obj,Constraint<Real> & con,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)312 virtual std::vector<std::string> run( Vector<Real> &x, 313 Vector<Real> &l, 314 Objective<Real> &obj, 315 Constraint<Real> &con, 316 BoundConstraint<Real> &bnd, 317 bool print = false, 318 std::ostream &outStream = std::cout, 319 bool printVectors = false, 320 std::ostream &vectorStream = std::cout) { 321 return run(x,x.dual(),l,l.dual(),obj,con,bnd,print,outStream,printVectors,vectorStream); 322 } 323 324 /** \brief Run algorithm on equality and bound constrained problems (Type-EB). 325 This general interface supports the use of dual optimization and 326 constraint vector spaces, where the user does not define the dual() method. 327 */ run(Vector<Real> & x,const Vector<Real> & g,Vector<Real> & l,const Vector<Real> & c,Objective<Real> & obj,Constraint<Real> & con,BoundConstraint<Real> & bnd,bool print=false,std::ostream & outStream=std::cout,bool printVectors=false,std::ostream & vectorStream=std::cout)328 virtual std::vector<std::string> run( Vector<Real> &x, 329 const Vector<Real> &g, 330 Vector<Real> &l, 331 const Vector<Real> &c, 332 Objective<Real> &obj, 333 Constraint<Real> &con, 334 BoundConstraint<Real> &bnd, 335 bool print = false, 336 std::ostream &outStream = std::cout, 337 bool printVectors = false, 338 std::ostream &vectorStream = std::cout ) { 339 if(printVectors) { 340 x.print(vectorStream); 341 } 342 343 std::vector<std::string> output; 344 345 // Initialize Current Iterate Container 346 if ( state_->iterateVec == ROL::nullPtr ) { 347 state_->iterateVec = x.clone(); 348 } 349 state_->iterateVec->set(x); 350 351 // Initialize Current Lagrange Multiplier Container 352 if ( state_->lagmultVec == ROL::nullPtr ) { 353 state_->lagmultVec = l.clone(); 354 } 355 state_->lagmultVec->set(l); 356 357 // Initialize Step Container 358 ROL::Ptr<Vector<Real> > s = x.clone(); 359 360 // Initialize Step 361 step_->initialize(x, g, l, c, obj, con, bnd, *state_); 362 output.push_back(step_->print(*state_,true)); 363 if ( print ) { 364 outStream << step_->print(*state_,true); 365 } 366 367 // Initialize Minimum Value and Vector 368 if ( state_->minIterVec == ROL::nullPtr ) { 369 state_->minIterVec = x.clone(); 370 } 371 state_->minIterVec->set(x); 372 state_->minIter = state_->iter; 373 state_->minValue = state_->value; 374 375 // Run Algorithm 376 while (status_->check(*state_)) { 377 step_->compute(*s, x, l, obj, con, bnd, *state_); 378 step_->update(x, l, *s, obj, con, bnd, *state_); 379 if( printVectors ) { 380 x.print(vectorStream); 381 } 382 output.push_back(step_->print(*state_,printHeader_)); 383 if ( print ) { 384 outStream << step_->print(*state_,printHeader_); 385 } 386 } 387 std::stringstream hist; 388 hist << "Optimization Terminated with Status: "; 389 hist << EExitStatusToString(state_->statusFlag); 390 hist << "\n"; 391 output.push_back(hist.str()); 392 if ( print ) { 393 outStream << hist.str(); 394 } 395 return output; 396 } 397 getIterHeader(void)398 std::string getIterHeader(void) { 399 return step_->printHeader(); 400 } 401 getIterInfo(bool withHeader=false)402 std::string getIterInfo(bool withHeader = false) { 403 return step_->print(*state_,withHeader); 404 } 405 getState(void) const406 ROL::Ptr<const AlgorithmState<Real> > getState(void) const { 407 return state_; 408 } 409 reset(void)410 void reset(void) { 411 state_->reset(); 412 } 413 414 415 416 417 418 419 }; // class Algorithm 420 421 422 } // namespace ROL 423 424 #endif 425