12. Explorando la puerta CNOT-Gate #
En la sección anterior, vimos algunos resultados muy básicos con la puerta CNOT. Aquí exploraremos algunos resultados más interesantes. .
Vimos que podíamos entrelazar los dos qubits colocando el qubit de control en el estado
Pero, ¿qué ocurre si ponemos el segundo qubit en superposición?
Veamos el resultado anterior con qiskit
from qiskit import QuantumCircuit, Aer, assemble
from math import pi
import numpy as np
from qiskit.visualization import plot_bloch_multivector, plot_histogram, array_to_latex
qc = QuantumCircuit(2)
qc.h(1) # convierto qubit 1 en X
qc.cx(1,0)
qc.draw(output='mpl')
D:\programas\Anaconda\Lib\site-packages\qiskit\visualization\circuit\matplotlib.py:266: FutureWarning: The default matplotlib drawer scheme will be changed to "iqp" in a following release. To silence this warning, specify the current default explicitly as style="clifford", or the new default as style="iqp".
self._style, def_font_ratio = load_style(self._style)

# Let's see the result
svsim = Aer.get_backend('aer_simulator')
qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\3758938065.py:2: DeprecationWarning: The 'qiskit.Aer' entry point is deprecated and will be removed in Qiskit 1.0. You should use 'qiskit_aer.Aer' directly instead.
svsim = Aer.get_backend('aer_simulator')
C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\3758938065.py:5: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
final_state = svsim.run(qobj).result().get_statevector()
Veamos ahora otro estado
qc = QuantumCircuit(2)
qc.h(0)
qc.h(1)
qc.cx(0,1)
qc.draw(output='mpl')

En el circuito anterior, tenemos la CNOT actuando sobre el estado:
Puesto que CNOT intercambia las amplitudes de
qc = QuantumCircuit(2)
qc.h(0)
qc.h(1)
qc.cx(0,1)
display(qc.draw(output='mpl')) # `display` is a command for Jupyter notebooks
# similar to `print`, but for rich content
# Let's see the result
svsim = Aer.get_backend('aer_simulator')
qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
plot_bloch_multivector(final_state)

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\4150523781.py:12: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
final_state = svsim.run(qobj).result().get_statevector()

Pongamos el qubit objetivo en el estado
qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
qc.h(1)
qc.draw(output='mpl')

Esto crea el estado:
qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
qc.h(1)
display(qc.draw(output='mpl'))
# See the result
qc1 = qc.copy()
qc1.save_statevector()
final_state = svsim.run(qc1).result().get_statevector()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
plot_bloch_multivector(final_state)


Si el CNOT actúa sobre este estado, intercambiaremos las amplitudes de
Esto es interesante, porque afecta al estado del qubit control mientras que deja el estado del qubit target sin cambios.
qc.cx(0,1)
display(qc.draw(output='mpl'))
qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
display(array_to_latex(final_state, prefix="\\text{Statevector} = "))
plot_bloch_multivector(final_state)

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\686013327.py:6: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
final_state = svsim.run(qobj).result().get_statevector()

Si recordamos las transformaciones H-gate
Podemos comprobarlo utilizando el simulador Aer de Qiskit:
qc = QuantumCircuit(2)
qc.h(0)
qc.h(1)
qc.cx(0,1)
qc.h(0)
qc.h(1)
display(qc.draw(output='mpl'))
qc.save_unitary()
usim = Aer.get_backend('aer_simulator')
qobj = assemble(qc)
unitary = usim.run(qobj).result().get_unitary()
array_to_latex(unitary, prefix="\\text{Circuit = }\n")

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\3061567878.py:12: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
unitary = usim.run(qobj).result().get_unitary()
qc = QuantumCircuit(2)
qc.cx(1,0)
display(qc.draw(output='mpl'))
qc.save_unitary()
qobj = assemble(qc)
unitary = usim.run(qobj).result().get_unitary()
array_to_latex(unitary, prefix="\\text{Circuit = }\n")

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\661953302.py:7: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
unitary = usim.run(qobj).result().get_unitary()
Esta identidad es un ejemplo de “retroceso de fase” (phase kickback), lo que nos lleva a la siguiente sección….
13. 2. Phase Kickback #
13.1. Explicación de la identidad del circuito CNOT #
En la sección anterior vimos esta identidad:
Este es un ejemplo de kickback (o, kickback de fase ) que es muy importante y se utiliza en casi todos los algoritmos cuánticos. Kickback es donde el valor propio añadido por una puerta a un qubit es “devuelto” a un qubit diferente a través de una operación controlada. Por ejemplo, vimos que realizar una puerta-X en un qubit
Cuando nuestro qubit de control está en
El efecto interesante es cuando nuestro qubit de control está en superposición. El componente del qubit de control que se encuentra en la dirección de
Esto se puede escribir como los dos estados de qubit separables:
colocar el CNOT en las puertas H transforma los qubits de la base computacional a la base
13.2. 2.2 Kickback con la puerta T-gate #
Veamos otra operación controlada, la puerta T controlada:
qc = QuantumCircuit(2)
qc.cp(pi/4, 0, 1)
qc.draw(output='mpl')

