Simbody  3.5
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 
00040 enum OptimizerAlgorithm {
00042      BestAvailable = 0,
00045      InteriorPoint = 1,
00048      LBFGS         = 2,
00051      LBFGSB        = 3,
00056      CFSQP         = 4,
00060      CMAES         = 5,
00061      UnknownOptimizerAlgorithm = 6, // the default impl. of getAlgorithm.
00063      UserSuppliedOptimizerAlgorithm = 7
00064 };
00065 
00071 class SimTK_SIMMATH_EXPORT OptimizerSystem {
00072 public:
00073     OptimizerSystem() : numParameters(0),
00074                         numEqualityConstraints(0),
00075                         numInequalityConstraints(0),
00076                         numLinearEqualityConstraints(0),
00077                         numLinearInequalityConstraints(0),
00078                         useLimits( false ),
00079                         lowerLimits(0),
00080                         upperLimits(0) { 
00081     }
00082 
00083     explicit OptimizerSystem(int nParameters ) { 
00084         new (this) OptimizerSystem(); // call the above constructor
00085         setNumParameters(nParameters);
00086     }
00087 
00088     virtual ~OptimizerSystem() {
00089         if( useLimits ) {
00090             delete lowerLimits;
00091             delete upperLimits;
00092         }
00093     }
00094 
00098     virtual int objectiveFunc      ( const Vector& parameters, 
00099                                  bool new_parameters, Real& f ) const {
00100                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "objectiveFunc" );
00101                                  return -1; }
00102   
00105     virtual int gradientFunc       ( const Vector &parameters, 
00106                                  bool new_parameters, Vector &gradient ) const  {
00107                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "gradientFunc" );
00108                                  return -1; }
00111     virtual int constraintFunc     ( const Vector & parameters, 
00112                                  bool new_parameters, Vector & constraints ) const {
00113                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintFunc" );
00114                                  return -1; }
00117     virtual int constraintJacobian ( const Vector& parameters, 
00118                                   bool new_parameters, Matrix& jac ) const {
00119                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintJacobian" );
00120                                  return -1; }
00123     virtual int hessian            (  const Vector &parameters, 
00124                                  bool new_parameters, Vector &gradient) const {
00125                                  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "hessian" );
00126                                  return -1; }
00127 
00129    void setNumParameters( const int nParameters ) {
00130        if(   nParameters < 1 ) {
00131            const char* where = " OptimizerSystem  Constructor";
00132            const char* szName = "number of parameters";
00133            SimTK_THROW5(SimTK::Exception::ValueOutOfRange, szName, 1, nParameters, INT_MAX, where);
00134        } else {
00135            numParameters = nParameters;
00136        }
00137    }
00139    void setNumEqualityConstraints( const int n ) {
00140        if( n < 0 ) {
00141            const char* where = " OptimizerSystem  setNumEqualityConstraints";
00142            const char* szName = "number of equality constraints";
00143            SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where);
00144        } else {
00145            numEqualityConstraints = n;
00146        }
00147    }
00149    void setNumInequalityConstraints( const int n ) {
00150        if( n < 0 ) {
00151            const char* where = " OptimizerSystem  setNumInequalityConstraints";
00152            const char* szName = "number of inequality constraints";
00153            SimTK_THROW3(SimTK::Exception::SizeWasNegative, szName, n, where);
00154        } else {
00155            numInequalityConstraints = n;
00156        }
00157    }
00159    void setNumLinearEqualityConstraints( const int n ) {
00160        if( n < 0 || n > numEqualityConstraints ) {
00161            const char* where = " OptimizerSystem  setNumLinearEqualityConstraints";
00162            const char* szName = "number of linear equality constraints";
00163            SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numEqualityConstraints, where);
00164        } else {
00165            numLinearEqualityConstraints = n;
00166        }
00167    }
00169    void setNumLinearInequalityConstraints( const int n ) {
00170        if( n < 0 || n > numInequalityConstraints ) {
00171            const char* where = " OptimizerSystem  setNumLinearInequalityConstraints";
00172            const char* szName = "number of linear inequality constraints";
00173            SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numInequalityConstraints, where);
00174        } else {
00175            numLinearInequalityConstraints = n;
00176        }
00177    }
00179    void setParameterLimits( const Vector& lower, const Vector& upper  ) {
00180        if(   upper.size() != numParameters  && upper.size() != 0) {
00181            const char* where = " OptimizerSystem  setParamtersLimits";
00182            const char* szName = "upper limits length";
00183            SimTK_THROW5(Exception::IncorrectArrayLength, szName, upper.size(), "numParameters", numParameters, where);
00184        }
00185        if(   lower.size() != numParameters  && lower.size() != 0 ) {
00186            const char* where = " OptimizerSystem  setParamtersLimits";
00187            const char* szName = "lower limits length";
00188            SimTK_THROW5(Exception::IncorrectArrayLength, szName, lower.size(), "numParameters", numParameters, where);
00189        } 
00190 
00191        // set the upper and lower limits
00192        if( useLimits ) {
00193            delete lowerLimits;
00194            delete upperLimits;
00195        }
00196 
00197        if( upper.size() == 0 ) {
00198           useLimits = false;
00199        } else {
00200           lowerLimits = new Vector( lower );
00201           upperLimits = new Vector( upper );
00202           useLimits = true;
00203        }
00204    }
00205 
00208    int getNumParameters() const {return numParameters;}
00210    int getNumConstraints() const {return numEqualityConstraints+numInequalityConstraints;}
00212    int getNumEqualityConstraints() const {return numEqualityConstraints;}
00214    int getNumInequalityConstraints() const {return numInequalityConstraints;}
00216    int getNumLinearEqualityConstraints() const {return numLinearEqualityConstraints;}
00218    int getNumNonlinearEqualityConstraints() const {return numEqualityConstraints-numLinearEqualityConstraints;}
00220    int getNumLinearInequalityConstraints() const {return numLinearInequalityConstraints;}
00222    int getNumNonlinearInequalityConstraints() const {return numInequalityConstraints-numLinearInequalityConstraints;}
00223 
00225    bool getHasLimits() const { return useLimits; }
00229    void getParameterLimits( Real **lower, Real **upper ) const {
00230         *lower = &(*lowerLimits)[0];
00231         *upper = &(*upperLimits)[0];
00232    }
00233 
00234 private:
00235    int numParameters;
00236    int numEqualityConstraints;
00237    int numInequalityConstraints;
00238    int numLinearEqualityConstraints;
00239    int numLinearInequalityConstraints;
00240    bool useLimits;
00241    Vector* lowerLimits;
00242    Vector* upperLimits;
00243 
00244 }; // class OptimizerSystem
00245 
00355 class SimTK_SIMMATH_EXPORT Optimizer {
00356 public:
00357     Optimizer();
00358     Optimizer( const OptimizerSystem& sys);
00359     Optimizer( const OptimizerSystem& sys, OptimizerAlgorithm algorithm);
00360     ~Optimizer();
00361 
00364     static bool isAlgorithmAvailable(OptimizerAlgorithm algorithm);
00365    
00367     void setConvergenceTolerance(Real accuracy );
00370     void setConstraintTolerance(Real tolerance);
00371 
00372 
00378     void setMaxIterations( int iter );
00381     void setLimitedMemoryHistory( int history );
00383     void setDiagnosticsLevel( int level ); 
00384 
00385     void setOptimizerSystem( const OptimizerSystem& sys  );
00386     void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm );
00387 
00389     bool setAdvancedStrOption( const char *option, const char *value );
00391     bool setAdvancedRealOption( const char *option, const Real value );
00393     bool setAdvancedIntOption( const char *option, const int value );
00395     bool setAdvancedBoolOption( const char *option, const bool value );
00396 
00397     
00407     void setDifferentiatorMethod(Differentiator::Method method);
00412     Differentiator::Method getDifferentiatorMethod() const;
00413 
00418     OptimizerAlgorithm getAlgorithm() const;
00419 
00431     void useNumericalGradient(bool flag, 
00432         Real estimatedAccuracyOfObjective = SignificantReal);
00445     void useNumericalJacobian(bool flag, 
00446         Real estimatedAccuracyOfConstraints = SignificantReal);
00447 
00449     Real optimize(Vector&);
00450 
00452     const OptimizerSystem& getOptimizerSystem() const;
00453 
00455     bool isUsingNumericalGradient() const;
00457     bool isUsingNumericalJacobian() const;
00459     Real getEstimatedAccuracyOfObjective() const;
00461     Real getEstimatedAccuracyOfConstraints() const;
00462 
00463     // This is a local class.
00464     class OptimizerRep;
00465 private:
00466     Optimizer( const Optimizer& c );
00467     Optimizer& operator=(const Optimizer& rhs);
00468 
00469     OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm);
00470     const OptimizerRep& getRep() const {assert(rep); return *rep;}
00471     OptimizerRep&       updRep()       {assert(rep); return *rep;}
00472 
00473     // Hidden implementation to preserve binary compatibility.
00474     OptimizerRep* rep;
00475 
00476 friend class OptimizerRep;
00477 }; // class Optimizer
00478  
00479 } // namespace SimTK
00480 
00481 #endif //SimTK_SIMMATH_OPTIMIZER_H_
00482 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines