"""ex06circlevsrandom.py — 第 5 章 圆环 vs 随机点的拓扑差异 对应教程:tutorials/05-visualization.md 5.7 节。 对照实验: 圆环:H1 有显著高持久点 均匀随机:H1 大量短命点(贴近对角线) 用瓶颈距离量化两者差异。 运行: python ex06circlevsrandom.py """ import numpy as np from ripser import ripser from persim import plotdiagrams, bottleneck import matplotlib.
"""ex06_circle_vs_random.py — 第 5 章 圆环 vs 随机点的拓扑差异
对应教程:tutorials/05-visualization.md 5.7 节。
对照实验:
运行:
python ex06_circle_vs_random.py
"""
import numpy as np
from ripser import ripser
from persim import plot_diagrams, bottleneck
import matplotlib.pyplot as plt
from common import sample_circle, sample_random
def main():
circle = sample_circle(n=100, noise=0.05, seed=11)
random = sample_random(n=100, dim=2, seed=11)
dgms_c = ripser(circle, maxdim=1)['dgms'] dgms_r = ripser(random, maxdim=1)['dgms'] # ── 可视化 ── fig, axes = plt.subplots(2, 2, figsize=(11, 8)) axes[0, 0].scatter(circle[:, 0], circle[:, 1], s=12, alpha=0.7) axes[0, 0].set_aspect('equal'); axes[0, 0].set_title('圆环点云') axes[0, 0].grid(alpha=0.3) axes[0, 1].scatter(random[:, 0], random[:, 1], s=12, alpha=0.7, c='C2') axes[0, 1].set_aspect('equal'); axes[0, 1].set_title('均匀随机点') axes[0, 1].grid(alpha=0.3) plot_diagrams(dgms_c, ax=axes[1, 0], labels=['H0', 'H1'], show=False) axes[1, 0].set_title('圆环持久图') plot_diagrams(dgms_r, ax=axes[1, 1], labels=['H0', 'H1'], show=False) axes[1, 1].set_title('随机点持久图') plt.tight_layout() # ── 瓶颈距离对比 ── print("=== H1 持久性对比 ===") for name, dgm in [("圆环", dgms_c[1]), ("随机", dgms_r[1])]: pers = dgm[:, 1] - dgm[:, 0] pers = pers[np.isfinite(pers)] print(f" {name}: {len(dgm)} 点, max persistence=" f"{pers.max() if len(pers) else 0:.4f}") d_cc, _ = bottleneck(dgms_c[1], dgms_r[1]) print(f"\nbottleneck(圆环 H1, 随机 H1) = {d_cc:.4f}(应较大)") # 同类对比:两个独立圆环 circle2 = sample_circle(n=100, noise=0.05, seed=22) dgm_c2 = ripser(circle2, maxdim=1)['dgms'][1] d_same, _ = bottleneck(dgms_c[1], dgm_c2) print(f"bottleneck(圆环1 H1, 圆环2 H1) = {d_same:.4f}(应较小)") plt.show()
if name == "main":
main()