Chronaxis用户手册English
本页目录

chronaxis.core.rate_numpy

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""用原dtype列、局部时间和中心化NumPy归约计算差分与等权拟合。23仅运行当前窗口,整数先在无符号幅度列计算精确差,再按IEEE表示检查提升。4拟合使用整列点积,最终只对两个标量归约结果还原倍率、秒与输出质量。5"""67import numpy as np8from .numeric import ScalarValue9from .numeric_numpy import DTYPES, _output, to_float_numpy10from .types import QualityFlag as Q, SignalDType as D111213def _relative_column(samples):14    """将已知数值打包为相对首样本的浮点列,给出纵轴缩放的二进制指数。1516    参数: samples为同型有效ScalarValue序列。返回: (相对列,指数,质量)。17    异常: 内存分配或内部结构错误传播。整数差转float不精确时返回精度质量。18    """19    dtype = samples[0].dtype20    raw = np.fromiter((v.value for v in samples),dtype=DTYPES[dtype],count=len(samples))21    if dtype is D.FLOAT64:22        # 先按2的幂缩放,异号相减不会产生无穷;单位倍率最后一次恢复。23        _, power = np.frexp(np.max(np.abs(raw)))24        scaled = np.ldexp(raw,-int(power))25        return scaled - scaled[0], int(power), Q.NONE26    # 对有符号整数翻转符号位后,uint64比较顺序恰好等于原带符号大小。27    ordered = raw.view(np.uint64)28    if dtype is D.INT64:29        ordered = ordered ^ np.uint64(1 << 63)30    base = ordered[0]31    magnitudes = np.maximum(ordered,base) - np.minimum(ordered,base)32    converted = to_float_numpy(_output(D.UINT64,magnitudes,np.zeros(len(samples),dtype=np.uint16)))33    quality = Q(int(np.bitwise_or.reduce(converted.quality,initial=0)))34    return np.where(ordered < base,-converted.values,converted.values), 0, quality353637def _restore(numerator, denominator, exponent, elapsed_ns):38    """还原局部纵轴数量级与所选纳秒跨度,不在中间乘法中溢出。3940    参数: 前两项为浮点归约的分子分母;exponent为纵轴2的幂;elapsed_ns为正数。41    返回: FLOAT64 ScalarValue。异常: 不可表示的最终数值以质量标识。42    """43    a,b = float(numerator).as_integer_ratio()44    c,d = float(denominator).as_integer_ratio()45    top = a * d * 1_000_000_000 * elapsed_ns.denominator46    bottom = b * c * elapsed_ns.numerator47    if exponent > 0:48        top <<= exponent49    else:50        bottom <<= -exponent51    try:52        value = top / bottom53    except OverflowError:54        return ScalarValue(None,D.FLOAT64,False,Q.NONFINITE)55    if value == 0 and top:56        return ScalarValue(None,D.FLOAT64,False,Q.PRECISION_LOSS)57    return ScalarValue(value,D.FLOAT64)585960def difference_numpy(left, right, elapsed_ns):61    """以原dtype两点列求差,恢复为所选周期或实际秒数上的导数。6263    参数: 同型有效的left/right及正elapsed_ns。返回: FLOAT64 ScalarValue。64    异常: 输入结构和分配错误传播。65    """66    values, exponent, quality = _relative_column((left,right))67    if quality:68        return ScalarValue(None,D.FLOAT64,False,quality)69    return _restore(values[-1],1.,exponent,elapsed_ns)707172def fit_numpy(positions, samples):73    """将实际或周期横轴先局部化,用整列中心积求等权回归斜率。7475    参数: positions为严格递增精确纳秒序列,samples为同行序有效样本。76    返回: FLOAT64 ScalarValue。异常: 结构和空间错误传播。77    """78    first, span = positions[0], positions[-1]-positions[0]79    if (all(type(t) is int for t in positions) and -(1 << 63) <= first80            and positions[-1] < (1 << 63) and span < (1 << 63)):81        # 普通实际时间在int64域先相减,靠近纪元上限的1ns仍然可区分。82        axis = np.asarray(positions,dtype=np.int64)83        x = (axis - axis[0]).astype(np.float64) / span84    else:85        # 介于两个驱动记录间的位置具有有理数表示,先在精确域移除起点;86        # 只打包相对坐标,后续中心化和每个样本的乘法均执行整列运算。87        x = np.fromiter((float((t-first)/span) for t in positions),dtype=np.float64,count=len(positions))88    y, exponent, quality = _relative_column(samples)89    if quality:90        return ScalarValue(None,D.FLOAT64,False,quality)91    x -= np.mean(x)92    y -= np.mean(y)93    return _restore(np.dot(x,y),np.dot(x,x),exponent,span)94
Chronaxis 用户手册 · 离线阅读