Quadratic Minimum
QuadraticMinFunction computes the minimum of a list of quadratic polynomials and offers an exact selector mode or a lower-envelope relaxation.
Contract
- Input:
polynomials: List<QuadraticPolynomial<V>>. - Output/helper: real
resultVarnamed by appending_mintoname. - Direct evaluation returns the minimum; missing symbols or an empty candidate list result in
null. exact = truecreates one binary selector per candidate and aims to enforce exact minimum;exact = falseregisters onlyconstraints. - Generic values require
V : RealNumber<V>, V : Ring<V>, V : NumberField<V>and anIntoValue<V>converter.
WARNING
exact = false is a lower-envelope relaxation. Without an objective or another constraint pushing y upward, it need not equal the mathematical minimum.
Definition and mathematical model
For candidates
Exact mode additionally creates
The direct evaluator always computes exact.
Solver mathematical model
Kotlin
Let the quadratic candidates be
With exact = false, these are the only upper-bound rows; an objective or another constraint must push exact = true, the function also creates
Equivalently,
Rust
Rust first creates a signed continuous bridge
and, in exact mode:
The minimum rows therefore agree across the languages; the main structural difference is Rust's explicit bridge for every quadratic candidate.
Current API
Kotlin
Source: QuadraticMin.kt (QuadraticMinFunction)
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.QuadraticMinFunction
import fuookami.ospf.kotlin.core.token.AutoTokenTable
import fuookami.ospf.kotlin.math.algebra.number.Flt64
import fuookami.ospf.kotlin.math.symbol.Quadratic
import fuookami.ospf.kotlin.math.symbol.Symbol
import fuookami.ospf.kotlin.math.symbol.monomial.QuadraticMonomial
import fuookami.ospf.kotlin.math.symbol.polynomial.QuadraticPolynomial
import fuookami.ospf.kotlin.core.variable.RealVar
val x = RealVar("x")
val y = RealVar("y")
val first = QuadraticPolynomial(
listOf(QuadraticMonomial.quadratic(Flt64.one, x, y)), Flt64.one
)
val second = QuadraticPolynomial(
listOf(QuadraticMonomial.linear(Flt64.one, x)), Flt64.two
)
val minimum = QuadraticMinFunction(
polynomials = listOf(first, second),
exact = true,
bigM = Flt64(10.0),
converter = IntoValue.Identity,
name = "quadratic_min"
)
val tokens = AutoTokenTable<Flt64>(Quadratic, false)
tokens.add(listOf(x, y))
val value = minimum.prepare(
mapOf<Symbol, Flt64>(x to Flt64.two, y to Flt64(5.0)),
tokens,
IntoValue.Identity
)
check(value == Flt64(4.0))
tokens.close()Rust
Rust exposes QuadraticMinFunction<V>:
QuadraticMinFunction::new(
id: u64,
name: &str,
inputs: Vec<Quadratic<V>>,
exact: bool,
) -> QuadraticMinFunction<V>result_variable returns the inner name + "_min" variable and with_declared_dependencies preserves explicit dependency IDs. Each input is bridged by QuadraticLinearFunction; exact = true creates the inner binary selectors, while exact = false keeps only the lower-envelope upper inequalities. calculate_value always computes the mathematical minimum. When token bounds are available, mechanism_constraints_with_tokens infers Big-M from the original quadratic candidates; otherwise the generic fallback policy is used. Rust has no bigM constructor argument on this type.
use ospf_rust_core::symbol::flatten::{Quadratic, QuadraticMonomial};
use ospf_rust_core::symbol::function::QuadraticMinFunction;
let first = Quadratic::new(
vec![QuadraticMonomial::new_quadratic(1.0, 0, 1)],
1.0,
);
let second = Quadratic::new(
vec![QuadraticMonomial::new_linear(1.0, 0)],
2.0,
);
let minimum = QuadraticMinFunction::new(15, "quadratic_min", vec![first, second], true);
assert!(minimum.result_variable().name().contains("quadratic_min_min"));Evaluate versus solver
Direct evaluation is always the exact minimum. Exact solver mode needs valid Big-M ranges for all candidates; relaxed mode only guarantees an upper bound on
Boundaries, tolerance, and Undefined
The input list should be non-empty; an empty list makes the direct minimum null and provides no meaningful solver model. Missing values return null. There is no tolerance or three-valued Undefined state. Invalid or insufficient Big-M values can make exact registration fail or weaken it.
Examples and tests
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.QuadraticMinFunction
import fuookami.ospf.kotlin.core.token.AutoTokenTable
import fuookami.ospf.kotlin.math.algebra.number.Flt64
import fuookami.ospf.kotlin.math.symbol.Quadratic
import fuookami.ospf.kotlin.math.symbol.Symbol
import fuookami.ospf.kotlin.math.symbol.monomial.QuadraticMonomial
import fuookami.ospf.kotlin.math.symbol.polynomial.QuadraticPolynomial
import fuookami.ospf.kotlin.core.variable.RealVar
val x = RealVar("x")
val y = RealVar("y")
val first = QuadraticPolynomial(
listOf(QuadraticMonomial.quadratic(Flt64.one, x, y)), Flt64.one
)
val second = QuadraticPolynomial(
listOf(QuadraticMonomial.linear(Flt64.one, x)), Flt64.two
)
val minimum = QuadraticMinFunction(
polynomials = listOf(first, second),
exact = true,
bigM = Flt64(10.0),
converter = IntoValue.Identity,
name = "quadratic_min"
)
val tokens = AutoTokenTable<Flt64>(Quadratic, false)
tokens.add(listOf(x, y))
val value = minimum.prepare(
mapOf<Symbol, Flt64>(x to Flt64.two, y to Flt64(5.0)),
tokens,
IntoValue.Identity
)
check(value == Flt64(4.0))
tokens.close()use ospf_rust_core::symbol::FunctionSymbol;
use ospf_rust_core::symbol::flatten::{Quadratic, QuadraticMonomial};
use ospf_rust_core::symbol::function::QuadraticMinFunction;
use ospf_rust_core::token::{MutableTokenList, Token, VecTokenList};
use ospf_rust_core::variable::{ContinuousVariableItem, VariableId};
let x = ContinuousVariableItem::create(VariableId::standalone(0), "x");
let y = ContinuousVariableItem::create(VariableId::standalone(1), "y");
let mut tokens = VecTokenList::<f64>::new();
let tx = Token::from_generic(x, 0);
tx.set_result(2.0);
tokens.add_token(tx);
let ty = Token::from_generic(y, 1);
ty.set_result(5.0);
tokens.add_token(ty);
let minimum = QuadraticMinFunction::new(
16,
"quadratic_min",
vec![
Quadratic::new(vec![QuadraticMonomial::new_quadratic(1.0, 0, 1)], 1.0),
Quadratic::new(vec![QuadraticMonomial::new_linear(1.0, 0)], 2.0),
],
true,
);
assert_eq!(minimum.calculate_value(&tokens, false), Some(4.0));Core evaluation:
QuadraticFunctionGenericEvaluationTest.ktCore registration:
FunctionSymbolGenericRegistrationTest.ktExample directory (no dedicated quadratic-min file): quadratic_function
Rust implementation and focused tests:
quadratic_min.rsandquadratic_function.rs