Skip to content

Cosine ​

CosFunction is a sampled, piecewise-linear approximation of cosine. It is a linear modeling primitive, not an exact trigonometric solver function.

WARNING

The default model is defined only by five samples on [−π,π]. Values outside the breakpoint domain evaluate to null, and values between samples follow straight-line interpolation.

Contract ​

  • Input: x: LinearPolynomial<V>.
  • Output: result, a linear polynomial supplied by the delegated univariate piecewise function.
  • Samples: List<Point<Dim2, Flt64>> containing (x,cos⁡x) points; the default list is generated by the implementation.
  • Generic values use V : RealNumber<V>, V : NumberField<V> and an IntoValue<V> converter.
  • Registration adds the ordinary univariate piecewise-linear helper variables and constraints.

Definition and mathematical model ​

For ordered sample points (ai,bi), each segment is

si=bi+1−biai+1−ai,ci=bi−siai,y=six+ci(ai≤x≤ai+1).

The default samples are exactly:

(−π,−1),(−π2,0),(0,1),(π2,0),(π,−1).

Thus the default is a five-point linear interpolation of cosine, with no periodic extension and no exact cos⁡(x) evaluation.

Solver mathematical model ​

Kotlin delegates to the binary-selector model. For every sampled segment [ti,ti+1] with affine interpolation fi(x)=aix+bi, it registers

∑izi=1,ti−MiL(1−zi)≤x≤ti+1+MiU(1−zi),fi(x)−Mi−(1−zi)≤y≤fi(x)+Mi+(1−zi),zi∈{0,1}.

Rust fixes 32 segments. With segment width h, selector zi∈{0,1}, and gated within-segment offset 0≤δi≤hzi, its equivalent registered form is

∑izi=1,x=∑i(tizi+δi),y=∑i(cos⁡tizi+aiδi).

Neither solver receives an exact trigonometric constraint.

Current API ​

Kotlin ​

Source: Cos.kt (CosFunction)

kotlin
CosFunction(
    x: LinearPolynomial<V>,
    samplingPoints: List<Point<Dim2, Flt64>> = defaultPoints(),
    converter: IntoValue<V>,
    name: String = "cos",
    displayName: String? = null
)

The factory also accepts an explicit samplingPoints list. Points must be finite, have at least two entries, and have strictly increasing x-coordinates when the delegated piecewise implementation is registered or evaluated.

Rust ​

Source: cos.rs

Rust provides CosFunction::new(id, name, input) with the flattened Linear<V> input, plus with_declared_dependencies. result_variable() and input_polynomial() expose the registered result and input. There is no public Rust sampling-point argument: the mechanism fixes 32 segments over [−π,π]. Rust's token evaluator calls exact f64::cos(), while its registered mechanism constraints use the 32-segment piecewise approximation; this differs from Kotlin, whose evaluator follows the supplied sampling-point interpolation.

rust
CosFunction::new(id: u64, name: &str, input: Linear<V>) -> Self
CosFunction::with_declared_dependencies(self, dependency_ids: Vec<u64>) -> Self
CosFunction::result_variable(&self) -> &ContinuousVariableItem
CosFunction::input_polynomial(&self) -> &Linear<V>

Evaluate versus solver ​

evaluate follows the same delegated piecewise interpolation used by registration, but returns null for a missing input or an x-value outside the first and last breakpoints. Solver registration does not add an exact trigonometric relation; it registers the piecewise linear approximation and its Big-M/segment constraints.

Boundaries, tolerance, and Undefined ​

This function has no three-valued condition classifier and no tolerance parameter of its own. The numeric conversion and piecewise validation are the relevant boundaries. A malformed sample list (fewer than two points, non-finite values, duplicate or descending x-coordinates) fails the delegated piecewise validation. The endpoint convention is closed for the available segments.

Minimal current example ​

kotlin
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.CosFunction
import fuookami.ospf.kotlin.math.algebra.number.Flt64
import fuookami.ospf.kotlin.math.symbol.Symbol
import fuookami.ospf.kotlin.math.symbol.monomial.LinearMonomial
import fuookami.ospf.kotlin.math.symbol.polynomial.LinearPolynomial
import fuookami.ospf.kotlin.core.variable.RealVar

val x = RealVar("x")
val xPoly = LinearPolynomial(
    listOf(LinearMonomial(Flt64.one, x)), Flt64.zero
)
val cosine = CosFunction(
    x = xPoly,
    converter = IntoValue.Identity,
    name = "cosine"
)
val value = cosine.evaluate(mapOf<Symbol, Flt64>(x to Flt64.zero))
check(value != null && value == Flt64.one)
rust
use ospf_rust_core::symbol::flatten::Linear;
use ospf_rust_core::symbol::function::CosFunction;
use ospf_rust_core::symbol::FunctionSymbol;
use ospf_rust_core::token::VecTokenList;

let function = CosFunction::new(1, "cos", Linear::new(vec![], 0.0));
let value = <CosFunction as FunctionSymbol>::calculate_value(
    &function,
    &VecTokenList::<f64>::new(),
    false,
);
assert_eq!(value, Some(1.0));

Tests and examples ​