Skip to main contentIBM Quantum Documentation Mirror

GroverOperator

class qiskit.circuit.library.GroverOperator(oracle, state_preparation=None, zero_reflection=None, reflection_qubits=None, insert_barriers=False, mcx_mode='noancilla', name='Q')

GitHub

Bases: QuantumCircuit

The Grover operator.

Grover’s search algorithm [1, 2] consists of repeated applications of the so-called Grover operator used to amplify the amplitudes of the desired output states. This operator, Q\mathcal{Q}, consists of the phase oracle, Sf\mathcal{S}_f, zero phase-shift or zero reflection, S0\mathcal{S}_0, and an input state preparation A\mathcal{A}:

Q=AS0ASf\mathcal{Q} = \mathcal{A} \mathcal{S}_0 \mathcal{A}^\dagger \mathcal{S}_f

In the standard Grover search we have A=Hn\mathcal{A} = H^{\otimes n}:

Q=HnS0HnSf=DSf\mathcal{Q} = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} \mathcal{S}_f = D \mathcal{S_f}

The operation D=HnS0HnD = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} is also referred to as diffusion operator. In this formulation we can see that Grover’s operator consists of two steps: first, the phase oracle multiplies the good states by -1 (with Sf\mathcal{S}_f) and then the whole state is reflected around the mean (with DD).

This class allows setting a different state preparation, as in quantum amplitude amplification (a generalization of Grover’s algorithm), A\mathcal{A} might not be a layer of Hardamard gates [3].

The action of the phase oracle Sf\mathcal{S}_f is defined as

Sf:x(1)f(x)x\mathcal{S}_f: |x\rangle \mapsto (-1)^{f(x)}|x\rangle

where f(x)=1f(x) = 1 if xx is a good state and 0 otherwise. To highlight the fact that this oracle flips the phase of the good states and does not flip the state of a result qubit, we call Sf\mathcal{S}_f a phase oracle.

Note that you can easily construct a phase oracle from a bitflip oracle by sandwiching the controlled X gate on the result qubit by a X and H gate. For instance

Bitflip oracle     Phaseflip oracle
q_0: ──■──         q_0: ────────────■────────────
     ┌─┴─┐              ┌───┐┌───┐┌─┴─┐┌───┐┌───┐
out: ┤ X ├         out: ┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├
     └───┘              └───┘└───┘└───┘└───┘└───┘

There is some flexibility in defining the oracle and A\mathcal{A} operator. Before the Grover operator is applied in Grover’s algorithm, the qubits are first prepared with one application of the A\mathcal{A} operator (or Hadamard gates in the standard formulation). Thus, we always have operation of the form ASfA\mathcal{A} \mathcal{S}_f \mathcal{A}^\dagger. Therefore it is possible to move bitflip logic into A\mathcal{A} and leaving the oracle only to do phaseflips via Z gates based on the bitflips. One possible use-case for this are oracles that do not uncompute the state qubits.

The zero reflection S0\mathcal{S}_0 is usually defined as

S0=20n0nIn\mathcal{S}_0 = 2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n

where In\mathbb{I}_n is the identity on nn qubits. By default, this class implements the negative version 20n0nIn2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n, since this can simply be implemented with a multi-controlled Z sandwiched by X gates on the target qubit and the introduced global phase does not matter for Grover’s algorithm.

Examples

>>> from qiskit.circuit import QuantumCircuit
>>> from qiskit.circuit.library import GroverOperator
>>> oracle = QuantumCircuit(2)
>>> oracle.z(0)  # good state = first qubit is |1>
>>> grover_op = GroverOperator(oracle, insert_barriers=True)
>>> grover_op.decompose().draw()
         ┌───┐ ░ ┌───┐ ░ ┌───┐          ┌───┐      ░ ┌───┐
state_0: ┤ Z ├─░─┤ H ├─░─┤ X ├───────■──┤ X ├──────░─┤ H ├
         └───┘ ░ ├───┤ ░ ├───┤┌───┐┌─┴─┐├───┤┌───┐ ░ ├───┤
state_1: ──────░─┤ H ├─░─┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├─░─┤ H ├
               ░ └───┘ ░ └───┘└───┘└───┘└───┘└───┘ ░ └───┘
>>> oracle = QuantumCircuit(1)
>>> oracle.z(0)  # the qubit state |1> is the good state
>>> state_preparation = QuantumCircuit(1)
>>> state_preparation.ry(0.2, 0)  # non-uniform state preparation
>>> grover_op = GroverOperator(oracle, state_preparation)
>>> grover_op.decompose().draw()
         ┌───┐┌──────────┐┌───┐┌───┐┌───┐┌─────────┐
state_0: ┤ Z ├┤ RY(-0.2) ├┤ X ├┤ Z ├┤ X ├┤ RY(0.2)
         └───┘└──────────┘└───┘└───┘└───┘└─────────┘