La puerta T-gate tiene la siguiente matriz:
Y la puerta T-gate controlada tiene la siguiente matriz:
Podemos comprobarlo utilizando el simulador Aer de Qiskit:
qc = QuantumCircuit(2)
qc.cp(pi/4, 0, 1)
display(qc.draw(output='mpl'))
# See Results:
qc.save_unitary()
qobj = assemble(qc)
unitary = usim.run(qobj).result().get_unitary()
array_to_latex(unitary, prefix="\\text{Controlled-T} = \n")

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\1088296195.py:7: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
unitary = usim.run(qobj).result().get_unitary()
De forma más general, podemos encontrar la matriz de cualquier operación controlada-U utilizando la regla:
O, usando la ordenación de qubits de Qiskit:
Si aplicamos la puerta T a un qubit en el estado
Esto es fase global y es inobservable. Pero si controlamos esta operación usando otro qubit en el estado
Esto tiene el efecto de rotar nuestro qubit de control alrededor del eje Z de la esfera de Bloch, mientras que deja el qubit objetivo sin cambios. Veamos esto en Qiskit:
qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
display(qc.draw(output='mpl'))
# See Results:
qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
plot_bloch_multivector(final_state)

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\4247561864.py:8: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
final_state = svsim.run(qobj).result().get_statevector()

qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)
# Add Controlled-T
qc.cp(pi/4, 0, 1)
display(qc.draw(output='mpl'))
# See Results:
qc.save_statevector()
qobj = assemble(qc)
final_state = svsim.run(qobj).result().get_statevector()
plot_bloch_multivector(final_state)

C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\2878867670.py:10: DeprecationWarning: Using a qobj for run() is deprecated as of qiskit-aer 0.9.0 and will be removed no sooner than 3 months from that release date. Transpiled circuits should now be passed directly using `backend.run(circuits, **run_options).
final_state = svsim.run(qobj).result().get_statevector()

Podemos ver que el qubit más a la izquierda ha sido rotado
13.3. Quick Ejercicios:#
- ¿Cuál sería el estado resultante del qubit de control (q0) si el qubit objetivo (q1) estuviera en el estado $|0\rangle$? (como se muestra en el circuito de abajo)? Utiliza Qiskit para comprobar tu respuesta.
- ¿Qué le ocurriría al qubit de control (q0) si el qubit de destino (q1) estuviera en el estado $|1\rangle$, y el circuito utilizara una puerta Sdg controlada en lugar de la T controlada (como se muestra en el circuito de abajo)?
- ¿Qué pasaría con el qubit de control (q0) si estuviera en el estado $|1\rangle$ en lugar del estado $|{+}\rangle$ antes de la aplicación de la T controlada (como se muestra en el circuito de abajo)?
import qiskit.tools.jupyter
%qiskit_version_table
C:\Users\Francisco\AppData\Local\Temp\ipykernel_18892\3369625891.py:1: DeprecationWarning: qiskit.tools.jupyter is deprecated and will be removed in Qiskit 1.0.0
import qiskit.tools.jupyter
Version Information
Software | Version |
---|---|
qiskit | 0.46.0 |
qiskit_aer | 0.13.2 |
System information | |
Python version | 3.11.4 |
Python compiler | MSC v.1916 64 bit (AMD64) |
Python build | main, Jul 5 2023 13:38:37 |
OS | Windows |
CPUs | 4 |
Memory (Gb) | 11.799663543701172 |
Sat Feb 03 21:20:23 2024 Hora estándar romance |