Home Qiskit Forest Cirq

Algoritmo 6 – Porta TOFFOLI

A porta quântica TOFFOLI atua em três qubits. O primeiro e o segundo qubit são qubits de controle, enquanto o terceiro qubit é o qubit alvo. Se os qubits de controle encontram-se no estado $\left|1\right\rangle$, então o estado do qubit alvo é alterado de $\left|0\right\rangle$ para $\left|1\right\rangle$ ou de $\left|1\right\rangle$ para $\left|0\right\rangle$. Se algum dos qubits de controle estiver no estado $\left|0\right\rangle$, o qubit alvo não sofre qualquer modificação. A porta TOFFOLI é representada por dois pontos, que marcam os qubits de controle, e uma porta de Pauli X no qubit alvo sendo que os pontos e a porta de Pauli X são ligados por uma linha vertical como mostrado na Figura 1.

 
Terminal picture

Figura 1. Formas de representação da porta TOFFOLI em circuitos quânticos.

Para demonstrar a atuação da porta TOFFOLI, será implementado o circuito quântico da Figura 2. Nesse circuito, a primeira porta TOFFOLI tem como qubits de controle os qubits qr[0] e qr[1] e, como qubit alvo, o qubit qr[2]. Os qubits qr[0] e qr[1] estão no estado inicial $\left|0\right\rangle$, portanto não há alteração no estado do qubit alvo qr[2]. Portas de Pauli X são aplicadas sobre os qubits qr[0] e qr[1] mudando os estados desses qubits para $\left|1\right\rangle$. Então, uma segunda porta TOFFOLI é implementada no circuito sendo qr[0] e qr[1] os qubits de controle e qr[3] o qubit alvo. Como qr[0] e qr[1] estão no estado $\left|1\right\rangle$, o estado de qr[3] é alterado de $\left|0\right\rangle$ para $\left|1\right\rangle$. As medições dos qubits qr[2] e qr[3] devem resultar em 0 e 1, respectivamente.

 
Terminal picture

Figura 2. Circuito quântico correspondente ao algoritmo 6 desse tutorial.

Qiskit

O sexto algoritmo para o SDK Qiskit inicia-se com as mesmas linhas de comando do algoritmo anterior para importar as bibliotecas necessárias ao algoritmo. Então, são instanciados quatro registradores quânticos e dois registradores clássicos. O circuito quântico também é instanciado. No Qiskit, a porta TOFFOLI é implementada pelo método ccx() que recebe como argumentos os qubits de controle e o qubit alvo. A primeira porta TOFFOLI é implementada por:
qc.ccx(qr[0],qr[1],qr[2]).
A seguir, há duas portas de Pauli X, que são implementadas por:
qc.x(qr[0])
e
qc.x(qr[1]).
A segunda porta TOFFOLI é implementada por:
qc.ccx(qr[0],qr[1],qr[3]).
Por fim, são implementados os medidores quânticos. Os comandos utilizados para a seleção do backend e para a execução do algoritmo foram discutidos no primeiro algoritmo. O algoritmo 6 completo é mostrado a seguir:

from qiskit import QuantumCircuit
from qiskit import QuantumRegister
from qiskit import ClassicalRegister
from qiskit import Aer
from qiskit import execute
qr = QuantumRegister(4)
cr = ClassicalRegister(2)
qc = QuantumCircuit(qr,cr)
qc.ccx(qr[0],qr[1],qr[2])
qc.x(qr[0])
qc.x(qr[1])
qc.ccx(qr[0],qr[1],qr[3])
qc.measure(qr[2],cr[0])
qc.measure(qr[3],cr[1])
backend = Aer.get_backend ( 'qasm_simulator' )
job = execute(qc,backend,shots=100)
resultado = job.result()
contagem = resultado.get_counts()
print(contagem)

O algoritmo foi executado pelo QASM Simulator. O número de execuções foi 100. O resultado que deve ser obtido é {'10': 100} que indica que o resultado da medição do qubit qr[3] é 1 e o resultado da medição do qubit qr[2] é 0 e que esses resultados foram obtidos em todas as 100 medições realizadas.

Forest

