init: 初始化 dpb 桃育种系统代码库
前后端 + 后端 FastAPI 全量源码、部署脚本与文档。
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"""F 分布 CDF / p 值(纯标准库,无需 scipy)。
|
||||
|
||||
用正则不完全 beta 连分数(Numerical Recipes betacf/Lentz 法)计算
|
||||
P(F ≤ f),供 ANOVA / 配合力显著性检验共用。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
|
||||
def _betacf(a: float, b: float, x: float, itmax: int = 200, eps: float = 3e-14) -> float:
|
||||
qab, qap, qam = a + b, a + 1.0, a - 1.0
|
||||
c = 1.0
|
||||
d = 1.0 - qab * x / qap
|
||||
if abs(d) < 1e-30:
|
||||
d = 1e-30
|
||||
d = 1.0 / d
|
||||
h = d
|
||||
for m in range(1, itmax + 1):
|
||||
m2 = 2 * m
|
||||
aa = m * (b - m) * x / ((qam + m2) * (a + m2))
|
||||
d = 1.0 + aa * d
|
||||
if abs(d) < 1e-30:
|
||||
d = 1e-30
|
||||
c = 1.0 + aa / c
|
||||
if abs(c) < 1e-30:
|
||||
c = 1e-30
|
||||
d = 1.0 / d
|
||||
h *= d * c
|
||||
aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2))
|
||||
d = 1.0 + aa * d
|
||||
if abs(d) < 1e-30:
|
||||
d = 1e-30
|
||||
c = 1.0 + aa / c
|
||||
if abs(c) < 1e-30:
|
||||
c = 1e-30
|
||||
d = 1.0 / d
|
||||
delta = d * c
|
||||
h *= delta
|
||||
if abs(delta - 1.0) < eps:
|
||||
break
|
||||
return h
|
||||
|
||||
|
||||
def _reg_beta(a: float, b: float, x: float) -> float:
|
||||
"""正则不完全 beta I_x(a,b)。"""
|
||||
if x <= 0.0:
|
||||
return 0.0
|
||||
if x >= 1.0:
|
||||
return 1.0
|
||||
ln_beta = math.lgamma(a) + math.lgamma(b) - math.lgamma(a + b)
|
||||
bt = math.exp(a * math.log(x) + b * math.log1p(-x) - ln_beta)
|
||||
if x < (a + 1.0) / (a + b + 2.0):
|
||||
return bt * _betacf(a, b, x) / a
|
||||
return 1.0 - bt * _betacf(b, a, 1.0 - x) / b
|
||||
|
||||
|
||||
def f_cdf(f: float, d1: float, d2: float) -> float:
|
||||
"""F 分布累积分布函数 P(F ≤ f),d1/d2 为两个自由度。"""
|
||||
if f <= 0.0 or d1 <= 0.0 or d2 <= 0.0:
|
||||
return 0.0
|
||||
x = d1 * f / (d1 * f + d2)
|
||||
return _reg_beta(d1 / 2.0, d2 / 2.0, x)
|
||||
|
||||
|
||||
def f_pvalue(f: float, d1: float, d2: float) -> float:
|
||||
"""双侧(右尾) p 值 = 1 - P(F ≤ f)。"""
|
||||
return 1.0 - f_cdf(f, d1, d2)
|
||||
|
||||
|
||||
def f_icdf(p: float, d1: float, d2: float, *, tol: float = 1e-9, max_iter: int = 200) -> float:
|
||||
"""F 分布分位数(CDF 反解):求 f 使 P(F ≤ f) = p。
|
||||
|
||||
用二分法(f_cdf 关于 f 严格递增),适用于 DUS LSD 等需临界值场景;
|
||||
高自由度下 F 值可能很大,上界从 1 起按 2 倍扩展。
|
||||
"""
|
||||
p = max(min(p, 1.0 - 1e-12), 1e-12)
|
||||
lo, hi = 0.0, 1.0
|
||||
while f_cdf(hi, d1, d2) < p and hi < 1e12:
|
||||
hi *= 2.0
|
||||
for _ in range(max_iter):
|
||||
mid = 0.5 * (lo + hi)
|
||||
if f_cdf(mid, d1, d2) < p:
|
||||
lo = mid
|
||||
else:
|
||||
hi = mid
|
||||
if hi - lo < tol:
|
||||
break
|
||||
return 0.5 * (lo + hi)
|
||||
|
||||
|
||||
def t_crit(alpha: float, df: float) -> float:
|
||||
"""双侧 t 分布临界值:P(|t| > t_crit) = alpha。
|
||||
|
||||
利用 t² ~ F(1, df)(df 为误差自由度),t_crit = √F_icdf(1-alpha, 1, df)。
|
||||
"""
|
||||
return math.sqrt(f_icdf(1.0 - alpha, 1.0, df))
|
||||
Reference in New Issue
Block a user