Controlled circuit mapper
The ControlledCircuitMapper algorithm in QDK/Chemistry converts a UnitaryRepresentation into a controlled quantum circuit.
Following QDK/Chemistry’s algorithm design principles, it takes a UnitaryRepresentation as input and produces a Circuit as output.
Control and target qubit indices are configured via settings.
Overview
Controlled unitaries — operations of the form \(C\text{-}U\) that apply \(U\) to a target register conditioned on the state of a control qubit — are a building block in many quantum algorithms. Mathematically, for a single control qubit the controlled unitary acts as:
That is, the target register is left unchanged when the control is \(|0\rangle\) and \(U\) is applied when the control is \(|1\rangle\).
The ControlledCircuitMapper synthesises these controlled operations from the abstract UnitaryRepresentation representation produced by a HamiltonianUnitaryBuilder.
This is a core component of algorithms such as PhaseEstimation, which requires repeated controlled applications \(C\text{-}U^{2^k}\).
The mapper takes inputs:
A
UnitaryRepresentation— produced by a HamiltonianUnitaryBuilder
Control and target qubit indices are configured via the mapper’s settings (control_indices and target_indices).
The resulting Circuit implements the controlled unitary and can be executed by a CircuitExecutor.
Using the ControlledCircuitMapper
Note
This algorithm is currently available only in the Python API.
This section demonstrates how to create, configure, and run the circuit mapper.
Input requirements
The ControlledCircuitMapper requires:
- UnitaryRepresentation
A
UnitaryRepresentationspecifying the unitary to be controlled.- Settings
control_indices(list of int): Which qubits serve as controls (default:[0]).target_indices(list of int): Which qubits the unitary acts on (default: auto-filled).
Creating a mapper
from qdk_chemistry.algorithms import create
# Create the default mapper (pauli_sequence)
mapper = create("controlled_circuit_mapper")
Running the mapper
import numpy as np
from qdk_chemistry.algorithms import create
from qdk_chemistry.data import Structure
# 1. Setup molecule
coords = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.4]])
symbols = ["H", "H"]
structure = Structure(coords, symbols=symbols)
# 2. SCF
scf_solver = create("scf_solver")
E_scf, wfn_scf = scf_solver.run(
structure, charge=0, spin_multiplicity=1, basis_or_guess="sto-3g"
)
# 3. Hamiltonian and qubit mapping
hamiltonian_constructor = create("hamiltonian_constructor")
hamiltonian = hamiltonian_constructor.run(wfn_scf.get_orbitals())
from qdk_chemistry.data import MajoranaMapping
n_spin_orbitals = 2 * hamiltonian.get_orbitals().get_num_molecular_orbitals()
qubit_mapper = create("qubit_mapper")
qubit_ham = qubit_mapper.run(
hamiltonian, MajoranaMapping.jordan_wigner(n_spin_orbitals)
)
# 4. Build time evolution unitary
trotter = create("hamiltonian_unitary_builder", "trotter", order=2, time=0.1)
evolution = trotter.run(qubit_ham)
# 5. Create a controlled version and map to a circuit
mapper = create("controlled_circuit_mapper", "pauli_sequence", control_indices=[0])
circuit = mapper.run(evolution)
print("Controlled evolution circuit generated")
Available implementations
You can discover available implementations programmatically:
from qdk_chemistry.algorithms import registry
# List all registered controlled circuit mapper implementations
implementations = registry.available("controlled_circuit_mapper")
print(implementations) # e.g. ['pauli_sequence']
Pauli sequence mapper
Factory name: "pauli_sequence" (default)
Given a time-evolution unitary expressed as a PauliProductFormulaContainer — a sequence of exponentiated Pauli terms \(e^{-i\theta_j P_j}\) — this mapper constructs a controlled version by:
Rotating each Pauli operator \(P_j\) into the Z basis
Entangling the target qubits with a CNOT ladder
Applying a controlled \(R_z(2\theta_j)\) rotation from the control qubit
Uncomputing the basis rotations and entangling operations
Note
The current implementation supports a single control qubit.
Further reading
The above examples can be downloaded as a complete Python script.
PhaseEstimation: Uses the circuit mapper to build controlled-\(U\) operations
HamiltonianUnitaryBuilder: Constructs the input unitaries
Settings: Configuration settings for algorithms
Factory Pattern: Understanding algorithm creation