codac 2.0.0
Loading...
Searching...
No Matches
codac2_Slice.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include "codac2_SliceBase.h"
14#include "codac2_CtcDeriv.h"
15#include "codac2_cart_prod.h"
16#include "codac2_trunc.h"
17
18namespace codac2
19{
37 template<class T>
38 class Slice : public SliceBase,
39 protected T
40 // T class inheritance is protected, because modifying a
41 // Slice's codomain can affect adjacent gates if they exist
42 {
43 public:
44
52 explicit Slice(const SlicedTubeBase& tube, const std::list<TSlice>::iterator& it_tslice, const T& codomain)
53 : SliceBase(tube, it_tslice), T(codomain)
54 { }
55
65 Slice(const Slice& s, const SlicedTubeBase& tube)
66 : SliceBase(tube, s._it_tslice), T(s.codomain())
67 { }
68
69 // Slice objects cannot be copyable or movable,
70 // as they are supposed to be connected to other Slice objects
71 Slice(const Slice& s) = delete;
72 Slice& operator=(const Slice&) = delete;
73 Slice(Slice&&) = delete;
74 Slice& operator=(Slice&&) = delete;
75
81 inline const SlicedTube<T>& tube() const
82 {
83 return static_cast<const SlicedTube<T>&>(_tube);
84 }
85
91 inline std::shared_ptr<SliceBase> copy() const override
92 {
93 return std::make_shared<Slice>(*this, this->_tube);
94 }
95
101 inline Index size() const
102 {
103 return this->T::size();
104 }
105
113 inline T& codomain()
114 {
115 return static_cast<T&>(*this);
116 }
117
123 inline const T& codomain() const
124 {
125 return static_cast<const T&>(*this);
126 }
127
135 inline bool is_gate() const
136 {
137 return t0_tf().is_degenerated();
138 }
139
145 inline std::shared_ptr<const Slice<T>> prev_slice() const
146 {
147 return std::static_pointer_cast<const Slice<T>>(
148 this->SliceBase::prev_slice());
149 }
150
156 inline std::shared_ptr<Slice<T>> prev_slice()
157 {
158 return std::const_pointer_cast<Slice<T>>(
159 static_cast<const Slice<T>&>(*this).prev_slice());
160 }
161
167 inline std::shared_ptr<const Slice<T>> next_slice() const
168 {
169 return std::static_pointer_cast<const Slice<T>>(
170 this->SliceBase::next_slice());
171 }
172
178 inline std::shared_ptr<Slice<T>> next_slice()
179 {
180 return std::const_pointer_cast<Slice<T>>(
181 static_cast<const Slice<T>&>(*this).next_slice());
182 }
183
194 inline T input_gate() const
195 {
196 if(!prev_slice())
197 return codomain();
198
199 else
200 {
201 if(prev_slice()->is_gate())
202 return prev_slice()->codomain();
203 else
204 return codomain() & prev_slice()->codomain();
205 }
206 }
207
218 inline T output_gate() const
219 {
220 if(!next_slice())
221 return codomain();
222
223 else
224 {
225 if(next_slice()->is_gate())
226 return next_slice()->codomain();
227 else
228 return codomain() & next_slice()->codomain();
229 }
230 }
231
242 inline std::pair<T,T> enclosed_bounds(const Interval& t) const
243 {
244 T x = *this; x.set_empty();
245 auto bounds = std::make_pair(x,x);
246
247 if(t.lb() < t0_tf().lb() || t.ub() > t0_tf().ub())
248 {
249 x.init(Interval(-oo,0));
250 bounds.first |= x;
251 x.init(Interval(0,oo));
252 bounds.second |= x;
253 }
254
255 if(t.contains(t0_tf().lb()))
256 {
257 bounds.first |= input_gate().lb();
258 bounds.second |= input_gate().ub();
259 }
260
261 if(t.contains(t0_tf().ub()))
262 {
263 bounds.first |= output_gate().lb();
264 bounds.second |= output_gate().ub();
265 }
266
267 if(t.is_subset(t0_tf()) && t != t0_tf().lb() && t != t0_tf().ub())
268 {
269 bounds.first |= this->lb();
270 bounds.second |= this->ub();
271 }
272
273 return bounds;
274 }
275
285 inline void set(const T& x, bool propagate = true)
286 {
287 assert_release(x.size() == this->size());
288 codomain() = x;
289 if(propagate)
291 }
292
298 inline void init()
299 {
300 this->T::init();
301 // Nothing to propagate to adjacent codomains
302 }
303
309 inline void set_empty()
310 {
311 set_empty(true);
312 }
313
322 inline bool operator==(const Slice& x) const
323 {
324 return codomain() == x.codomain();
325 }
326
336 inline ConvexPolygon polygon_slice(const Slice<T>& v) const
337 requires std::is_same_v<T,Interval>
338 {
339 const Interval& t = this->t0_tf();
340 Interval input = this->input_gate(), output = this->output_gate();
341
342 // /!\ .diam() method is not reliable (floating point result)
343 // -> We need to compute the diameter with intervals
344 Interval d = Interval(t.ub())-Interval(t.lb());
345
346 Interval proj_output = input + d * v;
347 Interval proj_input = output - d * v;
348
349 return CtcDeriv::polygon_slice(
350 t, *this,
351 input, proj_input,
352 output, proj_output,
353 v);
354 }
355
364 inline ConvexPolygon polygon_slice_i(const Slice<T>& v, Index i) const
365 requires std::is_same_v<T,IntervalVector>
366 {
367 const Interval& t = this->t0_tf();
368
369 // /!\ .diam() method is not reliable (floating point result)
370 // -> We need to compute the diameter with intervals
371 Interval d = Interval(t.ub())-Interval(t.lb());
372
373 Interval input = this->input_gate()[i], output = this->output_gate()[i];
374 Interval proj_output = input + d * v[i];
375 Interval proj_input = output - d * v[i];
376
377 return CtcDeriv::polygon_slice(
378 t, (*this)[i],
379 input, proj_input,
380 output, proj_output,
381 v[i]);
382 }
383
390 inline T operator()(double t) const
391 {
392 if(t == t0_tf().lb())
393 return input_gate();
394
395 else if(t == t0_tf().ub())
396 return output_gate();
397
398 else if(t0_tf().contains(t))
399 return codomain();
400
401 else
402 return all_reals_value();
403 }
404
411 inline T operator()(const Interval& t) const
412 {
413 if(t.is_degenerated())
414 return operator()(t.lb());
415
416 else if(t.is_subset(t0_tf()))
417 return codomain();
418
419 else
420 return all_reals_value();
421 }
422
431 inline T operator()(double t, const Slice<T>& v) const
432 requires (std::is_same_v<T,Interval> || std::is_same_v<T,IntervalVector>)
433 {
434 return operator()(Interval(t),v);
435 }
436
445 inline T operator()(const Interval& t, const Slice<T>& v) const
446 requires (std::is_same_v<T,Interval> || std::is_same_v<T,IntervalVector>)
447 {
448 if constexpr(std::is_same_v<T,Interval>)
449 return untrunc((polygon_slice(v) & ConvexPolygon(cart_prod(t,trunc(codomain())))).box()[1]);
450
451 else if constexpr(std::is_same_v<T,IntervalVector>)
452 {
453 T y = all_reals_value();
454 IntervalVector codom = codomain();
455 for(Index i = 0 ; i < size() ; i++)
456 y[i] &= untrunc((polygon_slice_i(v,i) & ConvexPolygon(cart_prod(t,trunc(codom[i])))).box()[1]);
457 return y;
458 }
459 }
460
468 inline Interval invert(const T& y, const Interval& t = Interval()) const
469 {
470 if(t.is_empty())
471 return Interval::empty();
472
473 else if(t.is_strict_superset(t0_tf()))
474 return Interval();
475
476 else if((t0_tf() & t) == t0_tf() && codomain().is_subset(y))
477 return t0_tf();
478
479 else if(t == t0_tf().lb())
480 {
481 if(y.intersects(input_gate()))
482 return t0_tf().lb();
483 else
484 return Interval::empty();
485 }
486
487 else if(t == t0_tf().ub())
488 {
489 if(y.intersects(output_gate()))
490 return t0_tf().ub();
491 else
492 return Interval::empty();
493 }
494
495 else
496 {
497 if(y.intersects(codomain()))
498 return t & t0_tf();
499 else
500 return Interval::empty();
501 }
502 }
503
514 inline Interval invert(const T& y, const Slice<T>& v, const Interval& t = Interval()) const
515 requires (std::is_same_v<T,Interval> || std::is_same_v<T,IntervalVector>)
516 {
517 if(t.is_empty() || y.is_empty())
518 return Interval::empty();
519
520 else if(!t.is_subset(t0_tf()))
521 return Interval();
522
523 else
524 {
525 if constexpr(std::is_same_v<T,Interval>)
526 return untrunc((polygon_slice(v) & ConvexPolygon(cart_prod(t,trunc(y)))).box()[0]);
527
528 else if constexpr(std::is_same_v<T,IntervalVector>)
529 {
530 Interval t_(t);
531 for(Index i = 0 ; i < size() ; i++)
532 if(!t_.is_empty())
533 t_ &= untrunc((polygon_slice_i(v,i) & ConvexPolygon(cart_prod(t_,trunc(y[i])))).box()[0]);
534 return t_;
535 }
536 }
537 }
538
546 friend inline std::ostream& operator<<(std::ostream& os, const Slice& x)
547 {
548 os << x.t0_tf()
549 << "↦" << x.codomain()
550 << std::flush;
551 return os;
552 }
553
559 inline T all_reals_value() const
560 {
561 T x = codomain();
562 x.init();
563 return x;
564 }
565
571 inline T empty_value() const
572 {
573 T x = codomain();
574 x.set_empty();
575 return x;
576 }
577
578
579 protected:
580
581 template<typename T_>
582 friend class SlicedTube;
583
589 inline void set_empty(bool propagate)
590 {
591 this->T::set_empty();
592 if(propagate)
594 }
595
603 {
604 if(prev_slice())
605 {
606 assert(prev_slice()->size() == this->size());
607 if(is_gate())
608 codomain() &= prev_slice()->codomain();
609 else if(prev_slice()->is_gate())
610 prev_slice()->codomain() &= codomain();
611 }
612
613 if(next_slice())
614 {
615 assert(next_slice()->size() == this->size());
616 if(is_gate())
617 codomain() &= next_slice()->codomain();
618 else if(next_slice()->is_gate())
619 next_slice()->codomain() &= codomain();
620 }
621 }
622 };
623}
Represents a convex polygon defined by vertices enclosed in IntervalVectors.
Definition codac2_ConvexPolygon.h:25
Interval class, for representing closed and connected subsets of .
Definition codac2_Interval.h:49
bool is_empty() const
Tests if this is empty.
Definition codac2_Interval_impl.h:205
double ub() const
Returns the upper bound of this.
Definition codac2_Interval_impl.h:115
bool is_degenerated() const
Tests if this is degenerated, that is, in the form of .
Definition codac2_Interval_impl.h:225
bool is_subset(const Interval &x) const
Tests if this is a subset of x.
Definition codac2_Interval_impl.h:255
bool contains(const double &x) const
Tests if this contains x.
Definition codac2_Interval_impl.h:210
double lb() const
Returns the lower bound of this.
Definition codac2_Interval_impl.h:110
static Interval empty()
Provides an empty interval.
Definition codac2_Interval_impl.h:568
SliceBase(const SlicedTubeBase &tube, const std::list< TSlice >::iterator &it_tslice)
Creates a slice attached to a tube and a temporal slice.
std::list< TSlice >::iterator _it_tslice
Iterator to the associated temporal slice.
Definition codac2_SliceBase.h:115
const SlicedTubeBase & _tube
Parent sliced tube.
Definition codac2_SliceBase.h:110
const Interval & t0_tf() const
Returns the temporal domain of this slice.
std::shared_ptr< const SliceBase > next_slice() const
Returns the next slice of the same tube.
std::shared_ptr< const SliceBase > prev_slice() const
Returns the previous slice of the same tube.
Codomain of a sliced tube over one temporal slice.
Definition codac2_Slice.h:42
std::shared_ptr< Slice< T > > prev_slice()
Returns the previous slice.
Definition codac2_Slice.h:156
void set_empty(bool propagate)
Sets this codomain to the empty set.
Definition codac2_Slice.h:589
std::shared_ptr< const Slice< T > > next_slice() const
Returns the next slice.
Definition codac2_Slice.h:167
Slice(const SlicedTubeBase &tube, const std::list< TSlice >::iterator &it_tslice, const T &codomain)
Creates a slice attached to a tube over a temporal slice.
Definition codac2_Slice.h:52
Interval invert(const T &y, const Interval &t=Interval()) const
Returns the interval inversion .
Definition codac2_Slice.h:468
std::shared_ptr< SliceBase > copy() const override
Duplicates this slice.
Definition codac2_Slice.h:91
T operator()(const Interval &t) const
Returns the evaluation of this slice over .
Definition codac2_Slice.h:411
ConvexPolygon polygon_slice_i(const Slice< T > &v, Index i) const
Returns the polygonal enclosure associated with one component of a vector slice.
Definition codac2_Slice.h:364
Interval invert(const T &y, const Slice< T > &v, const Interval &t=Interval()) const
Returns the optimal interval inversion .
Definition codac2_Slice.h:514
bool is_gate() const
Tests whether this slice is a gate.
Definition codac2_Slice.h:135
T all_reals_value() const
Returns the unbounded value associated with this codomain type.
Definition codac2_Slice.h:559
T & codomain()
Returns a mutable reference to the codomain.
Definition codac2_Slice.h:113
std::shared_ptr< const Slice< T > > prev_slice() const
Returns the previous slice.
Definition codac2_Slice.h:145
T input_gate() const
Returns the input gate of this slice.
Definition codac2_Slice.h:194
bool operator==(const Slice &x) const
Compares two slices.
Definition codac2_Slice.h:322
const T & codomain() const
Returns a constant reference to the codomain.
Definition codac2_Slice.h:123
Slice(const Slice &s, const SlicedTubeBase &tube)
Creates a slice from another one for a given tube.
Definition codac2_Slice.h:65
void set_empty()
Sets this codomain to the empty set.
Definition codac2_Slice.h:309
Index size() const
Returns the codomain dimension.
Definition codac2_Slice.h:101
T output_gate() const
Returns the output gate of this slice.
Definition codac2_Slice.h:218
T operator()(double t, const Slice< T > &v) const
Returns the optimal evaluation of this slice at , based on the derivative information .
Definition codac2_Slice.h:431
T empty_value() const
Returns the empty value associated with this codomain type.
Definition codac2_Slice.h:571
T operator()(double t) const
Returns the evaluation of this slice at .
Definition codac2_Slice.h:390
std::pair< T, T > enclosed_bounds(const Interval &t) const
Returns enclosed lower and upper bounds over a temporal interval.
Definition codac2_Slice.h:242
ConvexPolygon polygon_slice(const Slice< T > &v) const
Returns the polygonal enclosure associated with this scalar slice.
Definition codac2_Slice.h:336
void update_adjacent_codomains()
Propagates codomain contractions to adjacent gates.
Definition codac2_Slice.h:602
std::shared_ptr< Slice< T > > next_slice()
Returns the next slice.
Definition codac2_Slice.h:178
const SlicedTube< T > & tube() const
Returns the sliced tube owning this slice.
Definition codac2_Slice.h:81
void init()
Initializes this codomain to its unbounded value.
Definition codac2_Slice.h:298
void set(const T &x, bool propagate=true)
Sets the codomain of this slice.
Definition codac2_Slice.h:285
T operator()(const Interval &t, const Slice< T > &v) const
Returns the optimal evaluation of this slice over , based on the derivative information .
Definition codac2_Slice.h:445
friend std::ostream & operator<<(std::ostream &os, const Slice &x)
Stream output for a slice.
Definition codac2_Slice.h:546
Base class for tubes defined over a sliced temporal domain.
Definition codac2_SlicedTubeBase.h:35
Tube represented over a sliced temporal domain.
Definition codac2_SlicedTube.h:38
bool is_subset(const Matrix< codac2::Interval, RowsAtCompileTime, ColsAtCompileTime > &x) const
Checks whether this matrix is a subset of another interval matrix.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:678
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:408
auto ub() const
Returns a matrix containing the upper bounds of each interval element.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:103
auto lb() const
Returns a matrix containing the lower bounds of each interval element.
Definition codac2_MatrixBase_addons_IntervalMatrixBase.h:91
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