The IntervalVector class

Main author: Simon Rohou

An IntervalVector represents an axis-aligned box (Cartesian product of intervals) in \(\mathbb{R}^n\):

\[[\mathbf{x}] = [x_1]\times [x_2]\times \dots \times [x_n].\]

In C++, IntervalVector is an alias for an Eigen dynamic column vector whose scalar type is Interval (i.e., Eigen::Matrix<Interval,-1,1>). This means you can use the usual Eigen vector API (size/resize/segment/concatenation patterns) while benefiting from Codac’s interval arithmetic and utilities. In Python and Matlab, some of these functions are available.

Creating IntervalVectors

A box can be created from:

  • a dimension \(n\) (components initialized with the default interval \([-\infty,\infty]\)),

  • a dimension \(n\) and a common interval (a “cube”),

  • a list of intervals or bounds pairs,

  • a real vector (degenerate box wrapping a point).

# Default box: [-oo,oo]^n
x = IntervalVector(3)

# Cube [-1,3]^2
y = IntervalVector.constant(2,[-1,3])

# From a list of bounds (each entry is [lb,ub])
z = IntervalVector([[3,4],[4,6]]) # [3,4]×[4,6]

# From a list of components (Intervals and/or bounds pairs)
q = IntervalVector([y[1], z[0], [0,oo]]) # [-1,3]×[3,4]×[0,oo]

# From a point (degenerate intervals)
p = Vector([0.42,0.42,0.42])
bp = IntervalVector(p) # [0.42,0.42]^3

Note

Codac intentionally does not enable Eigen’s “initialize matrices by zero” option for interval-based vectors and matrices, because default-initializing an interval should produce \([-\infty,\infty]\) rather than 0. As a result, resizing an IntervalVector typically creates new components initialized as \([-\infty,\infty]\).

Accessing and modifying components

Components are intervals; indexing is 0-based in Python/C++ and 1-based in Matlab.

x = IntervalVector.constant(2,[-1,3]) # [-1,3]^2
x[1] = Interval(0,10) # [-1,3]×[0,10]

# Iterating/accessing over components
y = IntervalVector(2)
for i, xi in enumerate(x):
  y[i] = xi

# Unpacking (Python convenience)
a,b = x
assert a == x[0] and b == x[1]

# Building a new box from existing components
v = IntervalVector([*x, [3,6]]) # concatenation in Python
# v == [[-1,3]×[0,10]×[3,6]]

# Resize: new components are default-initialized ([-oo,oo])
v.resize(4) # v == [[-1,3]×[0,10]×[3,6]×[-oo,oo]]
s = v.subvector(1,2) # [0,10]×[3,6]

Box properties

Most scalar properties of Interval have natural extensions to boxes:

  • component-wise bounds: \(\mathbf{x}^-\) and \(\mathbf{x}^+\),

  • component-wise widths (diameters/radii),

  • geometric metrics such as volume or max diameter.

Typical accessors you will use in practice:

x = IntervalVector([[0,2],[-1,3]])

n = x.size()        # dimension
# Common box information (component-wise):
lo = x.lb()         # Vector of lower bounds
hi = x.ub()         # Vector of upper bounds
m  = x.mid()        # Vector of midpoints
d  = x.diam()       # Vector of diameters

Note

The exact set of box-wide metrics available (e.g., max_diam(), volume(), argmax_diam()) is provided by the interval-based Eigen extensions used in Codac. See the technical documentation section at the end of this page for the comprehensive list.

Testing boxes

Common predicates include:

  • is_empty(): tests whether the box represents the empty set (at least one empty component),

  • is_degenerated(): all components are degenerate,

  • is_degenerated(): at least one component is degenerate,

  • is_unbounded(): at least one bound is infinite,

  • contains(p): inclusion test of a point/vector,

  • intersects(y): non-empty intersection test with another box,

  • is_subset(y), is_strict_subset(y), etc.

x = IntervalVector([[0,1],[2,3]])
y = IntervalVector([[-0.5,2],[1,4]])

assert x.intersects(y)
assert x.is_subset(y)

Advanced operations

As for intervals, typical advanced operations on boxes include:

Common advanced methods for a given box \([\mathbf{x}]\)

Method

Description

inflate(rad)

Expands the box by ±rad (scalar radius for common inflation, or vector radius for specifying different inflation on each component).

bisect([ratio])

Splits the box into two sub-boxes along the widest dimension.

rand()

Returns a random sample Vector inside the box (when non-empty).

init()

Re-initializes to \([-\infty,\infty]^n\).

Arithmetic and linear algebra

Because IntervalVector is a vector of Interval, standard arithmetic is naturally extended component-wise:

  • box–box and box–scalar operations (+, -, *, /),

  • interactions with real vectors/matrices,

  • matrix–vector products involving IntervalMatrix.

    x = IntervalVector([[0,1],[2,3]])
    y = IntervalVector([[1,2],[0,1]])
    
    z1 = x+y
    z2 = 2*x
    z3 = x/2
    

Technical documentation

See the C++ API documentation of the IntervalVector class.