20#ifndef PIECEWISE_POLYNOM
21#define PIECEWISE_POLYNOM
23#include "fmatvec/fmatvec.h"
24#include "mbsim/functions/function.h"
25#include "mbsim/utils/utils.h"
26#include "mbsim/utils/eps.h"
27#include "mbsim/mbsim_event.h"
62 template<
typename Ret,
typename Arg>
65 using B = fmatvec::Function<Ret(Arg)>;
68 enum InterpolationMethod {
75 enum ExtrapolationMethod {
81 PiecewisePolynomFunction() : index(0), interpolationMethod(cSplineNatural), extrapolationMethod(error), f(
this), fd(
this), fdd(
this) { }
84 int getArgSize()
const {
return 1; }
86 std::pair<int, int> getRetSize()
const {
return std::make_pair(coefs[0].cols(),1); }
89 Function<Ret(Arg)>::init(stage, config);
91 if(interpolationMethod!=useBreaksAndCoefs) {
92 if(y.rows() != x.size())
93 this->throwError(
"Dimension missmatch in size of x");
94 for(
int i=1; i<x.size(); i++)
96 this->throwError(
"Values of x must be strictly monotonic increasing!");
100 for(
int i=1; i<breaks.size(); i++)
101 if(breaks(i) < breaks(i-1))
102 this->throwError(
"Values of breaks must be monotonic increasing!");
103 for(
int j=0; j<static_cast<int>(coefs.size()); j++) {
104 if(coefs[j].rows()!=breaks.size()-1)
105 this->throwError(
"Dimension missmatch in size of breaks and rows of coefficients!");
106 if(coefs[0].cols()!=coefs[j].cols())
107 this->throwError(
"Dimension missmatch in columns of coefficients!");
111 std::set<int> removeIdx;
112 for(
int i=0; i<breaks.size()-1; ++i)
113 if(breaks(i)==breaks(i+1))
114 removeIdx.emplace(i);
115 if(!removeIdx.empty()) {
116 auto breaksOld(std::move(breaks));
117 auto coefsOld(std::move(coefs));
118 breaks.resize(breaksOld.size()-removeIdx.size());
119 coefs.resize(coefsOld.size());
121 c.resize(coefsOld[0].rows()-removeIdx.size(),coefsOld[0].cols());
123 for(i=0; i<breaksOld.size()-1; ++i) {
124 if(removeIdx.find(i)!=removeIdx.end())
126 breaks(ii)=breaksOld(i);
127 for(
int o=0; o<static_cast<int>(coefs.size()); o++)
128 coefs[o].set(ii,coefsOld[o].row(i));
131 breaks(ii)=breaksOld(i);
135 nPoly = (coefs[0]).rows();
136 order = coefs.size()-1;
140 void calculateSpline() {
141 if(interpolationMethod == cSplinePeriodic) calculateSplinePeriodic();
142 else if(interpolationMethod == cSplineNatural) calculateSplineNatural();
143 else if(interpolationMethod == piecewiseLinear) calculatePLinear();
144 else this->throwError(
"(PiecewisePolynomFunction::init): No valid method to calculate pp-form");
155 Ret operator()(
const Arg &x) {
return f(ToDouble<Arg>::cast(x)); }
159 typename fmatvec::Der<Ret, Arg>::type parDer(
const Arg &x) {
return fd(ToDouble<Arg>::cast(x)); }
160 typename fmatvec::Der<Ret, Arg>::type parDerDirDer(
const Arg &argDir,
const Arg &arg) {
return fdd(ToDouble<Arg>::cast(arg))*ToDouble<Arg>::cast(argDir); }
179 void setExtrapolationMethod(ExtrapolationMethod method_) { extrapolationMethod = method_; }
181 void setx(
const fmatvec::VecV &x_) { x <<= x_; }
182 void sety(
const fmatvec::MatV &y_) { y <<= y_; }
183 void setxy(
const fmatvec::MatV &xy) {
185 this->throwError(
"Dimension missmatch in size of xy");
187 y <<= xy(fmatvec::RangeV(0, xy.rows() - 1), fmatvec::RangeV(1, xy.cols() - 1));
196 void addCoefficients(
const fmatvec::MatV &coef);
203 interpolationMethod=useBreaksAndCoefs;
247 ExtrapolationMethod extrapolationMethod;
270 void calculatePLinear();
276 class ZerothDerivative {
278 ZerothDerivative(
PiecewisePolynomFunction<Ret(Arg)> *polynom) : parent(polynom), xSave(0), ySave(), firstCall(
true) {}
280 void reset() { firstCall =
true; }
282 Ret operator()(
const double &x);
294 class FirstDerivative {
296 FirstDerivative(
PiecewisePolynomFunction<Ret(Arg)> *polynom) : parent(polynom), xSave(0), ySave(), firstCall(
true) {}
298 void reset() { firstCall =
true; }
300 Ret operator()(
const double& x);
312 class SecondDerivative {
314 SecondDerivative(
PiecewisePolynomFunction<Ret(Arg)> *polynom) : parent(polynom), xSave(0), ySave(), firstCall(
true) {}
316 void reset() { firstCall =
true; }
318 Ret operator()(
const double& x);
331 SecondDerivative fdd;
335 #include "piecewise_polynom_function_impl.h"
InitStage
The stages of the initialization.
Definition: element.h:62
@ preInit
Definition: element.h:64
Definition: function.h:53
void setBreaks(const fmatvec::VecV &breaks_u)
set interval boundaries
Definition: piecewise_polynom_function.h:202
void calculateSplinePeriodic()
calculation of periodic spline by interpolation
fmatvec::VecV getBreaks()
Definition: piecewise_polynom_function.h:165
fmatvec::VecV breaks
vector of breaks (interval boundaries)
Definition: piecewise_polynom_function.h:222
std::vector< fmatvec::MatV > coefs
vector of polynomial coefficents
Definition: piecewise_polynom_function.h:217
void calculateSplineNatural()
calculation of natural spline by interpolation
void setCoefficientsArray(const std::vector< fmatvec::MatV > &allCoefs)
set polynomial coefficients
int nPoly
number of defined piecewise polynomials
Definition: piecewise_polynom_function.h:227
int index
for internal use in ppeval functions
Definition: piecewise_polynom_function.h:237
int order
order of polynomial (3 for cubic polynomials)
Definition: piecewise_polynom_function.h:232
void init(Element::InitStage stage, const InitConfigSet &config=InitConfigSet())
plots time series header
Definition: piecewise_polynom_function.h:88
InterpolationMethod interpolationMethod
interpolation interpolationMethod
Definition: piecewise_polynom_function.h:245
void setInterpolationMethod(InterpolationMethod method_)
set interpolation
Definition: piecewise_polynom_function.h:177
virtual void initializeUsingXML(xercesc::DOMElement *element)
initialize function with XML code
Definition: piecewise_polynom_function.h:31
namespace MBSim
Definition: bilateral_constraint.cc:30