Snapkitty/quantum-kernel
0
1# tda_braid_map.jl — Barcodes → BraidWords on Heavy-Hex2 3module TDABraidMap4 5using LinearAlgebra6using Random7 8export barcode_to_braid_word, feature_diff_to_braid, heavy_hex_braid_generators9export pairwise_braid_words10 11# ═══════════════════════════════════════════════════════════════════════12# Types (imported from YaoTypes in full build)13# ═══════════════════════════════════════════════════════════════════════14 15struct BraidWord16 generators::Vector{Int}17 edge_indices::Vector{Int}18 n_strands::Int19 20 function BraidWord(gens::Vector{Int}, edges::Vector{Int}, n_strands::Int)21 @assert length(gens) == length(edges)22 new(gens, edges, n_strands)23 end24end25 26BraidWord(n_strands::Int) = BraidWord(Int[], Int[], n_strands)27 28struct PersistenceInterval29 dim::Int30 birth::Float6431 death::Float6432end33 34struct Barcode35 H0::Vector{PersistenceInterval}36 H1::Vector{PersistenceInterval}37end38 39const HERON_EDGES_0 = [40 (0, 1), (1, 2),41 (0, 3), (1, 3), (1, 4), (2, 4), (2, 5),42 (3, 4), (4, 5), (5, 6),43 (3, 7), (4, 7), (4, 8), (5, 8), (5, 9), (6, 9),44 (7, 8), (8, 9)45]46 47const HERON_EDGE_INDEX = Dict(edge => i for (i, edge) in enumerate(HERON_EDGES_0))48 49# ═══════════════════════════════════════════════════════════════════════50# Heavy-Hex Braid Generators51# ═══════════════════════════════════════════════════════════════════════52 53function heavy_hex_braid_generators(n_strands::Int)::Dict{Int, Tuple{Int,Int}}54 gens = Dict{Int, Tuple{Int,Int}}()55 for i in 1:min(n_strands-1, length(HERON_EDGES_0))56 gens[i] = HERON_EDGES_0[i]57 end58 return gens59end60 61# ═══════════════════════════════════════════════════════════════════════62# Barcode → Braid Word63# ═══════════════════════════════════════════════════════════════════════64 65"""66 barcode_to_braid_word(bc::Barcode, n_strands::Int; persistence_threshold=0.1)67 68Map persistent homology intervals to Artin generators.69High-persistence H1 features → over-crossings (σ)70Low-persistence / noise → under-crossings (σ⁻¹) or identity71"""72function barcode_to_braid_word(bc::Barcode, n_strands::Int;73 persistence_threshold::Float64=0.1)::BraidWord74 generators = Int[]75 edge_indices = Int[]76 77 gens_map = heavy_hex_braid_generators(n_strands)78 n_gens = length(gens_map)79 80 for (idx, intv) in enumerate(bc.H1)81 pers = intv.death - intv.birth82 if pers < persistence_threshold83 continue84 end85 86 gen_idx = (idx - 1) % n_gens + 187 edge = gens_map[gen_idx]88 edge_idx = HERON_EDGE_INDEX[edge]89 90 sign = (idx % 2 == 1) ? 1 : -191 92 push!(generators, sign * gen_idx)93 push!(edge_indices, edge_idx)94 end95 96 if isempty(generators)97 return BraidWord(n_strands)98 end99 100 BraidWord(generators, edge_indices, n_strands)101end102 103"""104 feature_diff_to_braid(x, x′, n_strands; epsilon=0.5)105 106Direct mapping: feature difference Δ = x - x' → braid word.107K(x,x') = ⟨0|U_Φ(x) U_Φ(x')†|0⟩ where U_Φ encodes braid.108"""109function feature_diff_to_braid(x::Vector{Float64}, x′::Vector{Float64},110 n_strands::Int; epsilon::Float64=0.5)::BraidWord111 Δ = x - x′112 generators = Int[]113 edge_indices = Int[]114 115 gens_map = heavy_hex_braid_generators(n_strands)116 n_gens = length(gens_map)117 118 for (i, δ) in enumerate(Δ)119 if abs(δ) < epsilon120 continue121 end122 123 gen_idx = (i - 1) % n_gens + 1124 edge = gens_map[gen_idx]125 edge_idx = HERON_EDGE_INDEX[edge]126 127 sign = δ > 0 ? 1 : -1128 129 repeats = min(max(1, Int(round(abs(δ) * 2))), 3)130 for _ in 1:repeats131 push!(generators, sign * gen_idx)132 push!(edge_indices, edge_idx)133 end134 end135 136 if isempty(generators)137 return BraidWord(n_strands)138 end139 140 BraidWord(generators, edge_indices, n_strands)141end142 143# ═══════════════════════════════════════════════════════════════════════144# Batch Operations145# ═══════════════════════════════════════════════════════════════════════146 147function pairwise_braid_words(X::Matrix{Float64}, n_strands::Int;148 epsilon::Float64=0.5)::Matrix{BraidWord}149 n_samples = size(X, 2)150 braids = Matrix{BraidWord}(undef, n_samples, n_samples)151 for i in 1:n_samples, j in 1:n_samples152 braids[i,j] = feature_diff_to_braid(X[:,i], X[:,j], n_strands; epsilon=epsilon)153 end154 return braids155end156 157end # module TDABraidMap158 