GroverOperator
class qiskit.circuit.library.GroverOperator(oracle, state_preparation=None, zero_reflection=None, reflection_qubits=None, insert_barriers=False, mcx_mode='noancilla', name='Q')
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, , se compose de l'oracle de phase, , du déphasage nul ou de la réflexion nulle, , et d'une préparation de l'état d'entrée :
Dans la recherche standard de Grover, nous avons :
L'opération 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 ) et ensuite l'état entier est réfléchi autour de la moyenne (avec ).
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' e pourrait ne pas être une superposition de portes de Hadamard [3].
L'action de l'oracle de phase est définie comme suit
où si 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 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 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 (ou des portes de Hadamard dans la formulation standard). Ainsi, nous avons toujours une opération de la forme . Il est donc possible de déplacer la logique bitflip dans 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 est généralement définie comme suit
où est l'identité sur qubits. Par défaut, cette classe implémente la version négative , 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 ├
« └─────────────────┘└───────────────┘└────────────┘└───┘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.
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 .
- zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – Réflexion sur l'état zéro, .
- 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