Simbody
|
00001 #ifndef _SimTK_OPTIMIZER_H 00002 #define _SimTK_OPTIMIZER_H 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simmath(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2006-10 Stanford University and the Authors. * 00013 * Authors: Jack Middleton * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00035 00036 #include "SimTKcommon.h" 00037 #include "simmath/internal/common.h" 00038 #include "simmath/Differentiator.h" 00039 00040 namespace SimTK { 00041 00042 enum OptimizerAlgorithm { 00043 BestAvailiable = 0, // Simmath will select best Optimizer based on problem type 00044 InteriorPoint = 1, // IPOPT interior point optimizer 00045 LBFGS = 2, // LBFGS optimizer 00046 LBFGSB = 3, // LBFGS optimizer with simple bounds 00047 CFSQP = 4 // CFSQP sequential quadratic programming optimizer (requires external library) 00048 }; 00049 00055 class SimTK_SIMMATH_EXPORT OptimizerSystem { 00056 public: 00057 OptimizerSystem() : numParameters(0), 00058 numEqualityConstraints(0), 00059 numInequalityConstraints(0), 00060 numLinearEqualityConstraints(0), 00061 numLinearInequalityConstraints(0), 00062 useLimits( false ), 00063 lowerLimits(0), 00064 upperLimits(0) { 00065 } 00066 00067 explicit OptimizerSystem(int nParameters ) { 00068 new (this) OptimizerSystem(); // call the above constructor 00069 setNumParameters(nParameters); 00070 } 00071 00072 virtual ~OptimizerSystem() { 00073 if( useLimits ) { 00074 delete lowerLimits; 00075 delete upperLimits; 00076 } 00077 } 00078 00081 virtual int objectiveFunc ( const Vector& parameters, 00082 const bool new_parameters, Real& f ) const { 00083 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "objectiveFunc" ); 00084 return -1; } 00085 00088 virtual int gradientFunc ( const Vector ¶meters, 00089 const bool new_parameters, Vector &gradient ) const { 00090 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "gradientFunc" ); 00091 return -1; } 00094 virtual int constraintFunc ( const Vector & parameters, 00095 const bool new_parameters, Vector & constraints ) const { 00096 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintFunc" ); 00097 return -1; } 00100 virtual int constraintJacobian ( const Vector& parameters, 00101 const bool new_parameters, Matrix& jac ) const { 00102 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintJacobian" ); 00103 return -1; } 00106 virtual int hessian ( const Vector ¶meters, 00107 const bool new_parameters, Vector &gradient) const { 00108 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "hessian" ); 00109 return -1; } 00110 00112 void setNumParameters( const int nParameters ) { 00113 if( nParameters < 1 ) { 00114 const char* where = " OptimizerSystem Constructor"; 00115 const char* szName = "number of parameters"; 00116 SimTK_THROW5(SimTK::Exception::ValueOutOfRange, szName, 1, nParameters, INT_MAX, where); 00117 } else { 00118 numParameters = nParameters; 00119 } 00120 } 00122 void setNumEqualityConstraints( const int n ) { 00123 if( n < 0 ) { 00124 const char* where = " OptimizerSystem setNumEqualityConstraints"; 00125 const char* szName = "number of equality constraints"; 00126 SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where); 00127 } else { 00128 numEqualityConstraints = n; 00129 } 00130 } 00132 void setNumInequalityConstraints( const int n ) { 00133 if( n < 0 ) { 00134 const char* where = " OptimizerSystem setNumInequalityConstraints"; 00135 const char* szName = "number of inequality constraints"; 00136 SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where); 00137 } else { 00138 numInequalityConstraints = n; 00139 } 00140 } 00142 void setNumLinearEqualityConstraints( const int n ) { 00143 if( n < 0 || n > numEqualityConstraints ) { 00144 const char* where = " OptimizerSystem setNumLinearEqualityConstraints"; 00145 const char* szName = "number of linear equality constraints"; 00146 SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numEqualityConstraints, where); 00147 } else { 00148 numLinearEqualityConstraints = n; 00149 } 00150 } 00152 void setNumLinearInequalityConstraints( const int n ) { 00153 if( n < 0 || n > numInequalityConstraints ) { 00154 const char* where = " OptimizerSystem setNumLinearInequalityConstraints"; 00155 const char* szName = "number of linear inequality constraints"; 00156 SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numInequalityConstraints, where); 00157 } else { 00158 numLinearInequalityConstraints = n; 00159 } 00160 } 00162 void setParameterLimits( const Vector& lower, const Vector& upper ) { 00163 if( upper.size() != numParameters && upper.size() != 0) { 00164 const char* where = " OptimizerSystem setParamtersLimits"; 00165 const char* szName = "upper limits length"; 00166 SimTK_THROW5(Exception::IncorrectArrayLength, szName, upper.size(), "numParameters", numParameters, where); 00167 } 00168 if( lower.size() != numParameters && lower.size() != 0 ) { 00169 const char* where = " OptimizerSystem setParamtersLimits"; 00170 const char* szName = "lower limits length"; 00171 SimTK_THROW5(Exception::IncorrectArrayLength, szName, lower.size(), "numParameters", numParameters, where); 00172 } 00173 00174 // set the upper and lower limits 00175 if( useLimits ) { 00176 delete lowerLimits; 00177 delete upperLimits; 00178 } 00179 00180 if( upper.size() == 0 ) { 00181 useLimits = false; 00182 } else { 00183 lowerLimits = new Vector( lower ); 00184 upperLimits = new Vector( upper ); 00185 useLimits = true; 00186 } 00187 } 00188 00191 int getNumParameters() const {return numParameters;} 00193 int getNumConstraints() const {return numEqualityConstraints+numInequalityConstraints;} 00195 int getNumEqualityConstraints() const {return numEqualityConstraints;} 00197 int getNumInequalityConstraints() const {return numInequalityConstraints;} 00199 int getNumLinearEqualityConstraints() const {return numLinearEqualityConstraints;} 00201 int getNumNonlinearEqualityConstraints() const {return numEqualityConstraints-numLinearEqualityConstraints;} 00203 int getNumLinearInequalityConstraints() const {return numLinearInequalityConstraints;} 00205 int getNumNonlinearInequalityConstraints() const {return numInequalityConstraints-numLinearInequalityConstraints;} 00206 00208 bool getHasLimits() const { return useLimits; } 00212 void getParameterLimits( double **lower, double **upper ) const { 00213 *lower = &(*lowerLimits)[0]; 00214 *upper = &(*upperLimits)[0]; 00215 } 00216 00217 private: 00218 int numParameters; 00219 int numEqualityConstraints; 00220 int numInequalityConstraints; 00221 int numLinearEqualityConstraints; 00222 int numLinearInequalityConstraints; 00223 bool useLimits; 00224 Vector* lowerLimits; 00225 Vector* upperLimits; 00226 00227 }; // class OptimizerSystem 00228 00249 class SimTK_SIMMATH_EXPORT Optimizer { 00250 public: 00251 Optimizer(); 00252 Optimizer( const OptimizerSystem& sys); 00253 Optimizer( const OptimizerSystem& sys, OptimizerAlgorithm algorithm); 00254 ~Optimizer(); 00255 00256 static bool isAlgorithmAvailable(OptimizerAlgorithm algorithm); 00257 00259 void setConvergenceTolerance(Real accuracy ); 00262 void setConstraintTolerance(Real tolerance); 00263 00264 00270 void setMaxIterations( int iter ); 00272 void setLimitedMemoryHistory( int history ); 00274 void setDiagnosticsLevel( int level ); 00276 void setDifferentiatorMethod( Differentiator::Method method); 00277 00278 void setOptimizerSystem( const OptimizerSystem& sys ); 00279 void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm ); 00280 00282 bool setAdvancedStrOption( const char *option, const char *value ); 00284 bool setAdvancedRealOption( const char *option, const Real value ); 00286 bool setAdvancedIntOption( const char *option, const int value ); 00288 bool setAdvancedBoolOption( const char *option, const bool value ); 00289 00291 void useNumericalGradient( bool flag ); 00293 void useNumericalJacobian( bool flag ); 00294 00296 Real optimize(Vector&); 00297 00299 const OptimizerSystem& getOptimizerSystem() const; 00300 00302 bool isUsingNumericalGradient() const; 00304 bool isUsingNumericalJacobian() const; 00305 00306 // This is a local class. 00307 class OptimizerRep; 00308 private: 00309 Optimizer( const Optimizer& c ); 00310 Optimizer& operator=(const Optimizer& rhs); 00311 00312 OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm); 00313 const OptimizerRep& getRep() const {assert(rep); return *rep;} 00314 OptimizerRep& updRep() {assert(rep); return *rep;} 00315 00316 // Hidden implementation to preserve binary compatibility. 00317 OptimizerRep* rep; 00318 00319 friend class OptimizerRep; 00320 }; // class Optimizer 00321 00322 } // namespace SimTK 00323 00324 #endif //_SimTK_OPTIMIZER_H 00325