12#ifndef __CODAC2_SLICE_H__
13#define __CODAC2_SLICE_H__
24#include "codac_ConvexPolygon.h"
27#define EPSILON_CONTAINS ibex::next_float(0.) * 1000.
31 using codac::Interval;
33 using codac::BoolInterval;
35 class AbstractSlicedTube;
39 class Slice :
public AbstractSlice
43 explicit Slice(
size_t n,
const AbstractSlicedTube& tube_vector,
const std::list<TSlice>::iterator& it_tslice) :
44 Slice(T(n), tube_vector, it_tslice)
49 explicit Slice(
const T& codomain,
const AbstractSlicedTube& tube_vector,
const std::list<TSlice>::iterator& it_tslice) :
50 AbstractSlice(tube_vector,it_tslice), _codomain(codomain)
55 Slice(
const Slice& s) :
56 Slice(s, s._tubevector)
61 Slice(
const Slice& s,
const AbstractSlicedTube& tubevector) :
62 AbstractSlice(tubevector, s._it_tslice), _codomain(s._codomain)
74 Slice& operator=(
const Slice&) =
delete;
75 Slice(Slice&&) =
delete;
76 Slice& operator=(Slice&&) =
delete;
78 const AbstractSlicedTube& tube_vector()
const
83 virtual std::shared_ptr<AbstractSlice> duplicate()
const
85 return std::make_shared<Slice>(*
this);
88 virtual size_t size()
const
91 if constexpr(std::is_same<T,Interval>::value)
94 return codomain().size();
99 if constexpr(std::is_same<T,Interval>::value)
100 return codomain().diam();
102 return codomain().volume();
107 return t0_tf().is_degenerated();
110 bool is_empty()
const
113 return _codomain.is_empty();
115 return input_gate().is_empty() || output_gate().is_empty();
118 bool is_unbounded()
const
120 return codomain().is_unbounded();
123 BoolInterval contains(
const TrajectoryVector& x)
const
125 if constexpr(!std::is_same<T,codac::IntervalVector>::value)
127 assert(
false &&
"not implemented");
128 return BoolInterval::MAYBE;
133 if(!t0_tf().intersects(x.tdomain()))
134 return BoolInterval::MAYBE;
136 BoolInterval is_contained = BoolInterval::YES;
137 if(!t0_tf().is_subset(x.tdomain()))
138 is_contained = BoolInterval::MAYBE;
140 Interval t_ = t0_tf() & x.tdomain();
141 T traj_tdomain(x(t_));
143 T traj_input(x(Interval(t_.lb())));
144 T traj_output(x(Interval(t_.ub())));
146 if(_codomain.intersects(traj_tdomain) == BoolInterval::NO
147 || input_gate().intersects(traj_input) == BoolInterval::NO
148 || output_gate().intersects(traj_output) == BoolInterval::NO)
149 return BoolInterval::NO;
153 if(!traj_input.is_subset(input_gate()) || !traj_output.is_subset(output_gate()))
154 return BoolInterval::MAYBE;
156 else if(traj_tdomain.is_subset(_codomain))
163 std::list<Interval> s_subtdomains;
164 s_subtdomains.push_front(t_);
166 while(!s_subtdomains.empty())
168 Interval t = s_subtdomains.front();
169 s_subtdomains.pop_front();
171 T thinner_eval(x(t));
173 if(!_codomain.intersects(thinner_eval))
175 return BoolInterval::NO;
178 else if(!thinner_eval.is_subset(_codomain))
181 return BoolInterval::MAYBE;
183 s_subtdomains.push_front(Interval(t.lb(), t.lb() + t.diam() / 2.));
184 s_subtdomains.push_front(Interval(t.lb() + t.diam() / 2., t.ub()));
194 const std::shared_ptr<Slice<T>> prev_slice_ptr()
const
196 return std::static_pointer_cast<Slice<T>>(prev_abstract_slice_ptr());
199 std::shared_ptr<Slice<T>> prev_slice_ptr()
201 return std::const_pointer_cast<Slice<T>>(
202 static_cast<const Slice&
>(*this).prev_slice_ptr());
205 const std::shared_ptr<Slice<T>> next_slice_ptr()
const
207 return std::static_pointer_cast<Slice<T>>(next_abstract_slice_ptr());
210 std::shared_ptr<Slice<T>> next_slice_ptr()
212 return std::const_pointer_cast<Slice<T>>(
213 static_cast<const Slice&
>(*this).next_slice_ptr());
216 const T& codomain()
const
223 if(!prev_slice_ptr())
228 if(prev_slice_ptr()->is_gate())
229 return prev_slice_ptr()->codomain();
231 return codomain() & prev_slice_ptr()->codomain();
235 T output_gate()
const
237 if(!next_slice_ptr())
242 if(next_slice_ptr()->is_gate())
243 return next_slice_ptr()->codomain();
245 return codomain() & next_slice_ptr()->codomain();
249 void set(
const T& x,
bool propagate =
true)
251 if constexpr(!std::is_same<T,Interval>::value) {
252 assert((
size_t)codomain().size() == size());
259 if constexpr(!std::is_same<T,Interval>::value) {
260 assert((
size_t)prev_slice_ptr()->codomain().size() == size());
263 _codomain &= prev_slice_ptr()->codomain();
264 else if(prev_slice_ptr()->is_gate())
265 prev_slice_ptr()->_codomain &= _codomain;
270 if constexpr(!std::is_same<T,Interval>::value) {
271 assert((
size_t)next_slice_ptr()->codomain().size() == size());
274 _codomain &= next_slice_ptr()->codomain();
275 else if(next_slice_ptr()->is_gate())
276 next_slice_ptr()->_codomain &= _codomain;
279 if(propagate && is_empty())
285 _codomain.set_empty();
297 if(prev_slice_ptr() && prev_slice_ptr()->is_gate())
298 prev_slice_ptr()->set_empty();
299 if(next_slice_ptr() && next_slice_ptr()->is_gate())
300 next_slice_ptr()->set_empty();
306 if constexpr(std::is_same<T,codac::IntervalVector>::value)
307 _codomain = T(size());
317 void set_component(
size_t i,
const Interval& xi)
319 assert((
size_t)codomain().size() == size());
324 _codomain[i] &= prev_slice_ptr()->codomain()[i];
326 _codomain[i] &= next_slice_ptr()->codomain()[i];
330 const Slice<T>& inflate(
double rad)
332 assert(rad >= 0. &&
"cannot inflate negative value");
333 _codomain.inflate(rad);
337 bool operator==(
const Slice& x)
const
339 return _codomain == x._codomain;
342 bool operator!=(
const Slice& x)
const
344 return _codomain != x._codomain;
347 friend std::ostream& operator<<(std::ostream& os,
const Slice& x)
350 <<
"↦" << x.codomain()
n-dimensional trajectory , defined as a temporal map of vector values
Definition codac_TrajectoryVector.h:38
#define EPSILON_CONTAINS
epsilon limit of the contains() algorithm
Definition codac2_Slice.h:27
TimePropag
Specifies the temporal propagation way (forward or backward in time)
Definition codac_DynCtc.h:27
@ BACKWARD
backward in time (from to )
@ FORWARD
forward in time (from to )