Differentiator.h

Go to the documentation of this file.
00001 #ifndef SimTK_DIFFERENTIATOR_H_
00002 #define SimTK_DIFFERENTIATOR_H_
00003 
00004 /* Portions copyright (c) 2006 Stanford University and Michael Sherman.
00005  * Contributors:
00006  * 
00007  * Permission is hereby granted, free of charge, to any person obtaining
00008  * a copy of this software and associated documentation files (the
00009  * "Software"), to deal in the Software without restriction, including 
00010  * without limitation the rights to use, copy, modify, merge, publish, 
00011  * distribute, sublicense, and/or sell copies of the Software, and to
00012  * permit persons to whom the Software is furnished to do so, subject
00013  * to the following conditions:
00014  * 
00015  * The above copyright notice and this permission notice shall be included 
00016  * in all copies or substantial portions of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00021  * IN NO EVENT SHALL THE AUTHORS, COPYRIGHT HOLDERS, OR CONTRIBUTORS BE
00022  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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     // This are local classes within Differentiator; defined below.
00052     class ScalarFunction;   // ordinary scalar function of a scalar
00053     class GradientFunction; // scalar function of vector
00054     class JacobianFunction; // vector function of vector
00055     class Function;         // abstraction of the above
00056 
00057     // These are the exceptions that can be thrown by this class.
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     // You can change the default method; normally it is ForwardDifference.
00078     // If you set it to 'UnspecifiedMethod' it goes back to the original default.
00079     Differentiator& setDefaultMethod(Method);
00080     Method          getDefaultMethod() const;
00081 
00082     // These are the real routines, which are efficient and flexible
00083     // but somewhat messy to use.
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     // These provide a simpler though less efficient interface. They will
00092     // do some heap allocation, and will make an initial unperturbed call
00093     // to the user function.
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     // Statistics (mutable)
00099     void resetAllStatistics();                // reset all stats to zero
00100     long getNDifferentiations() const;        // total # calls of calcWhatever
00101     long getNDifferentiationFailures() const; // # of those that failed
00102     long getNCallsToUserFunction() const;     // total # calls to user function
00103     
00104     class FunctionRep;
00105 private:
00106     // opaque implementation for binary compatibility
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     // These values are fixed after construction.
00131     int  getNFunctions()  const;
00132     int  getNParameters() const;
00133     Real getEstimatedAccuracy() const; // approx. "roundoff" in f calculation
00134 
00135     // Statistics (mutable)
00136     void resetAllStatistics();
00137     long getNCalls()    const; // # evaluations of this function since reset
00138     long getNFailures() const; // # of calls which failed
00139 
00140 protected:
00141     Function();
00142     ~Function();
00143 
00144     // opaque implementation for binary compatibility
00145     Differentiator::FunctionRep* rep;
00146 
00147 private:
00148     // suppress copy constructor and copy assignment
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     // must be inline for binary compatibility
00166     inline explicit ScalarFunction(Real acc=-1);
00167     virtual ~ScalarFunction() { }
00168 
00169 private:
00170     void librarySideConstruction(Real acc);
00171     void registerFunction(FuncWrapper);
00172 
00173     // suppress copy constructor and copy assignment
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     // must be inline for binary compatibility
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     // suppress copy constructor and copy assignment
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     // must be inline for binary compatibility
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     // suppress copy constructor and copy assignment
00222     JacobianFunction(const JacobianFunction&);
00223     JacobianFunction& operator=(const JacobianFunction&);
00224 };
00225 
00226 
00227 // These are used to supply the client-side virtual function to the library, without
00228 // the client and library having to agree on the layout of the virtual function tables.
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 } // namespace SimTK
00260 
00261 #endif // SimTK_DIFFERENTIATOR_H_

Generated on Fri Sep 26 07:44:10 2008 for SimTKcore by  doxygen 1.5.6