@@ -295,7 +295,7 @@ namespace codac2
295295 *
296296 * No propagation is performed on adjacent slices.
297297 */
298- inline void init () override
298+ inline void init ()
299299 {
300300 this ->T ::init ();
301301 // Nothing to propagate to adjacent codomains
@@ -306,7 +306,7 @@ namespace codac2
306306 *
307307 * Adjacent gates are updated accordingly.
308308 */
309- inline void set_empty () override
309+ inline void set_empty ()
310310 {
311311 set_empty (true );
312312 }
@@ -445,15 +445,39 @@ namespace codac2
445445 inline T operator ()(const Interval& t, const Slice<T>& v) const
446446 requires (std::is_same_v<T,Interval> || std::is_same_v<T,IntervalVector>)
447447 {
448+ // Avoid polygon intersections with truncated infinities.
449+ // Interval propagation gives a guaranteed (possibly less tight) enclosure.
450+ auto eval_unbounded = [&](const Interval& codom, const Interval& input,
451+ const Interval& output, const Interval& deriv) -> Interval
452+ {
453+ return codom
454+ & (input + (t-Interval (t0_tf ().lb ()))*deriv)
455+ & (output + (t-Interval (t0_tf ().ub ()))*deriv);
456+ };
457+
448458 if constexpr (std::is_same_v<T,Interval>)
459+ {
460+ Interval input = input_gate (), output = output_gate ();
461+ if (codomain ().is_unbounded () || input.is_unbounded ()
462+ || output.is_unbounded () || v.codomain ().is_unbounded ())
463+ return eval_unbounded (codomain (), input, output, v.codomain ());
464+
449465 return untrunc ((polygon_slice (v) & ConvexPolygon (cart_prod (t,trunc (codomain ())))).box ()[1 ]);
466+ }
450467
451468 else if constexpr (std::is_same_v<T,IntervalVector>)
452469 {
453470 T y = all_reals_value ();
454471 IntervalVector codom = codomain ();
472+ T input = input_gate (), output = output_gate ();
455473 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 ]);
474+ {
475+ if (codom[i].is_unbounded () || input[i].is_unbounded ()
476+ || output[i].is_unbounded () || v.codomain ()[i].is_unbounded ())
477+ y[i] &= eval_unbounded (codom[i], input[i], output[i], v.codomain ()[i]);
478+ else
479+ y[i] &= untrunc ((polygon_slice_i (v,i) & ConvexPolygon (cart_prod (t,trunc (codom[i])))).box ()[1 ]);
480+ }
457481 return y;
458482 }
459483 }
0 commit comments