Skip to content

Univariate Linear Piecewise Function ​

UnivariateLinearPiecewiseFunction represents the graph obtained by linearly interpolating consecutive points (ti,fi). Points must contain at least two entries and their ti values must be finite and strictly increasing. Evaluation outside [t0,tm] is undefined.

Solver mathematical model ​

Kotlin uses one binary selector zj per segment. With the affine formula gj(x)=ajx+bj, it enforces ∑jzj=1, gates x to the selected interval, and gates y=gj(x) with finite Big-M bounds.

Rust uses point weights λi∈[0,1] and the same one-hot segment selectors zj∈{0,1}. It enforces

∑iλi=1,∑jzj=1,x=∑itiλi,y=∑ifiλi.

Adjacency is enforced by

λ0≤z0,λm≤zm−1,λi≤zi−1+zi(0<i<m).

Consequently only the two endpoints of the selected segment may have positive weights. Although the internal formulas differ, both sides now represent the same single active segment and exclude arbitrary convex combinations of non-adjacent points.

Kotlin/Rust example ​

kotlin
val piecewise = UnivariateLinearPiecewiseFunction.fromPoints(
    x = input,
    points = points,
    converter = IntoValue.Identity,
    name = "ulp"
)
rust
let piecewise = UnivariateLinearPiecewiseFunction::new(
    1,
    "ulp",
    input,
    vec![
        Point2::new(0.0, 0.0),
        Point2::new(1.0, 2.0),
        Point2::new(2.0, 0.0),
    ],
);
assert_eq!(piecewise.selector_variables().len(), 2);

Evaluation and boundaries ​

On segment [ti,ti+1], direct evaluation uses

y=fi+x−titi+1−ti(fi+1−fi).

Missing input values and values outside the point domain return null in Kotlin and None in Rust. Duplicate, descending, non-finite, or insufficient points are rejected.

Tests and references ​

The focused tests assert the helper counts and every selector/segment graph row, along with endpoint and out-of-domain behavior and invalid point validation.

The point and segment forms share the same ordered-breakpoint contract. Kotlin uses breakpoints/slopes/intercepts directly; Rust also provides UnivariateLinearPiecewiseFunction::from_segments, with one slope and intercept for each adjacent breakpoint pair. Invalid values are rejected before helper registration.