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 — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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 y y utilizamos el método tensor para crear un nuevo vector .
Observa que aquí utilizamos el método from_label para definir los estados y , en lugar de especificarlos manualmente.
zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))
Otras etiquetas permitidas son "+" y "-" para los estados más y menos, así como "r" y "l" (abreviatura de "right" y "left") para los estados
Aquí, "+", "-" y "right" y "left" provienen del contexto del espín cuántico, donde una componente del espín 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 y .
plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))
Alternativamente, se puede utilizar el operador ^ para productos tensoriales, que produce los mismos resultados como era de esperar.
display((plus ^ minus_i).draw("latex"))
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"))
Al igual que con los vectores, el operador ^ es equivalente.
display((H ^ Id ^ X).draw("latex"))
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 para (que ya fue definido anteriormente).
display(phi.evolve(H ^ Id).draw("latex"))
A continuación se muestra código que define una operación y calcula para . Se trata de una operación donde el qubit izquierdo es el qubit de control y el qubit derecho es el qubit objetivo. El resultado es el estado de Bell .
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"))
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
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"))
Measured: 0
State after measurement:
Measured: 00
State after measurement: