State preparation
The StatePreparation algorithm in QDK/Chemistry constructs quantum circuits that load classical representations of target wavefunctions onto qubits.
Following QDK/Chemistry’s algorithm design principles, it takes a Wavefunction instance as input and produces an OpenQASM circuit as output.
The output circuit, when executed, prepares the qubit register in a state that encodes the input wavefunction.
Overview
The StatePreparation module provides tools for constructing quantum circuits that load classical representations of wavefunctions(e.g., a Slater determinant or a linear combination thereof, represented by the Wavefunction class) onto qubits. It supports multiple approaches for state preparation, allowing users to choose the method best suited to their problem. Each approach is designed to efficiently encode quantum states for chemistry applications.
For details on individual methods and their technical implementations, see the Available implementations section below.
Using the StatePreparation
Note
This algorithm is currently available only in the Python API.
This section demonstrates how to create, configure, and run a state preparation.
The run method returns an OpenQASM circuit string that, when executed, loads the input wavefunction onto a qubit register.
Input requirements
The StatePreparation requires the following input:
- Wavefunction
A
Wavefunctioninstance containing the quantum state to be loaded onto qubits. This is typically obtained from a multi-configuration calculation using the MultiConfigurationCalculator. The method with which this encoding is achieved is implementation dependent.
Creating a state preparation algorithm
from qdk_chemistry.algorithms import create
# Create a StatePreparation instance
sparse_prep = create("state_prep", "sparse_isometry_gf2x")
regular_prep = create("state_prep", "regular_isometry")
Configuring settings
Settings can be modified using the settings() object.
See Available implementations below for implementation-specific options.
# Configure transpilation settings
sparse_prep.settings().set("transpile", True)
sparse_prep.settings().set("basis_gates", ["rz", "cz", "sdg", "h"])
sparse_prep.settings().set("transpile_optimization_level", 3)
Running the calculation
Once configured, the StatePreparation can be used to generate a quantum circuit from a Wavefunction.
import numpy as np # noqa: E402
from qdk_chemistry.data import Structure # noqa: E402
# Specify a structure
coords = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.4]])
symbols = ["H", "H"]
structure = Structure(coords, symbols=symbols)
# Run scf
scf_solver = create("scf_solver")
E_scf, wfn_scf = scf_solver.run(
structure, charge=0, spin_multiplicity=1, basis_or_guess="sto-3g"
)
# Compute the Hamiltonian
hamiltonian_constructor = create("hamiltonian_constructor")
hamiltonian = hamiltonian_constructor.run(wfn_scf.get_orbitals())
# Compute CAS wavefunction
cas_solver = create("multi_configuration_calculator", "macis_cas")
E_cas, wfn_cas = cas_solver.run(hamiltonian, 1, 1)
# Construct the circuit
regular_circuit = regular_prep.run(wfn_cas)
sparse_circuit = sparse_prep.run(wfn_cas)
print(f"Regular isometry QASM:\n{regular_circuit.get_qasm()}")
print(f"Sparse isometry QASM:\n{sparse_circuit.get_qasm()}")
Available implementations
QDK/Chemistry’s StatePreparation provides a unified interface for state preparation methods.
You can discover available implementations programmatically:
from qdk_chemistry.algorithms import registry # noqa: E402
print(registry.available("state_prep"))
# ['sparse_isometry_gf2x', 'regular_isometry']
Sparse Isometry GF2+X
Factory name: "sparse_isometry_gf2x"
This method is an optimized approach that leverages sparsity in the target wavefunction. The GF2+X method, a modification of the original sparse isometry work in [MIC21], applies GF(2) Gaussian elimination to the binary matrix representation of the state to determine a reduced space representation of the sparse state. This reduced state is then densely encoded via regular isometry [ICK+16] on a smaller number of qubits, and finally scattered to the full qubit space using X and CNOT gates. These reductions correspond to efficient gate sequences that simplify the preparation basis. By focusing only on non-zero amplitudes, this approach substantially reduces circuit depth and gate count compared with dense isometry methods. This method is native to QDK/Chemistry and is especially efficient for wavefunctions with sparse amplitude structure.
Settings
Setting |
Type |
Description |
|---|---|---|
|
list[str] |
Basis gates for transpilation. Default is [“x”, “y”, “z”, “cx”, “cz”, “id”, “h”, “s”, “sdg”, “rz”]. |
|
bool |
Whether to transpile the circuit. Default is True. |
|
int |
Optimization level for transpilation (0-3). Default is 1. |
Regular Isometry
Factory name: "regular_isometry"
This method uses regular isometry synthesis via Qiskit, implementing the isometry-based approach proposed by Matthias Christandl [ICK+16]. It provides a general solution for state preparation, and is suitable for cases where a dense representation is required or preferred.
Settings
Setting |
Type |
Description |
|---|---|---|
|
list[str] |
Basis gates for transpilation. Default is [“x”, “y”, “z”, “cx”, “cz”, “id”, “h”, “s”, “sdg”, “rz”]. |
|
bool |
Whether to transpile the circuit. Default is True. |
|
int |
Optimization level for transpilation (0-3). Default is 1. |
For more details on how QDK/Chemistry interfaces with external packages, see the plugin system documentation.
Further reading
The above examples can be downloaded as a complete Python script.
EnergyEstimator: Estimate the energy of prepared states
QubitMapper: Map Hamiltonians to qubit operators
Settings: Configuration settings for algorithms
Factory Pattern: Understanding algorithm creation