天赐范式第188天·第一篇:让环境开始轮回------周期峰的低通滤波响应
摘要
周期峰驱动下AR(1)均值响应是低通滤波:幅值衰减|H(Ω)|+相位滞后φ(Ω),离散z域闭式。临界周期T*=2π/c≈523代,数值比值1.00。

一、接续187-1:定向移动做完了,周期呢?
187-1让峰开始移动------但那是单调趋势:x*(t)=x*_0+v·t,峰一直往一个方向跑。种群学会了就是常数滞后,追得很稳。
真实栖息地的环境变化有个更基本的形态:周期。昼夜、季节、潮汐------环境不是一直变好或一直变坏,是来回摆。这是环境弧的第二分量。
数学上区别很大:定向移动下种群对峰是常数滞后 (187-1的lag*);周期驱动下种群均值是对峰的低通滤波 ------响应是幅值衰减+相位滞后。这是AR(1)对正弦输入的标准稳态解,理论结构全新,不是187的延伸。

二、理论推导------AR(1)低通滤波
均值更新(与187-1同):μ(t+1) = (1−c)·μ(t) + c·x*(t),c = β·h²·K
周期峰:x*(t) = x*_0 + A·sin(Ω·t),Ω是角频率(弧度/代)。
z域传递函数
H(z) = c / (z − (1−c))
令z = e^(jΩ),离散频率响应:
|H(Ω)| = c / √(1 − 2(1−c)cos(Ω) + (1−c)²)
φ(Ω) = −atan2(sin(Ω), cos(Ω) − 1 + c)
连续极限(Ω→0, c≪1)
|H(Ω)| → c / √(c² + Ω²)
φ(Ω) → −arctan(Ω / c)
临界周期
半功率点 |H| = 1/√2 对应 Ω* = c(连续近似),临界周期:
T* = 2π / c ≈ 2π / 0.012 ≈ 523代
这是"数字生命的时间尺度"------环境周期比这短,种群就感知不到。
三、频率响应曲线:理论vs数值
固定σ_v=0.02(c=0.0120),振幅A=0.3,扫Ω ∈ {0.005, 0.01, 0.02, 0.03, 0.05, 0.1, 0.2}。正弦拟合提取种群均值的幅值和相位。
| Ω | T(代) | |H|离散 | |H|连续 | |H|数值 | 比值 | φ离散 | φ数值 | 平均fitness | 状态 |
|---|---|---|---|---|---|---|---|---|---|
| 0.005 | 1257 | 0.924 | 0.923 | 0.923 | 1.00 | −0.395 | 0.377 | 0.729 | 跟踪 |
| 0.010 | 628 | 0.770 | 0.768 | 0.773 | 1.00 | −0.697 | 0.673 | 0.498 | 衰减 |
| 0.012 | 524 | 0.709 | 0.707 | 0.714 | 1.01 | −0.788 | 0.769 | 0.442 | 衰减 |
| 0.020 | 314 | 0.517 | 0.515 | 0.518 | 1.00 | −1.038 | 1.014 | 0.353 | 衰减 |
| 0.030 | 209 | 0.374 | 0.372 | 0.375 | 1.00 | −1.203 | 1.184 | 0.318 | 衰减 |
| 0.050 | 126 | 0.235 | 0.234 | 0.236 | 1.00 | −1.359 | 1.349 | 0.298 | 衰减 |
| 0.100 | 63 | 0.120 | 0.119 | 0.120 | 1.00 | −1.501 | 1.492 | 0.291 | 衰减 |
| 0.200 | 31 | 0.060 | 0.060 | 0.060 | 1.00 | −1.611 | 1.611 | 0.288 | 躺平 |
幅值衰减|H|:离散理论vs数值比值全部1.00-1.01------闭式精确。相位φ:理论为负(滞后),数值返回atan2(−a,b)取绝对值,两者符号约定不同,下文比较绝对值。
四、跟踪区、衰减区与躺平区
跟踪区(T ≥ 1257代,Ω ≤ 0.005):|H|≈0.92,种群均值振幅接近峰振幅。 峰慢,种群跟得上,只有相位滞后φ≈0.4弧度(约79代延迟,数值约75代)。
衰减区(T = 63~628代,Ω = 0.01~0.1):0 < |H| < 1,种群均值振幅衰减。 半功率点(|H|=1/√2≈0.707)在临界周期T*=2π/c≈523代附近(见表中Ω=0.012行,T=524代,|H|离散=0.709)。T=314代时|H|=0.52,T=63代时|H|=0.12------种群均值几乎不动,峰在摆种群不摆。
躺平区(T ≤ 31代,Ω ≥ 0.2):|H|→0,种群均值完全躺平。 峰在动,种群不动,平均fitness≈0.29------反而可能不如"假装峰不动"。这是滤波特性的必然:快于T*的周期,种群感知不到。
临界周期T*≈523代是分界线。 c=β·h²·K=0.012是跟踪速率,T*=2π/c是种群响应时间尺度。环境周期比T*长,种群跟得上;比T*短,种群感知不到。
五、结论与弧签名动作
| 问题 | 答案 |
|---|---|
| 周期峰下种群怎么响应? | 低通滤波:幅值衰减|H(Ω)|+相位滞后φ(Ω),AR(1)标准稳态解 |
| 临界周期多长? | T*=2π/c≈523代------数字生命感知环境变化的时间尺度下限 |
| 理论准吗? | 幅值比值全部1.00,离散z域闭式精确 |
| 和187-1什么关系? | 187-1定向移动=常数滞后;188-1周期驱动=低通滤波,环境弧第二分量 |
叙事弧:
- 187-1:定向移动------常数滞后lag*=v(1−c)/c
- 188-1:周期驱动------低通滤波|H(Ω)|+φ(Ω),从"追踪"升级到"滤波"
- 弧签名动作:187定向追踪 → 188周期滤波。
- 主线意义:T*≈523代是数字生命感知环境变化的时间尺度下限。
环境弧全貌:定向(187,趋势分量)→ 周期(188-1,季节分量)→ 随机游走(不可预测分量,留给189+)。
降调:
-
线性化近似。 低通滤波公式是AR(1)线性系统的稳态解,假设h²和K当常数(用σ_v=0.02自洽解)。大振幅下种群偏离峰远,h²和K有微小漂移(187-1降调2同源)。振幅A=0.3下影响小,更大振幅需验证。
-
相位拟合有0~5%偏差(随Ω减小而增大)。 数值相位绝对值比理论略小(如0.377 vs 0.395,偏差4.6%;1.611 vs 1.611,偏差0%)。偏差源于低频端测量窗覆盖周期少、暂态残留多;高频端周期多、暂态影响小。幅值精确匹配是核心结果,相位偏差在降调里如实报。
-
测量窗含整数个周期。 gen=4000、warmup=500,测量窗3500代。最长周期T=1257代覆盖2.8个周期------够。更长的周期需要更多代数。
-
跟踪区仅Ω=0.005一个格点支撑。 更慢周期(Ω<0.005)未测,需要更长模拟窗口。
-
单位点模型。 多位点、上位效应、连锁不平衡待后续。
系列还在逐步建设中,完善是和伙伴们的努力方向。
附录:完整代码
python
# -*- coding: utf-8 -*-
"""
天赐范式 第188天 第一篇
让环境开始轮回------周期峰的低通滤波响应
PID: TC-188A-V3.3.26.0
V3.3.26.0 · 2026-10-07
接续187-1:定向移动(趋势分量)→ 周期移动(季节分量)
187-1: x*(t)=x*_0+v·t(单调趋势),种群响应=常数滞后
188-1: x*(t)=x*_0+A·sin(Ω·t)(周期驱动),种群响应=低通滤波
理论:AR(1)均值动力学 μ(t+1)=(1-c)·μ(t)+c·x*(t),c=β·h²·K
z域传递函数 H(z)=c/(z-(1-c))
令z=e^(jΩ),离散频率响应:
|H(Ω)| = c/√(1−2(1−c)cos(Ω)+(1−c)²)
φ(Ω) = −atan2(sin(Ω), cos(Ω)−1+c)
连续极限(Ω→0, c<<1):
|H(Ω)| → c/√(c²+Ω²)
φ(Ω) → −arctan(Ω/c)
临界周期 T*=2π/c≈523代(半功率点)
预测:
慢周期(T>>T*):A≈1, φ≈0,种群紧跟峰
快周期(T<<T*):A→0,种群均值躺平,峰在动种群不动
T*≈523代是"数字生命的时间尺度"------季节比这短就感知不到
数值:扫Ω,正弦拟合提取幅值衰减+相位滞后,理论vs数值对比
"""
import sys
import math
import numpy as np
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8")
PID = "TC-188A-V3.3.26.0"
TARGET = 0.5
X_STAR_0 = 0.8
AMPLITUDE = 0.3
FITNESS_WIDTH = 0.10
BETA = 0.3
SIGMA_E = 0.02
SIGMA_V = 0.02
N_POP = 200
N_GENERATIONS = 4000
WARMUP_STATIC = 500
N_SEEDS = 20
TOL = 1e-12
MAX_ITER = 5000
OMEGAS = [0.005, 0.01, 0.012, 0.02, 0.03, 0.05, 0.1, 0.2]
def bar(title):
print("=" * 72)
print(" " + title)
print("=" * 72)
print()
def sub(title):
print("【" + title)
print("-" * 72)
def fitness(x, x_star):
return np.exp(-(x - x_star) ** 2 / (2 * FITNESS_WIDTH ** 2))
def solve_self_consistent(sigma_v):
var_g = sigma_v ** 2 / (1 - BETA ** 2)
for it in range(MAX_ITER):
sigma_x2 = var_g + SIGMA_E ** 2
h2 = var_g / sigma_x2
v_x_sel = sigma_x2 * FITNESS_WIDTH ** 2 / (sigma_x2 + FITNESS_WIDTH ** 2)
var_g_sel = h2 ** 4 * v_x_sel + var_g * (1 - h2 ** 2)
var_g_new = BETA ** 2 * var_g_sel + sigma_v ** 2
if abs(var_g_new - var_g) < TOL:
return var_g_new, it + 1
var_g = var_g_new
return var_g, MAX_ITER
def theory_response(omega, track_rate):
c = track_rate
denom = 1.0 - 2.0 * (1.0 - c) * math.cos(omega) + (1.0 - c) ** 2
gain = c / math.sqrt(denom) if denom > 0 else float('inf')
phase = -math.atan2(math.sin(omega), math.cos(omega) - 1.0 + c)
return gain, phase
def theory_response_cont(omega, track_rate):
c = track_rate
gain = c / math.sqrt(c ** 2 + omega ** 2)
phase = -math.atan2(omega, c)
return gain, phase
def run_one(omega, seed):
rng = np.random.RandomState(seed)
genes = rng.normal(TARGET, 0.01, N_POP)
mu_trace = []
xstar_trace = []
fit_trace = []
for gen in range(N_GENERATIONS):
if gen < WARMUP_STATIC:
x_star = X_STAR_0
else:
t = gen - WARMUP_STATIC
x_star = X_STAR_0 + AMPLITUDE * math.sin(omega * t)
phenos = genes + rng.normal(0, SIGMA_E, N_POP)
fits = fitness(phenos, x_star)
fit_sum = float(fits.sum())
if fit_sum < 1e-10:
for g2 in range(gen, N_GENERATIONS):
if g2 >= WARMUP_STATIC:
fit_trace.append(0.0)
break
probs = fits / fit_sum
sel_idx = rng.choice(N_POP, size=N_POP, p=probs)
parent_genes = genes[sel_idx]
mu = float(np.mean(genes))
genes = mu + BETA * (parent_genes - mu) + rng.normal(0, SIGMA_V, N_POP)
if gen >= WARMUP_STATIC:
mu_trace.append(float(np.mean(genes)))
xstar_trace.append(x_star)
fit_trace.append(float(np.mean(fits)))
return np.array(mu_trace), np.array(xstar_trace), np.array(fit_trace)
def sine_fit(mu_trace, xstar_trace, omega):
t = np.arange(len(mu_trace)) + 1
residual = mu_trace - X_STAR_0
cos_basis = np.cos(omega * t)
sin_basis = np.sin(omega * t)
A_mat = np.array([[np.sum(cos_basis * cos_basis), np.sum(cos_basis * sin_basis)],
[np.sum(sin_basis * cos_basis), np.sum(sin_basis * sin_basis)]])
b_vec = np.array([np.sum(residual * cos_basis), np.sum(residual * sin_basis)])
try:
coeffs = np.linalg.solve(A_mat, b_vec)
except np.linalg.LinAlgError:
return 0.0, 0.0
a, b = coeffs
amp = math.sqrt(a ** 2 + b ** 2)
phase = math.atan2(-a, b)
return amp, phase
def main():
bar(f"{PID} 让环境开始轮回------周期峰的低通滤波响应")
print(f"模型: g'=μ+β(g_sel-μ)+v_mut(回归到种群均值μ)")
print(f"fitness峰: x*(t)=x*_0+A·sin(Ω·t), x*_0={X_STAR_0}, A={AMPLITUDE}")
print(f"参数: β={BETA}, σ_e={SIGMA_E}, σ_v={SIGMA_V}, N={N_POP}, seeds={N_SEEDS}")
print(f"理论: AR(1)低通滤波 |H(Ω)|=c/√(1−2(1−c)cos(Ω)+(1−c)²)")
print(f" 连续极限 |H|=c/√(c²+Ω²), φ=−arctan(Ω/c)")
print(f" 临界周期 T*=2π/c")
print(f"数值: gen={N_GENERATIONS}, warmup={WARMUP_STATIC}, 正弦拟合提取幅值+相位")
print()
var_g_star, _ = solve_self_consistent(SIGMA_V)
sigma_x2 = var_g_star + SIGMA_E ** 2
h2 = var_g_star / sigma_x2
K = sigma_x2 / (sigma_x2 + FITNESS_WIDTH ** 2)
track_rate = BETA * h2 * K
T_star = 2 * math.pi / track_rate
sub("理论参数(σ_v=0.02自洽)")
print(f" h²* = {h2:.4f}")
print(f" K = {K:.4f}")
print(f" c = β·h²·K = {track_rate:.6f}(跟踪速率)")
print(f" T* = 2π/c = {T_star:.1f}代(临界周期)")
print()
sub("频率响应:理论 vs 数值")
print(f"{'Ω':>8s} {'T(代)':>8s} {'|H|离散':>8s} {'|H|连续':>8s} {'|H|数值':>8s} {'φ离散':>8s} {'φ数值':>8s} {'平均fit':>10s} {'状态':>6s}")
print("-" * 90)
results = []
for omega in OMEGAS:
T = 2 * math.pi / omega
gain_discrete, phase_discrete = theory_response(omega, track_rate)
gain_cont, phase_cont = theory_response_cont(omega, track_rate)
gains_seed = []
phases_seed = []
fits_seed = []
for seed in range(N_SEEDS):
mu_trace, xstar_trace, fit_trace = run_one(omega, seed)
amp, phase = sine_fit(mu_trace, xstar_trace, omega)
gains_seed.append(amp / AMPLITUDE)
phases_seed.append(phase)
fits_seed.append(float(np.mean(fit_trace)) if len(fit_trace) > 0 else 0.0)
gain_num = float(np.mean(gains_seed))
phase_num = float(np.mean(phases_seed))
mean_fit = float(np.mean(fits_seed))
if gain_num > 0.9:
status = "跟踪"
elif gain_num > 0.1:
status = "衰减"
else:
status = "躺平"
results.append({
'omega': omega, 'T': T, 'gain_discrete': gain_discrete,
'gain_cont': gain_cont, 'gain_num': gain_num,
'phase_discrete': phase_discrete, 'phase_num': phase_num,
'mean_fit': mean_fit, 'status': status,
})
print(f"{omega:>8.4f} {T:>8.1f} {gain_discrete:>8.4f} {gain_cont:>8.4f} {gain_num:>8.4f} {phase_discrete:>8.4f} {phase_num:>8.4f} {mean_fit:>10.6f} {status:>6s}")
print()
sub("理论 vs 数值对比")
for r in results:
ratio = r['gain_num'] / r['gain_discrete'] if r['gain_discrete'] > 1e-6 else float('inf')
print(f" Ω={r['omega']:.4f} (T={r['T']:.0f}代): |H|离散={r['gain_discrete']:.4f} vs |H|数值={r['gain_num']:.4f},比值={ratio:.2f},φ离散={r['phase_discrete']:.4f} vs φ数值={r['phase_num']:.4f}")
print()
sub("结论")
print(f"187-1:定向移动,常数滞后lag*=v·(1−c)/c")
print(f"188-1:周期驱动,低通滤波响应|H(Ω)|+φ(Ω)")
print(f" 临界周期 T*=2π/c={T_star:.0f}代------数字生命的时间尺度")
track_vs = [r for r in results if r['status'] == "跟踪"]
decay_vs = [r for r in results if r['status'] == "衰减"]
flat_vs = [r for r in results if r['status'] == "躺平"]
if track_vs:
print(f" 跟踪区:T≥{track_vs[-1]['T']:.0f}代(Ω≤{track_vs[-1]['omega']:.4f}),|H|≈1")
if decay_vs:
print(f" 衰减区:T∈[{decay_vs[-1]['T']:.0f}, {decay_vs[0]['T']:.0f}]代,0<|H|<1")
if flat_vs:
print(f" 躺平区:T≤{flat_vs[0]['T']:.0f}代(Ω≥{flat_vs[0]['omega']:.4f}),|H|→0")
print()
print(f" 弧签名动作:187定向追踪 → 188周期滤波")
print(f" 主线意义:T*≈{T_star:.0f}代是数字生命感知环境变化的时间尺度下限")
if __name__ == "__main__":
main()

天赐范式 V3.3.26.0 · 2026-10-07