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
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, , consiste no oráculo de fase, , na mudança de fase zero ou na reflexão zero, , e em uma preparação do estado de entrada :
Na pesquisa padrão de Grover, temos :
A operação 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 ) e, em seguida, todo o estado é refletido em torno da média (com ).
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); pode não ser uma camada de portas de Hadamard [3].
A ação do oráculo de fase é definida como
em que se 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 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 . Antes de o operador de Grover ser aplicado no algoritmo de Grover, os qubits são primeiro preparados com uma aplicação do operador (ou portas Hadamard na formulação padrão). Assim, sempre temos uma operação do tipo . Portanto, é possível mover a lógica de bitflip para 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 é geralmente definida como
em que é a identidade em qubits. Por padrão, essa classe implementa a versão negativa , 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 ├
« └─────────────────┘└───────────────┘└────────────┘└───┘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.
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 .
- zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – A reflexão sobre o estado zero, .
- 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