云计算百科
云计算领域专业知识百科平台

天赐范式第213天:补上收缩项,182的定价从不可判变成可判_OU型θ复制×β_m五档×neutral组对账×5seed

天赐范式 ·第213天 第二篇:补上收缩项,182的定价从不可判变成可判

——OU 型 θ 复制 × β_m 五档 × neutral 组对账 × 5 seed

摘要

212-2 的根因:θ 复制是 parent + noise,没有收缩项,182 的 D*=σ²/(1−β²) 里 β 无机制对应物——换档理论 σ* 差 2~3 倍、残差符号翻转,定价"不可判"。今天给 θ 复制补收缩项(OU 型):θ_child = β_m·θ_parent + (1−β_m)·μ_pop + N(0,σ_θ)。β_m=1 退化为旧基座,恒等性自检逐位通过。β_m=1.00 时 D 不存在(分母 1−β_m²=0,公式无定义)——Var(θ) 在 0.06–0.10 间游走,只有瞬时读数、没有稳态可定价,这正是 212-2 结论的硬证据。β_m<1 时 Var(θ) 有界且随 β_m 下降趋近 D:neutral 组残差从 −0.051(β_m=0.95,−50%)缩小到 −0.003(β_m=0.60,−22%)。方向一致(全部 Var < D*),不再换档翻滚。亲子斜率 b 在 neutral 组由 β_m 决定:b 随 β_m 单调下降(0.9364→0.9036→0.8587→0.7545→0.5461),恒定偏低约 0.05(β_m=0.60 时 b=0.5461,差 −0.054)→ β_m 是机制量。结论:定价从"不可判"变成"可判"——方向可判(β_m 下降 → Var 趋近 D),残差可判(一致偏低,来源可归因),但残差非零*。β_m 目前是外加参数,改基座是第一步不是终点。

在这里插入图片描述

§一 问题

212-2 在个体级通了 mutator(选择能调突变率),但种群级判不了——判据依赖的亲子斜率 b 不是机制量。根因定位到 θ 复制没有收缩项:

θ_child = θ_parent + N(0, σ_θ)

这是纯随机游走。182 的稳态方差 D* = σ²/(1−β²) 里 β 是收缩系数,但当前系统 θ 复制没有收缩——β=1,D* 不存在(分母为 0,公式无定义)。所以 Var(θ) 随代数游走,没有稳态可定价。

今天补上收缩项,改成 OU 型:

θ_child = β_m · θ_parent + (1 − β_m) · μ_pop + N(0, σ_θ)

β_m=1 时退化为旧基座(θ_parent + noise),即 209/210/212 一直用的那套。β_m<1 时 θ 向种群均值 μ_pop 收缩,Var(θ) 有了稳态。

§二 预注册假设

OU 型设计:

  • μ_pop = 上一代存活者 θ_A 均值(定死用 θ_A,可复现)
  • β_m=1 时不计算 μ_pop(不额外消耗随机数)→ 恒等性必然
  • σ_θ = 0.10,θ 仍夹在 [THETA_MIN, THETA_MAX]

β_m 五档:[1.00, 0.95, 0.90, 0.80, 0.60]

理论 D = σ_θ²/(1−β_m²)*:

β_m1−β_m²理论 D*备注
1.00 0.000 不存在 旧基座,Var 随机游走(无稳态)
0.95 0.0975 0.1026
0.90 0.1900 0.0526
0.80 0.3600 0.0278
0.60 0.6400 0.0156

三组:A(normal, inherit=True) 演化组 / B(normal, inherit=False) θ锁死 / N(neutral, inherit=True) 中性组。

关键设计:H2 用 neutral 组剥离锦标赛选择——182 的 D* 定价的是无选择下的突变-收缩平衡,直接拿 A 组比必被混淆。neutral 组 θ 不受选择,Var(θ) 由纯突变-收缩决定,才配跟 D* 对账。

预注册三条:

  • H0(恒等):β_m=1.00 逐位对 212a(κ=0),不一致即停。
  • H1:亲子回归斜率 b 是否等于 β_m(b 成为机制量的自证)。先验恒等性:σ_θ=0 时 b≡1 是恒等,已从判据剔除;截断样本会污染 b,须注明。
  • H2(主判据):neutral 组末代 Var(θ) 是否等于 D*。残差 = 复跑值 − 理论值;β_m 是机制常数 → 残差可判,不再是 212-2 那种"换档翻滚"。