As bibliotecas utilizadas no algoritmo 6 para o SDK Forest são as mesmas utilizadas no algoritmo anterior. O circuito quântico é instanciado por:
p = Program().
No Forest, portas TOFFOLI são implementadas pelo método CCNOT() que recebe, como argumentos, os índices dos qubits de controle e do qubit alvo. A primeira porta TOFFOLI é implementada por:
p += CCNOT(0,1,2).
Antes da segunda porta TOFFOLI, são implementadas as duas portas de Pauli X para alterar os estados dos qubits de controle da segunda porta TOFFOLI. Essas portas quânticas são implementadas por:
p += X(0)
e
p += X(1).
A segunda porta TOFFOLI é implementada por:
p += CCNOT(0,1,3).
Os registradores clássicos são instanciados por:
ro = p.declare('ro', 'BIT', 2).
Por fim, os medidores quânticos são implementados através de:
p += MEASURE(2, ro[0])
e
p += MEASURE(3, ro[1]).
O algoritmo 6 requer uma máquina quântica virtual para quatro qubits que é instanciada por:
qc = get_qc("4q-qvm").
As linhas de comando finais do algoritmo 6 são explicadas no algoritmo 1. O algoritmo completo é mostrado a seguir:

from pyquil import get_qc, Program
from pyquil.gates import *
from pyquil.quilbase import Declare
p = Program()
p += CCNOT(0,1,2)
p += X(0)
p += X(1)
p += CCNOT(0,1,3)
ro = p.declare('ro', 'BIT', 2)
p += MEASURE(2, ro[0])
p += MEASURE(3, ro[1])
qc = get_qc("4q-qvm")
executable = qc.compile(p)
result = qc.run(executable)
print(result.readout_data.get('ro'))

O resultado da execução desse algoritmo é [ [0 1] ]. No resultado, o primeiro valor, que é 0, refere-se à medição do qubit com índice 2 e o segundo valor, que é 1, refere-se à medição do qubit com índice 3. A ordem em que os resultados das medições são impressos pelo SDK Forest é contrário à ordem de impressão dos resultados pelo SDK Qiskit.

Cirq

O algoritmo 6 para o SDK Cirq inicia-se com a importação da biblioteca cirq. Então, o circuito quântico deve ser instanciado por:
qc = cirq.Circuit().
Os quatro qubits necessários no circuito são instanciados por:
qr0 = cirq.NamedQubit('qr[0]'),
qr1 = cirq.NamedQubit('qr[1]'),
qr2 = cirq.NamedQubit('qr[2]')
e
qr3 = cirq.NamedQubit('qr[3]').
No Cirq, a porta TOFFOLI é implementada pelo método TOFFOLI() que recebe, como argumentos, as variáveis que identificam os qubits de controle e o qubit alvo. A primeira porta TOFFOLI é implementada no circuito seguida pelas duas portas de Pauli X e pela segunda porta TOFFOLI de acordo com o circuito da Figura 2. Essas portas quânticas são implementadas por:
qc.append(cirq.TOFFOLI(qr0,qr1,qr2)),
qc.append(cirq.X(qr0)),
qc.append(cirq.X(qr1))
e
qc.append(cirq.TOFFOLI(qr0,qr1,qr3)).
Então, os medidores quânticos são também implementados, o simulador é instanciado e o método run() é utilizado para a execução do algoritmo. O algoritmo 6 completo para o SDK Cirq é mostrado abaixo.

import cirq
qc = cirq.Circuit()
qr0 = cirq.NamedQubit('qr[0]')
qr1 = cirq.NamedQubit('qr[1]')
qr2 = cirq.NamedQubit('qr[2]')
qr3 = cirq.NamedQubit('qr[3]')
qc.append(cirq.TOFFOLI(qr0,qr1,qr2))
qc.append(cirq.X(qr0))
qc.append(cirq.X(qr1))
qc.append(cirq.TOFFOLI(qr0,qr1,qr3))
qc.append(cirq.measure(qr2,key = 'qr[2]'))
qc.append(cirq.measure(qr3,key = 'qr[3]'))
simulador = cirq.Simulator()
resultado = simulador.run(qc,repetitions=10)
print(resultado)

O resultado da execução é:
qr[2]=0000000000
qr[3]=1111111111

Nesse resultado, pode-se observar que a medição do qubit qr[2] sempre resulta no valor 0 e a medição do qubit qr[3] sempre resulta no valor 1 como observado na execução das versões do algoritmo 6 para os SDKs Qiskit e Forest.

Free Web Hosting