00001 #ifndef _SimTK_OPTIMIZER_H
00002 #define _SimTK_OPTIMIZER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "SimTKcommon.h"
00037 #include "SimTKmath.h"
00038 #include <limits.h>
00039
00040 namespace SimTK {
00041
00042 enum OptimizerAlgorithm {
00043 BestAvailiable = 0,
00044 InteriorPoint = 1,
00045 LBFGS = 2,
00046 LBFGSB = 3,
00047 CFSQP = 4
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();
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
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 };
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( const Real tolerance );
00261 void setMaxIterations( const int iter );
00263 void setLimitedMemoryHistory( const int history );
00265 void setDiagnosticsLevel( const int level );
00267 void setDifferentiatorMethod( Differentiator::Method method);
00268
00269 void setOptimizerSystem( const OptimizerSystem& sys );
00270 void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm );
00271
00273 bool setAdvancedStrOption( const char *option, const char *value );
00275 bool setAdvancedRealOption( const char *option, const Real value );
00277 bool setAdvancedIntOption( const char *option, const int value );
00279 bool setAdvancedBoolOption( const char *option, const bool value );
00280
00282 void useNumericalGradient( const bool flag );
00284 void useNumericalJacobian( const bool flag );
00285
00287 Real optimize(Vector&);
00288
00290 const OptimizerSystem& getOptimizerSystem() const;
00291
00293 bool isUsingNumericalGradient() const;
00295 bool isUsingNumericalJacobian() const;
00296
00297
00298 class OptimizerRep;
00299 private:
00300 Optimizer( const Optimizer& c );
00301 Optimizer& operator=(const Optimizer& rhs);
00302
00303 OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm);
00304 const OptimizerRep& getRep() const {assert(rep); return *rep;}
00305 OptimizerRep& updRep() {assert(rep); return *rep;}
00306
00307
00308 OptimizerRep* rep;
00309
00310 friend class OptimizerRep;
00311 };
00312
00313 }
00314
00315 #endif //_SimTK_OPTIMIZER_H
00316