22 class SlicedTube :
public SlicedTubeBase
26 explicit SlicedTube(
const std::shared_ptr<TDomain>& tdomain,
28 : SlicedTubeBase(tdomain)
30 for(
auto it = _tdomain->begin(); it != _tdomain->end(); ++it)
33 std::make_shared<Slice<T>>(*this, it, codomain)
37 explicit SlicedTube(
const std::shared_ptr<TDomain>& tdomain,
38 const AnalyticFunction<
typename ExprType<T>::Type>& f)
39 : SlicedTubeBase(tdomain)
41 assert_release(f.args().size() == 1
42 &&
"function's inputs must be limited to one system variable");
44 for(
auto it = _tdomain->begin(); it != _tdomain->end(); ++it)
47 std::make_shared<Slice<T>>(*
this, it, f.eval((Interval)*it))
52 requires std::is_same_v<typename Wrapper<V>::Domain,T>
53 explicit SlicedTube(
const std::shared_ptr<TDomain>& tdomain,
54 const SampledTraj<V>& f)
55 : SlicedTubeBase(tdomain)
57 for(
auto it = _tdomain->begin(); it != _tdomain->end(); ++it)
60 std::make_shared<Slice<T>>(*this, it, f((Interval)*it))
64 SlicedTube(
const SlicedTube<T>& x)
65 : SlicedTubeBase(x.tdomain())
67 for(
auto it = _tdomain->begin(); it != _tdomain->end(); ++it)
70 std::make_shared<Slice<T>>(*x(it), *this)
74 inline SlicedTube& operator=(
const SlicedTube& x)
76 assert_release(_tdomain == x._tdomain);
78 for(
auto it = _tdomain->begin(); it != _tdomain->end(); ++it)
79 (*this)(it)->set(x(it)->codomain(),
false);
84 inline Index size()
const
86 return first_slice()->size();
89 virtual std::pair<Index,Index> shape()
const
91 if constexpr(std::is_same_v<typename ExprType<T>::Type,ScalarType>)
94 return {first_slice()->codomain().rows(),first_slice()->codomain().cols()};
97 inline double volume()
const
100 for(
const auto& s : *
this)
102 volume += s.volume();
106 inline std::shared_ptr<Slice<T>> first_slice()
108 return std::const_pointer_cast<Slice<T>>(
109 static_cast<const SlicedTube&
>(*this).first_slice());
112 inline std::shared_ptr<const Slice<T>> first_slice()
const
114 return std::static_pointer_cast<const Slice<T>>(
115 this->SlicedTubeBase::first_slice());
118 inline std::shared_ptr<Slice<T>> last_slice()
120 return std::const_pointer_cast<Slice<T>>(
121 static_cast<const SlicedTube&
>(*this).last_slice());
124 inline std::shared_ptr<const Slice<T>> last_slice()
const
126 return std::static_pointer_cast<const Slice<T>>(
127 this->SlicedTubeBase::last_slice());
130 inline bool is_empty()
const
134 for(
const auto& s : *
this)
135 if(s.is_gate() && s.is_empty())
137 for(
const auto& s : *
this)
138 if(!s.is_gate() && s.is_empty())
143 inline bool is_unbounded()
const
145 for(
const auto& s : *
this)
151 inline T codomain()
const
153 T x = first_slice()->codomain();
154 for(
const auto& s : *
this)
159 inline std::shared_ptr<Slice<T>> operator()(
const std::list<TSlice>::iterator& it)
161 return std::const_pointer_cast<Slice<T>>(
162 static_cast<const SlicedTube&
>(*this).operator()(it));
165 inline std::shared_ptr<const Slice<T>> operator()(
const std::list<TSlice>::const_iterator& it)
const
167 return std::static_pointer_cast<const Slice<T>>(
168 it->slices().at(
this));
171 inline std::shared_ptr<Slice<T>> operator()(
const std::list<TSlice>::reverse_iterator& it)
173 return std::const_pointer_cast<Slice<T>>(
174 static_cast<const SlicedTube&
>(*this).operator()(it));
177 inline std::shared_ptr<const Slice<T>> operator()(
const std::list<TSlice>::const_reverse_iterator& it)
const
179 return std::static_pointer_cast<const Slice<T>>(
180 it->slices().at(
this));
183 inline T operator()(
double t)
const
186 return all_reals_codomain();
188 auto it_t = _tdomain->tslice(t);
189 assert(it_t != _tdomain->end());
190 T x = (*this)(it_t)->codomain();
191 if(!it_t->is_gate() && t==it_t->lb() && it_t!=_tdomain->begin())
192 x &= (*this)(--it_t)->codomain();
196 inline T operator()(
const Interval& t)
const
199 return all_reals_codomain();
201 if(t.is_degenerated())
202 return (*
this)(t.lb());
204 auto t_ = t & _tdomain->t0_tf();
206 auto it = _tdomain->tslice(t_.lb());
207 T codomain = (*this)(it)->codomain();
209 while(it != std::next(_tdomain->tslice(t_.ub())))
211 if(it->lb() == t_.ub())
break;
212 codomain |= (*this)(it)->codomain();
219 std::pair<T,T> enclosed_bounds(
const Interval& t)
const
221 auto x = this->empty_codomain();
222 auto bounds = std::make_pair(x,x);
224 if(t.lb() < _tdomain->t0_tf().lb() || t.ub() > _tdomain->t0_tf().ub())
226 x.init(Interval(-oo,0));
228 x.init(Interval(0,oo));
232 Interval t_inter = t & _tdomain->t0_tf();
233 auto si = (*this)(_tdomain->tslice(t_inter.lb()));
235 while(si && si->t0_tf().lb() <= t_inter.ub())
237 auto slice_bounds = si->enclosed_bounds(t_inter & si->t0_tf());
238 bounds.first |= slice_bounds.first;
239 bounds.second |= slice_bounds.second;
240 si = si->next_slice();
246 inline void set(
const T& codomain)
248 assert_release(codomain.size() == this->size());
252 s.set(codomain,
false);
256 s.set(codomain,
false);
259 inline void set(
const T& codomain,
double t)
261 assert_release(codomain.size() == this->size());
262 (*this)(_tdomain->sample(t,
true))->set(codomain);
265 inline void set(
const T& codomain,
const Interval& t)
267 auto it_lb = _tdomain->sample(t.lb(), t.is_degenerated());
268 std::list<TSlice>::iterator it_ub;
270 if(!t.is_degenerated())
272 it_ub = _tdomain->sample(t.ub(),
false);
274 if(it_ub->lb() == t.ub())
277 if(it_lb->ub() == t.lb())
286 (*this)(it_lb)->set(codomain);
287 }
while(it_lb != it_ub && (++it_lb) != _tdomain->end());
290 inline void set_ith_slice(
const T& codomain, Index i)
293 for(
auto& si : *
this)
301 const SlicedTube<T>& inflate(
double rad)
303 assert_release(
rad >= 0.);
307 s.set(T(s.codomain()).inflate(
rad),
false);
311 s.set(T(s.codomain()).inflate(
rad),
false);
316 SlicedTube<Interval> operator[](Index i)
const
318 assert_release(i >= 0 && i < size());
319 SlicedTube<Interval> xi(tdomain(), Interval());
320 for(
auto it = tdomain()->begin() ; it != tdomain()->end() ; it++)
321 xi(it)->codomain() = (*this)(it)->codomain()[i];
325 SlicedTube<IntervalVector> subvector(Index i, Index j)
const
327 assert_release(i >= 0 && i <= j && j < size());
329 for(
auto it = tdomain()->begin() ; it != tdomain()->end() ; it++)
330 xij(it)->codomain() = (*this)(it)->codomain().subvector(i,j);
334 inline bool operator==(
const SlicedTube& x)
const
336 if(!TDomain::are_same(tdomain(), x.tdomain()))
339 auto it_this = _tdomain->begin();
340 auto it_x = x.tdomain()->cbegin();
342 while(it_this != _tdomain->end())
343 if(*(*
this)(it_this++) != *x(it_x++))
349 inline SlicedTube operator&=(
const SlicedTube& x)
351 assert(TDomain::are_same(tdomain(), x.tdomain()));
352 auto it_this = _tdomain->begin();
353 auto it_x = x.tdomain()->cbegin();
355 while(it_this != _tdomain->end())
357 auto s = (*this)(it_this);
358 s->set(s->codomain() & x(it_x)->codomain());
362 assert(it_x == x.tdomain()->cend());
366 friend inline std::ostream& operator<<(std::ostream& os,
const SlicedTube<T>& x)
369 <<
"↦" << x.codomain()
370 <<
", " << x.nb_slices()
371 <<
" slice" << (x.nb_slices() > 1 ?
"s" :
"")
376 AnalyticFunction<typename ExprType<T>::Type> as_function()
const
380 AnalyticExprWrapper<typename ExprType<T>::Type>(
381 std::make_shared<AnalyticOperationExpr<
382 TubeOp<SlicedTube<T>>,
typename ExprType<T>::Type,ScalarType>>(*
this,t))
388 T integral(
const Interval& t)
const;
389 T integral(
const Interval& t1,
const Interval& t2)
const;
390 std::pair<T,T> partial_integral(
const Interval& t)
const;
391 std::pair<T,T> partial_integral(
const Interval& t1,
const Interval& t2)
const;
393 inline SlicedTube<T> primitive()
const
395 auto x0 = all_reals_codomain();
397 return primitive(x0);
400 inline SlicedTube<T> primitive(
const T& x0)
const
402 auto x = all_reals_codomain();
403 auto p = SlicedTube<T>(this->tdomain(), x);
404 p.set(x0, this->tdomain()->t0_tf().
lb());
413 using base_container = std::list<TSlice>;
415 struct iterator :
public base_container::iterator
419 iterator(SlicedTube& x, base_container::iterator it)
420 : base_container::iterator(it), _x(x) { }
422 std::shared_ptr<Slice<T>> operator->()
427 Slice<T>& operator*()
429 return *operator->();
437 iterator begin() {
return { *
this, _tdomain->begin() }; }
438 iterator end() {
return { *
this, _tdomain->end() }; }
440 struct reverse_iterator :
public base_container::reverse_iterator
444 reverse_iterator(SlicedTube& x, base_container::reverse_iterator it)
445 : base_container::reverse_iterator(it), _x(x) { }
447 std::shared_ptr<Slice<T>> operator->()
452 Slice<T>& operator*()
454 return *operator->();
462 reverse_iterator rbegin() {
return { *
this, _tdomain->rbegin() }; }
463 reverse_iterator rend() {
return { *
this, _tdomain->rend() }; }
465 struct const_iterator :
public base_container::const_iterator
469 const_iterator(
const SlicedTube& x, base_container::const_iterator it)
470 : base_container::const_iterator(it), _x(x) { }
472 std::shared_ptr<const Slice<T>> operator->()
477 const Slice<T>& operator*()
479 return *operator->();
484 const SlicedTube& _x;
487 const_iterator begin()
const {
return { *
this, _tdomain->cbegin() }; }
488 const_iterator end()
const {
return { *
this, _tdomain->cend() }; }
490 struct const_reverse_iterator :
public base_container::const_reverse_iterator
494 const_reverse_iterator(
const SlicedTube& x, base_container::const_reverse_iterator it)
495 : base_container::const_reverse_iterator(it), _x(x) { }
497 std::shared_ptr<const Slice<T>> operator->()
502 const Slice<T>& operator*()
504 return *operator->();
509 const SlicedTube& _x;
512 const_reverse_iterator rbegin()
const {
return { *
this, _tdomain->crbegin() }; }
513 const_reverse_iterator rend()
const {
return { *
this, _tdomain->crend() }; }
517 inline T all_reals_codomain()
const
519 T x = first_slice()->codomain();
524 inline T empty_codomain()
const
526 T x = first_slice()->codomain();
536 SlicedTube(
const std::shared_ptr<TDomain>& tdomain,
const AnalyticFunction<T>& f) ->
537 SlicedTube<typename Wrapper<T>::Domain>;
540 SlicedTube(
const std::shared_ptr<TDomain>& tdomain,
const SampledTraj<T>& f) ->
541 SlicedTube<typename Wrapper<T>::Domain>;
auto lb() const
Returns a matrix containing the lower bounds of each interval element.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:91
bool is_superset(const Matrix< codac2::Interval, RowsAtCompileTime, ColsAtCompileTime > &x) const
Checks whether this matrix is a superset of another interval matrix.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:648
bool contains(const Matrix< double, RowsAtCompileTime, ColsAtCompileTime > &x) const
Checks if this interval matrix contains the specified matrix x.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:198
auto rad() const
Returns a matrix containing the radii of each interval element.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:171
Definition codac2_OctaSym.h:21
Eigen::Matrix< Interval,-1, 1 > IntervalVector
Alias for a dynamic-size column vector of intervals.
Definition codac2_IntervalVector.h:25