Skip to content

正弦 ​

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

WARNING

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

契约 ​

  • 输入:x: LinearPolynomial<V>。
  • 输出:由委托的一元分段函数提供的线性多项式 result。
  • 采样点:包含 (x,sin⁡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).

默认采样点严格为:

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

因此默认实现是五点正弦线性插值,没有周期扩展,也不会精确计算 sin⁡(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(sin⁡tizi+aiδi).

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

当前 API ​

Kotlin ​

源码:Sin.kt(SinFunction)

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

kotlin
import fuookami.ospf.kotlin.core.solver.value.IntoValue
import fuookami.ospf.kotlin.core.symbol.function.SinFunction
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 sine = SinFunction(
    x = xPoly,
    converter = IntoValue.Identity,
    name = "sine"
)
val value = sine.evaluate(mapOf<Symbol, Flt64>(x to Flt64.zero))
check(value != null && value == Flt64.zero)

Rust ​

Rust 暴露 SinFunction:

rust
SinFunction::new(
    id: u64,
    name: &str,
    input: Linear<V>,
) -> SinFunction<V>

该构造器把建模网格固定为 [-π,π] 上的 32 个分段,创建有界连续 result_variable() 并注册分段线性约束。Rust 的 token 求值器直接计算 sin(input),没有 Kotlin 风格可配置的 samplingPoints 参数;因此直接求值可能与分段模型不同,尤其是在建模网格之外。

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.SinFunction
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 sine = SinFunction(
    x = xPoly,
    converter = IntoValue.Identity,
    name = "sine"
)
val value = sine.evaluate(mapOf<Symbol, Flt64>(x to Flt64.zero))
check(value != null && value == Flt64.zero)
rust
use ospf_rust_core::symbol::flatten::{Linear, LinearMonomial};
use ospf_rust_core::symbol::function::SinFunction;

let input = Linear::new(vec![LinearMonomial::new(1.0, 0)], 0.0);
let sine = SinFunction::new(1, "sin", input);
let _result = sine.result_variable();

Rust 源码:sin.rs。

相关页面 ​