Simbody  3.4 (development)
Differentiator.h
Go to the documentation of this file.
00001 #ifndef SimTK_DIFFERENTIATOR_H_
00002 #define SimTK_DIFFERENTIATOR_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-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
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 
00032 #include "SimTKcommon.h"
00033 #include "simmath/internal/common.h"
00034 
00035 namespace SimTK {
00036 
00037 
00077 class SimTK_SIMMATH_EXPORT Differentiator {
00078 public:
00079     // This are local classes within Differentiator; defined below.
00080     class ScalarFunction;   // ordinary scalar function of a scalar
00081     class GradientFunction; // scalar function of vector
00082     class JacobianFunction; // vector function of vector
00083     class Function;         // abstraction of the above
00084 
00085     // These are the exceptions that can be thrown by this class.
00086     class OpNotAllowedForFunctionOfThisShape;
00087     class UserFunctionThrewAnException;
00088     class UserFunctionReturnedNonzeroStatus;
00089     class UnknownMethodSpecified;
00090 
00091 
00092     enum Method {
00093         UnspecifiedMethod=0,
00094         ForwardDifference=1,
00095         CentralDifference=2
00096     };
00097     static bool        isValidMethod(Method);
00098     static const char* getMethodName(Method);
00099     static int         getMethodOrder(Method);
00100 
00101     virtual ~Differentiator();
00102     explicit Differentiator(const Function& f, 
00103                             Method          defaultMethod=UnspecifiedMethod);
00104 
00105     // You can change the default method; normally it is ForwardDifference.
00106     // If you set it to 'UnspecifiedMethod' it goes back to the original default.
00107     Differentiator& setDefaultMethod(Method);
00108     Method          getDefaultMethod() const;
00109 
00110     // These are the real routines, which are efficient and flexible
00111     // but somewhat messy to use.
00112     void calcDerivative(Real y0, Real fy0, Real& dfdy, 
00113                         Method=UnspecifiedMethod) const;
00114     void calcGradient  (const Vector& y0, Real fy0, Vector& gf,
00115                         Method=UnspecifiedMethod) const;
00116     void calcJacobian  (const Vector& y0, const Vector& fy0, Matrix& dfdy,
00117                         Method=UnspecifiedMethod) const;
00118 
00119     // These provide a simpler though less efficient interface. They will
00120     // do some heap allocation, and will make an initial unperturbed call
00121     // to the user function.
00122     Real   calcDerivative(Real          y0, Method=UnspecifiedMethod) const;
00123     Vector calcGradient  (const Vector& y0, Method=UnspecifiedMethod) const;
00124     Matrix calcJacobian  (const Vector& y0, Method=UnspecifiedMethod) const;
00125 
00126     // Statistics (mutable)
00127     void resetAllStatistics();                 // reset all stats to zero
00128     int getNumDifferentiations() const;        // total # calls of calcWhatever
00129     int getNumDifferentiationFailures() const; // # of those that failed
00130     int getNumCallsToUserFunction() const;     // total # calls to user function
00131 
00132     // This is a local class.
00133     class DifferentiatorRep;
00134 private:
00135     // opaque implementation for binary compatibility
00136     DifferentiatorRep* rep;
00137 };
00138 
00152 class SimTK_SIMMATH_EXPORT Differentiator::Function {
00153 public:
00154     Function& setNumFunctions(int);
00155     Function& setNumParameters(int);
00156     Function& setEstimatedAccuracy(Real);
00157 
00158     // These values are fixed after construction.
00159     int  getNumFunctions()  const;
00160     int  getNumParameters() const;
00161     Real getEstimatedAccuracy() const; // approx. "roundoff" in f calculation
00162 
00163     // Statistics (mutable)
00164     void resetAllStatistics();
00165     int getNumCalls()    const; // # evaluations of this function since reset
00166     int getNumFailures() const; // # of calls which failed
00167 
00168     // This is the declaration of a local class name.
00169     class FunctionRep;
00170 protected:
00171     Function();
00172     ~Function();
00173 
00174     // opaque implementation for binary compatibility
00175     FunctionRep* rep;
00176 
00177 private:
00178     // suppress copy constructor and copy assignment
00179     Function(const Function&);
00180     Function& operator=(const Function&);
00181 
00182 friend class Differentiator;
00183 };
00184 
00189 class SimTK_SIMMATH_EXPORT Differentiator::ScalarFunction : public Differentiator::Function {
00190 public:
00191     virtual int f(Real x, Real& fx) const=0;
00192 
00193 protected:
00194     explicit ScalarFunction(Real acc=-1);
00195     virtual ~ScalarFunction() { }
00196 
00197 private:
00198     // suppress copy constructor and copy assignment
00199     ScalarFunction(const Function&);
00200     ScalarFunction& operator=(const Function&);
00201 };
00202 
00208 class SimTK_SIMMATH_EXPORT Differentiator::GradientFunction : public Differentiator::Function {
00209 public:
00210     virtual int f(const Vector& y, Real& fy) const=0;
00211 
00212 protected:
00213     explicit GradientFunction(int ny=-1, Real acc=-1);
00214     virtual ~GradientFunction() { }
00215 
00216 private:
00217     // suppress copy constructor and copy assignment
00218     GradientFunction(const GradientFunction&);
00219     GradientFunction& operator=(const GradientFunction&);
00220 };
00221 
00227 class SimTK_SIMMATH_EXPORT Differentiator::JacobianFunction : public Differentiator::Function {
00228 public:
00229     virtual int f(const Vector& y, Vector& fy) const=0;
00230 
00231 protected:
00232     explicit JacobianFunction(int nf=-1, int ny=-1, Real acc=-1); 
00233     virtual ~JacobianFunction() { }
00234 
00235 private:
00236     // suppress copy constructor and copy assignment
00237     JacobianFunction(const JacobianFunction&);
00238     JacobianFunction& operator=(const JacobianFunction&);
00239 };
00240 
00241 } // namespace SimTK
00242 
00243 #endif // SimTK_DIFFERENTIATOR_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines