Guides
Chemistry
Molecular Hamiltonians, fermion-to-qubit mappings, UCCSD ansatz, and PySCF integration.
Superfermion's chemistry module handles molecular electronic structure: building Hamiltonians, mapping fermions to qubits, and constructing chemistry-inspired ansatze.
Quick Start
from superfermion.chemistry.hamiltonians import get_molecular_hamiltonian
from superfermion.chemistry.ansatz import uccsd_ansatz
import superfermion as sf
# Get a pre-built molecular Hamiltonian
H = get_molecular_hamiltonian("H2", basis="sto-3g")
print(f"H2 Hamiltonian: {len(H.terms)} terms")
# Build a UCCSD ansatz (minimal 2-qubit H2 ansatz)
ansatz = uccsd_ansatz(n_qubits=2, n_electrons=2)
print(f"Ansatz: {ansatz.n_parameters} parameter, {ansatz.gate_count} gates")
# Run VQE
from superfermion.algorithms.variational import VQE
vqe = VQE(ansatz, H)
result = vqe.minimize(iterations=100)
print(f"H2 ground state energy: {result.optimal_value:.6f} Hartree")Molecular Hamiltonians
Pre-built Library
from superfermion.chemistry.hamiltonians import get_molecular_hamiltonian
# Built-in molecules (pre-computed at equilibrium geometry)
h2 = get_molecular_hamiltonian("H2", basis="sto-3g")
print(f"H2: {len(h2.terms)} terms")
# Additional molecules (LiH, H2O, ...) require PySCF — install with:
# pip install "superfermion[chemistry]"PySCF Bridge — Custom Molecules
For any molecule, use the PySCF bridge:
from superfermion.chemistry.pyscf_bridge import molecule_from_geometry
# Define any molecule via an XYZ geometry string
mol = molecule_from_geometry("H 0 0 0; H 0 0 0.7414", basis="sto-3g", name="H2")
# With PySCF installed this computes HF + integrals; otherwise it falls
# back to the pre-computed molecule library
summary = mol.summary()
print(f"{summary['name']}: {summary['n_electrons']} electrons, "
f"{summary['n_orbitals']} orbitals, {summary['n_qubits']} qubits, "
f"pyscf={'available' if summary['pyscf_available'] else 'library fallback'}")
# Build the qubit Hamiltonian
H = mol.to_hamiltonian(active_space=(2, 2))
print(f"Qubit Hamiltonian: {len(H.terms)} terms")Fermion-to-Qubit Mappings
from superfermion.chemistry.hamiltonians import FermionicOperator
import numpy as np
# One-body integrals h1 (spin-orbital basis) — a two-site model
h1 = np.zeros((2, 2))
h1[0, 0] = -1.0
h1[1, 1] = -0.5
h1[0, 1] = h1[1, 0] = 0.2
fermion_op = FermionicOperator.from_coeffs(h1)
# Jordan-Wigner transform
jw_qubit_op = fermion_op.jordan_wigner(n_qubits=2)
print(f"Jordan-Wigner: {len(jw_qubit_op.terms)} terms")
# Bravyi-Kitaev transform
bk_qubit_op = fermion_op.bravyi_kitaev(n_qubits=2)
print(f"Bravyi-Kitaev: {len(bk_qubit_op.terms)} terms")| Mapping | Qubit Scaling | Locality | Best For |
|---|---|---|---|
| Jordan-Wigner | O(N) | O(N) weight | Small molecules |
| Bravyi-Kitaev | O(N) | O(log N) weight | Larger molecules |
UCCSD Ansatz
The Unitary Coupled Cluster Singles and Doubles ansatz is the standard choice for molecular VQE:
from superfermion.chemistry.ansatz import uccsd_ansatz
# Minimal 2-qubit H2 ansatz (single parameter, O'Malley et al. 2016)
h2_ansatz = uccsd_ansatz(n_qubits=2, n_electrons=2)
print(f"H2 ansatz: {h2_ansatz.n_parameters} parameter, {h2_ansatz.gate_count} gates")
# Hardware-efficient UCC-style ansatz for larger active spaces
uccsd = uccsd_ansatz(n_qubits=4, n_electrons=2)
print(f"4-qubit ansatz: {uccsd.n_parameters} parameters, {uccsd.gate_count} gates")Full VQE Workflow
End-to-end VQE with a custom molecule:
from superfermion.chemistry.hamiltonians import get_molecular_hamiltonian
from superfermion.chemistry.ansatz import uccsd_ansatz
from superfermion.algorithms.variational import VQE
import numpy as np
# 1. Build molecular Hamiltonian (pre-computed H2 library entry)
H = get_molecular_hamiltonian("H2", basis="sto-3g")
# 2. Build ansatz
ansatz = uccsd_ansatz(2, 2)
# 3. Initial parameters (array, ordered as ansatz.parameters)
init_params = np.zeros(ansatz.n_parameters)
# 4. Run VQE
vqe = VQE(ansatz, H)
result = vqe.minimize(initial_params=init_params, iterations=200)
print(f"Ground state energy: {result.optimal_value:.8f} Hartree")
print(f"Optimal parameters: {result.optimal_params}")Performance Notes
- Hamiltonian construction — runs in Python using PySCF's integral engine
- Expectation values — computed in Rust via
sf.State.expectation() - Gradients — adjoint method in Rust, O(1) scaling regardless of parameter count
- Recommendation — for molecules < 20 qubits, combine UCCSD + adjoint gradient for fastest convergence
