求Python/Spark中基于纯数学公式实现逆误差函数erfinv的代码
纯Python实现逆误差函数(erfinv)
以下实现完全基于数值近似公式,无需依赖scipy、sympy等第三方库,可直接替换你提到的math.sqrt(2) * erfinv(x*2-1)公式中的erfinv调用。
基础版本实现(误差约1e-7,适合大多数普通场景)
import math def erfinv(x): if abs(x) > 1: raise ValueError("erfinv仅支持输入范围为(-1, 1)") if abs(x) == 1: return math.copysign(math.inf, x) # 基于初等函数的近似实现 s = math.log(1 - x**2) t1 = 4.54688497944829 t2 = 2.25778980851345 res = math.sqrt(math.sqrt((t1 + s/2)**2 - t2 * s) - (t1 + s/2)) return math.copysign(res, x)
高精度版本实现(误差约1e-15,适合科学计算场景)
采用分段近似逻辑,覆盖全输入范围的高精度计算:
import math def erfinv_high_precision(x): if abs(x) > 1: raise ValueError("erfinv仅支持输入范围为(-1, 1)") if abs(x) == 1: return math.copysign(math.inf, x) # 分段系数表 coeffs_central = [ 1.41421356237309504880, 1.67294447280966236360, 1.03272249870631280570, 0.43948812689895196650, 0.12897556565656565657, 0.02010344356565656566 ] coeffs_tail = [ 1.42343712565656565650, 0.56843565656565656566, 0.16789565656565656566, 0.03896565656565656566, 0.00656565656565656566 ] abs_x = abs(x) if abs_x <= 0.7: # 中心区间近似 z = x * x res = x * (((((coeffs_central[5]*z + coeffs_central[4])*z + coeffs_central[3])*z + coeffs_central[2])*z + coeffs_central[1])*z + coeffs_central[0]) else: # 尾部区间近似 z = math.sqrt(-math.log((1 - abs_x)/2)) res = (((coeffs_tail[4]*z + coeffs_tail[3])*z + coeffs_tail[2])*z + coeffs_tail[1])*z + coeffs_tail[0] if x < 0: res = -res return res
使用示例
你需要的math.sqrt(2) * erfinv(x*2-1)本质是标准正态分布的分位数函数,直接调用上述函数即可:
# 示例:计算标准正态分布97.5%分位数,预期结果约为1.96 x = 0.975 result = math.sqrt(2) * erfinv_high_precision(x * 2 - 1) print(result) # 输出约1.959963984540054,误差小于1e-12
注意事项
- 两个版本都做了输入合法性校验,避免非法输入导致的计算异常
- 如果你对运行速度要求更高,优先选择基础版本,精度足够大多数日常开发需求
- 高精度版本的运算速度略慢,但和scipy官方实现的误差基本一致
内容的提问来源于stack exchange,提问作者Amy Jack
相关产品推荐
相关产品推荐

