00001 #ifndef SimTK_DIFFERENTIATOR_H_
00002 #define SimTK_DIFFERENTIATOR_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00032 #include "SimTKcommon.h"
00033 #include "internal/common.h"
00034 #include "SimTKcommon/internal/BigMatrix.h"
00035
00036 namespace SimTK {
00037
00038
00049 class SimTK_SIMMATH_EXPORT Differentiator {
00050 public:
00051
00052 class ScalarFunction;
00053 class GradientFunction;
00054 class JacobianFunction;
00055 class Function;
00056
00057
00058 class OpNotAllowedForFunctionOfThisShape;
00059 class UserFunctionThrewAnException;
00060 class UserFunctionReturnedNonzeroStatus;
00061 class UnknownMethodSpecified;
00062
00063
00064 enum Method {
00065 UnspecifiedMethod=0,
00066 ForwardDifference=1,
00067 CentralDifference=2
00068 };
00069 static bool isValidMethod(Method);
00070 static const char* getMethodName(Method);
00071 static int getMethodOrder(Method);
00072
00073 virtual ~Differentiator();
00074 explicit Differentiator(const Function& f,
00075 Method defaultMethod=UnspecifiedMethod);
00076
00077
00078
00079 Differentiator& setDefaultMethod(Method);
00080 Method getDefaultMethod() const;
00081
00082
00083
00084 void calcDerivative(Real y0, Real fy0, Real& dfdy,
00085 Method=UnspecifiedMethod) const;
00086 void calcGradient (const Vector& y0, Real fy0, Vector& gf,
00087 Method=UnspecifiedMethod) const;
00088 void calcJacobian (const Vector& y0, const Vector& fy0, Matrix& dfdy,
00089 Method=UnspecifiedMethod) const;
00090
00091
00092
00093
00094 Real calcDerivative(Real y0, Method=UnspecifiedMethod) const;
00095 Vector calcGradient (const Vector& y0, Method=UnspecifiedMethod) const;
00096 Matrix calcJacobian (const Vector& y0, Method=UnspecifiedMethod) const;
00097
00098
00099 void resetAllStatistics();
00100 long getNDifferentiations() const;
00101 long getNDifferentiationFailures() const;
00102 long getNCallsToUserFunction() const;
00103
00104 class FunctionRep;
00105 private:
00106
00107 class DifferentiatorRep* rep;
00108 friend class DifferentiatorRep;
00109 };
00110
00124 class SimTK_SIMMATH_EXPORT Differentiator::Function {
00125 public:
00126 Function& setNFunctions(int);
00127 Function& setNParameters(int);
00128 Function& setEstimatedAccuracy(Real);
00129
00130
00131 int getNFunctions() const;
00132 int getNParameters() const;
00133 Real getEstimatedAccuracy() const;
00134
00135
00136 void resetAllStatistics();
00137 long getNCalls() const;
00138 long getNFailures() const;
00139
00140 protected:
00141 Function();
00142 ~Function();
00143
00144
00145 Differentiator::FunctionRep* rep;
00146
00147 private:
00148
00149 Function(const Function&);
00150 Function& operator=(const Function&);
00151 friend class Differentiator;
00152 friend class Differentiator::FunctionRep;
00153 };
00154
00159 class SimTK_SIMMATH_EXPORT Differentiator::ScalarFunction : public Differentiator::Function {
00160 public:
00161 virtual int f(Real x, Real& fx) const=0;
00162 typedef int (*FuncWrapper)(const ScalarFunction&, Real, Real&);
00163
00164 protected:
00165
00166 inline explicit ScalarFunction(Real acc=-1);
00167 virtual ~ScalarFunction() { }
00168
00169 private:
00170 void librarySideConstruction(Real acc);
00171 void registerFunction(FuncWrapper);
00172
00173
00174 ScalarFunction(const Function&);
00175 ScalarFunction& operator=(const Function&);
00176 };
00177
00183 class SimTK_SIMMATH_EXPORT Differentiator::GradientFunction : public Differentiator::Function {
00184 public:
00185 virtual int f(const Vector& y, Real& fy) const=0;
00186 typedef int (*FuncWrapper)(const GradientFunction&, const Vector&, Real&);
00187
00188 protected:
00189
00190 inline explicit GradientFunction(int ny=-1, Real acc=-1);
00191 virtual ~GradientFunction() { }
00192
00193 private:
00194 void librarySideConstruction(int ny, Real acc);
00195 void registerFunction(FuncWrapper);
00196
00197
00198 GradientFunction(const GradientFunction&);
00199 GradientFunction& operator=(const GradientFunction&);
00200 };
00201
00207 class SimTK_SIMMATH_EXPORT Differentiator::JacobianFunction : public Differentiator::Function {
00208 public:
00209 virtual int f(const Vector& y, Vector& fy) const=0;
00210 typedef int (*FuncWrapper)(const JacobianFunction&, const Vector&, Vector&);
00211
00212 protected:
00213
00214 inline explicit JacobianFunction(int nf=-1, int ny=-1, Real acc=-1);
00215 virtual ~JacobianFunction() { }
00216
00217 private:
00218 void librarySideConstruction(int nf, int ny, Real acc);
00219 void registerFunction(FuncWrapper);
00220
00221
00222 JacobianFunction(const JacobianFunction&);
00223 JacobianFunction& operator=(const JacobianFunction&);
00224 };
00225
00226
00227
00228
00229 static int differentiatorScalarFunctionWrapper
00230 (const Differentiator::ScalarFunction& func,
00231 Real y, Real& fy) { return func.f(y,fy); }
00232
00233 inline Differentiator::ScalarFunction::ScalarFunction(Real acc)
00234 : Function() {
00235 librarySideConstruction(acc);
00236 registerFunction(differentiatorScalarFunctionWrapper);
00237 }
00238
00239 static int differentiatorGradientFunctionWrapper
00240 (const Differentiator::GradientFunction& func,
00241 const Vector& y, Real& fy) { return func.f(y,fy); }
00242
00243 inline Differentiator::GradientFunction::GradientFunction(int ny, Real acc)
00244 : Function() {
00245 librarySideConstruction(ny,acc);
00246 registerFunction(differentiatorGradientFunctionWrapper);
00247 }
00248
00249 static int differentiatorJacobianFunctionWrapper
00250 (const Differentiator::JacobianFunction& func, const Vector& y, Vector& fy)
00251 { return func.f(y,fy); }
00252
00253 inline Differentiator::JacobianFunction::JacobianFunction(int nf, int ny, Real acc)
00254 : Function() {
00255 librarySideConstruction(nf,ny,acc);
00256 registerFunction(differentiatorJacobianFunctionWrapper);
00257 }
00258
00259 }
00260
00261 #endif // SimTK_DIFFERENTIATOR_H_