Programming examples

Main author: Simon Rohou

The following examples illustrate basic operations on sliced tubes.

Example 1: building and evaluating a scalar tube

The following example builds a scalar tube over a sampled temporal domain and assigns different values on successive temporal intervals.

td = create_tdomain([0,3], 1., False)
x = SlicedTube(td, Interval()) # [-∞,∞] by default for any time
x.set([1,5], [0,1])
x.set([2,8], [1,2])
x.set([6,9], [2,3])
y0 = x([0,3])
y1 = x(1.5)
y2 = x(1.)

Example 2: refining a temporal domain from a tube update

Local assignments refine the shared temporal partition when necessary.

td = create_tdomain([0,1], 0.1, False)
x = SlicedTube(td, IntervalVector(3))
before = td.nb_tslices()
x.set(IntervalVector.constant(3,[2,3]), -42.)
after = td.nb_tslices() # the partition was extended and refined

The same partition is updated for all tubes sharing the temporal domain.

Example 3: tube from an analytic function

For \(f(t)=10\cos(t)+t\), a SlicedTube encloses the function over each time slice rather than evaluating it only at isolated timestamps.

td = create_tdomain([0,5], 0.1, True)
t = ScalarVar()
f = AnalyticFunction([t], 10*cos(t) + t)
x = SlicedTube(td, f) # encloses f(t) over each time slice

Example 4: derivative-aware slice reasoning

The following pattern uses a derivative tube and CtcDeriv to sharpen a scalar slice. The slice can then build a polygonal enclosure used for refined evaluation or inversion.

td = create_tdomain([6.4,6.5])
x = SlicedTube(td, Interval(0.759,1.205))
v = SlicedTube(td, Interval(-0.216,-0.115))
x.set(Interval(0.781,1.205), 6.4)
x.set(Interval(0.759,1.194), 6.5)
CtcDeriv().contract(x,v)
sx = x.first_slice()
sv = v.first_slice()
polygon = sx.polygon_slice(sv)

The derivative constraint can narrow the tube before evaluating individual slices.

Example 5: integration and primitive tubes

The integration API supports point and interval queries and can also build a primitive tube.

td = create_tdomain([0,2], 0.5, True)
x = SlicedTube(td, Interval(1,2))
integral_at_one = x.integral(Interval(1))
integral_over_range = x.integral(Interval(0.5,1.5))
p = x.primitive(Interval(0))

Example 6: Cartesian product of tubes

When several sliced tubes share the same temporal domain, you can build a vector-valued tube by stacking their codomains slice by slice.

td = create_tdomain([0,1], 0.5, False)
x1 = SlicedTube(td, Interval(0,1))
x2 = SlicedTube(td, IntervalVector([[1,2],[-1,1]]))
x = tube_cart_prod(x1, x2) # vector tube of dimension 3

All inputs must share the same temporal-domain object.

For the analogous operation on SampledTraj objects, see Operations on trajectories (traj_cart_prod).