codac
codac2_Slice.h
Go to the documentation of this file.
1 
12 #ifndef __CODAC2_SLICE_H__
13 #define __CODAC2_SLICE_H__
14 
15 #include <list>
16 #include <variant>
17 #include <memory>
18 #include "codac_Interval.h"
19 #include "codac_IntervalVector.h"
20 #include "codac_TrajectoryVector.h"
21 #include "codac_Exception.h"
22 #include "codac2_AbstractSlice.h"
23 #include "codac_BoolInterval.h"
24 #include "codac_ConvexPolygon.h"
25 #include "codac_DynCtc.h"
26 
27 #define EPSILON_CONTAINS ibex::next_float(0.) * 1000.
28 
29 namespace codac2
30 {
31  using codac::Interval;
33  using codac::BoolInterval;
34 
35  class AbstractSlicedTube;
36  class TSlice;
37 
38  template<class T>
39  class Slice : public AbstractSlice
40  {
41  public:
42 
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)
45  {
46 
47  }
48 
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)
51  {
52 
53  }
54 
55  Slice(const Slice& s) :
56  Slice(s, s._tubevector)
57  {
58 
59  }
60 
61  Slice(const Slice& s, const AbstractSlicedTube& tubevector) :
62  AbstractSlice(tubevector, s._it_tslice), _codomain(s._codomain)
63  {
64 
65  }
66 
67  ~Slice()
68  {
69 
70  }
71 
72  // Slice objects cannot be copyable or movable,
73  // as they are supposed to be connected to other Slice objects
74  Slice& operator=(const Slice&) = delete;
75  Slice(Slice&&) = delete;
76  Slice& operator=(Slice&&) = delete;
77 
78  const AbstractSlicedTube& tube_vector() const
79  {
80  return _tubevector;
81  }
82 
83  virtual std::shared_ptr<AbstractSlice> duplicate() const
84  {
85  return std::make_shared<Slice>(*this);
86  }
87 
88  virtual size_t size() const
89  {
90  // todo: define size() method in Interval class
91  if constexpr(std::is_same<T,Interval>::value)
92  return 1;
93  else
94  return codomain().size();
95  }
96 
97  double volume() const
98  {
99  if constexpr(std::is_same<T,Interval>::value)
100  return codomain().diam();
101  else
102  return codomain().volume();
103  }
104 
105  bool is_gate() const
106  {
107  return t0_tf().is_degenerated();
108  }
109 
110  bool is_empty() const
111  {
112  if(is_gate())
113  return _codomain.is_empty();
114  else
115  return input_gate().is_empty() || output_gate().is_empty();
116  }
117 
118  bool is_unbounded() const
119  {
120  return codomain().is_unbounded();
121  }
122 
123  BoolInterval contains(const TrajectoryVector& x) const
124  {
125  if constexpr(!std::is_same<T,codac::IntervalVector>::value)
126  {
127  assert(false && "not implemented");
128  return BoolInterval::MAYBE;
129  }
130 
131  else
132  {
133  if(!t0_tf().intersects(x.tdomain()))
134  return BoolInterval::MAYBE;
135 
136  BoolInterval is_contained = BoolInterval::YES;
137  if(!t0_tf().is_subset(x.tdomain()))
138  is_contained = BoolInterval::MAYBE;
139 
140  Interval t_ = t0_tf() & x.tdomain();
141  T traj_tdomain(x(t_));
142  // Using x(Interval(double)) for reliable evaluation:
143  T traj_input(x(Interval(t_.lb())));
144  T traj_output(x(Interval(t_.ub())));
145 
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;
150 
151  else
152  {
153  if(!traj_input.is_subset(input_gate()) || !traj_output.is_subset(output_gate()))
154  return BoolInterval::MAYBE;
155 
156  else if(traj_tdomain.is_subset(_codomain))
157  return is_contained;
158 
159  else // too much pessimism for the trajectory evaluation on t0_tf()
160  {
161  // Bisections are performed to reach an accurate evaluation
162 
163  std::list<Interval> s_subtdomains;
164  s_subtdomains.push_front(t_);
165 
166  while(!s_subtdomains.empty())
167  {
168  Interval t = s_subtdomains.front();
169  s_subtdomains.pop_front();
170 
171  T thinner_eval(x(t));
172 
173  if(!_codomain.intersects(thinner_eval))
174  {
175  return BoolInterval::NO;
176  }
177 
178  else if(!thinner_eval.is_subset(_codomain))
179  {
180  if(t.diam() < EPSILON_CONTAINS)
181  return BoolInterval::MAYBE;
182 
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()));
185  }
186  }
187 
188  return is_contained;
189  }
190  }
191  }
192  }
193 
194  const std::shared_ptr<Slice<T>> prev_slice_ptr() const
195  {
196  return std::static_pointer_cast<Slice<T>>(prev_abstract_slice_ptr());
197  }
198 
199  std::shared_ptr<Slice<T>> prev_slice_ptr()
200  {
201  return std::const_pointer_cast<Slice<T>>(
202  static_cast<const Slice&>(*this).prev_slice_ptr());
203  }
204 
205  const std::shared_ptr<Slice<T>> next_slice_ptr() const
206  {
207  return std::static_pointer_cast<Slice<T>>(next_abstract_slice_ptr());
208  }
209 
210  std::shared_ptr<Slice<T>> next_slice_ptr()
211  {
212  return std::const_pointer_cast<Slice<T>>(
213  static_cast<const Slice&>(*this).next_slice_ptr());
214  }
215 
216  const T& codomain() const
217  {
218  return _codomain;
219  }
220 
221  T input_gate() const
222  {
223  if(!prev_slice_ptr())
224  return codomain();
225 
226  else
227  {
228  if(prev_slice_ptr()->is_gate())
229  return prev_slice_ptr()->codomain();
230  else
231  return codomain() & prev_slice_ptr()->codomain();
232  }
233  }
234 
235  T output_gate() const
236  {
237  if(!next_slice_ptr())
238  return codomain();
239 
240  else
241  {
242  if(next_slice_ptr()->is_gate())
243  return next_slice_ptr()->codomain();
244  else
245  return codomain() & next_slice_ptr()->codomain();
246  }
247  }
248 
249  void set(const T& x, bool propagate = true)
250  {
251  if constexpr(!std::is_same<T,Interval>::value) { // 'if' to be removed with virtual set classes
252  assert((size_t)codomain().size() == size());
253  }
254 
255  _codomain = x;
256 
257  if(prev_slice_ptr())
258  {
259  if constexpr(!std::is_same<T,Interval>::value) { // 'if' to be removed with virtual set classes
260  assert((size_t)prev_slice_ptr()->codomain().size() == size());
261  }
262  if(is_gate())
263  _codomain &= prev_slice_ptr()->codomain();
264  else if(prev_slice_ptr()->is_gate())
265  prev_slice_ptr()->_codomain &= _codomain;
266  }
267 
268  if(next_slice_ptr())
269  {
270  if constexpr(!std::is_same<T,Interval>::value) { // 'if' to be removed with virtual set classes
271  assert((size_t)next_slice_ptr()->codomain().size() == size());
272  }
273  if(is_gate())
274  _codomain &= next_slice_ptr()->codomain();
275  else if(next_slice_ptr()->is_gate())
276  next_slice_ptr()->_codomain &= _codomain;
277  }
278 
279  if(propagate && is_empty())
281  }
282 
283  void set_empty(bool propagate = true, codac::TimePropag t_propa = codac::TimePropag::FORWARD | codac::TimePropag::BACKWARD)
284  {
285  _codomain.set_empty();
286 
287  if(propagate)
288  {
289  if(t_propa & codac::TimePropag::BACKWARD && prev_slice_ptr())
290  prev_slice_ptr()->set_empty(true, codac::TimePropag::BACKWARD);
291  if(t_propa & codac::TimePropag::FORWARD && next_slice_ptr())
292  next_slice_ptr()->set_empty(true, codac::TimePropag::FORWARD);
293  }
294 
295  else if(!is_gate())
296  {
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();
301  }
302  }
303 
304  void set_unbounded()
305  {
306  if constexpr(std::is_same<T,codac::IntervalVector>::value)
307  _codomain = T(size());
308  else
309  _codomain = T();
310 
311  //if constexpr(std::is_same<T,Interval>::value || std::is_same<T,codac::ConvexPolygon>::value) // 'if' to be removed with virtual set classes
312  // _codomain = T();
313  //else
314  // _codomain = T(size());
315  }
316 
317  void set_component(size_t i, const Interval& xi)
318  {
319  assert((size_t)codomain().size() == size());
320  _codomain[i] = xi;
321  if(is_gate())
322  {
323  if(prev_slice_ptr())
324  _codomain[i] &= prev_slice_ptr()->codomain()[i];
325  if(next_slice_ptr())
326  _codomain[i] &= next_slice_ptr()->codomain()[i];
327  }
328  }
329 
330  const Slice<T>& inflate(double rad)
331  {
332  assert(rad >= 0. && "cannot inflate negative value");
333  _codomain.inflate(rad);
334  return *this;
335  }
336 
337  bool operator==(const Slice& x) const
338  {
339  return _codomain == x._codomain;
340  }
341 
342  bool operator!=(const Slice& x) const
343  {
344  return _codomain != x._codomain;
345  }
346 
347  friend std::ostream& operator<<(std::ostream& os, const Slice& x)
348  {
349  os << x.t0_tf()
350  << "↦" << x.codomain()
351  << std::flush;
352  return os;
353  }
354 
355 
356  protected:
357 
358  T _codomain;
359  };
360 
361 } // namespace codac
362 
363 #endif
Definition: codac2_eigen.h:38
backward in time (from to )
n-dimensional trajectory , defined as a temporal map of vector values
Definition: codac_TrajectoryVector.h:37
forward in time (from to )
TimePropag
Specifies the temporal propagation way (forward or backward in time)
Definition: codac_DynCtc.h:26
#define EPSILON_CONTAINS
epsilon limit of the contains() algorithm
Definition: codac2_Slice.h:27