47 const size_t funcSize = funcsSize();
48 funcEvalCache_.resize(funcSize);
49 for (
auto& funcEvalCacheI : funcEvalCache_)
51 funcEvalCacheI.clear();
53 arc2func_.resize(funcsArcSize());
54 for (
auto& arc2funcI : arc2func_)
58 funcEvalArcCacheIdxUnder_.resize(funcsArcSize());
60 for (
size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
62 const size_t funcISize = funcCtrlPt_[funcIdx].size();
65 for (
size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
67 funcEvalCache_[funcIdx].emplace_back(
FuncCacheData(funcCtrlPt_[funcIdx][ctrlPtIdx]));
69 arc2func_[func2Arc_[funcIdx]].emplace_back(funcIdx);
77 for (
size_t arcIdx = 0; arcIdx < funcsArcSize(); ++arcIdx)
79 for (
size_t arcKnot = 1; arcKnot < funcsArcSize(arcIdx); ++arcKnot)
81 funcsArc(arcIdx, arcKnot) = fmax(funcsArc(arcIdx, arcKnot), funcsArc(arcIdx, arcKnot - 1));
85 const double funcSize = funcCtrlPt_.size();
86 for (
size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
88 auto& funcIEvalCache = funcEvalCache_[funcIdx];
89 auto funcIEvalCacheIter = funcIEvalCache.begin();
92 const auto& endIter = funcIEvalCache.end() - 1;
94 funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]] = 0;
95 while (funcIEvalCacheIter != endIter)
97 auto& funcIEvalCacheLow = *(funcIEvalCacheIter);
98 auto& funcIEvalCacheHig = *(++funcIEvalCacheIter);
101 if (fabs(funcIEvalCacheLow.arc - funcIEvalCacheHig.arc) <= FLT_MIN)
108 (funcIEvalCacheHig.val - funcIEvalCacheLow.val) / (funcIEvalCacheHig.arc - funcIEvalCacheLow.arc);
115 funcIEvalCacheLow.cache[
asInt(
fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
120 funcIEvalCacheLow.cache[
asInt(
fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
123 ++funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]];
125 --funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]];
126 auto& funcIEvalCacheHig = *(funcIEvalCacheIter);
127 auto& funcIEvalCacheLow = *(--funcIEvalCacheIter);
139 funcIEvalCacheLow.cache[
asInt(
fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
144 funcIEvalCacheLow.cache[
asInt(
fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
155 funcsArcEval_ = fmax(fmin(_funcsArcEval, funcsArcEnd_), funcsArcBegin_);
156 const size_t& funcsArcSz = funcsArcSize();
157 switch (_evalArcGuarantee)
159 case eag::AFTER_LAST:
160 for (
size_t i = 0; i < funcsArcSz; ++i)
162 const size_t arcISize = funcCtrlPt_[i].size();
163 size_t& j = funcEvalArcCacheIdxUnder_[i];
164 while (funcsArc(i, j) < funcsArcEval_)
172 j = std::max(0, (
int)j - 1);
176 for (
size_t i = 0; i < funcsArcSz; ++i)
178 funcEvalArcCacheIdxUnder_[i] = 0;
182 for (
size_t i = 0; i < funcsArcSz; ++i)
184 funcEvalArcCacheIdxUnder_[i] = funcCtrlPt_[arc2func_[i][0]].size();
188 for (
size_t i = 0; i < funcsArcSz; ++i)
190 auto& aFuncAtArc = funcCtrlPt_[arc2func_[i][0]];
191 static double referenceArc;
193 referenceArc = funcsArcEval_;
194 funcEvalArcCacheIdxUnder_[i] =
195 std::max((
int)distance(aFuncAtArc.begin(), upper_bound(aFuncAtArc.begin(), aFuncAtArc.end(), dummy,
198 return a.
arc <= b.arc;
204 case eag::BEFORE_LAST:
205 for (
size_t i = 0; i < funcsArcSz; ++i)
207 size_t& j = funcEvalArcCacheIdxUnder_[i];
208 while (funcsArc(i, j) >= funcsArcEval_)
223 const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
229 const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
239 const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
244 const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
250 const FuncCacheData& ctrlPtLow = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
251 const double dt = _arcEnd - ctrlPtLow.
arc;
252 return ctrlPtLow.
val * dt + computeFuncDiff1(_funcIdx) * dt * dt / 2.;
256 const FuncCacheData& ctrlPtLow = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
257 const double dt = _arcEnd - ctrlPtLow.
arc;
258 const double dtdt = dt * dt;
259 return ctrlPtLow.
val * dtdt / 2. + computeFuncDiff1(_funcIdx) * dtdt * dt / 6.;
virtual double computeFuncInt2(const std::size_t &_funcIdx) const override
Computes double integral of parametric function with index _funcIdx on interval [funcsArcBegin_, funcsArcEnd_].
virtual double computeFuncDiff2(const std::size_t &_funcIdx) const override
Computes 2nd derivative of parametric function with index _funcIdx at parametric arc set by setEvalAr...
virtual void initImpl() override
Called at end of init. To be used by extended classes.
Helper function needed to upgrade c++ 2011.
function second derivative
constexpr auto asInt(Enumeration const value) -> typename std::underlying_type< Enumeration >::type
double computeFuncDeltaInt2(const std::size_t &_funcIdx, const double &_arcEnd) const
Computes the double integral integral of the parametric function _ on interval [funcEvalArcCacheIdxOl...
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
double & arc
control point arc parameter
virtual double computeFuncInt1(const std::size_t &_funcIdx) const override
Computes integral of parametric function with index _funcIdx on interval [funcsArcBegin_, funcsArcEnd_].
virtual void precompute() override
Precomputes cached data. To be called after ANY control point modifications.
void setEvalArc(const double &_funcsArcEval, const EvalArcGuarantee &_evalArcGuarantee=EvalArcGuarantee::NONE) override
Sets parametric function evaluation arc.
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
double computeFuncDeltaInt1(const std::size_t &_funcIdx, const double &_arcEnd) const
Computes the integral of the parametric function _ on interval [funcEvalArcCacheIdxOld_[func2Arc_[_fu...
virtual double computeFuncDiff1(const std::size_t &_funcIdx) const override
Computes 1st derivative of parametric function with index _funcIdx at parametric arc set by setEvalAr...
virtual double computeFuncVal(const std::size_t &_funcIdx) const override
Computes value of parametric function with index _funcIdx at parametric arc set by setEvalArc...
FuncEvalMode
Required type of computation relative to the parametric function.
std::array< TNumType, nrModesMax_ > cache
this evaluation arc is at the arc parametrization begin
this evaluation arc is at the arc parametrization end
function first derivative