Simbody  3.4 (development)
Optimizer.h
Go to the documentation of this file.
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 
00034 enum OptimizerAlgorithm {
00035      BestAvailable  = 0, // Simmath will select best Optimizer based on problem type
00036      InteriorPoint  = 1, // IPOPT interior point optimizer
00037      LBFGS          = 2, // LBFGS optimizer
00038      LBFGSB         = 3, // LBFGS optimizer with simple bounds
00039      CFSQP          = 4  // CFSQP sequential quadratic programming optimizer (requires external library)
00040 };
00041 
00047 class SimTK_SIMMATH_EXPORT OptimizerSystem {
00048 public:
00049     OptimizerSystem() : numParameters(0),
00050                         numEqualityConstraints(0),
00051                         numInequalityConstraints(0),
00052                         numLinearEqualityConstraints(0),
00053                         numLinearInequalityConstraints(0),
00054                         useLimits( false ),
00055                         lowerLimits(0),
00056                         upperLimits(0) { 
00057     }
00058 
00059     explicit OptimizerSystem(int nParameters ) { 
00060         new (this) OptimizerSystem(); // call the above constructor
00061         setNumParameters(nParameters);
00062     }
00063 
00064     virtual ~OptimizerSystem() {
00065         if( useLimits ) {
00066             delete lowerLimits;
00067             delete upperLimits;
00068         }
00069     }
00070 
00073     virtual int objectiveFunc      ( const Vector& parameters, 
00074                                  bool new_parameters, Real& f ) const {
00075                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "objectiveFunc" );
00076                                  return -1; }
00077   
00080     virtual int gradientFunc       ( const Vector &parameters, 
00081                                  bool new_parameters, Vector &gradient ) const  {
00082                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "gradientFunc" );
00083                                  return -1; }
00086     virtual int constraintFunc     ( const Vector & parameters, 
00087                                  bool new_parameters, Vector & constraints ) const {
00088                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintFunc" );
00089                                  return -1; }
00092     virtual int constraintJacobian ( const Vector& parameters, 
00093                                   bool new_parameters, Matrix& jac ) const {
00094                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintJacobian" );
00095                                  return -1; }
00098     virtual int hessian            (  const Vector &parameters, 
00099                                  bool new_parameters, Vector &gradient) const {
00100                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "hessian" );
00101                                  return -1; }
00102 
00104    void setNumParameters( const int nParameters ) {
00105        if(   nParameters < 1 ) {
00106            const char* where = " OptimizerSystem  Constructor";
00107            const char* szName = "number of parameters";
00108            SimTK_THROW5(SimTK::Exception::ValueOutOfRange, szName, 1, nParameters, INT_MAX, where);
00109        } else {
00110            numParameters = nParameters;
00111        }
00112    }
00114    void setNumEqualityConstraints( const int n ) {
00115        if( n < 0 ) {
00116            const char* where = " OptimizerSystem  setNumEqualityConstraints";
00117            const char* szName = "number of equality constraints";
00118            SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where);
00119        } else {
00120            numEqualityConstraints = n;
00121        }
00122    }
00124    void setNumInequalityConstraints( const int n ) {
00125        if( n < 0 ) {
00126            const char* where = " OptimizerSystem  setNumInequalityConstraints";
00127            const char* szName = "number of inequality constraints";
00128            SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where);
00129        } else {
00130            numInequalityConstraints = n;
00131        }
00132    }
00134    void setNumLinearEqualityConstraints( const int n ) {
00135        if( n < 0 || n > numEqualityConstraints ) {
00136            const char* where = " OptimizerSystem  setNumLinearEqualityConstraints";
00137            const char* szName = "number of linear equality constraints";
00138            SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numEqualityConstraints, where);
00139        } else {
00140            numLinearEqualityConstraints = n;
00141        }
00142    }
00144    void setNumLinearInequalityConstraints( const int n ) {
00145        if( n < 0 || n > numInequalityConstraints ) {
00146            const char* where = " OptimizerSystem  setNumLinearInequalityConstraints";
00147            const char* szName = "number of linear inequality constraints";
00148            SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numInequalityConstraints, where);
00149        } else {
00150            numLinearInequalityConstraints = n;
00151        }
00152    }
00154    void setParameterLimits( const Vector& lower, const Vector& upper  ) {
00155        if(   upper.size() != numParameters  && upper.size() != 0) {
00156            const char* where = " OptimizerSystem  setParamtersLimits";
00157            const char* szName = "upper limits length";
00158            SimTK_THROW5(Exception::IncorrectArrayLength, szName, upper.size(), "numParameters", numParameters, where);
00159        }
00160        if(   lower.size() != numParameters  && lower.size() != 0 ) {
00161            const char* where = " OptimizerSystem  setParamtersLimits";
00162            const char* szName = "lower limits length";
00163            SimTK_THROW5(Exception::IncorrectArrayLength, szName, lower.size(), "numParameters", numParameters, where);
00164        } 
00165 
00166        // set the upper and lower limits
00167        if( useLimits ) {
00168            delete lowerLimits;
00169            delete upperLimits;
00170        }
00171 
00172        if( upper.size() == 0 ) {
00173           useLimits = false;
00174        } else {
00175           lowerLimits = new Vector( lower );
00176           upperLimits = new Vector( upper );
00177           useLimits = true;
00178        }
00179    }
00180 
00183    int getNumParameters() const {return numParameters;}
00185    int getNumConstraints() const {return numEqualityConstraints+numInequalityConstraints;}
00187    int getNumEqualityConstraints() const {return numEqualityConstraints;}
00189    int getNumInequalityConstraints() const {return numInequalityConstraints;}
00191    int getNumLinearEqualityConstraints() const {return numLinearEqualityConstraints;}
00193    int getNumNonlinearEqualityConstraints() const {return numEqualityConstraints-numLinearEqualityConstraints;}
00195    int getNumLinearInequalityConstraints() const {return numLinearInequalityConstraints;}
00197    int getNumNonlinearInequalityConstraints() const {return numInequalityConstraints-numLinearInequalityConstraints;}
00198 
00200    bool getHasLimits() const { return useLimits; }
00204    void getParameterLimits( Real **lower, Real **upper ) const {
00205         *lower = &(*lowerLimits)[0];
00206         *upper = &(*upperLimits)[0];
00207    }
00208 
00209 private:
00210    int numParameters;
00211    int numEqualityConstraints;
00212    int numInequalityConstraints;
00213    int numLinearEqualityConstraints;
00214    int numLinearInequalityConstraints;
00215    bool useLimits;
00216    Vector* lowerLimits;
00217    Vector* upperLimits;
00218 
00219 }; // class OptimizerSystem
00220 
00241 class SimTK_SIMMATH_EXPORT Optimizer {
00242 public:
00243     Optimizer();
00244     Optimizer( const OptimizerSystem& sys);
00245     Optimizer( const OptimizerSystem& sys, OptimizerAlgorithm algorithm);
00246     ~Optimizer();
00247 
00248     static bool isAlgorithmAvailable(OptimizerAlgorithm algorithm);
00249    
00251     void setConvergenceTolerance(Real accuracy );
00254     void setConstraintTolerance(Real tolerance);
00255 
00256 
00262     void setMaxIterations( int iter );
00264     void setLimitedMemoryHistory( int history );
00266     void setDiagnosticsLevel( int level ); 
00267 
00268     void setOptimizerSystem( const OptimizerSystem& sys  );
00269     void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm );
00270 
00272     bool setAdvancedStrOption( const char *option, const char *value );
00274     bool setAdvancedRealOption( const char *option, const Real value );
00276     bool setAdvancedIntOption( const char *option, const int value );
00278     bool setAdvancedBoolOption( const char *option, const bool value );
00279 
00280     
00290     void setDifferentiatorMethod(Differentiator::Method method);
00295     Differentiator::Method getDifferentiatorMethod() const;
00296 
00308     void useNumericalGradient(bool flag, 
00309         Real estimatedAccuracyOfObjective = SignificantReal);
00322     void useNumericalJacobian(bool flag, 
00323         Real estimatedAccuracyOfConstraints = SignificantReal);
00324 
00326     Real optimize(Vector&);
00327 
00329     const OptimizerSystem& getOptimizerSystem() const;
00330 
00332     bool isUsingNumericalGradient() const;
00334     bool isUsingNumericalJacobian() const;
00336     Real getEstimatedAccuracyOfObjective() const;
00338     Real getEstimatedAccuracyOfConstraints() const;
00339 
00340     // This is a local class.
00341     class OptimizerRep;
00342 private:
00343     Optimizer( const Optimizer& c );
00344     Optimizer& operator=(const Optimizer& rhs);
00345 
00346     OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm);
00347     const OptimizerRep& getRep() const {assert(rep); return *rep;}
00348     OptimizerRep&       updRep()       {assert(rep); return *rep;}
00349 
00350     // Hidden implementation to preserve binary compatibility.
00351     OptimizerRep* rep;
00352 
00353 friend class OptimizerRep;
00354 }; // class Optimizer
00355  
00356 } // namespace SimTK
00357 
00358 #endif //SimTK_SIMMATH_OPTIMIZER_H_
00359 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines