Optimizer.h

Go to the documentation of this file.
00001 
00002 #ifndef _SimTK_OPTIMIZER_H
00003 #define _SimTK_OPTIMIZER_H
00004 
00005 /* -------------------------------------------------------------------------- *
00006  *                      SimTK Core: SimTK Simmath(tm)                         *
00007  * -------------------------------------------------------------------------- *
00008  * This is part of the SimTK Core biosimulation toolkit originating from      *
00009  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00010  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00011  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00012 
00013  * Portions copyright (c) 2006-2007 Stanford University and Jack Middleton.   *
00014  * Contributors:                                                              *
00015  *
00016  * Permission is hereby granted, free of charge, to any person obtaining      *
00017  * a copy of this software and associated documentation files (the            *
00018  * "Software"), to deal in the Software without restriction, including        *
00019  * without limitation the rights to use, copy, modify, merge, publish,        *
00020  * distribute, sublicense, and/or sell copies of the Software, and to         *
00021  * permit persons to whom the Software is furnished to do so, subject         *
00022  * to the following conditions:                                               *
00023  *
00024  * The above copyright notice and this permission notice shall be included    *
00025  * in all copies or substantial portions of the Software.                     *
00026  *
00027  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    *
00028  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                 *
00029  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.     *
00030  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY       *
00031  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,       *
00032  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE          *
00033  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                     *
00034  */
00035 
00036 
00037 #include "SimTKcommon.h"
00038 #include "SimTKmath.h"
00039 #include <limits.h>
00040 
00041 namespace SimTK {
00042 
00043 enum OptimizerAlgorithm {
00044      BestAvailiable = 0, // Simmath will select best Optimizer based on problem type
00045      InteriorPoint  = 1, // IPOPT interior point optimizer
00046      LBFGS          = 2, // LBFGS optimizer
00047      LBFGSB         = 3, // LBFGS optimizer with simple bounds
00048      CFSQP          = 4  // CFSQP sequential quadratic programming optimizer (requires external library)
00049 };
00056 class SimTK_SIMMATH_EXPORT OptimizerSystem {
00057 public:
00058     OptimizerSystem() : numParameters(0),
00059                         numEqualityConstraints(0),
00060                         numInequalityConstraints(0),
00061                         numLinearEqualityConstraints(0),
00062                         numLinearInequalityConstraints(0),
00063                         useLimits( false ),
00064                         lowerLimits(0),
00065                         upperLimits(0) { 
00066     }
00067 
00068     OptimizerSystem(int nParameters ) : numEqualityConstraints(0),
00069                                       numInequalityConstraints(0),
00070                                       numLinearEqualityConstraints(0),
00071                                       numLinearInequalityConstraints(0),
00072                                       useLimits( false ),
00073                                       lowerLimits(0),
00074                                       upperLimits(0) { 
00075         setNumParameters(nParameters);
00076     }
00077 
00078   virtual ~OptimizerSystem() {
00079      if( useLimits ) {
00080          delete lowerLimits;
00081          delete upperLimits;
00082      }
00083   }
00084 
00087   virtual int objectiveFunc      ( const Vector& parameters, 
00088                                  const bool new_parameters, Real& f ) const {
00089                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "objectiveFunc" );
00090                                  return -1; }
00091   
00094   virtual int gradientFunc       ( const Vector &parameters, 
00095                                  const bool new_parameters, Vector &gradient ) const  {
00096                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "gradientFunc" );
00097                                  return -1; }
00100   virtual int constraintFunc     ( const Vector & parameters, 
00101                                  const bool new_parameters, Vector & constraints ) const {
00102                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintFunc" );
00103                                  return -1; }
00106   virtual int constraintJacobian ( const Vector& parameters, 
00107                                   const bool new_parameters, Matrix& jac ) const {
00108                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintJacobian" );
00109                                  return -1; }
00112   virtual int hessian            (  const Vector &parameters, 
00113                                  const bool new_parameters, Vector &gradient) const {
00114                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "hessian" );
00115                                  return -1; }
00117    virtual void setNumParameters( const int nParameters ) {
00118 
00119        if(   nParameters < 1 ) {
00120            const char* where = " OptimizerSystem  Constructor";
00121            const char* szName = "number of parameters";
00122            SimTK_THROW5(SimTK::Exception::ValueOutOfRange, szName, 1, nParameters, INT_MAX, where);
00123        }else {
00124             numParameters = nParameters;
00125        }
00126    }
00128    void setNumEqualityConstraints( const int n ) {
00129  
00130         if( n < 0 ) {
00131            const char* where = " OptimizerSystem  setNumEqualityConstraints";
00132            const char* szName = "number of equality constraints";
00133            SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where);
00134         } else {
00135            numEqualityConstraints = n;
00136         }
00137    }
00139    void setNumInequalityConstraints( const int n ) {
00140 
00141        if( n < 0 ) {
00142            const char* where = " OptimizerSystem  setNumInequalityConstraints";
00143            const char* szName = "number of inequality constraints";
00144            SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where);
00145        }else {
00146             numInequalityConstraints = n;
00147        }
00148    }
00150    void setNumLinearEqualityConstraints( const int n ) {
00151  
00152         if( n < 0 || n > numEqualityConstraints ) {
00153            const char* where = " OptimizerSystem  setNumLinearEqualityConstraints";
00154            const char* szName = "number of linear equality constraints";
00155            SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numEqualityConstraints, where);
00156         } else {
00157            numLinearEqualityConstraints = n;
00158         }
00159    }
00161    void setNumLinearInequalityConstraints( const int n ) {
00162 
00163        if( n < 0 || n > numInequalityConstraints ) {
00164            const char* where = " OptimizerSystem  setNumLinearInequalityConstraints";
00165            const char* szName = "number of linear inequality constraints";
00166            SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numInequalityConstraints, where);
00167        }else {
00168             numLinearInequalityConstraints = n;
00169        }
00170    }
00172    void setParameterLimits( const Vector& lower, const Vector& upper  ) {
00173  
00174         if(   upper.size() != numParameters  && upper.size() != 0) {
00175            const char* where = " OptimizerSystem  setParamtersLimits";
00176            const char* szName = "upper limits length";
00177            SimTK_THROW5(Exception::IncorrectArrayLength, szName, upper.size(), "numParameters", numParameters, where);
00178         }
00179         if(   lower.size() != numParameters  && lower.size() != 0 ) {
00180            const char* where = " OptimizerSystem  setParamtersLimits";
00181            const char* szName = "lower limits length";
00182            SimTK_THROW5(Exception::IncorrectArrayLength, szName, lower.size(), "numParameters", numParameters, where);
00183         } 
00184        // set the upper and lower limits
00185        if( useLimits ) {
00186            delete lowerLimits;
00187            delete upperLimits;
00188        }
00189 
00190        if( upper.size() == 0 ) {
00191           useLimits = false;
00192        } else {
00193           lowerLimits = new Vector( lower );
00194           upperLimits = new Vector( upper );
00195           useLimits = true;
00196        }
00197 
00198        return;
00199    }
00201    int getNumParameters() const {return numParameters;}
00202 
00204    int getNumConstraints() const {return numEqualityConstraints+numInequalityConstraints;}
00206    int getNumEqualityConstraints() const {return numEqualityConstraints;}
00208    int getNumInequalityConstraints() const {return numInequalityConstraints;}
00210    int getNumLinearEqualityConstraints() const {return numLinearEqualityConstraints;}
00212    int getNumNonlinearEqualityConstraints() const {return numEqualityConstraints-numLinearEqualityConstraints;}
00214    int getNumLinearInequalityConstraints() const {return numLinearInequalityConstraints;}
00216    int getNumNonlinearInequalityConstraints() const {return numInequalityConstraints-numLinearInequalityConstraints;}
00217 
00219    bool getHasLimits() const { return useLimits; }
00221    void getParameterLimits( double **lower, double **upper ) const {
00222         *lower = &(*lowerLimits)[0];
00223         *upper = &(*upperLimits)[0];
00224    }
00225 
00226 
00227    int numParameters;
00228    int numEqualityConstraints;
00229    int numInequalityConstraints;
00230    int numLinearEqualityConstraints;
00231    int numLinearInequalityConstraints;
00232    bool useLimits;
00233    Vector* lowerLimits;
00234    Vector* upperLimits;
00235 
00236 }; // class OptimizerSystem
00237 
00238 // These static functions are private to the current (client-side) compilation
00239 // unit. They are used to navigate the client-side OptimizerSystem virtual function
00240 // table, which cannot be done on the library side. Note that these are defined
00241 // in the SimTK namespace so don't need "SimTK" in their names.
00242 static int objectiveFunc_static(const OptimizerSystem& sys,
00243                                  const Vector& parameters, 
00244                                 const bool new_parameters, Real& f ) {
00245 
00246     return sys.objectiveFunc(parameters, new_parameters,  f);
00247 }
00248 static int gradientFunc_static(const OptimizerSystem& sys,
00249                                 const Vector &parameters, 
00250                                const bool new_parameters, Vector &gradient ) {
00251     return sys.gradientFunc( parameters, new_parameters, gradient);
00252 }
00253 static int constraintFunc_static(const OptimizerSystem& sys,
00254                                  const Vector &parameters, 
00255                                  const bool new_parameters, Vector& constraints ) {
00256     return sys.constraintFunc( parameters, new_parameters, constraints);
00257 }
00258 static int constraintJacobian_static(const OptimizerSystem& sys,
00259                                  const Vector &parameters, 
00260                                  const bool new_parameters, Matrix& jac ) {
00261     return sys.constraintJacobian( parameters, new_parameters, jac);
00262 }
00263 static int hessian_static(const OptimizerSystem& sys,
00264                                  const Vector &parameters,
00265                                  const bool new_parameters, Vector& gradient ) {
00266     return sys.hessian( parameters, new_parameters, gradient);
00267 }
00268 
00291 class SimTK_SIMMATH_EXPORT Optimizer  {
00292 
00293    public:
00294 
00295     Optimizer();
00296     Optimizer( const OptimizerSystem& sys);
00297     Optimizer( const OptimizerSystem& sys, OptimizerAlgorithm algorithm);
00298 
00299 
00300     ~Optimizer();
00301 
00302     static bool isAlgorithmAvailable(OptimizerAlgorithm algorithm);
00303    
00305     void setConvergenceTolerance( const Real tolerance );
00307     void setMaxIterations( const int iter );
00309     void setLimitedMemoryHistory( const int history );
00311     void setDiagnosticsLevel( const int level ); 
00313     void setDifferentiatorMethod( Differentiator::Method method);
00314 
00315     void setOptimizerSystem( const OptimizerSystem& sys  );
00316     void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm );
00317 
00319     bool setAdvancedStrOption( const char *option, const char *value );
00321     bool setAdvancedRealOption( const char *option, const Real value );
00323     bool setAdvancedIntOption( const char *option, const int value );
00325     bool setAdvancedBoolOption( const char *option, const bool value );
00326 
00328     void useNumericalGradient( const bool flag );
00330     void useNumericalJacobian( const bool flag );
00331 
00333     double optimize(Vector&);
00334     
00335 private:
00336   typedef int (*ObjectiveFunc)      ( const OptimizerSystem&,
00337                                     const Vector& parameters,  const bool new_parameters,
00338                                     Real& f );
00339 
00340   typedef int (*GradientFunc)       ( const OptimizerSystem&,
00341                                     const Vector &parameters, const bool new_parameters,
00342                                     Vector &gradient );
00343 
00344   typedef int (*ConstraintFunc)     ( const OptimizerSystem&,
00345                                     const Vector & parameters, const bool new_parameters,
00346                                     Vector &constraints );
00347 
00348   typedef int (*ConstraintJacobian) ( const OptimizerSystem&,
00349                                     const Vector& parameters, const bool new_parameters,
00350                                     Matrix& jac );
00351 
00352   typedef int (*Hessian)            ( const OptimizerSystem&,
00353                                     const Vector &parameters, const bool new_parameters,
00354                                     Vector &gradient);
00355 
00356   void registerObjectiveFunc( ObjectiveFunc );
00357   void registerGradientFunc( GradientFunc );
00358   void registerConstraintFunc( ConstraintFunc );
00359   void registerConstraintJacobian( ConstraintJacobian );
00360   void registerHessian( Hessian );
00361 
00362     // This is the library-side part of the CPodes constructor. This must
00363     // be done prior to the client side construction.
00364   void librarySideOptimizerConstructor(const OptimizerSystem& sys, OptimizerAlgorithm algorithm);
00365 
00366   void clientSideOptimizerConstructor() {
00367        registerObjectiveFunc( objectiveFunc_static );
00368        registerGradientFunc( gradientFunc_static );
00369        registerConstraintFunc( constraintFunc_static );
00370        registerConstraintJacobian( constraintJacobian_static );
00371        registerHessian( hessian_static );
00372   }
00373 
00374     class OptimizerRep* rep;
00375     friend class OptimizerRep;
00376 
00377     const OptimizerRep& getRep() const {assert(rep); return *rep;}
00378     OptimizerRep&       updRep()       {assert(rep); return *rep;}
00379 
00380     Optimizer( const Optimizer& c );
00381     Optimizer& operator=(const Optimizer& rhs);
00382 
00383 }; // Class Optimizer
00384  
00385 } // namespace SimTK
00386 
00387 #endif //_SimTK_OPTIMIZER_H
00388 

Generated on Fri Sep 26 07:44:15 2008 for SimTKcore by  doxygen 1.5.6