The Slice and TSlice classes
Main author: Simon Rohou
At the implementation level, sliced tubes are built from two complementary classes:
TSlice, which stores one temporal support,Slice, which stores one codomain over that support for one given tube.
Slice: one codomain over one temporal support
A Slice is the codomain carried by one sliced tube over one temporal interval. The codomain type is typically Interval or IntervalVector, and the class uses protected inheritance from this codomain type so that updates can be controlled and, if necessary, propagated to adjacent gates.
Each slice knows:
its parent tube,
its temporal interval
t0_tf(),its previous and next slices,
its codomain,
whether its temporal support is a gate.
Input and output gates
A central concept in the current implementation is the distinction between the interior codomain of a slice and its endpoint values. For a non-gate slice, endpoint values are obtained through
input_gate()output_gate()
If an explicit neighboring gate exists, its codomain is used. Otherwise, the endpoint enclosure is the intersection of adjacent slice codomains. This is what makes endpoint evaluation meaningful even when gates are not explicitly represented.
Without explicit gates, evaluating a tube at a slice boundary returns the intersection of the neighboring slice values.
td = create_tdomain([0,2], 1., False)
x = SlicedTube(td, Interval())
x.set([1,5], [0,1])
x.set([2,8], [1,2])
s = x.first_slice()
boundary = s.output_gate() # [2,5]
auto td = create_tdomain({0,2}, 1., false);
SlicedTube x(td, Interval());
x.set({1,5}, {0,1});
x.set({2,8}, {1,2});
auto s = x.first_slice();
auto boundary = s->output_gate(); // [2,5]
Evaluation and inversion at slice level
A scalar or vector slice can be evaluated with:
s(t)at one time,s([ta,tb])over a temporal interval.
At the lower bound, evaluation returns the input gate. At the upper bound, it returns the output gate. Inside the slice, it returns the interior codomain. Outside the temporal support, it returns the unbounded codomain value.
The inversion API mirrors this structure:
invert(y, t)computes a local inverse image,invert(y, v, t)uses a derivative slice for a sharper inverse image.
The following example illustrates inversion over a selected temporal interval.
td = create_tdomain([0,1])
x = SlicedTube(td, Interval(0,10))
x.set([2,3], 0)
x.set([5,6], 1)
s = x.first_slice()
possible_times = s.invert([2.5,6], [0.2,0.5])
auto td = create_tdomain({0,1});
SlicedTube x(td, Interval(0,10));
x.set({2,3}, 0.);
x.set({5,6}, 1.);
auto s = x.first_slice();
auto possible_times = s->invert(Interval(2.5,6), Interval(0.2,0.5));
Derivative-aware polygonal model
For scalar codomains, and componentwise for vector codomains, a slice can build a polygonal enclosure from:
its temporal support,
its input and output gates,
a derivative slice.
This is exposed by:
polygon_slice(v)for scalar slices,polygon_slice_i(v, i)for vector slices.
This polygonal enclosure is used in derivative-aware evaluation and inversion.
Enclosed bounds
The method enclosed_bounds(t) returns a pair of codomain objects whose components enclose the reachable lower and upper bounds over the queried temporal interval. This is useful when you want more structural information than the plain union returned by a simple evaluation.