cost_functions.hpp
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 
33 #ifndef COST_FUNCTIONS_H
34 #define COST_FUNCTIONS_H
35 
36 #include <vector>
37 #include <math.h>
38 #include <float.h>
39 #include <functional>
40 
41 #include <tuw_control/utils.h>
42 
43 #include <iostream>
44 
45 namespace tuw
46 {
47 namespace cost_functions
48 {
50 
51 class CostFunc
52 {
53 public:
55  {
56  }
57 
58 public:
59  void setBoundIdxBegin(const std::size_t& _idxBoundBegin)
60  {
61  latBeginIdx_ = _idxBoundBegin;
62  }
63 
64 public:
65  void setBoundArcEnd(const double& _arcBoundEnd)
66  {
67  latBackArc_ = _arcBoundEnd;
68  }
69 
70 public:
71  void setCost0(const double& _cost0)
72  {
73  cost0_ = _cost0;
74  }
75 
76 public:
78  {
79  cost_ = cost0_;
81  finish_ = false;
82  }
83 
84 public:
86  {
87  while (!finish_)
88  {
89  if (finish_ || !hasReqData(iterIdx_))
90  {
91  break;
92  }
94  }
95  }
96 
97 public:
98  void calcCostsFull(const double& _arcLimit)
99  {
100  while (!finish_)
101  {
102  // std::cout<<std::endl<<"entered1StepLow, ";
103  if (finish_ || !hasReqData(iterIdx_))
104  { /*std::cout<<"finished1, cost="<<cost_<<std::endl;*/
105  break;
106  }
107  if ((arcAcc(iterIdx_) > _arcLimit))
108  { /*std::cout<<"finished2, cost="<<cost_<<std::endl;*/
109  break;
110  }
111 
112  if (arcAcc(iterIdx_) < latBackArc_)
113  {
114  cost_ = fL2(cost_, iterIdx_); /*std::cout<<"partialFL2, cost="<<cost_<<std::endl;*/
115  }
116  else if (arcAcc(iterIdx_) == latBackArc_)
117  {
118  cost_ = fL2(cost_, iterIdx_);
119  finish_ = true; /*std::cout<<"finishedFL23, cost="<<cost_<<std::endl;*/
120  }
121  // else { cost_ = fL3(cost_); finish_ = true;
122  // /*std::cout<<"finishedFL 3, cost="<<cost_<<std::endl;*/ }
123  ++iterIdx_;
124  }
125  }
126 
127 public:
129  {
130  if (arcAcc(iterIdx_) < latBackArc_)
131  {
132  cost_ = fL2(cost_, iterIdx_); /*std::cout<<"partialFL2, cost="<<cost_<<std::endl;*/
133  }
134  else if (arcAcc(iterIdx_) == latBackArc_)
135  {
136  cost_ = fL2(cost_, iterIdx_);
137  cost_ = fL3(cost_);
138  finish_ = true; /*std::cout<<"finishedFL23, cost="<<cost_<<std::endl;*/
139  }
140  // else { cost_ = fL3(cost_); finish_ = true;
141  // /*std::cout<<"finishedFL 3, cost="<<cost_<<std::endl;*/ }
142  ++iterIdx_;
143  // std::cout<<"increment, ";
144  }
145 
146 public:
147  const double& cost() const
148  {
149  return cost_;
150  }
151 
152 private:
153  virtual bool hasReqData(size_t _iterIdx)
154  {
155  return true;
156  }
157 
158 public:
159  bool finish_;
160 
161 public:
162  size_t iterIdx_;
163 
164 protected:
165  std::function<double(const size_t&)> arcAcc;
166 
167 protected:
168  std::function<double(const size_t&)> stAcc;
169 
170 protected:
171  std::function<double(const size_t&)> fL1;
172 
173 protected:
174  std::function<double(const double&, const size_t&)> fL2;
175 
176 protected:
177  std::function<double(const double&)> fL3;
178 
179 public:
180  size_t latBeginIdx_;
181 
182 protected:
183  double latBackArc_;
184 
185 protected:
186  double cost0_;
187 
188 private:
189  double cost_;
190 
191  friend class funcPredef_FL1;
192  friend class funcPredef_FL2;
193  friend class funcPredef_FL3;
194  template <typename Lattice, typename MapData>
195  friend class CostsArrayLatBase;
196 };
197 
198 template <typename Lattice, typename MapData>
200 {
201 public:
202  void initLatticeMap(std::shared_ptr<Lattice>& _lattPtr, std::shared_ptr<MapData>& _mapDataPtr)
203  {
204  latticePtr_ = _lattPtr;
205  mapDataPtr_ = _mapDataPtr;
206  }
207 
208 public:
209  void setWeight(const double& _weight)
210  {
211  weight_ = _weight;
212  }
213 
214 public:
215  std::shared_ptr<Lattice> latticePtr_;
216 
217 protected:
218  std::shared_ptr<MapData> mapDataPtr_;
219 
220 public:
221  double weight_;
222 };
223 
224 template <typename Lattice, typename MapData>
225 class CFLatMap1WeightBase : public CostFunc, public LatticeMapWeight<Lattice, MapData>
226 {
227 private:
228  bool hasReqData(size_t _iterIdx) override
229  {
230  return (this->latticePtr_->size() > _iterIdx);
231  }
232 };
233 
234 template <typename Lattice, typename MapData>
235 using CostFuncLatMap1WeightPtr = std::unique_ptr<CFLatMap1WeightBase<Lattice, MapData>>;
236 
237 template <typename Lattice, typename MapData>
239 {
240 public:
241  CostsArrayLatBase() : weight_(1)
242  {
243  }
244 
245 public:
246  virtual size_t latFuncLayerIdx() = 0;
247 
248 public:
249  virtual size_t latKnotLayerIdx() = 0;
250 
251 private:
252  virtual CostFuncLatMap1WeightPtr<Lattice, MapData> allocateCostFunc() = 0;
253 
254 public:
255  const double& cost(const size_t& _i) const
256  {
257  return pieceWiseCosts[_i]->cost();
258  }
259 
260 public:
261  const size_t costsSize() const
262  {
263  return pieceWiseCosts.size();
264  }
265 
266 public:
267  void setWeight(const double& _weight)
268  {
269  weight_ = _weight;
270  for (auto& costI : pieceWiseCosts)
271  {
272  costI->setWeight(_weight);
273  }
274  }
275 
276 public:
278  {
279  while (!finish_)
280  {
281  calcCosts1KnotStep();
282  }
283  }
284 
285 public:
287  {
288  while (!finish_)
289  {
290  if (iterIdx_ >= pieceWiseCosts.size())
291  {
292  finish_ = true;
293  return;
294  }
295  pieceWiseCosts[iterIdx_]->calcCostsFull();
296  if (++iterIdx_ >= pieceWiseCosts.size())
297  {
298  finish_ = true;
299  return;
300  }
301  pieceWiseCosts[iterIdx_]->iterIdx_ = pieceWiseCosts[iterIdx_ - 1]->iterIdx_;
302  }
303  }
304 
305 public:
306  void calcCosts1KnotStep(const double& _arcLimit)
307  {
308  iterIdx_ = iterIdxPartBegin_;
309  finish_ = false;
310  // while(!finish_){
311  if (iterIdx_ >= pieceWiseCosts.size())
312  {
313  iterIdxPartBegin_ = iterIdx_;
314  finish_ = true;
315  return;
316  }
317  pieceWiseCosts[iterIdx_]->calcCostsFull(_arcLimit);
318  if (pieceWiseCosts[iterIdx_]->finish_)
319  {
320  iterIdxPartBegin_++;
321  }
322  if (++iterIdx_ >= pieceWiseCosts.size())
323  {
324  finish_ = true;
325  return;
326  }
327  pieceWiseCosts[iterIdx_]->iterIdx_ = pieceWiseCosts[iterIdx_ - 1]->iterIdx_;
328  // }
329  }
330 
331 public:
332  void reset()
333  {
334  finish_ = false;
335  iterIdx_ = 0;
336  iterIdxPartBegin_ = 0;
337  resizeInitNew();
338  resetBounds(0);
339  for (auto& costI : pieceWiseCosts)
340  {
341  costI->resetFunction();
342  }
343  }
344 
345 public:
346  void resetNew()
347  {
348  finish_ = false;
349  int firstResetBound = resizeInitNew();
350  resetBounds(firstResetBound);
351  // for ( size_t i = firstResetBound; i < pieceWiseCosts.size(); ++i ) { pieceWiseCosts[i]->setBoundIdxBegin(
352  // pieceWiseCosts[i]->latBeginIdx_ ); }
353  }
354  // public : double arcAtLattIdxPrev () const { return
355  // lattKnotPtr_->at(std::max(0,(int)pieceWiseCosts[std::max(0,(int)iterIdx_-1)]->iterIdx_-2) ).arc; }
356 public:
357  double arcAtLattIdxPrev() const
358  {
359  return lattKnotPtr_->at(std::max(0, (int)iterIdx_ - 1)).arc;
360  }
361 
362 private:
363  void resetBounds(int _fistResetBound)
364  {
365  _fistResetBound = std::max(_fistResetBound, 0) + 1;
366  for (size_t i = _fistResetBound; i <= this->pieceWiseCosts.size(); ++i)
367  {
368  this->pieceWiseCosts[i - 1]->setBoundIdxBegin(_fistResetBound);
369  this->pieceWiseCosts[i - 1]->setBoundArcEnd(this->lattKnotPtr_->at(_fistResetBound++).arc);
370  }
371  }
372 
373 private:
375  {
376  int sizeOld = pieceWiseCosts.size();
377  if (!lattKnotPtr_)
378  {
379  pieceWiseCosts.clear();
380  return 0;
381  }
382  else
383  {
384  if (lattKnotPtr_->size() < 2)
385  {
386  pieceWiseCosts.clear();
387  return 0;
388  }
389  }
390  pieceWiseCosts.resize(std::max(0, (int)lattKnotPtr_->size() - 1));
391  int deltaSize = (int)pieceWiseCosts.size() - sizeOld;
392  if (deltaSize > 0)
393  {
394  for (size_t i = sizeOld; i < this->pieceWiseCosts.size(); ++i)
395  {
396  pieceWiseCosts[i] = allocateCostFunc();
397  pieceWiseCosts[i]->initLatticeMap(lattFuncPtr_, mapDataPtr_);
398  pieceWiseCosts[i]->resetFunction();
399  pieceWiseCosts[i]->setWeight(weight_);
400  }
401  }
402  return sizeOld - 1;
403  }
404 
405 public:
406  void initLatticeMap(std::vector<std::shared_ptr<Lattice>>& _lattPtr, std::shared_ptr<MapData>& _mapDataPtr)
407  {
408  size_t latIdx;
409  latIdx = latFuncLayerIdx();
410  lattFuncPtr_ = nullptr;
411  if (_lattPtr.size() > latIdx)
412  {
413  lattFuncPtr_ = _lattPtr[latIdx];
414  }
415  latIdx = latKnotLayerIdx();
416  lattKnotPtr_ = nullptr;
417  if (_lattPtr.size() > latIdx)
418  {
419  lattKnotPtr_ = _lattPtr[latIdx];
420  knotLatIdx_ = latIdx;
421  }
422  mapDataPtr_ = _mapDataPtr;
423  pieceWiseCosts.clear();
424  pieceWiseCosts.reserve(1000);
425  resizeInitNew();
426  }
427 
428 public:
429  const size_t& knotLatIdx() const
430  {
431  return knotLatIdx_;
432  }
433 
434 protected:
435  std::vector<CostFuncLatMap1WeightPtr<Lattice, MapData>> pieceWiseCosts;
436 
437 protected:
438  bool finish_;
439 
440 public:
441  size_t iterIdx_;
442 
443 public:
445 
446 protected:
447  std::shared_ptr<Lattice> lattFuncPtr_;
448 
449 protected:
450  std::shared_ptr<Lattice> lattKnotPtr_;
451 
452 protected:
453  std::shared_ptr<MapData> mapDataPtr_;
454 
455 private:
456  size_t knotLatIdx_;
457 
458 private:
459  double weight_;
460 };
461 
462 template <typename Lattice, typename MapData>
463 class CFLatMap1Weight : public CFLatMap1WeightBase<Lattice, MapData>
464 {
465 };
466 
468 {
469 public:
470  template <typename CF>
471  static void lin(CF* _cf)
472  {
473  _cf->fL1 = [_cf](const size_t& _i)
474  {
475  return _cf->stAcc(_i);
476  };
477  }
478  template <typename CF>
479  static void sqr(CF* _cf)
480  {
481  _cf->fL1 = [_cf](const size_t& _i)
482  {
483  return _cf->stAcc(_i) * _cf->stAcc(_i);
484  };
485  }
486  template <typename CF>
487  static void ln(CF* _cf)
488  {
489  _cf->fL1 = [_cf](const size_t& _i)
490  {
491  return log(_cf->stAcc(_i));
492  };
493  }
494 };
496 {
497 public:
498  template <typename CF>
499  static void sum(CF* _cf)
500  {
501  _cf->fL2 = [_cf](const double& _ansPrev, const size_t& _i)
502  {
503  return _ansPrev + _cf->fL1(_i);
504  };
505  }
506  template <typename CF>
507  static void min(CF* _cf)
508  {
509  _cf->fL2 = [_cf](const double& _ansPrev, const size_t& _i)
510  {
511  return fmin(_ansPrev, _cf->fL1(_i));
512  };
513  }
514  template <typename CF>
515  static void max(CF* _cf)
516  {
517  _cf->fL2 = [_cf](const double& _ansPrev, const size_t& _i)
518  {
519  return fmax(_ansPrev, _cf->fL1(_i));
520  };
521  }
522  template <typename CF>
523  static void intTrap(CF* _cf)
524  {
525  _cf->fL2 = [_cf](const double& _ansPrev, const size_t& _i)
526  {
527  if ((_cf->iterIdx_ == 0))
528  {
529  return _cf->cost0_;
530  }
531  return _ansPrev + (_cf->arcAcc(_i) - _cf->arcAcc(_i - 1)) * (_cf->fL1(_i) + _cf->fL1(_i - 1)) / 2.;
532  };
533  }
534 };
536 {
537 public:
538  template <typename CF>
539  static void weight(CF* _cf)
540  {
541  _cf->fL3 = [_cf](const double& _ansPrev)
542  {
543  return _ansPrev * _cf->weight_;
544  };
545  }
546  template <typename CF>
547  static void weightBy2(CF* _cf)
548  {
549  _cf->fL3 = [_cf](const double& _ansPrev)
550  {
551  return _ansPrev * _cf->weight_ / 2.;
552  };
553  }
554  template <typename CF>
555  static void weightNorm(CF* _cf)
556  {
557  _cf->fL3 = [_cf](const double& _ansPrev)
558  {
559  int beginIdx = _cf->latBeginIdx_;
560  if (_cf->iterIdx_ == 0)
561  {
562  return 0.;
563  }
564  /*else if( _cf->iterIdx_ == _cf->latBeginIdx_ ) { */ beginIdx = std::max(0, (int)_cf->latBeginIdx_ - 1); /* }*/
565  return _ansPrev * _cf->weight_ / (_cf->arcAcc(_cf->iterIdx_) - _cf->arcAcc(beginIdx));
566  };
567  }
568 };
569 
570 template <typename Lattice, typename MapData>
571 class CfSum : public CFLatMap1Weight<Lattice, MapData>
572 {
573 public:
575  {
576  funcPredef_FL1::lin(this);
577  funcPredef_FL2::sum(this);
579  }
580 };
581 template <typename Lattice, typename MapData>
582 class CfSumSqr : public CFLatMap1Weight<Lattice, MapData>
583 {
584 public:
586  {
587  funcPredef_FL1::sqr(this);
588  funcPredef_FL2::sum(this);
590  }
591 };
592 template <typename Lattice, typename MapData>
593 class CfIntTrapSqr : public CFLatMap1Weight<Lattice, MapData>
594 {
595 public:
597  {
598  funcPredef_FL1::sqr(this);
601  }
602 };
603 template <typename Lattice, typename MapData>
604 class CfPowTrapSqr : public CFLatMap1Weight<Lattice, MapData>
605 {
606 public:
608  {
609  funcPredef_FL1::sqr(this);
612  }
613 };
614 
615 template <typename Lattice, typename MapData, typename CostFunction>
616 class CostsArrayLat : public CostsArrayLatBase<Lattice, MapData>
617 {
618 private:
620  {
621  return std::unique_ptr<CostFunction>(new CostFunction);
622  }
623 };
624 
625 } // namespace cost_functions
626 
627 } // namespace tuw
628 
629 #endif // COST_FUNCTIONS_H
virtual bool hasReqData(size_t _iterIdx)
std::shared_ptr< Lattice > lattFuncPtr_
void setWeight(const double &_weight)
std::shared_ptr< MapData > mapDataPtr_
std::shared_ptr< Lattice > lattKnotPtr_
CostFuncLatMap1WeightPtr< Lattice, MapData > allocateCostFunc() override
std::shared_ptr< Lattice > latticePtr_
const double & cost(const size_t &_i) const
void initLatticeMap(std::shared_ptr< Lattice > &_lattPtr, std::shared_ptr< MapData > &_mapDataPtr)
std::function< double(const size_t &)> fL1
std::function< double(const double &)> fL3
std::function< double(const size_t &)> stAcc
void calcCosts1KnotStep(const double &_arcLimit)
std::shared_ptr< MapData > mapDataPtr_
void setBoundIdxBegin(const std::size_t &_idxBoundBegin)
void setWeight(const double &_weight)
std::function< double(const size_t &)> arcAcc
bool hasReqData(size_t _iterIdx) override
void resetBounds(int _fistResetBound)
std::vector< CostFuncLatMap1WeightPtr< Lattice, MapData > > pieceWiseCosts
void initLatticeMap(std::vector< std::shared_ptr< Lattice >> &_lattPtr, std::shared_ptr< MapData > &_mapDataPtr)
void setBoundArcEnd(const double &_arcBoundEnd)
std::function< double(const double &, const size_t &)> fL2
std::unique_ptr< CFLatMap1WeightBase< Lattice, MapData >> CostFuncLatMap1WeightPtr
void setCost0(const double &_cost0)
void calcCostsFull(const double &_arcLimit)
const double & cost() const


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