FockMap

Five Encodings, One Interface

Every encoding function in FockMap has the exact same type signature:

type EncoderFn = LadderOperatorUnit -> uint32 -> uint32 -> PauliRegisterSequence
//                    Raise/Lower       mode     total       result
//                                      index    qubits

This makes them drop-in replacements for each other:

let n = 8u
let mode = 2u

let jw  = jordanWignerTerms       Raise mode n   // O(n) weight
let bk  = bravyiKitaevTerms       Raise mode n   // O(log₂ n)
let par = parityTerms             Raise mode n   // O(n)
let bt  = balancedBinaryTreeTerms Raise mode n   // O(log₂ n)
let tt  = ternaryTreeTerms        Raise mode n   // O(log₃ n) — optimal

Side-by-side comparison

let encodings = [
    ("Jordan-Wigner",     jordanWignerTerms)
    ("Bravyi-Kitaev",     bravyiKitaevTerms)
    ("Parity",            parityTerms)
    ("Binary Tree",       balancedBinaryTreeTerms)
    ("Ternary Tree",      ternaryTreeTerms)
]

printfn "%-20s  %s" "Encoding" "Pauli weight of a†₂"
printfn "%-20s  %s" "────────" "───────────────────"

for (name, encode) in encodings do
    let terms = encode Raise 2u 8u
    let weight =
        terms.DistributeCoefficient.SummandTerms
        |> Array.map (fun t ->
            t.Signature |> Seq.filter (fun c -> c <> 'I') |> Seq.length)
        |> Array.max
    printfn "%-20s  %d" name weight

Understanding the output: PauliRegister and PauliRegisterSequence

Every encoding returns a PauliRegisterSequence — a sum of PauliRegister terms. Let’s unpack these types:

// A PauliRegister is a fixed-width Pauli string with a coefficient:
let reg = PauliRegister("ZZXI", Complex.One)

reg.Signature       // "ZZXI"
reg.Coefficient     // Complex(1.0, 0.0)
reg.[0]             // Some Z — first qubit
reg.[2]             // Some X — third qubit

// Immutable update:
let modified = reg.WithOperatorAt 2 Y       // "ZZYI"

// Multiply registers (qubit-by-qubit):
let product = reg * modified

// A PauliRegisterSequence is a sum of registers:
let seq = PauliRegisterSequence([| reg; modified |])
seq.SummandTerms              // PauliRegister[]
seq.DistributeCoefficient     // folds global coeff into each term

// Look up by signature:
let (found, r) = seq.["ZZXI"]

Next: Encoding Internals — Majorana decomposition and custom schemes