Function.h
Go to the documentation of this file.00001 #ifndef SimTK_SIMMATH_FUNCTION_H_
00002 #define SimTK_SIMMATH_FUNCTION_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
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "SimTKcommon.h"
00036
00037 namespace SimTK {
00038
00051 template <class T>
00052 class Function_ {
00053 public:
00054 class Constant;
00055 class Linear;
00056 class Polynomial;
00057 virtual ~Function_() {
00058 }
00064 virtual T calcValue(const Vector& x) const = 0;
00076 virtual T calcDerivative(const std::vector<int>& derivComponents, const Vector& x) const = 0;
00080 virtual int getArgumentSize() const = 0;
00084 virtual int getMaxDerivativeOrder() const = 0;
00085 };
00086
00087 typedef Function_<Real> Function;
00088
00093 template <class T>
00094 class Function_<T>::Constant : public Function_<T> {
00095 public:
00102 Constant(T value, int argumentSize) : value(value), argumentSize(argumentSize) {
00103 }
00104 T calcValue(const Vector& x) const {
00105 assert(x.size() == argumentSize);
00106 return value;
00107 }
00108 T calcDerivative(const std::vector<int>& derivComponents, const Vector& x) const {
00109 return static_cast<T>(0);
00110 }
00111 virtual int getArgumentSize() const {
00112 return argumentSize;
00113 }
00114 int getMaxDerivativeOrder() const {
00115 return std::numeric_limits<int>::max();
00116 }
00117 private:
00118 const int argumentSize;
00119 const T value;
00120 };
00121
00127 template <class T>
00128 class Function_<T>::Linear : public Function_<T> {
00129 public:
00138 explicit Linear(const Vector_<T>& coefficients) : coefficients(coefficients) {
00139 }
00140 T calcValue(const Vector& x) const {
00141 assert(x.size() == coefficients.size()-1);
00142 T value = static_cast<T>(0);
00143 for (int i = 0; i < x.size(); ++i)
00144 value += x[i]*coefficients[i];
00145 value += coefficients[x.size()];
00146 return value;
00147 }
00148 T calcDerivative(const std::vector<int>& derivComponents, const Vector& x) const {
00149 assert(x.size() == coefficients.size()-1);
00150 assert(derivComponents.size() > 0);
00151 if (derivComponents.size() == 1)
00152 return coefficients(derivComponents[0]);
00153 return static_cast<T>(0);
00154 }
00155 virtual int getArgumentSize() const {
00156 return coefficients.size()-1;
00157 }
00158 int getMaxDerivativeOrder() const {
00159 return std::numeric_limits<int>::max();
00160 }
00161 private:
00162 const Vector_<T> coefficients;
00163 };
00164
00165
00171 template <class T>
00172 class Function_<T>::Polynomial : public Function_<T> {
00173 public:
00179 Polynomial(const Vector_<T>& coefficients) : coefficients(coefficients) {
00180 }
00181 T calcValue(const Vector& x) const {
00182 assert(x.size() == 1);
00183 Real arg = x[0];
00184 T value = static_cast<T>(0);
00185 for (int i = 0; i < coefficients.size(); ++i)
00186 value = value*arg + coefficients[i];
00187 return value;
00188 }
00189 T calcDerivative(const std::vector<int>& derivComponents, const Vector& x) const {
00190 assert(x.size() == 1);
00191 assert(derivComponents.size() > 0);
00192 Real arg = x[0];
00193 T value = static_cast<T>(0);
00194 const int derivOrder = (int)derivComponents.size();
00195 const int polyOrder = coefficients.size()-1;
00196 for (int i = 0; i <= polyOrder-derivOrder; ++i) {
00197 T coeff = coefficients[i];
00198 for (int j = 0; j < derivOrder; ++j)
00199 coeff *= polyOrder-i-j;
00200 value = value*arg + coeff;
00201 }
00202 return value;
00203 }
00204 virtual int getArgumentSize() const {
00205 return 1;
00206 }
00207 int getMaxDerivativeOrder() const {
00208 return std::numeric_limits<int>::max();
00209 }
00210 private:
00211 const Vector_<T> coefficients;
00212 };
00213
00214 }
00215
00216 #endif // SimTK_SIMMATH_FUNCTION_H_
00217
00218