Simbody
|
00001 #ifndef SimTK_DIFFERENTIATOR_H_ 00002 #define SimTK_DIFFERENTIATOR_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simmath(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core 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. * 00011 * * 00012 * Portions copyright (c) 2006-10 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00040 #include "SimTKcommon.h" 00041 #include "simmath/internal/common.h" 00042 00043 namespace SimTK { 00044 00045 00085 class SimTK_SIMMATH_EXPORT Differentiator { 00086 public: 00087 // This are local classes within Differentiator; defined below. 00088 class ScalarFunction; // ordinary scalar function of a scalar 00089 class GradientFunction; // scalar function of vector 00090 class JacobianFunction; // vector function of vector 00091 class Function; // abstraction of the above 00092 00093 // These are the exceptions that can be thrown by this class. 00094 class OpNotAllowedForFunctionOfThisShape; 00095 class UserFunctionThrewAnException; 00096 class UserFunctionReturnedNonzeroStatus; 00097 class UnknownMethodSpecified; 00098 00099 00100 enum Method { 00101 UnspecifiedMethod=0, 00102 ForwardDifference=1, 00103 CentralDifference=2 00104 }; 00105 static bool isValidMethod(Method); 00106 static const char* getMethodName(Method); 00107 static int getMethodOrder(Method); 00108 00109 virtual ~Differentiator(); 00110 explicit Differentiator(const Function& f, 00111 Method defaultMethod=UnspecifiedMethod); 00112 00113 // You can change the default method; normally it is ForwardDifference. 00114 // If you set it to 'UnspecifiedMethod' it goes back to the original default. 00115 Differentiator& setDefaultMethod(Method); 00116 Method getDefaultMethod() const; 00117 00118 // These are the real routines, which are efficient and flexible 00119 // but somewhat messy to use. 00120 void calcDerivative(Real y0, Real fy0, Real& dfdy, 00121 Method=UnspecifiedMethod) const; 00122 void calcGradient (const Vector& y0, Real fy0, Vector& gf, 00123 Method=UnspecifiedMethod) const; 00124 void calcJacobian (const Vector& y0, const Vector& fy0, Matrix& dfdy, 00125 Method=UnspecifiedMethod) const; 00126 00127 // These provide a simpler though less efficient interface. They will 00128 // do some heap allocation, and will make an initial unperturbed call 00129 // to the user function. 00130 Real calcDerivative(Real y0, Method=UnspecifiedMethod) const; 00131 Vector calcGradient (const Vector& y0, Method=UnspecifiedMethod) const; 00132 Matrix calcJacobian (const Vector& y0, Method=UnspecifiedMethod) const; 00133 00134 // Statistics (mutable) 00135 void resetAllStatistics(); // reset all stats to zero 00136 int getNumDifferentiations() const; // total # calls of calcWhatever 00137 int getNumDifferentiationFailures() const; // # of those that failed 00138 int getNumCallsToUserFunction() const; // total # calls to user function 00139 00140 // This is a local class. 00141 class DifferentiatorRep; 00142 private: 00143 // opaque implementation for binary compatibility 00144 DifferentiatorRep* rep; 00145 00146 private: 00147 //OBSOLETE NAMES 00148 int getNDifferentiations() const {return getNumDifferentiations();} 00149 int getNDifferentiationFailures() const {return getNumDifferentiationFailures();} 00150 int getNCallsToUserFunction() const {return getNumCallsToUserFunction();} 00151 }; 00152 00166 class SimTK_SIMMATH_EXPORT Differentiator::Function { 00167 public: 00168 Function& setNumFunctions(int); 00169 Function& setNumParameters(int); 00170 Function& setEstimatedAccuracy(Real); 00171 00172 // These values are fixed after construction. 00173 int getNumFunctions() const; 00174 int getNumParameters() const; 00175 Real getEstimatedAccuracy() const; // approx. "roundoff" in f calculation 00176 00177 // Statistics (mutable) 00178 void resetAllStatistics(); 00179 int getNumCalls() const; // # evaluations of this function since reset 00180 int getNumFailures() const; // # of calls which failed 00181 00182 // This is the declaration of a local class name. 00183 class FunctionRep; 00184 protected: 00185 Function(); 00186 ~Function(); 00187 00188 // opaque implementation for binary compatibility 00189 FunctionRep* rep; 00190 00191 private: 00192 // suppress copy constructor and copy assignment 00193 Function(const Function&); 00194 Function& operator=(const Function&); 00195 00196 private: 00197 //OBSOLETE NAMES 00198 Function& setNFunctions(int n) {return setNumFunctions(n);} 00199 Function& setNParameters(int n) {return setNumParameters(n);} 00200 int getNFunctions() const {return getNumFunctions();} 00201 int getNParameters() const {return getNumParameters();} 00202 int getNCalls() const {return getNumCalls();} 00203 int getNFailures() const {return getNumFailures();} 00204 00205 00206 00207 friend class Differentiator; 00208 }; 00209 00214 class SimTK_SIMMATH_EXPORT Differentiator::ScalarFunction : public Differentiator::Function { 00215 public: 00216 virtual int f(Real x, Real& fx) const=0; 00217 00218 protected: 00219 explicit ScalarFunction(Real acc=-1); 00220 virtual ~ScalarFunction() { } 00221 00222 private: 00223 // suppress copy constructor and copy assignment 00224 ScalarFunction(const Function&); 00225 ScalarFunction& operator=(const Function&); 00226 }; 00227 00233 class SimTK_SIMMATH_EXPORT Differentiator::GradientFunction : public Differentiator::Function { 00234 public: 00235 virtual int f(const Vector& y, Real& fy) const=0; 00236 00237 protected: 00238 explicit GradientFunction(int ny=-1, Real acc=-1); 00239 virtual ~GradientFunction() { } 00240 00241 private: 00242 // suppress copy constructor and copy assignment 00243 GradientFunction(const GradientFunction&); 00244 GradientFunction& operator=(const GradientFunction&); 00245 }; 00246 00252 class SimTK_SIMMATH_EXPORT Differentiator::JacobianFunction : public Differentiator::Function { 00253 public: 00254 virtual int f(const Vector& y, Vector& fy) const=0; 00255 00256 protected: 00257 explicit JacobianFunction(int nf=-1, int ny=-1, Real acc=-1); 00258 virtual ~JacobianFunction() { } 00259 00260 private: 00261 // suppress copy constructor and copy assignment 00262 JacobianFunction(const JacobianFunction&); 00263 JacobianFunction& operator=(const JacobianFunction&); 00264 }; 00265 00266 } // namespace SimTK 00267 00268 #endif // SimTK_DIFFERENTIATOR_H_