chronaxis.core.expression_math_numpy
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""在NumPy列上执行极值、限幅与开方,结果与质量均按行输出。23输入为已通过表达式编译器统一数值类型/尺度的等长列。运算沿同一行跨参数4择值或开方;掩码控制无效位置。没有逐样本Python循环,不修改借用输入。5"""67import numpy as np8from .numeric_numpy import _output, to_float_numpy9from .types import QualityFlag as Q, SignalDType as D101112def math_numpy(name, args):13 """用掩码和ufunc求同长数值列的逐行结果。1415 参数: name为编译好的函数名;args为同长NumericArray元组。16 返回: 同行数NumericArray,开方返回FLOAT64,其余保持公共dtype。17 异常: ValueError为内部未注册名称。内存分配异常直接传播。18 """19 value = args[0]20 quality = value.quality.copy()21 if name == 'sqrt':22 # 负值直接归类为DOMAIN_ERROR;仅非负有效整数才进入精确float转换。23 quality[value.valid & (value.values < 0)] |= np.uint16(Q.DOMAIN_ERROR)24 converted = to_float_numpy(_output(value.dtype, value.values, quality))25 out = np.zeros(len(quality), dtype=np.float64)26 np.sqrt(converted.values, out=out, where=converted.valid)27 return _output(D.FLOAT64, out, converted.quality)28 for arg in args[1:]:29 quality |= arg.quality30 out = value.values.copy()31 if name == 'clip':32 # 只要两条边界均可用即可诊断倒置,即便当前输入也有其他质量原因。33 lower, upper = args[1:]34 bad = lower.valid & upper.valid & (lower.values > upper.values)35 quality[bad] |= np.uint16(Q.DOMAIN_ERROR)36 valid = quality == 037 np.copyto(out, lower.values, where=valid & (value.values < lower.values))38 np.copyto(out, upper.values, where=valid & (value.values > upper.values))39 elif name in ('minimum', 'maximum'):40 # 循环只遍历静态参数,每次比较整列;严格比较使相等值保留第一参数的符号。41 valid = quality == 042 compare = np.less if name == 'minimum' else np.greater43 for arg in args[1:]:44 np.copyto(out, arg.values, where=valid & compare(arg.values, out))45 else:46 raise ValueError('未注册的逐点数值函数')47 return _output(value.dtype, out, quality)48