Simbody

Optimizer.h

Go to the documentation of this file.
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 &parameters, 
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 &parameters, 
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines