Simbody
3.5
|
00001 #ifndef SimTK_SIMMATH_OPTIMIZER_H_ 00002 #define SimTK_SIMMATH_OPTIMIZER_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKmath * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK 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/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2006-13 Stanford University and the Authors. * 00013 * Authors: Jack Middleton * 00014 * Contributors: Michael Sherman * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00027 00028 #include "SimTKcommon.h" 00029 #include "simmath/internal/common.h" 00030 #include "simmath/Differentiator.h" 00031 00032 namespace SimTK { 00033 00040 enum OptimizerAlgorithm { 00042 BestAvailable = 0, 00045 InteriorPoint = 1, 00048 LBFGS = 2, 00051 LBFGSB = 3, 00056 CFSQP = 4, 00060 CMAES = 5, 00061 UnknownOptimizerAlgorithm = 6, // the default impl. of getAlgorithm. 00063 UserSuppliedOptimizerAlgorithm = 7 00064 }; 00065 00071 class SimTK_SIMMATH_EXPORT OptimizerSystem { 00072 public: 00073 OptimizerSystem() : numParameters(0), 00074 numEqualityConstraints(0), 00075 numInequalityConstraints(0), 00076 numLinearEqualityConstraints(0), 00077 numLinearInequalityConstraints(0), 00078 useLimits( false ), 00079 lowerLimits(0), 00080 upperLimits(0) { 00081 } 00082 00083 explicit OptimizerSystem(int nParameters ) { 00084 new (this) OptimizerSystem(); // call the above constructor 00085 setNumParameters(nParameters); 00086 } 00087 00088 virtual ~OptimizerSystem() { 00089 if( useLimits ) { 00090 delete lowerLimits; 00091 delete upperLimits; 00092 } 00093 } 00094 00098 virtual int objectiveFunc ( const Vector& parameters, 00099 bool new_parameters, Real& f ) const { 00100 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "objectiveFunc" ); 00101 return -1; } 00102 00105 virtual int gradientFunc ( const Vector ¶meters, 00106 bool new_parameters, Vector &gradient ) const { 00107 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "gradientFunc" ); 00108 return -1; } 00111 virtual int constraintFunc ( const Vector & parameters, 00112 bool new_parameters, Vector & constraints ) const { 00113 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintFunc" ); 00114 return -1; } 00117 virtual int constraintJacobian ( const Vector& parameters, 00118 bool new_parameters, Matrix& jac ) const { 00119 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintJacobian" ); 00120 return -1; } 00123 virtual int hessian ( const Vector ¶meters, 00124 bool new_parameters, Vector &gradient) const { 00125 SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "hessian" ); 00126 return -1; } 00127 00129 void setNumParameters( const int nParameters ) { 00130 if( nParameters < 1 ) { 00131 const char* where = " OptimizerSystem Constructor"; 00132 const char* szName = "number of parameters"; 00133 SimTK_THROW5(SimTK::Exception::ValueOutOfRange, szName, 1, nParameters, INT_MAX, where); 00134 } else { 00135 numParameters = nParameters; 00136 } 00137 } 00139 void setNumEqualityConstraints( const int n ) { 00140 if( n < 0 ) { 00141 const char* where = " OptimizerSystem setNumEqualityConstraints"; 00142 const char* szName = "number of equality constraints"; 00143 SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where); 00144 } else { 00145 numEqualityConstraints = n; 00146 } 00147 } 00149 void setNumInequalityConstraints( const int n ) { 00150 if( n < 0 ) { 00151 const char* where = " OptimizerSystem setNumInequalityConstraints"; 00152 const char* szName = "number of inequality constraints"; 00153 SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where); 00154 } else { 00155 numInequalityConstraints = n; 00156 } 00157 } 00159 void setNumLinearEqualityConstraints( const int n ) { 00160 if( n < 0 || n > numEqualityConstraints ) { 00161 const char* where = " OptimizerSystem setNumLinearEqualityConstraints"; 00162 const char* szName = "number of linear equality constraints"; 00163 SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numEqualityConstraints, where); 00164 } else { 00165 numLinearEqualityConstraints = n; 00166 } 00167 } 00169 void setNumLinearInequalityConstraints( const int n ) { 00170 if( n < 0 || n > numInequalityConstraints ) { 00171 const char* where = " OptimizerSystem setNumLinearInequalityConstraints"; 00172 const char* szName = "number of linear inequality constraints"; 00173 SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numInequalityConstraints, where); 00174 } else { 00175 numLinearInequalityConstraints = n; 00176 } 00177 } 00179 void setParameterLimits( const Vector& lower, const Vector& upper ) { 00180 if( upper.size() != numParameters && upper.size() != 0) { 00181 const char* where = " OptimizerSystem setParamtersLimits"; 00182 const char* szName = "upper limits length"; 00183 SimTK_THROW5(Exception::IncorrectArrayLength, szName, upper.size(), "numParameters", numParameters, where); 00184 } 00185 if( lower.size() != numParameters && lower.size() != 0 ) { 00186 const char* where = " OptimizerSystem setParamtersLimits"; 00187 const char* szName = "lower limits length"; 00188 SimTK_THROW5(Exception::IncorrectArrayLength, szName, lower.size(), "numParameters", numParameters, where); 00189 } 00190 00191 // set the upper and lower limits 00192 if( useLimits ) { 00193 delete lowerLimits; 00194 delete upperLimits; 00195 } 00196 00197 if( upper.size() == 0 ) { 00198 useLimits = false; 00199 } else { 00200 lowerLimits = new Vector( lower ); 00201 upperLimits = new Vector( upper ); 00202 useLimits = true; 00203 } 00204 } 00205 00208 int getNumParameters() const {return numParameters;} 00210 int getNumConstraints() const {return numEqualityConstraints+numInequalityConstraints;} 00212 int getNumEqualityConstraints() const {return numEqualityConstraints;} 00214 int getNumInequalityConstraints() const {return numInequalityConstraints;} 00216 int getNumLinearEqualityConstraints() const {return numLinearEqualityConstraints;} 00218 int getNumNonlinearEqualityConstraints() const {return numEqualityConstraints-numLinearEqualityConstraints;} 00220 int getNumLinearInequalityConstraints() const {return numLinearInequalityConstraints;} 00222 int getNumNonlinearInequalityConstraints() const {return numInequalityConstraints-numLinearInequalityConstraints;} 00223 00225 bool getHasLimits() const { return useLimits; } 00229 void getParameterLimits( Real **lower, Real **upper ) const { 00230 *lower = &(*lowerLimits)[0]; 00231 *upper = &(*upperLimits)[0]; 00232 } 00233 00234 private: 00235 int numParameters; 00236 int numEqualityConstraints; 00237 int numInequalityConstraints; 00238 int numLinearEqualityConstraints; 00239 int numLinearInequalityConstraints; 00240 bool useLimits; 00241 Vector* lowerLimits; 00242 Vector* upperLimits; 00243 00244 }; // class OptimizerSystem 00245 00355 class SimTK_SIMMATH_EXPORT Optimizer { 00356 public: 00357 Optimizer(); 00358 Optimizer( const OptimizerSystem& sys); 00359 Optimizer( const OptimizerSystem& sys, OptimizerAlgorithm algorithm); 00360 ~Optimizer(); 00361 00364 static bool isAlgorithmAvailable(OptimizerAlgorithm algorithm); 00365 00367 void setConvergenceTolerance(Real accuracy ); 00370 void setConstraintTolerance(Real tolerance); 00371 00372 00378 void setMaxIterations( int iter ); 00381 void setLimitedMemoryHistory( int history ); 00383 void setDiagnosticsLevel( int level ); 00384 00385 void setOptimizerSystem( const OptimizerSystem& sys ); 00386 void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm ); 00387 00389 bool setAdvancedStrOption( const char *option, const char *value ); 00391 bool setAdvancedRealOption( const char *option, const Real value ); 00393 bool setAdvancedIntOption( const char *option, const int value ); 00395 bool setAdvancedBoolOption( const char *option, const bool value ); 00396 00397 00407 void setDifferentiatorMethod(Differentiator::Method method); 00412 Differentiator::Method getDifferentiatorMethod() const; 00413 00418 OptimizerAlgorithm getAlgorithm() const; 00419 00431 void useNumericalGradient(bool flag, 00432 Real estimatedAccuracyOfObjective = SignificantReal); 00445 void useNumericalJacobian(bool flag, 00446 Real estimatedAccuracyOfConstraints = SignificantReal); 00447 00449 Real optimize(Vector&); 00450 00452 const OptimizerSystem& getOptimizerSystem() const; 00453 00455 bool isUsingNumericalGradient() const; 00457 bool isUsingNumericalJacobian() const; 00459 Real getEstimatedAccuracyOfObjective() const; 00461 Real getEstimatedAccuracyOfConstraints() const; 00462 00463 // This is a local class. 00464 class OptimizerRep; 00465 private: 00466 Optimizer( const Optimizer& c ); 00467 Optimizer& operator=(const Optimizer& rhs); 00468 00469 OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm); 00470 const OptimizerRep& getRep() const {assert(rep); return *rep;} 00471 OptimizerRep& updRep() {assert(rep); return *rep;} 00472 00473 // Hidden implementation to preserve binary compatibility. 00474 OptimizerRep* rep; 00475 00476 friend class OptimizerRep; 00477 }; // class Optimizer 00478 00479 } // namespace SimTK 00480 00481 #endif //SimTK_SIMMATH_OPTIMIZER_H_ 00482