@coherent components — a phase oracle that marks your target state with a −1 phase, and a diffusion operator that amplifies its amplitude. Both are structurally safe: ancilla qubits are allocated and fully uncomputed through the compute/phase/uncompute discipline.
Imports
make_phase_oracle— factory function that returns a@coherentoracle for any target bit patternphase_oracle— pre-built oracle for the 2-qubit|11⟩state (equivalent tomake_phase_oracle([1, 1]))diffusion_operator—@coherentGrover diffusion operator (works on any register width)
Phase oracle
The phase oracle flips the sign of the marked basis state. You describe the target as a sequence of bits, one per qubit —1 for qubits that must be |1⟩ and 0 for qubits that must be |0⟩.
marked_bits— a sequence of0s and1s, one element per qubit. Must have at least one element. All entries must be0or1.
@coherent function oracle(sys: QReg) that applies the phase flip to |marked_bits⟩.
Implementation details:
- For a 1-qubit register: applies
Zdirectly (wrapping withX/Xifmarked_bits[0] == 0). - For 2+ qubits: copies system bits into a 1-qubit ancilla via
MCX(inside acomputeblock), appliesZvia phase kickback, then uncomputes. The ancilla is always returned to|0⟩.
Diffusion operator
The diffusion operator implements the inversion-about-average step:2|s⟩⟨s| − I where |s⟩ is the uniform superposition. It works on any register width.
@coherent function, takes a single QReg of any width.
Implementation:
- Applies
HthenXon every qubit. - Applies a multi-controlled-Z (using
CZfor 2 qubits, orMCX+CZ+uncompute for 3+, all ancilla-clean). - Applies
XthenHon every qubit.
Complete example: Grover search on 2 qubits
This example mirrors thedemos/grover_search/search.py demo. It searches for |11⟩ in a 2-qubit space with 2 Grover iterations, which is the optimal number for N=4.
Write the Grover step
Combine the oracle and diffusion into a single step using
@parametric (required for use inside @adaptive).Write the full search circuit
Use
@adaptive to create a circuit that prepares a uniform superposition, runs 2 Grover iterations, and measures.Using zoo components directly
If you prefer to use the zoo’smake_phase_oracle and diffusion_operator directly rather than inlining gate sequences, you can call them inside a @coherent host:
The
@coherent decorator cannot be used directly inside @adaptive. Wrap your @coherent Grover step in a @parametric function, or inline the gate sequences as shown in the full example above.Scaling to more qubits
make_phase_oracle and diffusion_operator both scale to any number of qubits. For n qubits you typically want ⌊π/4 · √(2^n)⌋ iterations: