codac 1.5.6
Loading...
Searching...
No Matches
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"
21#include "codac_Exception.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
29namespace 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
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 )