Simbody  3.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Optimizer.h
Go to the documentation of this file.
1 #ifndef SimTK_SIMMATH_OPTIMIZER_H_
2 #define SimTK_SIMMATH_OPTIMIZER_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKmath *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2006-13 Stanford University and the Authors. *
13  * Authors: Jack Middleton *
14  * Contributors: Michael Sherman *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
27 
28 #include "SimTKcommon.h"
30 #include "simmath/Differentiator.h"
31 
32 namespace SimTK {
33 
35  BestAvailable = 0, // Simmath will select best Optimizer based on problem type
36  InteriorPoint = 1, // IPOPT interior point optimizer
37  LBFGS = 2, // LBFGS optimizer
38  LBFGSB = 3, // LBFGS optimizer with simple bounds
39  CFSQP = 4 // CFSQP sequential quadratic programming optimizer (requires external library)
40 };
41 
48 public:
49  OptimizerSystem() : numParameters(0),
50  numEqualityConstraints(0),
51  numInequalityConstraints(0),
52  numLinearEqualityConstraints(0),
53  numLinearInequalityConstraints(0),
54  useLimits( false ),
55  lowerLimits(0),
56  upperLimits(0) {
57  }
58 
59  explicit OptimizerSystem(int nParameters ) {
60  new (this) OptimizerSystem(); // call the above constructor
61  setNumParameters(nParameters);
62  }
63 
64  virtual ~OptimizerSystem() {
65  if( useLimits ) {
66  delete lowerLimits;
67  delete upperLimits;
68  }
69  }
70 
73  virtual int objectiveFunc ( const Vector& parameters,
74  bool new_parameters, Real& f ) const {
75  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "objectiveFunc" );
76  return -1; }
77 
80  virtual int gradientFunc ( const Vector &parameters,
81  bool new_parameters, Vector &gradient ) const {
82  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "gradientFunc" );
83  return -1; }
86  virtual int constraintFunc ( const Vector & parameters,
87  bool new_parameters, Vector & constraints ) const {
88  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintFunc" );
89  return -1; }
92  virtual int constraintJacobian ( const Vector& parameters,
93  bool new_parameters, Matrix& jac ) const {
94  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "constraintJacobian" );
95  return -1; }
98  virtual int hessian ( const Vector &parameters,
99  bool new_parameters, Vector &gradient) const {
100  SimTK_THROW2(SimTK::Exception::UnimplementedVirtualMethod , "OptimizerSystem", "hessian" );
101  return -1; }
102 
104  void setNumParameters( const int nParameters ) {
105  if( nParameters < 1 ) {
106  const char* where = " OptimizerSystem Constructor";
107  const char* szName = "number of parameters";
108  SimTK_THROW5(SimTK::Exception::ValueOutOfRange, szName, 1, nParameters, INT_MAX, where);
109  } else {
110  numParameters = nParameters;
111  }
112  }
114  void setNumEqualityConstraints( const int n ) {
115  if( n < 0 ) {
116  const char* where = " OptimizerSystem setNumEqualityConstraints";
117  const char* szName = "number of equality constraints";
119  } else {
120  numEqualityConstraints = n;
121  }
122  }
124  void setNumInequalityConstraints( const int n ) {
125  if( n < 0 ) {
126  const char* where = " OptimizerSystem setNumInequalityConstraints";
127  const char* szName = "number of inequality constraints";
129  } else {
130  numInequalityConstraints = n;
131  }
132  }
134  void setNumLinearEqualityConstraints( const int n ) {
135  if( n < 0 || n > numEqualityConstraints ) {
136  const char* where = " OptimizerSystem setNumLinearEqualityConstraints";
137  const char* szName = "number of linear equality constraints";
138  SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numEqualityConstraints, where);
139  } else {
140  numLinearEqualityConstraints = n;
141  }
142  }
144  void setNumLinearInequalityConstraints( const int n ) {
145  if( n < 0 || n > numInequalityConstraints ) {
146  const char* where = " OptimizerSystem setNumLinearInequalityConstraints";
147  const char* szName = "number of linear inequality constraints";
148  SimTK_THROW4(SimTK::Exception::SizeOutOfRange, szName, n, numInequalityConstraints, where);
149  } else {
150  numLinearInequalityConstraints = n;
151  }
152  }
154  void setParameterLimits( const Vector& lower, const Vector& upper ) {
155  if( upper.size() != numParameters && upper.size() != 0) {
156  const char* where = " OptimizerSystem setParamtersLimits";
157  const char* szName = "upper limits length";
158  SimTK_THROW5(Exception::IncorrectArrayLength, szName, upper.size(), "numParameters", numParameters, where);
159  }
160  if( lower.size() != numParameters && lower.size() != 0 ) {
161  const char* where = " OptimizerSystem setParamtersLimits";
162  const char* szName = "lower limits length";
163  SimTK_THROW5(Exception::IncorrectArrayLength, szName, lower.size(), "numParameters", numParameters, where);
164  }
165 
166  // set the upper and lower limits
167  if( useLimits ) {
168  delete lowerLimits;
169  delete upperLimits;
170  }
171 
172  if( upper.size() == 0 ) {
173  useLimits = false;
174  } else {
175  lowerLimits = new Vector( lower );
176  upperLimits = new Vector( upper );
177  useLimits = true;
178  }
179  }
180 
183  int getNumParameters() const {return numParameters;}
185  int getNumConstraints() const {return numEqualityConstraints+numInequalityConstraints;}
187  int getNumEqualityConstraints() const {return numEqualityConstraints;}
189  int getNumInequalityConstraints() const {return numInequalityConstraints;}
191  int getNumLinearEqualityConstraints() const {return numLinearEqualityConstraints;}
193  int getNumNonlinearEqualityConstraints() const {return numEqualityConstraints-numLinearEqualityConstraints;}
195  int getNumLinearInequalityConstraints() const {return numLinearInequalityConstraints;}
197  int getNumNonlinearInequalityConstraints() const {return numInequalityConstraints-numLinearInequalityConstraints;}
198 
200  bool getHasLimits() const { return useLimits; }
204  void getParameterLimits( Real **lower, Real **upper ) const {
205  *lower = &(*lowerLimits)[0];
206  *upper = &(*upperLimits)[0];
207  }
208 
209 private:
210  int numParameters;
211  int numEqualityConstraints;
212  int numInequalityConstraints;
213  int numLinearEqualityConstraints;
214  int numLinearInequalityConstraints;
215  bool useLimits;
216  Vector* lowerLimits;
217  Vector* upperLimits;
218 
219 }; // class OptimizerSystem
220 
242 public:
243  Optimizer();
244  Optimizer( const OptimizerSystem& sys);
245  Optimizer( const OptimizerSystem& sys, OptimizerAlgorithm algorithm);
246  ~Optimizer();
247 
248  static bool isAlgorithmAvailable(OptimizerAlgorithm algorithm);
249 
251  void setConvergenceTolerance(Real accuracy );
254  void setConstraintTolerance(Real tolerance);
255 
256 
262  void setMaxIterations( int iter );
265  void setLimitedMemoryHistory( int history );
267  void setDiagnosticsLevel( int level );
268 
269  void setOptimizerSystem( const OptimizerSystem& sys );
270  void setOptimizerSystem( const OptimizerSystem& sys, OptimizerAlgorithm algorithm );
271 
273  bool setAdvancedStrOption( const char *option, const char *value );
275  bool setAdvancedRealOption( const char *option, const Real value );
277  bool setAdvancedIntOption( const char *option, const int value );
279  bool setAdvancedBoolOption( const char *option, const bool value );
280 
281 
291  void setDifferentiatorMethod(Differentiator::Method method);
296  Differentiator::Method getDifferentiatorMethod() const;
297 
302  OptimizerAlgorithm getAlgorithm() const;
303 
315  void useNumericalGradient(bool flag,
316  Real estimatedAccuracyOfObjective = SignificantReal);
329  void useNumericalJacobian(bool flag,
330  Real estimatedAccuracyOfConstraints = SignificantReal);
331 
333  Real optimize(Vector&);
334 
336  const OptimizerSystem& getOptimizerSystem() const;
337 
339  bool isUsingNumericalGradient() const;
341  bool isUsingNumericalJacobian() const;
343  Real getEstimatedAccuracyOfObjective() const;
345  Real getEstimatedAccuracyOfConstraints() const;
346 
347  // This is a local class.
348  class OptimizerRep;
349 private:
350  Optimizer( const Optimizer& c );
351  Optimizer& operator=(const Optimizer& rhs);
352 
353  OptimizerRep* constructOptimizerRep(const OptimizerSystem&, OptimizerAlgorithm);
354  const OptimizerRep& getRep() const {assert(rep); return *rep;}
355  OptimizerRep& updRep() {assert(rep); return *rep;}
356 
357  // Hidden implementation to preserve binary compatibility.
358  OptimizerRep* rep;
359 
360 friend class OptimizerRep;
361 }; // class Optimizer
362 
363 } // namespace SimTK
364 
365 #endif //SimTK_SIMMATH_OPTIMIZER_H_
366