Skip to content

Quadratic Positive Part ​

QuadraticPositivePartFunction gives both implementations the same unambiguous operation:

y=max{p(x),0}.

This is a positive-part function, not a semi-continuous variable. The old Rust name QuadraticSemiFunction has been removed. Semi-continuous domains remain the responsibility of the separate linear SemiFunction API.

Solver mathematical model ​

Kotlin ​

Kotlin uses the identity y=−min{−p(x),0}. Let t=min{−p(x),0} and u0,u1∈{0,1}. Its exact selector model is:

t≤−p(x),t≤0,t≥−p(x)−M(1−u0),t≥−M(1−u1),u0+u1=1,y=−t.

The public quadratic result expression is -resultVar; resultVar itself is the internal minimum t.

Rust ​

Rust first bridges the quadratic input as b=p(x) and then applies an exact two-candidate maximum:

b=p(x),y≥b,y≥0,y≤b+M(1−u0),y≤M(1−u1),u0+u1=1.

The formulations differ internally but define the same result and direct-evaluation contract.

API and examples ​

kotlin
val p = QuadraticPolynomial(
    monomials = listOf(QuadraticMonomial.quadratic(Flt64.one, x, x)),
    constant = -Flt64(4.0)
)
val positivePart = QuadraticPositivePartFunction(
    input = p,
    bigM = Flt64(100.0),
    converter = IntoValue.Identity,
    name = "positive_part"
)
// x = 1: max(1^2 - 4, 0) = 0
rust
let p = Quadratic::new(
    vec![QuadraticMonomial::new_quadratic(1.0, x_index, x_index)],
    -4.0,
);
let positive_part = QuadraticPositivePartFunction::new(
    17,
    "positive_part",
    p,
);
// x = 1: max(1^2 - 4, 0) = 0

Kotlin accepts an optional explicit bigM; otherwise it derives candidate-specific values from finite polynomial bounds. Rust derives the selector Big-M from registered token bounds when possible and otherwise uses its configured fallback.

Evaluation and boundaries ​

Direct evaluation returns zero for a negative input, the input for a positive value, and zero at the origin. Missing input values return null/None. This arithmetic function has no tolerance-based Undefined region.

Tests and source ​