1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
#ifndef SimTK_SIMMATH_OPTIMIZER_REP_H_
#define SimTK_SIMMATH_OPTIMIZER_REP_H_
/* -------------------------------------------------------------------------- *
* Simbody(tm): SimTKmath *
* -------------------------------------------------------------------------- *
* This is part of the SimTK biosimulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
* *
* Portions copyright (c) 2006-13 Stanford University and the Authors. *
* Authors: Jack Middleton *
* Contributors: Michael Sherman *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain a *
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* -------------------------------------------------------------------------- */
#include "SimTKcommon.h"
#include "simmath/Optimizer.h"
#include "simmath/Differentiator.h"
#include <map>
namespace SimTK {
/* class for Diff jacobian */
class SysObjectiveFunc : public Differentiator::GradientFunction {
public:
SysObjectiveFunc(int ny, const OptimizerSystem* sysPtr )
: Differentiator::GradientFunction(ny) { sysp = sysPtr; }
// Must provide this pure virtual function.
int f(const Vector& y, Real& fy) const override {
return(sysp->objectiveFunc(y, true, fy)); // class user's objectiveFunc
}
const OptimizerSystem* sysp;
};
/* class for Diff gradient */
class SysConstraintFunc : public Differentiator::JacobianFunction {
public:
SysConstraintFunc(int nf, int ny, const OptimizerSystem* sysPtr)
: Differentiator::JacobianFunction(nf,ny) { sysp = sysPtr; }
// Must provide this pure virtual function.
int f(const Vector& y, Vector& fy) const override {
return(sysp->constraintFunc(y, true, fy)); // calls user's contraintFunc
}
const OptimizerSystem* sysp;
};
class SimTK_SIMMATH_EXPORT Optimizer::OptimizerRep {
public:
virtual ~OptimizerRep();
OptimizerRep(const OptimizerSystem& sys)
: sysp(&sys),
myHandle(0),
cf(0),
of(0),
jacDiff(0),
gradDiff(0),
convergenceTolerance(Real(1e-3)),
constraintTolerance(Real(1e-4)),
maxIterations(1000),
limitedMemoryHistory(50),
diagnosticsLevel(0),
diffMethod(Differentiator::CentralDifference),
objectiveEstimatedAccuracy(SignificantReal),
constraintsEstimatedAccuracy(SignificantReal),
numericalGradient(false),
numericalJacobian(false)
{
}
OptimizerRep()
: sysp(0),
myHandle(0),
cf(0),
of(0),
jacDiff(0),
gradDiff(0),
convergenceTolerance(Real(1e-3)),
constraintTolerance(Real(1e-4)),
maxIterations(1000),
limitedMemoryHistory(50),
diagnosticsLevel(0),
diffMethod(Differentiator::CentralDifference),
objectiveEstimatedAccuracy(SignificantReal),
constraintsEstimatedAccuracy(SignificantReal),
numericalGradient(false),
numericalJacobian(false)
{
}
virtual OptimizerRep* clone() const { return 0; };
static bool isAvailable() { return true; }
virtual Real optimize( Vector &results ) = 0;
const OptimizerSystem& getOptimizerSystem() const {return *sysp;}
void setDiagnosticsLevel( const int level );
void setConvergenceTolerance( Real accuracy );
void setConstraintTolerance( Real tolerance );
void setMaxIterations( const int iter );
void setLimitedMemoryHistory( const int history );
bool setAdvancedStrOption( const std::string &option, const std::string &value );
bool setAdvancedRealOption( const std::string &option, const Real value );
bool setAdvancedIntOption( const std::string &option, const int value );
bool setAdvancedBoolOption( const std::string &option, const bool value );
bool setAdvancedVectorOption( const std::string &option, const Vector value );
bool getAdvancedStrOption( const std::string &option, std::string &value ) const;
bool getAdvancedRealOption( const std::string &option, Real &value ) const;
bool getAdvancedIntOption( const std::string &option, int &value ) const;
bool getAdvancedBoolOption( const std::string &option, bool &value ) const;
bool getAdvancedVectorOption( const std::string &option, Vector &value ) const;
void setMyHandle(Optimizer& cp) {myHandle = &cp;}
const Optimizer& getMyHandle() const {assert(myHandle); return *myHandle;}
void clearMyHandle() {myHandle=0;}
void useNumericalGradient(bool flag, Real objEstAccuracy);
void useNumericalJacobian(bool flag, Real consEstAccuracy);
void setDifferentiatorMethod( Differentiator::Method method);
bool isUsingNumericalGradient() const { return numericalGradient; }
bool isUsingNumericalJacobian() const { return numericalJacobian; }
Differentiator::Method getDifferentiatorMethod() const {return diffMethod;}
Real getEstimatedAccuracyOfObjective() const
{ return objectiveEstimatedAccuracy; }
Real getEstimatedAccuracyOfConstraints() const
{ return constraintsEstimatedAccuracy; }
const Differentiator& getGradientDifferentiator() const {
assert(gradDiff);
return *gradDiff;
}
const Differentiator& getJacobianDifferentiator() const {
assert(jacDiff);
return *jacDiff;
}
virtual OptimizerAlgorithm getAlgorithm() const {
return UnknownOptimizerAlgorithm;
}
static int numericalGradient_static( const OptimizerSystem&, const Vector & parameters, const bool new_parameters, Vector &gradient );
static int numericalJacobian_static(const OptimizerSystem&,
const Vector& parameters, const bool new_parameters, Matrix& jacobian );
protected:
// These methods are to be called by derived classes as an interface
// to the OptimizerSystem virtuals. The signature must match that required by
// IpOpt's matching callbacks. We're using the "user data" argument to pass in
// the current OptimizerRep, making these behave like non-static members.
static int objectiveFuncWrapper ( int n, const Real* x, int new_x, Real* f, void* rep);
static int gradientFuncWrapper ( int n, const Real* x, int new_x, Real* gradient, void* rep);
static int constraintFuncWrapper( int n, const Real* x, int new_x, int m, Real* g, void* rep);
static int constraintJacobianWrapper( int n, const Real* x, int new_x,int m, int nele_jac,
int* iRow, int* jCol, Real* values, void* rep);
static int hessianWrapper( int n, const Real* x, int new_x, Real obj_factor,
int m, Real* lambda, int new_lambda,
int nele_hess, int* iRow, int* jCol,
Real* values, void* rep);
int diagnosticsLevel;
Real convergenceTolerance;
Real constraintTolerance;
int maxIterations;
int limitedMemoryHistory;
Differentiator::Method diffMethod;
Real objectiveEstimatedAccuracy;
Real constraintsEstimatedAccuracy;
private:
const OptimizerSystem* sysp;
bool numericalGradient; // true if optimizer will compute an numerical gradient
bool numericalJacobian; // true if optimizer will compute an numerical Jacobian
Differentiator *gradDiff;
Differentiator *jacDiff;
SysObjectiveFunc *of;
SysConstraintFunc *cf;
std::map<std::string, std::string> advancedStrOptions;
std::map<std::string, Real> advancedRealOptions;
std::map<std::string, int> advancedIntOptions;
std::map<std::string, bool> advancedBoolOptions;
std::map<std::string, Vector> advancedVectorOptions;
friend class Optimizer;
Optimizer* myHandle; // The owner handle of this Rep.
}; // end class OptimizerRep
class DefaultOptimizer: public Optimizer::OptimizerRep {
Real optimize( Vector &results ) override;
OptimizerRep* clone() const override;
OptimizerAlgorithm getAlgorithm() const override;
};
} // namespace SimTK
#endif // SimTK_SIMMATH_OPTIMIZER_REP_H_
|