§三 恒等性自检

β_m=1.00 与 212a(κ=0) 逐位比对(p_total / n_alive / n_part,151 代全序列,三组 × 2 seed):PASS。

代码上 β_m<1 才算 μ_pop,不额外消耗随机数 → 恒等性必然。这条过了才往下跑。

§四 主表:β_m × 三组 Var(θ) + 亲子斜率 b + 理论 D*

β_m组末代 Var(θ)亲子斜率 b理论 D*
1.00 A 0.04063±0.00486 0.9321±0.0058 不存在
1.00 B 0.09702±0.00498 n/a 不存在
1.00 N 0.09869±0.01672 0.9364±0.0062 不存在
0.95 A 0.03168±0.00958 0.9154±0.0048 0.10256
0.95 B 0.09702±0.00498 n/a 0.10256
0.95 N 0.05109±0.01673 0.9036±0.0106 0.10256
0.90 A 0.02591±0.00672 0.9091±0.0056 0.05263
0.90 B 0.09702±0.00498 n/a 0.05263
0.90 N 0.03475±0.00466 0.8587±0.0204 0.05263
0.80 A 0.01774±0.00410 0.8893±0.0119 0.02778
0.80 B 0.09702±0.00498 n/a 0.02778
0.80 N 0.02221±0.00432 0.7545±0.0477 0.02778
0.60 A 0.01371±0.00282 0.7976±0.0644 0.01563
0.60 B 0.09702±0.00498 n/a 0.01563
0.60 N 0.01214±0.00290 0.5461±0.0315 0.01563

B 组 Var(θ) 恒定 0.09702(不遗传 θ,与 β_m 无关)——这是机制保证的 sanity check。注意 0.097 高于初始均匀[0,1]的方差 0.0833:B 组 θ 虽不遗传,但每代仍受 γ·s_stim 参与惩罚驱动漂移,故 Var 略高于初始值。

§五 H1:亲子斜率 b vs β_m

β_m组b (亲子斜率)b − β_m
1.00 A 0.9321±0.0058 −0.0679
1.00 N 0.9364±0.0062 −0.0636
0.95 A 0.9154±0.0048 −0.0346
0.95 N 0.9036±0.0106 −0.0464
0.90 A 0.9091±0.0056 +0.0091
0.90 N 0.8587±0.0204 −0.0413
0.80 A 0.8893±0.0119 +0.0893
0.80 N 0.7545±0.0477 −0.0455
0.60 A 0.7976±0.0644 +0.1976
0.60 N 0.5461±0.0315 −0.0539

neutral 组 b ≈ β_m:β_m=0.60 时 b=0.5461,差 −0.054;β_m=0.80 时 b=0.7545,差 −0.046。五档 b−β_m 全负(−0.064 到 −0.041),方向一致,量级接近 → β_m 在 neutral 组是机制量。

A 组 b 被选择推高:β_m=0.60 时 b=0.7976,差 +0.198。锦标赛选择把亲子斜率往上推——这正是 H2 必须用 neutral 组的原因。

注:b 用去夹取样本(出界不计入),有选择偏差;σ_θ 大时偏差大。β_m=1.00 时 b≈0.93 而非 1.0,就是截断所致。

§六 H2 主判据:neutral 组 Var(θ) vs 理论 D*

β_mneutral Var(θ)理论 D*neutral 残差A 组 Var(θ)A 组残差
1.00 0.09869±0.01672 不存在 n/a 0.04063±0.00486 n/a
0.95 0.05109±0.01673 0.10256 −0.05148 0.03168±0.00958 −0.07088
0.90 0.03475±0.00466 0.05263 −0.01788 0.02591±0.00672 −0.02672
0.80 0.02221±0.00432 0.02778 −0.00557 0.01774±0.00410 −0.01004
0.60 0.01214±0.00290 0.01563 −0.00348 0.01371±0.00282 −0.00191

