param_func_spline0.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Software License Agreement (BSD License) *
3  * Copyright (C) 2016 by Horatiu George Todoran <todorangrg@gmail.com> *
4  * *
5  * Redistribution and use in source and binary forms, with or without *
6  * modification, are permitted provided that the following conditions *
7  * are met: *
8  * *
9  * 1. Redistributions of source code must retain the above copyright *
10  * notice, this list of conditions and the following disclaimer. *
11  * 2. Redistributions in binary form must reproduce the above copyright *
12  * notice, this list of conditions and the following disclaimer in *
13  * the documentation and/or other materials provided with the *
14  * distribution. *
15  * 3. Neither the name of the copyright holder nor the names of its *
16  * contributors may be used to endorse or promote products derived *
17  * from this software without specific prior written permission. *
18  * *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY *
29  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
30  * POSSIBILITY OF SUCH DAMAGE. *
31  ***************************************************************************/
32 
34 #include <tuw_control/utils.h>
35 
36 #include <float.h>
37 #include <math.h>
38 #include <algorithm>
39 #include <limits>
40 #include <vector>
41 
42 using namespace tuw;
43 using namespace std;
44 
46 {
47  const size_t funcSize = funcsSize();
48  funcEvalCache_.resize(funcSize);
49  for (auto& funcEvalCacheI : funcEvalCache_)
50  {
51  funcEvalCacheI.clear();
52  }
53  arc2func_.resize(funcsArcSize());
54  for (auto& arc2funcI : arc2func_)
55  {
56  arc2funcI.clear();
57  }
58  funcEvalArcCacheIdxUnder_.resize(funcsArcSize());
59 
60  for (size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
61  {
62  const size_t funcISize = funcCtrlPt_[funcIdx].size();
63  funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF1)] = true; // force caching of DIFF1, used by computeFuncVal
64  funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF2)] = false; // second function derivative is allways 0
65  for (size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
66  {
67  funcEvalCache_[funcIdx].emplace_back(FuncCacheData(funcCtrlPt_[funcIdx][ctrlPtIdx]));
68  }
69  arc2func_[func2Arc_[funcIdx]].emplace_back(funcIdx);
70  }
71 }
72 
74 {
75  using fem = FuncEvalMode;
76 
77  for (size_t arcIdx = 0; arcIdx < funcsArcSize(); ++arcIdx)
78  {
79  for (size_t arcKnot = 1; arcKnot < funcsArcSize(arcIdx); ++arcKnot)
80  {
81  funcsArc(arcIdx, arcKnot) = fmax(funcsArc(arcIdx, arcKnot), funcsArc(arcIdx, arcKnot - 1));
82  }
83  }
84 
85  const double funcSize = funcCtrlPt_.size();
86  for (size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
87  {
88  auto& funcIEvalCache = funcEvalCache_[funcIdx];
89  auto funcIEvalCacheIter = funcIEvalCache.begin();
90  funcIEvalCacheIter->cache[asInt(fem::INT1)] = 0;
91  funcIEvalCacheIter->cache[asInt(fem::INT2)] = 0;
92  const auto& endIter = funcIEvalCache.end() - 1;
93 
94  funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]] = 0;
95  while (funcIEvalCacheIter != endIter)
96  {
97  auto& funcIEvalCacheLow = *(funcIEvalCacheIter);
98  auto& funcIEvalCacheHig = *(++funcIEvalCacheIter);
99  if (funcEvalReq_[funcIdx][asInt(fem::DIFF1)])
100  {
101  if (fabs(funcIEvalCacheLow.arc - funcIEvalCacheHig.arc) <= FLT_MIN)
102  {
103  funcIEvalCacheLow.cache[asInt(fem::DIFF1)] = 0;
104  }
105  else
106  {
107  funcIEvalCacheLow.cache[asInt(fem::DIFF1)] =
108  (funcIEvalCacheHig.val - funcIEvalCacheLow.val) / (funcIEvalCacheHig.arc - funcIEvalCacheLow.arc);
109  }
110  }
111  funcIEvalCacheLow.cache[asInt(fem::DIFF2)] = 0;
112  if (funcEvalReq_[funcIdx][asInt(fem::INT1)])
113  {
114  funcIEvalCacheHig.cache[asInt(fem::INT1)] =
115  funcIEvalCacheLow.cache[asInt(fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
116  }
117  if (funcEvalReq_[funcIdx][asInt(fem::INT2)])
118  {
119  funcIEvalCacheHig.cache[asInt(fem::INT2)] =
120  funcIEvalCacheLow.cache[asInt(fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
121  }
122 
123  ++funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]];
124  }
125  --funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]];
126  auto& funcIEvalCacheHig = *(funcIEvalCacheIter);
127  auto& funcIEvalCacheLow = *(--funcIEvalCacheIter);
128 
129  if (funcEvalReq_[funcIdx][asInt(fem::DIFF1)])
130  {
131  funcIEvalCacheHig.cache[asInt(fem::DIFF1)] = funcIEvalCacheLow.cache[asInt(fem::DIFF1)];
132  }
133 
134  funcIEvalCacheHig.cache[asInt(fem::DIFF2)] = 0;
135 
136  if (funcEvalReq_[funcIdx][asInt(fem::INT1)])
137  {
138  funcIEvalCacheHig.cache[asInt(fem::INT1)] =
139  funcIEvalCacheLow.cache[asInt(fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
140  }
141  if (funcEvalReq_[funcIdx][asInt(fem::INT2)])
142  {
143  funcIEvalCacheHig.cache[asInt(fem::INT2)] =
144  funcIEvalCacheLow.cache[asInt(fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
145  }
146  }
147  setEvalArc(funcsArcBegin_, EvalArcGuarantee::AT_BEGIN);
148  precomputeDist();
149 }
150 
151 void ParamFuncsSpline0Dist::setEvalArc(const double& _funcsArcEval, const EvalArcGuarantee& _evalArcGuarantee)
152 {
153  using eag = EvalArcGuarantee;
154 
155  funcsArcEval_ = fmax(fmin(_funcsArcEval, funcsArcEnd_), funcsArcBegin_);
156  const size_t& funcsArcSz = funcsArcSize();
157  switch (_evalArcGuarantee)
158  {
159  case eag::AFTER_LAST:
160  for (size_t i = 0; i < funcsArcSz; ++i)
161  {
162  const size_t arcISize = funcCtrlPt_[i].size();
163  size_t& j = funcEvalArcCacheIdxUnder_[i];
164  while (funcsArc(i, j) < funcsArcEval_)
165  {
166  if (++j >= arcISize)
167  {
168  break;
169  }
170  }
171  // --j;
172  j = std::max(0, (int)j - 1);
173  }
174  break;
175  case eag::AT_BEGIN:
176  for (size_t i = 0; i < funcsArcSz; ++i)
177  {
178  funcEvalArcCacheIdxUnder_[i] = 0;
179  }
180  break;
181  case eag::AT_END:
182  for (size_t i = 0; i < funcsArcSz; ++i)
183  {
184  funcEvalArcCacheIdxUnder_[i] = funcCtrlPt_[arc2func_[i][0]].size();
185  }
186  break;
187  case eag::NONE:
188  for (size_t i = 0; i < funcsArcSz; ++i)
189  {
190  auto& aFuncAtArc = funcCtrlPt_[arc2func_[i][0]];
191  static double referenceArc;
192  static FuncCtrlPt dummy(0, referenceArc);
193  referenceArc = funcsArcEval_;
194  funcEvalArcCacheIdxUnder_[i] =
195  std::max((int)distance(aFuncAtArc.begin(), upper_bound(aFuncAtArc.begin(), aFuncAtArc.end(), dummy,
196  [](const FuncCtrlPt& a, const FuncCtrlPt& b)
197  {
198  return a.arc <= b.arc;
199  })) -
200  1,
201  0);
202  }
203  break;
204  case eag::BEFORE_LAST:
205  for (size_t i = 0; i < funcsArcSz; ++i)
206  {
207  size_t& j = funcEvalArcCacheIdxUnder_[i];
208  while (funcsArc(i, j) >= funcsArcEval_)
209  {
210  if (j == 0)
211  {
212  break;
213  }
214  --j;
215  }
216  }
217  break;
218  }
219 }
220 
221 double ParamFuncsSpline0Dist::computeFuncVal(const size_t& _funcIdx) const
222 {
223  const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
224  return cacheData.val + cacheData.cache[asInt(FuncEvalMode::DIFF1)] * (funcsArcEval_ - cacheData.arc);
225 }
226 
227 double ParamFuncsSpline0Dist::computeFuncDiff1(const size_t& _funcIdx) const
228 {
229  const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
230  return cacheData.cache[asInt(FuncEvalMode::DIFF1)];
231 }
232 double ParamFuncsSpline0Dist::computeFuncDiff2(const size_t& _funcIdx) const
233 {
234  return 0;
235 }
236 
237 double ParamFuncsSpline0Dist::computeFuncInt1(const size_t& _funcIdx) const
238 {
239  const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
240  return cacheData.cache[asInt(FuncEvalMode::INT1)] + computeFuncDeltaInt1(_funcIdx, funcsArcEval_);
241 }
242 double ParamFuncsSpline0Dist::computeFuncInt2(const size_t& _funcIdx) const
243 {
244  const FuncCacheData& cacheData = funcEvalCache_[_funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[_funcIdx]]];
245  return cacheData.cache[asInt(FuncEvalMode::INT2)] + computeFuncDeltaInt2(_funcIdx, funcsArcEval_);
246 }
247 
248 double ParamFuncsSpline0Dist::computeFuncDeltaInt1(const size_t& _funcIdx, const double& _arcEnd) const
249 {
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.;
253 }
254 double ParamFuncsSpline0Dist::computeFuncDeltaInt2(const size_t& _funcIdx, const double& _arcEnd) const
255 {
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.;
260 }
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...
double computeFuncDeltaInt1(const std::size_t &_funcIdx, const double &_arcEnd) const
Computes the integral of the parametric function _ on interval [funcEvalArcCacheIdxOld_[func2Arc_[_fu...
virtual void initImpl() override
Called at end of init. To be used by extended classes.
Helper function needed to upgrade c++ 2011.
Definition: utils.h:193
function second derivative
constexpr auto asInt(Enumeration const value) -> typename std::underlying_type< Enumeration >::type
Definition: utils.h:87
std::array< double, nrModesMax_ > cache
function single integral
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
Definition: param_func.h:80
Control point variable.
Definition: param_func.h:115
double & arc
control point arc parameter
Definition: param_func.h:121
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.
Structure referencing a control point and storing cached relevant function evaluation data (derivativ...
void setEvalArc(const double &_funcsArcEval, const EvalArcGuarantee &_evalArcGuarantee=EvalArcGuarantee::NONE) override
Sets parametric function evaluation arc.
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.
Definition: param_func.hpp:61
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.
Definition: param_func.hpp:45
function double integral
this evaluation arc is at the arc parametrization begin
this evaluation arc is at the arc parametrization end
function first derivative


tuw_control
Author(s): George Todoran
autogenerated on Mon Jun 10 2019 15:27:21