网络化简
先对满足规则且腿数较少的局部张量执行确定性收缩,再把缩减网络路径接回原网络。
本页目录
化简到固定点
simplify 反复扫描当前活张量;每次收缩都会减少一个活张量,结构发生变化后从头扫描,直到没有规则可以继续应用。规则只依赖当前腿结构和秩。
S · T[p,q]U[p,q]标量乘入当前 rank 最小的活张量Σx V[x] T[x,p,q]U[p,q]x 不属于输出,且只出现在这两个张量中Σy M[x,y] T[y,p]U[x,p]y 可消去,且结果 rank 不超过相邻张量每次收缩后重新扫描;没有可用规则时结束。
prefix已确定的原网络 SSA 步骤reduced固定点后的张量网络map缩减输入 → 原网络 SSA node| 当前张量 | 确定性处理规则 |
|---|---|
| rank 0 标量 | 吸收到当前秩最小的另一个活张量 |
| rank 1 向量 | 吸收到共享其唯一腿的张量 |
| rank 2 矩阵 | 与共享腿的邻居收缩;仅当结果秩不高于该邻居原秩时应用 |
| rank ≥ 3 | 没有以此张量为起点的规则;仍可与满足规则的邻居收缩 |
精确的结构变换
这里的 rank 是张量当前保留腿的数量。化简规则不是低秩近似,也没有奇异值截断。
网络化简规则循环的伪代码;省略函数外围
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 编号映射伪代码;省略函数签名
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)));
}
在缩减网络上寻路
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 的接口定义。