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

O operador Grover.

O algoritmo de busca de Grover [1, 2] consiste em aplicações repetidas do chamado operador de Grover usado para amplificar as amplitudes dos estados de saída desejados. Esse operador, Q\mathcal{Q}, consiste no oráculo de fase, Sf\mathcal{S}_f, na mudança de fase zero ou na reflexão zero, S0\mathcal{S}_0, e em uma preparação do estado de entrada A\mathcal{A} :

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

Na pesquisa padrão de Grover, temos 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}

A operação D=HnS0HnD = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} também é chamada de operador de difusão. Nessa formulação, podemos ver que o operador de Grover consiste em duas etapas: primeiro, o oráculo de fase multiplica os estados bons por -1 (com Sf\mathcal{S}_f ) e, em seguida, todo o estado é refletido em torno da média (com DD ).

Essa classe permite definir uma preparação de estado diferente, como na amplificação de amplitude quântica (uma generalização do algoritmo de Grover); A\mathcal{A} pode não ser uma camada de portas de Hadamard [3].

A ação do oráculo de fase Sf\mathcal{S}_f é definida como

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

em que f(x)=1f(x) = 1 se xx for um bom estado e 0 caso contrário. Para destacar o fato de que esse oráculo inverte a fase dos estados bons e não inverte o estado de um qubit resultante, chamamos o Sf\mathcal{S}_f de oráculo de fase.

Observe que você pode construir facilmente um oráculo de fase a partir de um oráculo de bitflip, colocando a porta X controlada no qubit de resultado por uma porta X e H. Por exemplo

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

Há alguma flexibilidade na definição do oráculo e do operador A\mathcal{A}. Antes de o operador de Grover ser aplicado no algoritmo de Grover, os qubits são primeiro preparados com uma aplicação do operador A\mathcal{A} (ou portas Hadamard na formulação padrão). Assim, sempre temos uma operação do tipo ASfA\mathcal{A} \mathcal{S}_f \mathcal{A}^\dagger. Portanto, é possível mover a lógica de bitflip para A\mathcal{A} e deixar o oráculo apenas para fazer as mudanças de fase por meio de portas Z baseadas nos bitflips. Um possível caso de uso para isso são os oráculos que não descomputam os qubits de estado.

A reflexão zero S0\mathcal{S}_0 é geralmente definida como

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

em que In\mathbb{I}_n é a identidade em nn qubits. Por padrão, essa classe implementa a versão negativa 20n0nIn2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n, uma vez que ela pode ser implementada simplesmente com um Z multicontrolado imprensado por portas X no qubit de destino e a fase global introduzida não importa para o algoritmo de Grover.

Exemplos

>>> 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 ├
«         └─────────────────┘└───────────────┘└────────────┘└───┘
Veja Também

O grover_operator() implementa a mesma funcionalidade, mas mantém o MCXGate abstrato, de modo que o compilador possa escolher a decomposição ideal. Recomendamos o uso de grover_operator() por motivos de desempenho, que não envolve o circuito em uma porta opaca.

Referências

[1] L. K. Grover (1996), A fast quantum mechanical algorithm for database search, arXiv:quant-ph/9605043.

[2] I. Chuang e M. Nielsen, Quantum Computation and Quantum Information, Cambridge: Cambridge University Press, 2000. Capítulo 6.1.2.

[3] Brassard, G., Hoyer, P., Mosca, M., & Tapp, A. (2000). Amplificação e estimativa da amplitude quântica. arXiv:quant-ph/0005055.

Descontinuado desde a versão 2.1

A classe qiskit.circuit.library.grover_operator.GroverOperator está obsoleta desde o Qiskit 2.1. Ele será removido no Qiskit 3.0. Em vez disso, use qiskit.circuit.library.grover_operator.

Parâmetros

  • oracle (QuantumCircuit |Statevector) – O oráculo de fase que implementa uma reflexão sobre o estado incorreto. Observe que este não é um oráculo de inversão de bits; consulte a descrição da função para obter mais informações.
  • state_preparation (QuantumCircuit | None) – O operador que prepara o estado bom e o estado ruim. No caso do algoritmo de Grover, trata-se de uma porta de Hadamard de n qubits e, para amplificação ou estimativa de amplitude, o operador A\mathcal{A}.
  • zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – A reflexão sobre o estado zero, S0\mathcal{S}_0.
  • reflection_qubits (list[int] | None) – Qubits sobre os quais atua a reflexão zero.
  • insert_barriers (bool) – Se devem ser inseridas barreiras entre as reflexões e A.
  • mcx_mode (str) – O modo a ser usado para criar a reflexão zero padrão.
  • name (str) – O nome do circuito.

Atributos

oracle

O oráculo implementa uma reflexão sobre o estado ruim.

reflection_qubits

Qubits de reflexão, nos quais S0 é aplicado (se S0 não for especificado pelo usuário).

state_preparation

O subcircuito que implementa o operador A ou Hadamards.

zero_reflection

O subcircuito que implementa a reflexão em torno de 0.

name

Tipo: str

Um nome legível por humanos para o circuito.

Exemplo

from qiskit import QuantumCircuit

qc = QuantumCircuit(2, 2, name="my_circuit")
print(qc.name)
my_circuit
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.