12#ifndef __CODAC2_TUBE_H__
13#define __CODAC2_TUBE_H__
17#include "codac_TFnc.h"
24#include "codac_ConvexPolygon.h"
29 using codac::BoolInterval;
36 class ConstTubeEvaluation;
42 class Tube :
public AbstractSlicedTube,
public AbstractConstTube<T,Tube<T>>
46 explicit Tube(
const std::shared_ptr<TDomain>& tdomain) :
50 explicit Tube(
const std::shared_ptr<TDomain>& tdomain,
const TFnc& f) :
51 Tube(tdomain, (std::is_same<T,Interval>::value ? T() : T(f.image_dim())))
53 assert(f.nb_var() == 0 &&
"function's inputs must be limited to system variable");
54 if constexpr(std::is_same<T,Interval>::value) {
55 assert(f.image_dim() == 1);
60 if constexpr(std::is_same<T,Interval>::value)
61 s.set(f.eval(s.t0_tf()));
64 s.set(f.eval_vector(s.t0_tf()));
67 std::cout <<
"IS EMPTY: " << s << std::endl;
71 explicit Tube(
const std::shared_ptr<TDomain>& tdomain,
const T& default_value) :
72 AbstractSlicedTube(tdomain)
74 for(std::list<TSlice>::iterator it = _tdomain->_tslices.begin();
75 it != _tdomain->_tslices.end(); ++it)
78 std::pair<
const AbstractSlicedTube*,std::shared_ptr<Slice<T>>>(
this,
79 std::make_shared<Slice<T>>(default_value, *
this, it)));
83 Tube(
const Tube<T>& x) :
84 AbstractSlicedTube(x.tdomain())
86 for(std::list<TSlice>::iterator it = _tdomain->_tslices.begin();
87 it != _tdomain->_tslices.end(); ++it)
89 std::shared_ptr<Slice<T>> s_ptr = std::make_shared<Slice<T>>(x(it), *
this);
90 it->_slices.insert(std::pair<
const AbstractSlicedTube*,std::shared_ptr<Slice<T>>>(
this, s_ptr));
96 for(
auto& s : _tdomain->_tslices)
97 s._slices.erase(this);
100 Tube& operator=(
const Tube& x)
102 if(_tdomain != x._tdomain)
103 throw std::exception();
105 for(
auto it = _tdomain->_tslices.begin();
106 it != _tdomain->_tslices.end(); ++it)
107 (*
this)(it).set(x(it).codomain());
112 virtual Interval t0_tf()
const
114 return AbstractSlicedTube::t0_tf();
120 if constexpr(std::is_same<T,Interval>::value)
123 return first_slice().size();
126 size_t nb_slices()
const
128 return _tdomain->nb_tslices();
131 double volume()
const
134 for(
const auto& s : *this)
135 volume += s.volume();
139 virtual const std::shared_ptr<AbstractSlice>& first_abstract_slice_ptr()
const
141 return _tdomain->tslices().front().slices().at(
this);
144 virtual const std::shared_ptr<AbstractSlice>& last_abstract_slice_ptr()
const
146 return _tdomain->tslices().back().slices().at(
this);
149 const std::shared_ptr<Slice<T>> first_slice_ptr()
const
151 return std::static_pointer_cast<Slice<T>>(first_abstract_slice_ptr());
154 const Slice<T>& first_slice()
const
156 return *first_slice_ptr();
159 Slice<T>& first_slice()
161 return const_cast<Slice<T>&
>(
162 static_cast<const Tube&
>(*this).first_slice());
165 const std::shared_ptr<Slice<T>> last_slice_ptr()
const
167 return std::static_pointer_cast<Slice<T>>(last_abstract_slice_ptr());
170 const Slice<T>& last_slice()
const
172 return *last_slice_ptr();
175 Slice<T>& last_slice()
177 return const_cast<Slice<T>&
>(
178 static_cast<const Tube&
>(*this).last_slice());
181 bool is_empty()
const
185 for(
const auto& s : *this)
186 if(s.is_gate() && s.is_empty())
188 for(
const auto& s : *this)
189 if(!s.is_gate() && s.is_empty())
194 bool is_unbounded()
const
196 for(
const auto& s : *this)
202 BoolInterval contains(
const TrajectoryVector& x)
const
204 assert(x.tdomain() == tdomain()->t0_tf());
206 BoolInterval result = BoolInterval::YES;
207 for(
const auto& s : *this)
209 if(s.is_gate())
continue;
210 BoolInterval b = s.contains(x);
211 if(b == BoolInterval::NO)
return BoolInterval::NO;
212 else if(b == BoolInterval::MAYBE) result = BoolInterval::MAYBE;
220 T codomain = first_slice().codomain();
221 codomain.set_empty();
222 for(
const auto& s : *this)
223 codomain |= s.codomain();
228 std::shared_ptr<Slice<T>> slice_ptr(
const std::list<TSlice>::iterator& it)
230 return std::static_pointer_cast<Slice<T>>(it->slices().at(
this));
233 Slice<T>& operator()(
const std::list<TSlice>::iterator& it)
235 return const_cast<Slice<T>&
>(
236 static_cast<const Tube&
>(*this).operator()(it));
239 const Slice<T>& operator()(
const std::list<TSlice>::iterator& it)
const
241 return *std::static_pointer_cast<Slice<T>>(it->slices().at(
this));
244 TubeEvaluation<T> operator()(
double t)
246 return TubeEvaluation<T>(
this, t);
249 const TubeEvaluation<T> operator()(
double t)
const
251 return ConstTubeEvaluation<T>(
this, t);
254 TubeEvaluation<T> operator()(
const Interval& t)
256 return TubeEvaluation<T>(
this, t);
259 const TubeEvaluation<T> operator()(
const Interval& t)
const
261 return TubeEvaluation<T>(
this, t);
264 T eval(
double t)
const
266 if(!tdomain()->t0_tf().contains(t))
268 if constexpr(!std::is_same<T,codac::IntervalVector>::value)
273 std::list<TSlice>::iterator it_t = _tdomain->iterator_tslice(t);
274 assert(it_t != _tdomain->_tslices.end());
275 T x = std::static_pointer_cast<Slice<T>>(it_t->_slices.at(
this))->codomain();
276 if(!it_t->is_gate() && t==it_t->t0_tf().lb() && it_t!=_tdomain->_tslices.begin())
277 x &= std::static_pointer_cast<Slice<T>>((--it_t)->_slices.at(
this))->codomain();
281 T eval(
const Interval& t)
const
283 if(!tdomain()->t0_tf().is_superset(t))
285 if constexpr(!std::is_same<T,codac::IntervalVector>::value)
291 if(t.is_degenerated())
294 std::list<TSlice>::iterator it = _tdomain->iterator_tslice(t.lb());
295 T codomain = std::static_pointer_cast<Slice<T>>(it->_slices.at(
this))->codomain();
297 while(it != std::next(_tdomain->iterator_tslice(t.ub())))
299 if(it->t0_tf().lb() == t.ub())
break;
300 codomain |= std::static_pointer_cast<Slice<T>>(it->_slices.at(
this))->codomain();
307 void set(
const T& codomain)
309 if constexpr(std::is_same<T,codac::IntervalVector>::value) {
310 assert((
size_t)codomain.size() == size());
320 void set(
const T& codomain,
double t)
322 if constexpr(std::is_same<T,codac::IntervalVector>::value) {
323 assert((
size_t)codomain.size() == size());
325 std::list<TSlice>::iterator it = _tdomain->sample(t,
true);
326 (*this)(it).set(codomain);
329 const Tube<T>& inflate(
double rad)
340 TubeComponent<T> operator[](
size_t i)
342 assert(i >= 0 && i < size());
343 return TubeComponent<T>(*
this, i);
346 bool operator==(
const Tube& x)
const
348 if(!TDomain::are_same(tdomain(), x.tdomain()))
351 std::list<TSlice>::iterator it_this = _tdomain->_tslices.begin();
352 std::list<TSlice>::const_iterator it_x = x.tdomain()->tslices().cbegin();
354 while(it_this != _tdomain->tslices().end())
356 if(*std::static_pointer_cast<Slice<T>>(it_this->_slices.at(
this)) !=
357 *std::static_pointer_cast<Slice<T>>(it_x->slices().at(&x)))
365 Tube operator&=(
const Tube& x)
367 assert(TDomain::are_same(tdomain(), x.tdomain()));
368 std::list<TSlice>::iterator it_this = _tdomain->_tslices.begin();
369 std::list<TSlice>::const_iterator it_x = x.tdomain()->tslices().cbegin();
371 while(it_this != _tdomain->tslices().end())
373 std::shared_ptr<Slice<T>> s = std::static_pointer_cast<Slice<T>>(it_this->_slices.at(
this));
374 s->set(s->codomain() & std::static_pointer_cast<Slice<T>>(it_x->slices().at(&x))->codomain());
378 assert(it_x == x.tdomain()->tslices().cend());
382 friend std::ostream& operator<<(std::ostream& os,
const Tube<T>& x)
384 x.AbstractConstTube<T,Tube<T>>::print(os);
386 os <<
", " << x.nb_slices()
387 <<
" slice" << (x.nb_slices() > 1 ?
"s" :
"")
395 using base_container = std::list<TSlice>;
397 struct iterator :
public base_container::iterator
399 using iterator_category =
typename base_container::iterator::iterator_category;
400 using difference_type =
typename base_container::iterator::difference_type;
402 using value_type = Slice<T>;
403 using pointer = Slice<T>*;
404 using reference = Slice<T>&;
408 iterator(
const Tube& x, base_container::iterator it) :
409 base_container::iterator(it), _x(x) { }
411 reference operator*()
413 return static_cast<reference
>(*((*this)->_slices.at(&_x)));
421 iterator begin() {
return iterator(*
this, _tdomain->_tslices.begin()); }
422 iterator end() {
return iterator(*
this, _tdomain->_tslices.end()); }
424 struct reverse_iterator :
public base_container::reverse_iterator
426 using iterator_category =
typename base_container::reverse_iterator::iterator_category;
427 using difference_type =
typename base_container::reverse_iterator::difference_type;
429 using value_type = Slice<T>;
430 using pointer = Slice<T>*;
431 using reference = Slice<T>&;
435 reverse_iterator(
const Tube& x, base_container::reverse_iterator it) :
436 base_container::reverse_iterator(it), _x(x) { }
438 reference operator*()
440 return static_cast<reference
>(*((*this)->_slices.at(&_x)));
448 reverse_iterator rbegin() {
return reverse_iterator(*
this, _tdomain->_tslices.rbegin()); }
449 reverse_iterator rend() {
return reverse_iterator(*
this, _tdomain->_tslices.rend()); }
451 struct const_iterator :
public base_container::const_iterator
453 using iterator_category =
typename base_container::const_iterator::iterator_category;
454 using difference_type =
typename base_container::const_iterator::difference_type;
456 using value_type = Slice<T>;
457 using pointer =
const Slice<T>*;
458 using reference =
const Slice<T>&;
462 const_iterator(
const Tube& x, base_container::const_iterator it) :
463 base_container::const_iterator(it), _x(x) { }
465 reference operator*()
const
467 return static_cast<reference
>(*((*this)->_slices.at(&_x)));
475 const_iterator begin()
const {
return const_iterator(*
this, _tdomain->_tslices.cbegin()); }
476 const_iterator end()
const {
return const_iterator(*
this, _tdomain->_tslices.cend()); }
479 codac::Tube to_codac1(
const codac2::Tube<Interval>& x);
482 codac2::Tube<Interval> to_codac2(
const codac::Tube& x);
One dimensional tube , defined as an interval of scalar trajectories.
Definition codac_Tube.h:48
n-dimensional tube , defined as an interval of n-dimensional trajectories
Definition codac_TubeVector.h:39