Chronaxis用户手册English
本页目录

chronaxis.core.rate_reference

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""用独立标量差分和中心化等权回归计算有效真实样本的每秒变化率。23相邻/窗口的两个端点只做一次精确差,再转浮点输出。拟合使用局部时间和按4二进制指数缩放的值,避免绝对时间精度损失及大温度/电压背景造成的相消。5没有跨调用状态,窗口、真实间隔有效性及临时预算由时间线调用者提供。6"""78from fractions import Fraction9from math import frexp, fsum, ldexp10from .numeric import ScalarValue, _exact_float11from .types import QualityFlag as Q, SignalDType as D121314def _result(exact):15    """将已经得到的有限有理数转为一个每秒FLOAT64斜率。1617    参数: exact为最终斜率。返回: ScalarValue,真溢出或下溢有独立原因。18    异常: 内存不足原样传播。19    """20    try:21        value = float(exact)22    except OverflowError:23        return ScalarValue(None,D.FLOAT64,False,Q.NONFINITE)24    if not value and exact:25        return ScalarValue(None,D.FLOAT64,False,Q.PRECISION_LOSS)26    return ScalarValue(value,D.FLOAT64)272829def difference_reference(left, right, elapsed_ns):30    """按原值精确相减,再除以秒数,免去巨大相近整数的绝对值舍入。3132    参数: 两个同型有效标量与正的精确纳秒跨度。返回: FLOAT64 ScalarValue。33    异常: 内部调用需先校验模型。不能精确进入浮点的整数差量报PRECISION_LOSS。34    """35    delta = Fraction(right.value) - Fraction(left.value)36    if left.dtype is not D.FLOAT64:37        _, reason = _exact_float(delta.numerator)38        if reason:39            return ScalarValue(None,D.FLOAT64,False,reason)40    # 数学凸/差值仅用于两个端点,避免极大异号值先相减溢出但最终斜率可表示。41    return _result(delta * 1_000_000_000 / elapsed_ns)424344def fit_reference(positions, samples):45    """用局部时间、真实样本等权及补偿求和计算最小二乘斜率。4647    参数: 严格递增的精确纳秒与至少两个同型有效样本。48    返回: FLOAT64 ScalarValue。异常: 内部结构错误传播,数值失效转为质量。49    """50    first, span = positions[0], positions[-1] - positions[0]51    # 先在精确坐标域去掉纪元,再缩到[0,1],最大64位绝对时间不影响相邻差。52    x = [float(Fraction(t-first,span)) for t in positions]53    if samples[0].dtype is D.FLOAT64:54        exponent = frexp(max(abs(sample.value) for sample in samples))[1]55        base = ldexp(samples[0].value, -exponent)56        y = [ldexp(sample.value,-exponent) - base for sample in samples]57    else:58        # 精确相减后才提升,uint64也允许相对首值为负。59        exponent, y = 0, []60        for sample in samples:61            value, reason = _exact_float(sample.value - samples[0].value)62            if reason:63                return ScalarValue(None,D.FLOAT64,False,reason)64            y.append(value)65    mean_x, mean_y = fsum(x)/len(x), fsum(y)/len(y)66    cross = fsum((t-mean_x)*(v-mean_y) for t,v in zip(x,y))67    spread = fsum((t-mean_x)**2 for t in x)68    # 还原纵轴二进制倍率及横轴真实跨度时只做一次最终浮点舍入。69    return _result(Fraction(cross) * Fraction(2)**exponent * 1_000_000_000 / (Fraction(spread)*span))70
Chronaxis 用户手册 · 离线阅读