Skip to content

余弦 ​

CosFunction 是余弦函数的采样分段线性近似。它是线性建模原语,不是精确的三角函数求解器函数。

WARNING

默认模型只在 [−π,π] 上使用五个采样点定义。断点域外的值求值为 null,采样点之间使用直线插值。

契约 ​

  • 输入:x: LinearPolynomial<V>。
  • 输出:由委托的一元分段函数提供的线性多项式 result。
  • 采样点:包含 (x,cos⁡x) 点的 List<Point<Dim2, Flt64>>;默认列表由实现生成。
  • 泛型值使用 V : RealNumber<V>, V : NumberField<V>,并配合 IntoValue<V> 转换器。
  • 注册时添加普通一元分段线性实现的辅助变量和约束。

定义与数学模型 ​

对于有序采样点 (ai,bi),每段为

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

默认采样点严格为:

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

因此默认实现是五点余弦线性插值,没有周期扩展,也不会精确计算 cos⁡(x)。

求解器数学模型 ​

Kotlin 委托给二值分段选择模型。对每个采样段 [ti,ti+1] 及其仿射插值 fi(x)=aix+bi,实际注册

∑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 固定使用 32 段。令段宽为 h、选择变量 zi∈{0,1}、段内偏移满足 0≤δi≤hzi,其等价注册形式为

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

两种实现都不会向求解器传入精确三角函数约束。

当前 API ​

Kotlin ​

源码:Cos.kt(CosFunction)

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

工厂也接受显式的 samplingPoints 列表。交给分段实现注册或求值时,点必须至少有两个、值为有限数,且 x 坐标严格递增。

Rust ​

源码:cos.rs

Rust 使用平展后的 Linear<V> 输入提供 CosFunction::new(id, name, input),并支持 with_declared_dependencies。result_variable() 和 input_polynomial() 暴露已注册的结果与输入。Rust 没有公开的采样点参数:机理层固定在 [−π,π] 上使用 32 段。Rust token 求值器调用精确的 f64::cos(),而注册的机理约束使用 32 段分段近似;这不同于 Kotlin(Kotlin 的求值器遵循调用方提供的采样点插值)。

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 与 solver 的差异 ​

evaluate 使用与注册相同的分段线性插值;输入缺失或 x 落在首尾断点之外时返回 null。solver 注册不会添加精确三角函数关系,而是注册分段线性近似及其 Big-M/分段约束。

边界、tolerance 与 Undefined ​

该函数没有自己的三值条件判定器或 tolerance 参数,相关边界是数值转换和分段校验。采样点少于两个、存在非有限值、x 坐标重复或逆序时,委托的分段实现校验失败。可用分段的端点按闭区间处理。

当前最小示例 ​

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));

测试与示例 ​

相关页面 ​