>>> oracle = QuantumCircuit(4)
>>> oracle.z(3)
>>> reflection_qubits = [0, 3]
>>> state_preparation = QuantumCircuit(4)
>>> state_preparation.cry(0.1, 0, 3)
>>> state_preparation.ry(0.5, 3)
>>> grover_op = GroverOperator(oracle, state_preparation,
... reflection_qubits=reflection_qubits)
>>> grover_op.decompose().draw()
                                      ┌───┐          ┌───┐
state_0: ──────────────────────■──────┤ X ├───────■──┤ X ├──────────■────────────────
                               │      └───┘       │  └───┘          │
state_1: ──────────────────────┼──────────────────┼─────────────────┼────────────────
                               │                  │                 │
state_2: ──────────────────────┼──────────────────┼─────────────────┼────────────────
         ┌───┐┌──────────┐┌────┴─────┐┌───┐┌───┐┌─┴─┐┌───┐┌───┐┌────┴────┐┌─────────┐
state_3: ┤ Z ├┤ RY(-0.5) ├┤ RY(-0.1) ├┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├┤ RY(0.1) ├┤ RY(0.5)
         └───┘└──────────┘└──────────┘└───┘└───┘└───┘└───┘└───┘└─────────┘└─────────┘
>>> mark_state = Statevector.from_label('011')
>>> diffuse_operator = 2 * DensityMatrix.from_label('000') - Operator.from_label('III')
>>> grover_op = GroverOperator(oracle=mark_state, zero_reflection=diffuse_operator)
>>> grover_op.decompose().draw(fold=70)
         ┌─────────────────┐      ┌───┐                          »
state_0:0                ├──────┤ H ├──────────────────────────»
         │                 │┌─────┴───┴─────┐     ┌───┐          »
state_1:1 UCRZ(0,pi,0,0) ├┤0              ├─────┤ H ├──────────»
         │                 ││  UCRZ(pi/2,0) │┌────┴───┴────┐┌───┐»
state_2:2                ô1              ô UCRZ(-pi/4) ô H ï
         └─────────────────┘└───────────────┘└─────────────┘└───┘»
«         ┌─────────────────┐      ┌───┐
«state_0:0                ├──────┤ H ├─────────────────────────
«         │                 │┌─────┴───┴─────┐    ┌───┐
«state_1:1 UCRZ(pi,0,0,0) ├┤0              ├────┤ H ├──────────
«         │                 ││  UCRZ(pi/2,0) │┌───┴───┴────┐┌───┐
«state_2:2                ├┤1              ├┤ UCRZ(pi/4) ├┤ H ├
«         └─────────────────┘└───────────────┘└────────────┘└───┘
See also

The grover_operator() implements the same functionality but keeping the MCXGate abstract, such that the compiler may choose the optimal decomposition. We recommend using grover_operator() for performance reasons, which does not wrap the circuit into an opaque gate.

References

[1]: L. K. Grover (1996), A fast quantum mechanical algorithm for database search,

arXiv:quant-ph/9605043.

[2]: I. Chuang & M. Nielsen, Quantum Computation and Quantum Information,

Cambridge: Cambridge University Press, 2000. Chapter 6.1.2.

[3]: Brassard, G., Hoyer, P., Mosca, M., & Tapp, A. (2000).

Quantum Amplitude Amplification and Estimation. arXiv:quant-ph/0005055.

Deprecated since version 2.1

The class qiskit.circuit.library.grover_operator.GroverOperator is deprecated as of Qiskit 2.1. It will be removed in Qiskit 3.0. Use qiskit.circuit.library.grover_operator instead.

Parameters

  • oracle (Union[QuantumCircuit, Statevector]) – The phase oracle implementing a reflection about the bad state. Note that this is not a bitflip oracle, see the docstring for more information.
  • state_preparation (Optional[QuantumCircuit]) – The operator preparing the good and bad state. For Grover’s algorithm, this is a n-qubit Hadamard gate and for amplitude amplification or estimation the operator A\mathcal{A}.
  • zero_reflection (Optional[Union[QuantumCircuit, DensityMatrix, Operator]]) – The reflection about the zero state, S0\mathcal{S}_0.
  • reflection_qubits (Optional[List[int]]) – Qubits on which the zero reflection acts on.
  • insert_barriers (bool) – Whether barriers should be inserted between the reflections and A.
  • mcx_mode (str) – The mode to use for building the default zero reflection.
  • name (str) – The name of the circuit.

Attributes

oracle

The oracle implementing a reflection about the bad state.

reflection_qubits

Reflection qubits, on which S0 is applied (if S0 is not user-specified).

state_preparation

The subcircuit implementing the A operator or Hadamards.

zero_reflection

The subcircuit implementing the reflection about 0.

name

Type: str

A human-readable name for the circuit.

Example

from qiskit import QuantumCircuit
 
qc = QuantumCircuit(2, 2, name="my_circuit")
print(qc.name)
my_circuit