网络化简

先对满足规则且腿数较少的局部张量执行确定性收缩,再把缩减网络路径接回原网络。

本页目录

化简到固定点

simplify 反复扫描当前活张量;每次收缩都会减少一个活张量,结构发生变化后从头扫描,直到没有规则可以继续应用。规则只依赖当前腿结构和秩。

三条规则都是精确的结构收缩;图中 rank 1 与 rank 2 是满足输出腿和 holder 条件的具体例子。任一规则改变网络后,扫描从头开始;无规则可用时得到 fixed point。
当前张量 确定性处理规则
rank 0 标量 吸收到当前秩最小的另一个活张量
rank 1 向量 吸收到共享其唯一腿的张量
rank 2 矩阵 与共享腿的邻居收缩;仅当结果秩不高于该邻居原秩时应用
rank ≥ 3 没有以此张量为起点的规则;仍可与满足规则的邻居收缩

精确的结构变换

这里的 rank 是张量当前保留腿的数量。化简规则不是低秩近似,也没有奇异值截断。

网络化简规则循环的伪代码;省略函数外围

rust
loop {
    let ids: Vec<usize> = (0..st.legs.len())
        .filter(|&i| st.alive(i))
        .collect();
    if ids.len() <= 1 { break; }
    let mut fired = false;
    for &i in &ids {
        if !st.alive(i) { continue; }
        match st.rank(i) {
            0 => {
                if let Some(j) = ids.iter().copied()
                    .filter(|&j| j != i && st.alive(j))
                    .min_by_key(|&j| st.rank(j))
                {
                    st.contract(i, j);
                    fired = true;
                }
            }
            1 => {
                let leg = st.legs[i].as_ref().unwrap()[0];
                if let Some(j) = st.other_holder(leg, i) {
                    st.contract(i, j);
                    fired = true;
                }
            }
            2 => {
                let legs = st.legs[i].as_ref().unwrap().clone();
                for &leg in &legs {
                    if let Some(j) = st.other_holder(leg, i) {
                        let result = st.result_legs(i.min(j), i.max(j));
                        if result.len() <= st.rank(j) {
                            st.contract(i, j);
                            fired = true;
                            break;
                        }
                    }
                }
            }
            _ => {}
        }
        if fired { break; }
    }
    if !fired { break; }
}

Simplified 的保存内容

字段 含义
prefix 已经确定的原网络 SSA 收缩步骤
reduced 保留原腿 ID 与输出顺序的缩减 TensorNetwork
map 每个缩减输入张量所代表的原网络 SSA 节点

stitch 把缩减路径中的叶节点和新 SSA 节点映射回原网络编号,再接在 prefix 后面。最终交付的仍是原网络上的完整路径。

stitch 的 SSA 编号映射伪代码;省略函数签名

rust
let base = n_orig + prefix.len();
let trans = |x: usize| -> usize {
    if x < map.len() { map[x] } else { base + (x - map.len()) }
};
let mut full = prefix.clone();
for &(a, b) in reduced_path {
    let (x, y) = (trans(a), trans(b));
    full.push((x.min(y), x.max(y)));
}

在缩减网络上寻路

rust
use arctn::{random_greedy, simplify, simulate_path, stitch};

let reduced = simplify(&net);
let (reduced_path, _) = random_greedy(&reduced.reduced, 64, 7)?;
let path = stitch(
    net.n_tensors(),
    &reduced.prefix,
    &reduced.map,
    &reduced_path,
);
let stats = simulate_path(&net, &path)?;

若只需要这一常用组合,random_greedy_simplified 会完成网络验证、化简、缩减网络 random-greedy、stitch 和原网络重放。得到的路径属于原始完整网络,因此可以与其他完整路径使用同一 evaluator 比较。

公开入口与边界

入口 返回内容 是否运行完整寻路
simplify Simplified { prefix, reduced, map }
stitch 原网络完整 SSA path
random_greedy_simplified 完整路径与 PathStats 只运行缩减网络 random-greedy,不运行 Auto
arctn_simplify Python 化简统计、前缀和缩减结构信息

能力边界

网络化简不是数值执行后端,也不会修改张量网络所表示的数学收缩。只查看 arctn_simplify 的张量数统计,不能代替生成并验证一条完整路径。

Warning

fixed point 不等于最优化简

simplify 按当前确定性扫描规则反复应用可用收缩,直到这一规则集的 fixed point。它不保证得到所有可能化简结果中张量数最少的网络,也不保证 prefix 对规划目标最优。调用低层 Rust API 时,应先验证网络,并在 stitch 后用 simulate_path 复核原网络上的完整路径。

API 层级

低层化简 API 可独立调用;Light 与 Heavy 的内部组合和调度不属于该 API 的接口定义。