Sintetizar operações unitárias
Versões dos pacotes
O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos usar essas versões ou mais recentes.
qiskit[all]~=2.3.0
Uma operação unitária descreve uma mudança que preserva a norma de um sistema quântico. Para qubits, essa mudança é descrita por uma matriz complexa de dimensão , , cujo adjunto é igual ao inverso, ou seja, .
Sintetizar opera ções unitárias específicas em um conjunto de Gates quânticos é uma tarefa fundamental usada, por exemplo, no design e na aplicação de algoritmos quânticos ou na compilação de Circuits quânticos.
Embora a síntese eficiente seja possível para certas classes de unitários — como aqueles compostos por Gates de Clifford ou com estrutura de produto tensorial — a maioria dos unitários não se enquadra nessas categorias. Para matrizes unitárias gerais, a síntese é uma tarefa complexa com custos computacionais que crescem exponencialmente com o número de qubits. Portanto, se você conhece uma decomposição eficiente para o unitário que deseja implementar, ela provavelmente será melhor do que uma síntese geral.
Se nenhuma decomposição estiver disponível, o Qiskit SDK fornece as ferramentas para encontrar uma. No entanto, observe que isso geralmente gera Circuits profundos que podem ser inadequados para execução em computadores quânticos ruidosos.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
import numpy as np
from qiskit import QuantumCircuit
U = 0.5 * np.array(
[[1, 1, 1, 1], [-1, 1, -1, 1], [-1, -1, 1, 1], [-1, 1, 1, -1]]
)
circuit = QuantumCircuit(2)
circuit.unitary(U, circuit.qubits)
<qiskit.circuit.instructionset.InstructionSet at 0x7fedb83e7a90>
Re-síntese para otimização de Circuit
Às vezes é vantajoso re-sintetizar uma longa sequência de Gates de um e dois qubits, caso o comprimento possa ser reduzido. Por exemplo, o Circuit a seguir usa três Gates de dois qubits.
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
qreg_q = QuantumRegister(2, "q")
creg_c = ClassicalRegister(4, "c")
circuit = QuantumCircuit(qreg_q, creg_c)
circuit.h(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.sx(qreg_q[1])
circuit.cz(qreg_q[0], qreg_q[1])
circuit.x(qreg_q[1])
circuit.x(qreg_q[0])
circuit.cx(qreg_q[0], qreg_q[1])
circuit.h(qreg_q[0])
circuit.draw("mpl")
No entanto, após a re-síntese com o código a seguir, ele precisa apenas de um único Gate CX. (Aqui usamos o método QuantumCircuit.decompose() para visualizar melhor os Gates usados para re-sintetizar o unitário.)
from qiskit.quantum_info import Operator
# compute unitary matrix of circuit
U = Operator(circuit)
# re-synthesize
better_circuit = QuantumCircuit(2)
better_circuit.unitary(U, range(2))
better_circuit.decompose().draw()
global phase: 6.2071
┌───────────────┐ ┌────────────────┐
q_0: ─┤ U(π/2,π/2,-π) ├────■────┤ U(π/2,-π,-π/2) ├─
┌┴───────────────┴─┐┌─┴─┐┌─┴────────────────┴┐
q_1: ┤ U(1.7229,π/2,-π) ├┤ X ├┤ U(π/2,0.15207,-π) ├
└──────────────────┘└───┘└───────────────────┘
A função transpile do Qiskit realiza automaticamente essa re-síntese para um nível de otimização suficientemente alto.
Próximos passos
- Veja um exemplo de decomposição de Circuit no tutorial Algoritmo de Grover.
- Para mais informações sobre o Transpiler do Qiskit, visite a seção Transpile.