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(Real accuracy );
00262 void setConstraintTolerance(Real tolerance);
00263
00264
00266 void setMaxIterations( int iter );
00268 void setLimitedMemoryHistory( int history );
00270 void setDiagnosticsLevel( int level );
00272 void setDifferentiatorMethod( Differentiator::Method method);
00273
00274 void setOptimizerSystem( const OptimizerSystem& sys );
00275 void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm );
00276
00278 bool setAdvancedStrOption( const char *option, const char *value );
00280 bool setAdvancedRealOption( const char *option, const Real value );
00282 bool setAdvancedIntOption( const char *option, const int value );
00284 bool setAdvancedBoolOption( const char *option, const bool value );
00285
00287 void useNumericalGradient( bool flag );
00289 void useNumericalJacobian( bool flag );
00290
00292 Real optimize(Vector&);
00293
00295 const OptimizerSystem& getOptimizerSystem() const;
00296
00298 bool isUsingNumericalGradient() const;
00300 bool isUsingNumericalJacobian() const;
00301
00302
00303 class OptimizerRep;
00304 private:
00305 Optimizer( const Optimizer& c );
00306 Optimizer& operator=(const Optimizer& rhs);
00307
00308 OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm);
00309 const OptimizerRep& getRep() const {assert(rep); return *rep;}
00310 OptimizerRep& updRep() {assert(rep); return *rep;}
00311
00312
00313 OptimizerRep* rep;
00314
00315 friend class OptimizerRep;
00316 };
00317
00318 }
00319
00320 #endif //_SimTK_OPTIMIZER_H
00321