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