FockMap

Building a Real Hamiltonian

Everything so far has been about single operators. Now let’s build a complete molecular Hamiltonian — the ultimate goal of the library.

The second-quantized Hamiltonian

In quantum chemistry, the electronic Hamiltonian is:

\[H = \sum_{pq} h_{pq}\, a^\dagger_p a_q \;+\; \tfrac{1}{2} \sum_{pqrs} \langle pq|rs\rangle\, a^\dagger_p a^\dagger_q a_s a_r\]

where $h_{pq}$ are one-body integrals (kinetic energy + nuclear attraction) and $\langle pq|rs\rangle$ are two-body integrals (electron-electron repulsion).

Step 1 — Define integrals

For H₂ in the STO-3G basis, we have 4 spin-orbitals:

let nModes = 4u

let oneBody = Map [
    ("00", Complex(-1.2563, 0.0))    // h₀₀ = ⟨σg↑|h|σg↑⟩
    ("11", Complex(-1.2563, 0.0))    // h₁₁ = ⟨σg↓|h|σg↓⟩
    ("22", Complex(-0.4719, 0.0))    // h₂₂ = ⟨σu↑|h|σu↑⟩
    ("33", Complex(-0.4719, 0.0))    // h₃₃ = ⟨σu↓|h|σu↓⟩
]

let twoBody = Map [
    ("0000", Complex(0.6745, 0.0)); ("1111", Complex(0.6745, 0.0))
    ("2222", Complex(0.6974, 0.0)); ("3333", Complex(0.6974, 0.0))
    ("0011", Complex(0.6745, 0.0)); ("1100", Complex(0.6745, 0.0))
    ("0022", Complex(0.6636, 0.0)); ("2200", Complex(0.6636, 0.0))
    ("0033", Complex(0.6636, 0.0)); ("3300", Complex(0.6636, 0.0))
    ("1122", Complex(0.6636, 0.0)); ("2211", Complex(0.6636, 0.0))
    ("1133", Complex(0.6636, 0.0)); ("3311", Complex(0.6636, 0.0))
    ("2233", Complex(0.6974, 0.0)); ("3322", Complex(0.6974, 0.0))
    ("0220", Complex(0.1809, 0.0)); ("2002", Complex(0.1809, 0.0))
    ("1331", Complex(0.1809, 0.0)); ("3113", Complex(0.1809, 0.0))
]

Step 2 — Build a coefficient lookup

The Hamiltonian builder needs a function that returns Some coefficient for known integrals and None for zero entries:

let lookup (key : string) =
    match key.Length with
    | 2 -> oneBody |> Map.tryFind key
    | 4 -> twoBody |> Map.tryFind key
    | _ -> None

Step 3 — Compute the qubit Hamiltonian

One function call does everything — loops over indices, looks up coefficients, encodes each term, and combines results:

let hamiltonian = computeHamiltonian lookup nModes

printfn "H₂ Hamiltonian: %d Pauli terms\n" hamiltonian.SummandTerms.Length

for term in hamiltonian.DistributeCoefficient.SummandTerms do
    let sign = if term.Coefficient.Real >= 0.0 then "+" else ""
    printfn "  %s%.4f  %s" sign term.Coefficient.Real term.Signature

Step 4 — Swap the encoding

Use computeHamiltonianWith to try any encoding:

let hBK = computeHamiltonianWith bravyiKitaevTerms lookup nModes
let hTT = computeHamiltonianWith ternaryTreeTerms  lookup nModes

// Or your custom scheme from the Encoding Internals chapter:
let hCustom = computeHamiltonianWith (encodeOperator myJW) lookup nModes

All three Hamiltonians have the same eigenvalues — they represent identical physics. They differ only in the Pauli weight and number of terms, which affects measurement cost on real quantum hardware.


Next: Mixed Bosonic–Fermionic Systems — sector tags and hybrid workflows