Saltar al contenido principal

Implementación en Qiskit

En la lección anterior echamos un primer vistazo a las clases Statevector y Operator de Qiskit y las utilizamos para simular operaciones y mediciones en qubits individuales. En esta sección utilizaremos estas clases para explorar el comportamiento de múltiples qubits.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__

print(__version__)
2.1.1

Comenzamos importando las clases Statevector y Operator, así como la función de raíz cuadrada de NumPy. De ahora en adelante, nos ocuparemos generalmente de todas las importaciones necesarias al comienzo de cada lección.

from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt

Productos tensoriales

La clase Statevector tiene un método tensor que devuelve el producto tensorial de este Statevector con otro que se pasa como argumento. El argumento se interpreta como el factor tensorial derecho.

En el siguiente ejemplo, creamos dos vectores de estado para 0\vert 0\rangle y 1\vert 1\rangle y utilizamos el método tensor para crear un nuevo vector ψ=01\vert \psi\rangle = \vert 0\rangle \otimes \vert 1\rangle. Observa que aquí utilizamos el método from_label para definir los estados 0\vert 0\rangle y 1\vert 1\rangle, en lugar de especificarlos manualmente.

zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))

01 |01\rangle

Otras etiquetas permitidas son "+" y "-" para los estados plus y minus, así como "r" y "l" (abreviatura de "right" y "left") para los estados

+i=120+i21yi=120i21.\vert {+i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle + \frac{i}{\sqrt{2}} \vert 1 \rangle \qquad\text{y}\qquad \vert {-i} \rangle = \frac{1}{\sqrt{2}} \vert 0 \rangle - \frac{i}{\sqrt{2}} \vert 1 \rangle.

Aquí, "+", "-" y "right" y "left" provienen del contexto del espin cuántico, donde una componente de espin en un experimento puede apuntar a la izquierda o a la derecha; no se trata del qubit a la derecha o a la izquierda en sistemas de múltiples qubits. A continuación se muestra un ejemplo del producto tensorial de +\vert {+} \rangle y i.\vert {-i} \rangle.

plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

Alternativamente, se puede utilizar el operador ^ para productos tensoriales, que produce los mismos resultados como era de esperar.

display((plus ^ minus_i).draw("latex"))

1200i201+1210i211\frac{1}{2} |00\rangle- \frac{i}{2} |01\rangle+\frac{1}{2} |10\rangle- \frac{i}{2} |11\rangle

La clase Operator también tiene un método tensor (así como un método from_label), como se muestra en los siguientes ejemplos.

H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
[220220022022220220022022] \begin{bmatrix} \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & \frac{\sqrt{2}}{2} \\ \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & - \frac{\sqrt{2}}{2} \\ \end{bmatrix} [02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

Al igual que con los vectores, el operador ^ es equivalente.

display((H ^ Id ^ X).draw("latex"))
[02200022002200022000000220002200220002200220002200220002200000022000220022000220] \begin{bmatrix} 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 \\ 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 \\ \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 \\ 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} \\ 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 \\ \end{bmatrix}

Los estados compuestos pueden evolucionar con operaciones compuestas, tal como era de esperar, de la misma manera que lo vimos para sistemas individuales en la lección anterior. El siguiente código calcula, por ejemplo, el estado (HI)ϕ(H\otimes I)\vert\phi\rangle para ϕ=+i\vert\phi\rangle = \vert + \rangle \otimes \vert {-i}\rangle (que ya fue definido anteriormente).

display(phi.evolve(H ^ Id).draw("latex"))

22002i201\frac{\sqrt{2}}{2} |00\rangle- \frac{\sqrt{2} i}{2} |01\rangle

A continuación se muestra código que define una operación CXCX y calcula CXψCX \vert\psi\rangle para ψ=+0\vert\psi\rangle = \vert + \rangle \otimes \vert 0 \rangle. Se trata de una operación CXCX donde el qubit izquierdo es el qubit de control y el qubit derecho es el qubit objetivo. El resultado es el estado de Bell ϕ+.\vert\phi^{+}\rangle.

CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))

2200+2211\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle

Mediciones parciales

En la lección anterior utilizamos el método measure para simular una medición de un vector de estado cuántico. Este método devuelve dos valores: el resultado simulado de la medición y el nuevo Statevector después de dicha medición.

Por defecto, measure mide todos los qubits del vector de estado. Alternativamente, se puede pasar una lista de enteros como argumento, lo que hace que solo se midan los qubits con esos índices. Para demostrar esto, el siguiente código crea el estado

w=001+010+1003\vert w\rangle = \frac{\vert 001\rangle + \vert 010\rangle + \vert 100\rangle}{\sqrt{3}}

y mide el qubit número 0, es decir, el qubit situado más a la derecha. (Qiskit numera los qubits comenzando desde 0, de derecha a izquierda. Volveremos sobre esta convención de numeración en la siguiente lección.)

w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))

result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))

33001+33010+33100\frac{\sqrt{3}}{3} |001\rangle+\frac{\sqrt{3}}{3} |010\rangle+\frac{\sqrt{3}}{3} |100\rangle

Measured: 0
State after measurement:

22010+22100\frac{\sqrt{2}}{2} |010\rangle+\frac{\sqrt{2}}{2} |100\rangle

Measured: 00
State after measurement:

100 |100\rangle