1#ifndef SimTK_SimTKCOMMON_FUNCTION_H_
2#define SimTK_SimTKCOMMON_FUNCTION_H_
149 : argumentSize(argumentSize), value(value) {
152 assert(x.
size() == argumentSize);
157 return static_cast<T
>(0);
163 return std::numeric_limits<int>::max();
197 : coefficients(coefficients) {
200 assert(x.
size() == coefficients.size()-1);
201 T value =
static_cast<T
>(0);
202 for (
int i = 0; i < x.
size(); ++i)
203 value += x[i]*coefficients[i];
204 value += coefficients[x.
size()];
209 assert(x.
size() == coefficients.size()-1);
210 assert(derivComponents.size() > 0);
211 if (derivComponents.size() == 1)
212 return coefficients[derivComponents[0]];
213 return static_cast<T
>(0);
216 return coefficients.size()-1;
219 return std::numeric_limits<int>::max();
248 : coefficients(coefficients) {
251 assert(x.
size() == 1);
253 T value =
static_cast<T
>(0);
254 for (
int i = 0; i < coefficients.size(); ++i)
255 value = value*arg + coefficients[i];
260 assert(x.
size() == 1);
261 assert(derivComponents.size() > 0);
263 T value =
static_cast<T
>(0);
264 const int derivOrder = (int)derivComponents.
size();
265 const int polyOrder = coefficients.size()-1;
266 for (
int i = 0; i <= polyOrder-derivOrder; ++i) {
267 T coeff = coefficients[i];
268 for (
int j = 0; j < derivOrder; ++j)
269 coeff *= polyOrder-i-j;
270 value = value*arg + coeff;
278 return std::numeric_limits<int>::max();
310 Sinusoid(
double amplitude,
double frequency,
double phase=0)
311 : a(amplitude), w(frequency), p(phase) {}
326 const double t = x[0];
331 const std::vector<int>& derivComponents,
334 const double t = x[0];
335 const int order = derivComponents.
size();
341 case 0:
return a*
std::sin(w*t + p);
342 case 1:
return a*w*
std::cos(w*t + p);
343 case 2:
return -a*w*w*
std::sin(w*t + p);
344 case 3:
return -a*w*w*w*
std::cos(w*t + p);
346 const double sign = double(((order/2) & 0x1) ? -1 : 1);
348 const double wn =
std::pow(w, order);
355 return std::numeric_limits<int>::max();
396 Step(
const T& y0,
const T& y1,
double x0,
double x1)
397 : m_y0(y0), m_y1(y1), m_yr(y1-y0), m_zero(double(0)*y0),
398 m_x0(x0), m_x1(x1), m_ooxr(1/(x1-x0)), m_sign(copysign(1,m_ooxr))
405 std::printf(
"Function_<T>::Step::ctor():"
406 "A zero-length switching interval "
407 "is illegal; both ends were %g.", x0);
417 assert(xin.
size() == 1);
418 std::printf(
"Function_<T>::Step::calcValue() "
419 "Expected just one input argument but got %d.",
423 const double x = xin[0];
424 if ((x-m_x0)*m_sign <= 0)
return m_y0;
425 if ((x-m_x1)*m_sign >= 0)
return m_y1;
427 const double f = step01(m_x0,m_ooxr, x);
428 return m_y0 + f*m_yr;
438 assert(xin.
size() == 1);
439 std::printf(
"Function_<T>::Step::calcDerivative() "
440 "Expected just one input argument but got %d.",
443 const int derivOrder = (int)derivComponents.size();
451 assert(1 <= derivOrder && derivOrder <= 3);
452 std::printf(
"Function_<T>::Step::calcDerivative() "
453 "Only 1st, 2nd, and 3rd derivatives of the step are available,"
454 " but derivative %d was requested.", derivOrder);
456 const double x = xin[0];
457 if ((x-m_x0)*m_sign <= 0)
return m_zero;
458 if ((x-m_x1)*m_sign >= 0)
return m_zero;
460 case 1:
return dstep01(m_x0,m_ooxr, x) * m_yr;
461 case 2:
return d2step01(m_x0,m_ooxr, x) * m_yr;
462 case 3:
return d3step01(m_x0,m_ooxr, x) * m_yr;
463 default: assert(!
"impossible derivOrder");
484 double step01(
double x0,
double x1,
double x){
485 double u = (x-x0)/(x1-x0);
488 return (3*u2 - 2*u3);
491 double dstep01(
double x0,
double x1,
double x){
492 double u = (x-x0)/(x1-x0);
493 double du = (1)/(x1-x0);
495 double du3 = 3*u*u*du;
496 return (3*du2 - 2*du3);
500 double u = (x-x0)/(x1-x0);
501 double du = (1)/(x1-x0);
503 double ddu2 = 2*du*du;
504 double ddu3 = 3*du*u*du + 3*u*du*du;
505 return (3*ddu2 - 2*ddu3);
509 double u = (x-x0)/(x1-x0);
510 double du = (1)/(x1-x0);
514 double dddu3 = 3*du*du*du + 3*du*du*du;
515 return (3*dddu2 - 2*dddu3);
unsigned int size() const
Constant(T value, int argumentSize=1)
virtual int getArgumentSize() const
T calcDerivative(const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const
T calcValue(const RigidBodyDynamics::Math::VectorNd &x) const
int getMaxDerivativeOrder() const
const RigidBodyDynamics::Math::VectorNd coefficients
Linear(const RigidBodyDynamics::Math::VectorNd &coefficients)
virtual int getArgumentSize() const
T calcDerivative(const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const
T calcValue(const RigidBodyDynamics::Math::VectorNd &x) const
int getMaxDerivativeOrder() const
const RigidBodyDynamics::Math::VectorNd coefficients
virtual int getArgumentSize() const
T calcDerivative(const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const
T calcValue(const RigidBodyDynamics::Math::VectorNd &x) const
Polynomial(const RigidBodyDynamics::Math::VectorNd &coefficients)
int getMaxDerivativeOrder() const
virtual int getMaxDerivativeOrder() const
void setFrequency(double frequency)
double getFrequency() const
void setPhase(double phase)
Sinusoid(double amplitude, double frequency, double phase=0)
virtual int getArgumentSize() const
virtual double calcDerivative(const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const
double getAmplitude() const
virtual double calcValue(const RigidBodyDynamics::Math::VectorNd &x) const
void setAmplitude(double amplitude)
double step01(double x0, double x1, double x)
double dstep01(double x0, double x1, double x)
double d2step01(double x0, double x1, double x)
virtual int getArgumentSize() const
T calcValue(const RigidBodyDynamics::Math::VectorNd &xin) const
double d3step01(double x0, double x1, double x)
T calcDerivative(const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &xin) const
Step(const T &y0, const T &y1, double x0, double x1)
int getMaxDerivativeOrder() const
virtual T calcValue(const RigidBodyDynamics::Math::VectorNd &x) const =0
virtual int getArgumentSize() const =0
virtual T calcDerivative(const std::vector< int > &derivComponents, const RigidBodyDynamics::Math::VectorNd &x) const =0
virtual int getMaxDerivativeOrder() const =0
Function_< double > Function
MX_Xd_static< nrows, ncols > pow(const MX_Xd_static< nrows, ncols > &m, int exponent)
MX_Xd_scalar cos(const MX_Xd_scalar &x)
MX_Xd_scalar sin(const MX_Xd_scalar &x)