Skip to main content
IBM Quantum Platform

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

L'opérateur Grover.

L'algorithme de recherche de Grover [1, 2] consiste en des applications répétées de l'opérateur dit de Grover utilisé pour amplifier les amplitudes des états de sortie souhaités. Cet opérateur, Q\mathcal{Q}, se compose de l'oracle de phase, Sf\mathcal{S}_f, du déphasage nul ou de la réflexion nulle, S0\mathcal{S}_0, et d'une préparation de l'état d'entrée A\mathcal{A} :

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

Dans la recherche standard de Grover, nous avons 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}

L'opération D=HnS0HnD = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} est également appelée opérateur de diffusion. Dans cette formulation, nous pouvons voir que l'opérateur de Grover consiste en deux étapes : tout d'abord, l'oracle de phase multiplie les bons états par -1 (avec Sf\mathcal{S}_f ) et ensuite l'état entier est réfléchi autour de la moyenne (avec DD ).

Cette classe permet de définir une préparation d'état différente, comme dans l'amplification d'amplitude quantique (une généralisation de l'algorithme de Grover); l' A\mathcal{A} e pourrait ne pas être une superposition de portes de Hadamard [3].

L'action de l'oracle de phase Sf\mathcal{S}_f est définie comme suit

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

f(x)=1f(x) = 1 si xx est un bon état et 0 sinon. Pour souligner le fait que cet oracle renverse la phase des bons états et ne renverse pas l'état d'un qubit de résultat, nous appelons Sf\mathcal{S}_f un oracle de phase.

Notez que vous pouvez facilement construire un oracle de phase à partir d'un oracle de bitflip en prenant en sandwich la porte X contrôlée sur le qubit de résultat par une porte X et une porte H. Par exemple

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

La définition de l'oracle et de l'opérateur A\mathcal{A} offre une certaine souplesse. Avant d'appliquer l'opérateur de Grover dans l'algorithme de Grover, les qubits sont d'abord préparés avec une application de l'opérateur A\mathcal{A} (ou des portes de Hadamard dans la formulation standard). Ainsi, nous avons toujours une opération de la forme ASfA\mathcal{A} \mathcal{S}_f \mathcal{A}^\dagger. Il est donc possible de déplacer la logique bitflip dans A\mathcal{A} et de ne laisser l'oracle que pour effectuer des phasesflips via des portes Z basées sur les bitflips. Les oracles qui ne calculent pas les qubits d'état constituent un cas d'utilisation possible.

La réflexion zéro S0\mathcal{S}_0 est généralement définie comme suit

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

In\mathbb{I}_n est l'identité sur nn qubits. Par défaut, cette classe implémente la version négative 20n0nIn2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n, puisqu'elle peut simplement être implémentée avec un Z multi-contrôlé pris en sandwich par des portes X sur le qubit cible et que la phase globale introduite n'a pas d'importance pour l'algorithme de Grover.

Exemples

>>> 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 ├
«         └─────────────────┘└───────────────┘└────────────┘└───┘
Voir aussi

L'application grover_operator() met en œuvre la même fonctionnalité, mais en conservant l'abstraction de l'élément MCXGate abstraite, de sorte que le compilateur puisse choisir la décomposition optimale. Pour des raisons de performance, nous recommandons d'utiliser grover_operator() pour des raisons de performance, qui n'enferme pas le circuit dans une porte opaque.

Références :

[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. Chapitre 6.1.2.

[3] Brassard, G., Hoyer, P., Mosca, M., & Tapp, A. (2000). Amplification et estimation de l'amplitude quantique. arXiv:quant-ph/0005055.

Déclassé depuis la version 2.1

La classe qiskit.circuit.library.grover_operator.GroverOperator est obsolète depuis Qiskit 2.1. Elle sera supprimée à Qiskit 3.0. Utilisez plutôt qiskit.circuit.library.grover_operator.

Paramètres

  • oracle (QuantumCircuit |Statevector) – L'oracle de phase mettant en œuvre une réflexion sur l'état incorrect. Notez qu'il ne s'agit pas d'un oracle de type « bitflip »; consultez la chaîne de documentation pour plus d'informations.
  • state_preparation (QuantumCircuit | None) – L'opérateur chargé de préparer les états « bon » et « mauvais ». Pour l'algorithme de Grover, il s'agit d'une porte de Hadamard à n qubits, et pour l'amplification ou l'estimation d'amplitude, l'opérateur A\mathcal{A}.
  • zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – Réflexion sur l'état zéro, S0\mathcal{S}_0.
  • reflection_qubits (list[int] | None) – Les qubits sur lesquels agit la réflexion nulle.
  • insert_barriers (bool) – Si des barrières doivent être insérées entre les réflexions et A.
  • mcx_mode (str) – Le mode à utiliser pour construire la réflexion zéro par défaut.
  • name (str) – Le nom du circuit.

Attributs

oracle

L'oracle met en œuvre une réflexion sur le mauvais état.

reflection_qubits

Qubits de réflexion, sur lesquels S0 est appliqué (si S0 n'est pas spécifié par l'utilisateur).

state_preparation

Le sous-circuit mettant en œuvre l'opérateur A ou Hadamards.

zero_reflection

Le sous-circuit mettant en œuvre la réflexion d'environ 0.

name

Type : str

Un nom lisible par l'homme pour le circuit.

Exemple

from qiskit import QuantumCircuit

qc = QuantumCircuit(2, 2, name="my_circuit")
print(qc.name)
my_circuit
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.