"""ex09utils.py — 第 8 章 fathonUtils 工具与窗口设计 演示 fathonUtils 提供的工具函数: toAggregated / subtractMean / forceGSL linRangeByStep / linRangeByCount:生成窗口向量 并讲解窗口设计的经验法则。 对应教程:tutorials/08-fathonUtils.md、第 9 章窗口选择。 运行: python ex09utils.
"""ex09_utils.py — 第 8 章 fathonUtils 工具与窗口设计
演示 fathonUtils 提供的工具函数:
对应教程:tutorials/08-fathonUtils.md、第 9 章窗口选择。
运行:
python ex09_utils.py
"""
import numpy as np
import fathon
from fathon import fathonUtils as fu
def demo_toaggregated():
"""toAggregated = 去均值 + 累积和。"""
np.random.seed(0)
x = np.random.randn(10) + 5.0
Y = fu.toAggregated(x)
Y_manual = np.cumsum(x - np.mean(x))
print("=== toAggregated ===")
print(" 原始前 5 个:", np.round(x[:5], 3))
print(" profile前5个:", np.round(Y[:5], 3))
print(" 手算 vs 工具 max 差:", np.max(np.abs(Y - Y_manual)))
def demo_subtract_mean():
"""subtractMean 仅去均值不累积(与 toAggregated 对比)。"""
x = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
print("\n=== subtractMean ===")
print(" 原始 :", x)
print(" 去均值后 :", fu.subtractMean(x))
print(" toAggregated:", fu.toAggregated(x))
def demo_window_ranges():
"""两种窗口向量生成器对比。"""
print("\n=== linRangeByStep vs linRangeByCount ===")
by_step = fu.linRangeByStep(10, 100, step=10)
by_count = fu.linRangeByCount(10, 100, num=5)
print(" byStep(10,100,step=10):", by_step)
print(" byCount(10,100,num=5) :", by_count)
print(" byCount 适合需要固定窗口点数的场景(如对数等距)。")
def demo_window_design():
"""窗口设计的经验法则。"""
np.random.seed(0)
L = 4000
profile = fu.toAggregated(np.random.randn(L))
dfa = fathon.DFA(profile)
# 法则 1:最小窗口 ≥ 10(保证段内多项式拟合有样本) # 法则 2:最大窗口 ≤ L/4(保证至少 4 段,统计稳定) # 法则 3:窗口数 ≥ 8~10 个(log-log 拟合才有意义) cases = [ ("最小窗口集", fu.linRangeByStep(10, 50, step=10)), ("标准集 ", fu.linRangeByStep(10, L // 4, step=20)), ("对数等距 ", fu.linRangeByCount(16, L // 4, num=15)), ] print("\n=== 窗口设计对比 ===") for name, wins in cases: n, F = dfa.computeFlucVec(wins, revSeg=True) H, _ = dfa.fitFlucVec() print(f" {name} 窗口数={len(wins):3d} H={H:.4f}")
def demo_force_gsl():
"""forceGSL:在构建了 Cython 模块的环境下,强制使用 GSL 后端。"""
print("\n=== forceGSL ===")
try:
fu.forceGSL()
print(" forceGSL() 调用成功(如果未编译 GSL,会回退)。")
except AttributeError:
print(" 当前版本无 forceGSL(正常,依平台而定)。")
def main():
demo_toaggregated()
demo_subtract_mean()
demo_window_ranges()
demo_window_design()
demo_force_gsl()
if name == "main":
main()