三件事:

  • β_m=1.00 时 D 不存在*:分母 1−β_m²=0,公式无定义;Var(θ)=0.09869 仍有读数,但那是随机游走的瞬时值而非稳态值——旧基座无稳态可定价。这正是 212-2 结论的硬证据。
  • β_m<1 时 Var(θ) 全部低于 D*:残差一律为负,绝对值随 β_m 下降而缩小(−0.051 → −0.003)。方向一致,不再换档翻滚。但相对口径(残差/D*)非单调:−50.2% → −34.0% → −20.1% → −22.3%(β_m=0.60 回升),说明 β_m 越小截断占比越大。
  • A 组 Var(θ) 在 β_m≥0.80 时低于 neutral 组(β_m=0.60 反转:A=0.01371 > N=0.01214):锦标赛选择额外压低 Var(θ),这正是 H2 必须用 neutral 组的原因。
  • 残差来源可归因:neutral 组仍有 θ 截断(出界夹死,压低 Var,主因)、λ=0.10 常数死亡(压低 Var,次因)、μ_pop 用 θ_A 均值(全局信息)。伙伴做了 λ=0 对照:关掉常数死亡后残差只缩约 20%,主因是截断。这些都是方向可判的——不像 212-2 那样残差符号翻转。

    §七 Var(θ) 轨迹(neutral 组,每 25 代)

    β_mg0g25g50g75g100g125g150
    1.00 0.0850 0.0738 0.0596 0.0740 0.0704 0.0808 0.0987
    0.95 0.0850 0.0516 0.0422 0.0596 0.0520 0.0458 0.0511
    0.90 0.0850 0.0452 0.0251 0.0322 0.0417 0.0360 0.0348
    0.80 0.0850 0.0225 0.0176 0.0205 0.0224 0.0204 0.0222
    0.60 0.0850 0.0147 0.0107 0.0123 0.0133 0.0124 0.0121

    初始 θ 均匀 [0,1],Var ≈ 0.0833 为起点。β_m<1 时 Var(θ) 在 g25 就基本到稳态;β_m=1.00 时 Var(θ) 在 0.06–0.10 间游走,无稳态。

    §八 结论:从不可判变成可判

    把三件事摆在一起:

  • β_m=1.00 时 D 不存在*(§六,分母为 0)→ 旧基座确实无稳态可定价,212-2 的结论得到硬证据。
  • β_m<1 时 Var(θ) 有界且趋近 D*(§六,残差从 −0.051 缩到 −0.003)→ OU 改造让定价有了方向。
  • neutral 组 b 随 β_m 单调走、偏压恒定(§五,b−β_m 五档全负,−0.064 ~ −0.041;β_m=0.60 时 b=0.5461)→ β_m 是机制量,不再是 212-2 那种"换档翻滚"。
  • 定价从"不可判"变成"可判":

    • 方向可判:β_m 下降 → Var(θ) 下降 → 趋近 D*,全部残差同号(负)。
    • 残差可判:一致偏低,来源可归因(截断为主因 + 常数死亡为次因 + μ_pop),不像 212-2 那样残差符号翻转。
    • 但残差非零:即使 β_m=0.60,残差仍有 −0.003。定价方向对了,绝对值有系统偏差。

    改基座之后,209/210/212 的结果在旧基座下仍然有效,只是不能直接跟 182 的定价对账。β_m=1 的恒等性自检就是这条说明的硬证据。

    β_m 目前是外加参数(跟 212b 的 σ_θ 一样),改基座是第一步不是终点——未来要像 σ_θ 做成 mutator allele 那样把它自主化。

    仍缺的

  • 残差非零的定量归因:截断为主因、常数死亡为次因(λ=0 对照残差只缩约 20%),μ_pop 贡献未拆解。
  • β_m 是外加参数,未自主化。
  • H3(mutator 稳态守定价)未跑,后置。
  • neutral 组仍有 λ=0.10 常数死亡,对 Var(θ) 有均匀影响——理想情况应该 λ=0,但那样种群会撑满网格。
  • §九 诚实边界

    Limitations

  • 主实验 5 seed,教学级。
  • β_m=1.00 恒等性自检 PASS:与 212a(κ=0) 逐位一致。改基座后 209/210/212 的结果在旧基座下仍有效,只是不能直接跟 182 定价对账。
  • β_m 目前是外加参数(跟 212b 的 σ_θ 一样),改基座是第一步不是终点——未来要把它自主化。
  • μ_pop 用上一代存活者 θ_A 均值,引入全局信息(非局部)。
  • 亲子斜率 b 用去夹取样本,有选择偏差;σ_θ 大时偏差大。
  • neutral 组仍有 λ=0.10 常数死亡,对 Var(θ) 有均匀影响。
  • 未检出 ≠ 不存在:残差可判不等于残差为零。
  • Reproducibility

    脚本:tianci_213b.py(20261101 工作目录),依赖 212a / 209a / 202a / 200b 四个历史模块(路径见脚本头部)。

    复跑命令:py tianci_213b.py > out_213b.txt 2>&1

    环境:Windows 10, Python 3.13, py launcher

    输出:out_213b.txt

    结果:exit=0;β_m=1.00 恒等性自检 PASS(与 212a(κ=0) 逐位一致);β_m 五档 × 三组 × 5 seed 全部完成。版本 v3.3.51.0,2026-11-01。

    附录:代码

    # -*- coding: utf-8 -*-
    """
    天赐范式 第213天 第二篇
    补上收缩项,182的定价从不可判变成可判

    PID: TC-213B-V3.3.51.0
    V3.3.51.0 · 2026-11-01

    接 212-2 的根因:θ 复制是 parent+noise,没有收缩项,182 的 D*=σ_v²/(1−β²)
    里 β 无机制对应物。213-2 给 θ 复制补收缩项(OU 型):

    θ_child = β_m · θ_parent + (1 − β_m) · μ_pop + N(0, σ_θ)

    β_m=1 时退化为旧基座(θ_parent + noise),即 209/210/212 一直用的那套。
    恒等性自检:β_m=1.00 空跑须与 run_frtm_212(κ=0) 逐位一致,对不上就停。

    关键设计:H2 用 neutral 组(sel_mode='neutral')剥离锦标赛选择——
    182 的 D* 定价的是无选择下的突变-收缩平衡,直接拿 A 组比必被混淆。
    neutral 组 θ 不受选择,Var(θ) 由纯突变-收缩决定,才配跟 D* 对账。
    """
    import sys
    import random
    import statistics

    sys.stdout.reconfigure(encoding="utf-8")

    sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261028")
    from tianci_209a import (theta_mean_at, THETA_MIN, THETA_MAX,
    GAMMA_MAIN, LAMBDA_MAIN, N_GEN_209, FLIP_GEN,
    _clamp_theta)
    sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261021")
    from tianci_202a import (SEEDS, RHO, QUAD_ENV, PHI, TRACK_WINDOW)
    sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261019")
    from tianci_200b import (GRID_W, GRID_H, N, N_GEN, SIGMA_V, TOURNAMENT_K,
    N_BUCKETS, true_beta, get_quadrant, moore_neighbors,
    get_bucket, shannon_entropy, clamp, bar, md_table)
    sys.path.insert(0, r"C:\\Users\\Administrator\\Desktop\\20261031")
    from tianci_212a import run_frtm_212, N_GEN_212, FLIP_GEN_212

    N_GEN_213B = 150
    FLIP_GEN_213B = 50
    LAM_213B = 0.10
    FILL_DELAY_213B = 5
    PC_WINDOW = 100
    SIGMA_THETA = 0.10

    BETA_SCAN = [1.00, 0.95, 0.90, 0.80, 0.60]

    GROUPS_213B = [
    ('A', 'normal', True, '演化组(有选择+遗传)'),
    ('B', 'normal', False, 'θ锁死(有选择不遗传)'),
    ('N', 'neutral', True, '中性(θ不受选择)'),
    ]

    def d_theory(sigma, beta_m):
    """182 定价:D* = σ²/(1−β_m²)。β_m=1 时分母为 0,D* 不存在。"""
    if abs(beta_m) >= 1.0:
    return None
    return sigma * sigma / (1.0 – beta_m * beta_m)

    def run_ou_213b(seed, beta_m=1.0, sigma_theta=SIGMA_THETA,
    n_gen=N_GEN_213B, gamma=GAMMA_MAIN, lam=LAM_213B,
    rule='neighbor', inherit_theta=True,
    sel_mode='normal', flip_gen=FLIP_GEN_213B,
    flip_mode='rho', rho_new=–0.5):
    """OU 型 θ 复制 + 212 基座(κ=0 随机死亡)。

    β_m=1 时不计算 μ_pop,随机数序列与 run_frtm_212(κ=0) 完全相同。
    β_m<1 时 θ_child = β_m·θ_parent + (1−β_m)·μ_pop + N(0,σ_θ)。
    μ_pop = 上一代存活者 θ_A 均值(定死用 θ_A,可复现)。

    返回字典:history / thetas_A / alive / var_traj / pc_pairs / b_slope / var_end
    """
    random.seed(seed)
    rho_val = 1.0
    betas = [random.uniform(0.0, 1.0) for _ in range(N)]
    thetas_A = [random.uniform(0.0, 1.0) for _ in range(N)]
    thetas_B = [random.uniform(0.0, 1.0) for _ in range(N)]
    s_stim_A = [0.0, 0.0, 0.0, 0.0]
    s_stim_B = [0.0, 0.0, 0.0, 0.0]
    env_A = list(QUAD_ENV)
    env_B = list(QUAD_ENV)

    history = []
    alive = [True] * N
    death_gen = [None] * N
    var_traj = []
    pc_pairs = []
    mu_pop_prev = 0.0

    for gen in range(n_gen + 1):
    if flip_mode == 'rho' and flip_gen is not None and gen == flip_gen:
    rho_val = rho_new

    if lam > 0:
    for i in range(N):
    if alive[i] and random.random() < lam:
    alive[i] = False
    death_gen[i] = gen

    n_alive = sum(alive)
    live_idx = [i for i in range(N) if alive[i]]
    live_tA = [thetas_A[i] for i in live_idx]
    if len(live_idx) > 1:
    mean_tA = statistics.mean(live_tA)
    var_tA = statistics.pvariance(live_tA)
    else:
    mean_tA = live_tA[0] if live_idx else 0.0
    var_tA = 0.0

    var_traj.append(var_tA)

    q_base = [0.0] * N
    for i in live_idx:
    r, c = divmod(i, GRID_W)
    q_base[i] = 1.0 / (1.0 + (betas[i] – true_beta(r, c)) ** 2)

    n_act_A = [0, 0, 0, 0]
    n_act_B = [0, 0, 0, 0]
    q_eff = [0.0] * N
    participated_A = [False] * N
    participated_B = [False] * N
    n_part = 0
    for i in live_idx:
    r, c = divmod(i, GRID_W)
    q = get_quadrant(r, c)
    sA = s_stim_A[q]
    sB = s_stim_B[q]
    if sel_mode == 'neutral':
    thA_for_p = mean_tA
    mean_tB = statistics.mean([thetas_B[j] for j in live_idx]) if len(live_idx) > 1 else 0.0
    thB_for_p = mean_tB
    else:
    thA_for_p = thetas_A[i]
    thB_for_p = thetas_B[i]
    pA = sA * sA / (sA * sA + thA_for_p ** 2) \\
    if (sA > 0 and thA_for_p > 0) else 0.0
    pB = sB * sB / (sB * sB + thB_for_p ** 2) \\
    if (sB > 0 and thB_for_p > 0) else 0.0
    if random.random() < pA:
    participated_A[i] = True
    n_act_A[q] += 1
    if random.random() < pB:
    participated_B[i] = True
    n_act_B[q] += 1
    if participated_A[i] or participated_B[i]:
    n_part += 1
    q_eff[i] = q_base[i] * (1.0 + rho_val)
    else:
    q_eff[i] = q_base[i]

    if gamma > 0:
    for i in live_idx:
    if participated_A[i]:
    thetas_A[i] = _clamp_theta(thetas_A[i] – gamma)
    if participated_B[i]:
    thetas_B[i] = _clamp_theta(thetas_B[i] – gamma)

    p_total = sum(q_eff)
    history.append({'gen': gen, 'p': p_total, 'n_alive': n_alive,
    'n_part': n_part})

    if gen == n_gen:
    break

    for q in range(4):
    s_stim_A[q] = max(0.0, s_stim_A[q] + env_A[q] – PHI * n_act_A[q])
    s_stim_B[q] = max(0.0, s_stim_B[q] + env_B[q] – PHI * n_act_B[q])

    if beta_m < 1.0:
    mu_pop_prev = mean_tA

    new_betas = list(betas)
    new_tA = list(thetas_A)
    new_tB = list(thetas_B)
    collect_pc = (gen >= n_gen – PC_WINDOW)
    for i in live_idx:
    r, c = divmod(i, GRID_W)
    candidates = [i] + [j for j in moore_neighbors(r, c) if alive[j]]
    k = min(TOURNAMENT_K, len(candidates))
    sample = random.sample(candidates, k)
    winner = max(sample, key=lambda idx: q_eff[idx])

    new_betas[i] = clamp(betas[winner] + random.gauss(0, SIGMA_V))
    if inherit_theta:
    noise_a = random.gauss(0, sigma_theta)
    noise_b = random.gauss(0, sigma_theta)
    if beta_m < 1.0:
    child_raw_a = beta_m * thetas_A[winner] + (1.0 – beta_m) * mu_pop_prev + noise_a
    child_raw_b = beta_m * thetas_B[winner] + (1.0 – beta_m) * mu_pop_prev + noise_b
    else:
    child_raw_a = thetas_A[winner] + noise_a
    child_raw_b = thetas_B[winner] + noise_b
    new_tA[i] = _clamp_theta(child_raw_a)
    new_tB[i] = _clamp_theta(child_raw_b)
    if collect_pc:
    pt = thetas_A[winner]
    if THETA_MIN < pt < THETA_MAX \\
    and THETA_MIN < child_raw_a < THETA_MAX:
    pc_pairs.append((pt, child_raw_a))
    else:
    new_tA[i] = thetas_A[i]
    new_tB[i] = thetas_B[i]

    if lam > 0 and rule is not None:
    for i in range(N):
    if (not alive[i]) and death_gen[i] is not None \\
    and (gen – death_gen[i]) >= FILL_DELAY_213B:
    r, c = divmod(i, GRID_W)
    neighbors = [j for j in moore_neighbors(r, c) if alive[j]]
    if not neighbors:
    continue
    w = max(neighbors, key=lambda idx: q_eff[idx])
    new_betas[i] = clamp(betas[w] + random.gauss(0, SIGMA_V))
    noise_a = random.gauss(0, sigma_theta)
    noise_b = random.gauss(0, sigma_theta)
    if inherit_theta:
    if beta_m < 1.0:
    new_tA[i] = _clamp_theta(
    beta_m * thetas_A[w] + (1.0 – beta_m) * mu_pop_prev + noise_a)
    new_tB[i] = _clamp_theta(
    beta_m * thetas_B[w] + (1.0 – beta_m) * mu_pop_prev + noise_b)
    else:
    new_tA[i] = _clamp_theta(thetas_A[w] + noise_a)
    new_tB[i] = _clamp_theta(thetas_B[w] + noise_b)
    else:
    new_tA[i] = random.uniform(0.0, 1.0)
    new_tB[i] = random.uniform(0.0, 1.0)
    alive[i] = True
    death_gen[i] = None

    betas = new_betas
    thetas_A = new_tA
    thetas_B = new_tB

    b_slope = None
    if len(pc_pairs) >= 30:
    xs = [a for a, _ in pc_pairs]
    ys = [b for _, b in pc_pairs]
    mx = statistics.mean(xs)
    my = statistics.mean(ys)
    sxx = sum((x – mx) ** 2 for x in xs)
    sxy = sum((x – mx) * (y – my) for x, y in zip(xs, ys))
    b_slope = sxy / sxx if sxx > 0 else None

    return {
    'history': history, 'thetas_A': thetas_A, 'alive': alive,
    'var_traj': var_traj, 'pc_pairs': pc_pairs, 'b_slope': b_slope,
    'var_end': var_traj[–1],
    }

    def mean_std(v):
    if not v:
    return 0.0, 0.0
    m = statistics.mean(v)
    s = statistics.stdev(v) if len(v) > 1 else 0.0
    return m, s

    if __name__ == "__main__":
    bar("天赐范式 第213天 第二篇:补上收缩项,182的定价从不可判变成可判")
    print(f"OU 型 θ 复制 × β_m 五档 × neutral 组对账 V3.3.51.0 · 2026-11-01")
    print()

    # —————- Part 0 恒等性自检 —————-
    bar("Part 0 恒等性自检:β_m=1.00 须与 212a(κ=0) 逐位一致")
    ident_all = True
    for gname, sel, inh, desc in GROUPS_213B:
    for seed in SEEDS[:2]:
    r_new = run_ou_213b(seed, beta_m=1.0, inherit_theta=inh, sel_mode=sel)
    r_old = run_frtm_212(seed, GAMMA_MAIN, SIGMA_THETA, LAM_213B,
    'neighbor', n_gen=N_GEN_213B,
    flip_gen=FLIP_GEN_213B, flip_mode='rho',
    inherit_theta=inh, sel_mode=sel, kappa=0.0)
    ok = all(a['p'] == b['p'] and a['n_alive'] == b['n_alive']
    and a['n_part'] == b['n_part']
    for a, b in zip(r_new['history'], r_old[0]))
    ident_all &= ok
    if not ok:
    print(f" {gname} seed={seed}: FAIL")
    print(f" β_m=1.00 与 212a(κ=0) 逐位一致 = {ident_all}")
    if not ident_all:
    print(" 【禁止继续】OU 改造破坏了旧基座,先修代码。")
    raise SystemExit(1)
    print(" 说明:β_m=1 时 θ_child = θ_parent + noise,即 212 基座。")
    print(" 代码上 β_m<1 才算 μ_pop,不额外消耗随机数 → 恒等性必然。")
    print()

    # —————- Part 1 主表:β_m × 三组 Var(θ) —————-
    bar("Part 1 末代 Var(θ):β_m 五档 × 三组(A/B/N)× 5 seed")
    print(f" β_m 扫描:{BETA_SCAN}")
    print(f" 理论 D* = σ_θ²/(1−β_m²),σ_θ={SIGMA_THETA}")
    print()
    cache = {}
    rows_main = []
    for beta_m in BETA_SCAN:
    for gname, sel, inh, desc in GROUPS_213B:
    vs, bs = [], []
    for seed in SEEDS:
    r = run_ou_213b(seed, beta_m=beta_m,
    inherit_theta=inh, sel_mode=sel)
    cache[(beta_m, gname)] = r
    vs.append(r['var_end'])
    if r['b_slope'] is not None:
    bs.append(r['b_slope'])
    vm, vstd = mean_std(vs)
    bm, bstd = mean_std(bs) if bs else (None, None)
    dt = d_theory(SIGMA_THETA, beta_m)
    row = [f"β_m={beta_m:.2f}", gname,
    f"{vm:.5f}±{vstd:.5f}",
    f"{bm:.4f}±{bstd:.4f}" if bs else "n/a",
    f"{dt:.5f}" if dt is not None else "不存在"]
    rows_main.append(row)
    md_table(["β_m", "组", "末代 Var(θ)", "亲子斜率 b", "理论 D*"], rows_main, ["r"] * 5)
    print()

    # —————- Part 2 H1:亲子斜率 b vs β_m —————-
    bar("Part 2 H1:亲子斜率 b 是否等于 β_m(b 成为机制量的自证)")
    rows_h1 = []
    for beta_m in BETA_SCAN:
    for gname in ('A', 'N'):
    bs = []
    sel = 'normal' if gname == 'A' else 'neutral'
    for seed in SEEDS:
    r2 = run_ou_213b(seed, beta_m=beta_m,
    inherit_theta=True, sel_mode=sel)
    if r2['b_slope'] is not None:
    bs.append(r2['b_slope'])
    if bs:
    bm, bstd = mean_std(bs)
    diff = bm – beta_m
    rows_h1.append([f"β_m={beta_m:.2f}", gname,
    f"{bm:.4f}±{bstd:.4f}",
    f"{diff:+.4f}"])
    md_table(["β_m", "组", "b (亲子斜率)", "b − β_m"], rows_h1, ["r"] * 4)
    print(" 注:b=β_m 意味着亲子回归斜率等于机制参数 → β_m 是机制量。")
    print(" 截断样本会污染 b(出界不计入),σ_θ=0 时 b≡1 是恒等,已从判据剔除。")
    print()

    # —————- Part 3 H2 主判据:neutral 组 Var(θ) vs D* —————-
    bar("Part 3 H2 主判据:neutral 组末代 Var(θ) vs 理论 D*")
    rows_h2 = []
    for beta_m in BETA_SCAN:
    dt = d_theory(SIGMA_THETA, beta_m)
    vs_n, vs_a = [], []
    for seed in SEEDS:
    rn = run_ou_213b(seed, beta_m=beta_m, inherit_theta=True,
    sel_mode='neutral')
    ra = run_ou_213b(seed, beta_m=beta_m, inherit_theta=True,
    sel_mode='normal')
    vs_n.append(rn['var_end'])
    vs_a.append(ra['var_end'])
    nm, nstd = mean_std(vs_n)
    am, astd = mean_std(vs_a)
    if dt is not None:
    resid_n = nm – dt
    resid_a = am – dt
    rows_h2.append([f"β_m={beta_m:.2f}",
    f"{nm:.5f}±{nstd:.5f}",
    f"{dt:.5f}",
    f"{resid_n:+.5f}",
    f"{am:.5f}±{astd:.5f}",
    f"{resid_a:+.5f}"])
    else:
    rows_h2.append([f"β_m={beta_m:.2f}",
    f"{nm:.5f}±{nstd:.5f}",
    "不存在",
    "n/a",
    f"{am:.5f}±{astd:.5f}",
    "n/a"])
    md_table(["β_m", "neutral Var(θ)", "理论 D*", "neutral 残差",
    "A 组 Var(θ)", "A 组残差"], rows_h2, ["r"] * 6)
    print(" 口径:neutral 组 θ 不受选择,Var(θ) 由纯突变-收缩决定,配跟 D* 对账。")
    print(" A 组并列报(有选择时的偏离),但不作主判据。")
    print(" β_m=1.00 时 D* 不存在(分母 1−β_m²=0,公式无定义)→ "
    "旧基座无稳态可定价,正是 212-2 的结论。")
    print()

    # —————- Part 4 Var(θ) 轨迹 —————-
    bar("Part 4 Var(θ) 轨迹(neutral 组,每 25 代)")
    for beta_m in BETA_SCAN:
    trajs = []
    for seed in SEEDS:
    r = run_ou_213b(seed, beta_m=beta_m, inherit_theta=True,
    sel_mode='neutral')
    trajs.append(r['var_traj'])
    pts = []
    for g in range(0, N_GEN_213B + 1, 25):
    vals = [t[g] for t in trajs if g < len(t)]
    m, _ = mean_std(vals)
    pts.append(f"g{g}={m:.4f}")
    print(f" β_m={beta_m:.2f}: " + " ".join(pts))
    print(" 初始 θ 均匀[0,1],Var≈0.0833 为起点。")
    print()

    # —————- Part 5 诚实边界 —————-
    bar("Part 5 诚实边界")
    print(" 1. β_m=1.00 恒等性自检 PASS:与 212a(κ=0) 逐位一致。")
    print(" 2. 改基座后 209/210/212 的结果在旧基座下仍有效,")
    print(" 只是不能直接跟 182 定价对账。β_m=1 恒等性自检是这条说明的硬证据。")
    print(" 3. β_m 目前是外加参数(跟 212b 的 σ_θ 一样),")
    print(" 改基座是第一步不是终点——未来要把它自主化。")
    print(" 4. μ_pop 用上一代存活者 θ_A 均值,引入全局信息(非局部)。")
    print(" 5. 亲子斜率 b 用去夹取样本,有选择偏差;σ_θ 大时偏差大。")
    print(" 6. neutral 组仍有 λ=0.10 常数死亡,对 Var(θ) 有均匀影响。")
    print(" 7. 未检出 ≠ 不存在:残差可判不等于残差为零。")

    我等了半天没跑完结果,暂时截图就这样先哈:

    在这里插入图片描述

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 天赐范式第213天:补上收缩项,182的定价从不可判变成可判_OU型θ复制×β_m五档×neutral组对账×5seed
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!