Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/translations/es/ch-states/representing-qubit-states.ipynb
3855 views
Kernel: Python 3

Representación de Estados de Qubit

Ahora sabes algo sobre los bits y sobre cómo funcionan nuestras conocidas computadoras digitales. Todas las variables complejas, objetos y estructuras de datos que se utilizan en el software moderno son básicamente grandes pilas de bits. Quienes trabajamos en computación cuántica llamamos a estas variables clásicas. Las computadoras que las usan, como la que estás usando para leer este artículo, las llamamos computadoras clásicas.

En las computadoras cuánticas, nuestra variable básica es el qubit: una variante cuántica del bit. Estos tienen exactamente las mismas restricciones que los bits normales: solo pueden almacenar una única pieza de información binaria y solo pueden darnos una salida de [[0 o 1|-1 o 1|0|1|-1]]. Sin embargo, también se pueden manipular de formas que solo pueden ser descritas por la mecánica cuántica. Esto nos brinda nuevas compuertas con las que jugar, lo que nos permite encontrar nuevas formas de diseñar algoritmos.

Para comprender completamente estas nuevas compuertas, primero debemos entender cómo escribir los estados del qubit. Para ello utilizaremos las matemáticas de vectores, matrices y números complejos. Aunque presentaremos estos conceptos a medida que avanzamos, sería mejor si ya te sientes cómodo con ellos. Si necesitas una explicación más detallada o un repaso, puedes encontrar la guía aquí.

1. Bits Clásicos vs Cuánticos

1.1 Vectores de estado

En física cuántica usamos vectores de estado para describir el estado de nuestro sistema. Digamos que queríamos describir la posición de un automóvil a lo largo de una pista, este es un sistema clásico, por lo que podríamos usar un número xx:

seguimiento de un coche con escalares

x=4x=4

Alternativamente, podríamos usar una colección de números en un vector llamado statevector (vector de estado). Cada elemento en el vector de estado contiene la probabilidad de encontrar el automóvil en un lugar determinado:

seguimiento de un coche con vectores

ParseError: KaTeX parse error: Undefined control sequence: \cssId at position 1: \̲c̲s̲s̲I̲d̲{x_ket}{|x\rang…

Esto no se limita a la posición, también podríamos mantener un vector de estado de todas las velocidades posibles que podría tener el automóvil y todos los colores posibles que podría tener este. Con los sistemas clásicos (como el ejemplo del automóvil anterior), esto es absurdo de hacer, ya que requiere mantener vectores enormes cuando solo necesitamos un número. Pero como veremos en este capítulo, los vectores de estado resultan ser una forma muy buena de realizar un seguimiento de los sistemas cuánticos, incluidas las computadoras cuánticas.

1.2 Notación del Qubit

Los bits clásicos siempre son 0 o 1 en cada punto durante un cálculo. No hay más detalle que podamos agregar al estado de un bit que este. Entonces, para escribir el estado de un bit clásico (c), podemos usar estos dos valores binarios. Por ejemplo:

c=0c = 0

Esta restricción se levanta para los bits cuánticos. Solo es necesario definir bien si obtenemos un 0 o un 1 de un qubit cuando se realiza una medición para extraer un resultado. En ese momento, debe comprometerse con una de estas dos opciones. En todos los demás momentos, su estado será algo más complejo de lo que puede ser capturado por un valor binario simple.

Para ver cómo describirlos, primero podemos centrarnos en los dos casos más simples. Como vimos en la última sección, es posible preparar un qubit en un estado para el cual definitivamente da el resultado 0 cuando se mide.

Necesitamos un nombre para este estado. Seamos poco imaginativos y llamémoslo 00. Del mismo modo, existe un estado de qubit que seguramente generará un 1. Llamaremos a esto 11. Estos dos estados son completamente mutuamente [[exclusivos|inclusivos]]. O el qubit definitivamente genera un 0, o definitivamente genera un 1. No hay traslape. Una forma de representar esto con las matemáticas es usar dos vectores ortogonales.

ParseError: KaTeX parse error: Undefined control sequence: \cssId at position 1: \̲c̲s̲s̲I̲d̲{|0\rangle…

Esta es una gran cantidad de notación para tomar todo a la vez. Primero, analicemos los extraños | y \rangle. Su trabajo es esencialmente solo recordarnos que estamos hablando de los vectores que representan los estados de qubit etiquetados como 00 y 11. Esto nos ayuda a distinguirlos de cosas como los valores de bits 0 y 1 o los números 0 y 1. Es parte de la notación bra-ket, introducida por Dirac.

Si no estás familiarizado con los vectores, básicamente puedes pensar en ellos como listas de números que manipulamos usando ciertas reglas. Si estás familiarizado con los vectores de tus clases de física de la preparatoria, sabrás que estas reglas hacen que los vectores sean muy adecuados para describir cantidades con una magnitud y una dirección. Por ejemplo, la velocidad de un objeto se describe perfectamente con un vector. Sin embargo, la forma en que usamos los vectores para los estados cuánticos es ligeramente diferente a esta, así que no te aferres demasiado a tu intuición anterior. ¡Es hora de hacer algo nuevo!

Con vectores podemos describir estados más complejos que solo 0|0\rangle y 1|1\rangle. Por ejemplo, considera el vector

ParseError: KaTeX parse error: Undefined control sequence: \cssId at position 1: \̲c̲s̲s̲I̲d̲{|q_0\rangle…

Para entender lo que significa este estado, necesitaremos usar las reglas matemáticas para manipular vectores. Específicamente, necesitaremos entender cómo sumar vectores y cómo multiplicarlos por escalares.

Recordatorios

Matemáticas de Matriz Para sumar dos vectores, sumamos sus elementos:
a=[a0 a1  an],b=[b0 b1  bn]|a\rangle = \begin{bmatrix}a_0 \ a_1 \ \vdots \ a_n \end{bmatrix}, \quad |b\rangle = \begin{bmatrix}b_0 \ b_1 \ \vdots \ b_n \end{bmatrix}a+b=[a0+b0 a1+b1  an+bn]|a\rangle + |b\rangle = \begin{bmatrix}a_0 + b_0 \ a_1 + b_1 \ \vdots \ a_n + b_n \end{bmatrix}

Y para multiplicar un vector por un escalar, multiplicamos cada elemento por el escalar:

xa=[x×a0 x×a1  x×an]x|a\rangle = \begin{bmatrix}x \times a_0 \ x \times a_1 \ \vdots \ x \times a_n \end{bmatrix}

Estas dos reglas se usan para reescribir el vector q0|q_0\rangle (como se muestra arriba):

q0amp;=120+i21 amp;=12[1 0]+i2[0 1] amp;=[12 0]+[0 i2] amp;=[12 i2] \begin{aligned} |q_0\rangle &= \tfrac{1}{\sqrt{2}}|0\rangle + \tfrac{i}{\sqrt{2}}|1\rangle \ &= \tfrac{1}{\sqrt{2}}\begin{bmatrix}1 \ 0\end{bmatrix} + \tfrac{i}{\sqrt{2}}\begin{bmatrix}0 \ 1\end{bmatrix} \ &= \begin{bmatrix}\tfrac{1}{\sqrt{2}} \ 0\end{bmatrix} + \begin{bmatrix}0 \ \tfrac{i}{\sqrt{2}}\end{bmatrix} \ &= \begin{bmatrix}\tfrac{1}{\sqrt{2}} \ \tfrac{i}{\sqrt{2}} \end{bmatrix} \ \end{aligned}
Bases Ortonormales Se dijo antes que los dos vectores 0|0\rangle y 1|1\rangle son ortonormales, esto significa que ambos son _ortogonales_ y _normalizados_. Ortogonal significa que los vectores están en ángulo recto:

base

Y normalizado significa que sus magnitudes (longitud de la flecha) es igual a 1. Los dos vectores 0|0\rangle y 1|1\rangle son linealmente independientes, lo que significa que no podemos describir 0|0\rangle en términos de 1|1\rangle, y viceversa. Sin embargo, usando los vectores 0|0\rangle y 1|1\rangle, y nuestras reglas de suma y multiplicación por escalares, podemos describir todos los vectores posibles en el espacio 2D:

base

Debido a que los vectores 0|0\rangle y 1|1\rangle son linealmente independientes y se pueden usar para describir cualquier vector en el espacio 2D mediante la suma de vectores y la multiplicación escalar, decimos que los vectores 0|0\rangle y 1 |1\rangle forman una base. En este caso, dado que ambos son ortogonales y normalizados, la llamamos base ortonormal.

Dado que los estados 0|0\rangle y 1|1\rangle forman una base ortonormal, podemos representar cualquier vector 2D con una combinación de estos dos estados. Esto nos permite escribir el estado de nuestro qubit en la forma alternativa:

ParseError: KaTeX parse error: Undefined control sequence: \cssId at position 1: \̲c̲s̲s̲I̲d̲{|q_0\rangle…

Este vector, q0|q_0\rangle, se llama statevector (vector de estado) del qubit y nos dice todo lo que podríamos saber sobre este qubit. Por ahora, solo podemos sacar algunas conclusiones simples sobre este ejemplo particular de vector de estado: no es completamente 0|0\rangle y no es completamente 1|1\rangle. En cambio, se describe mediante una combinación lineal de los dos. En mecánica cuántica, normalmente describimos combinaciones lineales como esta, usando la palabra 'superposición'.

Aunque nuestro estado de ejemplo q0|q_0\rangle se puede expresar como una superposición de 0|0\rangle y 1|1\rangle, no es menos que un estado de qubit determinado y bien definido como esos. Para ver esto, podemos comenzar a explorar cómo se puede manipular un qubit.

1.3 Explorando los Qubits con Qiskit

Primero, necesitamos importar todas las herramientas que necesitaremos:

from qiskit import QuantumCircuit, assemble, Aer from qiskit.visualization import plot_histogram, plot_bloch_vector from math import sqrt, pi

En Qiskit, usamos el objeto QuantumCircuit para almacenar nuestros circuitos, esta es esencialmente una lista de las operaciones cuánticas en nuestro circuito y los qubits a los que se aplican.

qc = QuantumCircuit(1) # Crear un circuito cuántico con un qubit

En nuestros circuitos cuánticos, nuestros qubits siempre comienzan en el estado 0|0\rangle. Podemos usar el método initialize() para transformar esto en cualquier estado. Damos a initialize() el vector que queremos en forma de lista y le decimos qué qubit(s) queremos inicializar en este estado:

qc = QuantumCircuit(1) # Crear un circuito cuántico con un qubit initial_state = [0,1] # Definir initial_state como |1> qc.initialize(initial_state, 0) # Aplicar la operación de inicialización al qubit 0 qc.draw() # Veamos nuestro circuito
Image in a Jupyter notebook

Luego podemos usar uno de los simuladores de Qiskit para ver el estado resultante de nuestro qubit.

sim = Aer.get_backend('aer_simulator') # indicarle a Qiskit cómo simular nuestro circuito

Para obtener los resultados de nuestro circuito, usamos run para ejecutar nuestro circuito, dando el circuito y el backend como argumentos. Luego usamos .result() para obtener el resultado de esto:

qc = QuantumCircuit(1) # Crear un circuito cuántico con un qubit initial_state = [0,1] # Definir initial_state como |1> qc.initialize(initial_state, 0) # Aplicar la operación de inicialización al qubit 0 qc.save_statevector() # Indicar al simulador que guarde el vector de estado qobj = assemble(qc) # Crear un Qobj del circuito para que se ejecute el simulador result = sim.run(qobj).result() # Hacer la simulación y devolver el resultado.

a partir del result, podemos obtener el vector de estado final usando .get_statevector():

out_state = result.get_statevector() print(out_state) # Mostrar el vector de estado de salida
[0.+0.j 1.+0.j]

Nota: Python usa j para representar la ii de los números complejos. Vemos un vector con dos elementos complejos: 0.+0.j = 0 y 1.+0.j = 1.

Ahora midamos nuestro qubit como lo haríamos en una computadora cuántica real y veamos el resultado:

qc.measure_all() qc.draw()
Image in a Jupyter notebook

Esta vez, en lugar del vector de estado, obtendremos los recuentos de los resultados 0 y 1 mediante .get_counts():

qobj = assemble(qc) result = sim.run(qobj).result() counts = result.get_counts() plot_histogram(counts)
Image in a Jupyter notebook

Podemos ver que (como era de esperar) tenemos un [[100]]% de posibilidades de medir 1|1\rangle.

Esta vez, pongamos nuestro qubit en una superposición y veamos qué sucede. Usaremos el estado q0|q_0\rangle de antes en esta sección:

ParseError: KaTeX parse error: Undefined control sequence: \cssId at position 53: …angle + \tfrac{\̲c̲s̲s̲I̲d̲{i}{i}}{\sqrt{2…

Necesitamos agregar estas amplitudes a una lista de python. Para agregar una amplitud compleja, Python usa j para la unidad imaginaria (normalmente la llamamos "ii" matemáticamente):

initial_state = [1/sqrt(2), 1j/sqrt(2)] # Definir el estado |q_0>

Y luego repetimos los pasos para inicializar el qubit como antes:

qc = QuantumCircuit(1) # Se debe redefinir qc qc.initialize(initial_state, 0) # Inicializar el qubit 0 en el estado `initial_state` qc.save_statevector() # Guardar el vector de estado qobj = assemble(qc) state = sim.run(qobj).result().get_statevector() # Ejecutar el circuito print(state) # Imprimir el resultado
[0.70710678+0.j 0. +0.70710678j]
qobj = assemble(qc) results = sim.run(qobj).result().get_counts() plot_histogram(results)
Image in a Jupyter notebook

Podemos ver que tenemos [[igual|menor|mayor]] probabilidad de medir 0|0\rangle en comparación con 1|1\rangle. Para explicar esto, necesitamos hablar de medición.

2. Las Reglas de Medición

2.1 Una Regla Muy Importante

Hay una regla simple para medir. Para encontrar la probabilidad de medir un estado ψ|\psi \rangle en el estado x|x\rangle hacemos:

p(x)=xψ2p(|x\rangle) = | \langle x| \psi \rangle|^2

Los símbolos \langle y | nos dicen que x\langle x | es un vector fila. En mecánica cuántica llamamos a los vectores columna kets y a los vectores fila bras. Juntos forman la notación bra-ket. Cualquier ket a|a\rangle tiene un bra correspondiente a\langle a|, y convertimos entre ellos usando la transpuesta conjugada.

Recordatorios

El Producto Interior Hay diferentes formas de multiplicar vectores, aquí usamos el _producto interno_. El producto interno es una generalización del _producto punto_ con el que quizás ya estés familiarizado. En esta guía, usamos el producto interno entre un bra (vector renglón) y un ket (vector columna), y sigue esta regla:
a=[a0,amp;a1,amp;amp;an]\langle a| = \begin{bmatrix}a_0, & a_1, & \dots & a_n \end{bmatrix}b=[b0 b1  bn]|b\rangle = \begin{bmatrix}b_0 \ b_1 \ \vdots \ b_n \end{bmatrix}ab=a0b0+a1b1anbn\langle a|b\rangle = a_0 b_0 + a_1 b_1 \dots a_n b_n

Podemos ver que el producto interno de dos vectores siempre nos da un escalar. Algo útil para recordar es que el producto interno de dos vectores ortogonales es 0, por ejemplo, si tenemos los vectores ortogonales 0|0\rangle y 1|1\rangle:

10=[0,amp;1][1 0]=0\langle1|0\rangle = \begin{bmatrix} 0 , & 1\end{bmatrix}\begin{bmatrix}1 \ 0\end{bmatrix} = 0

Además, recuerda que los vectores 0|0\rangle y 1|1\rangle también están normalizados (las magnitudes son iguales a 1):

00amp;=[1,amp;0][1 0]=1 11amp;=[0,amp;1][0 1]=1\begin{aligned} \langle0|0\rangle &= \begin{bmatrix} 1 , & 0\end{bmatrix}\begin{bmatrix}1 \ 0\end{bmatrix} = 1 \ \langle1|1\rangle &= \begin{bmatrix} 0 , & 1\end{bmatrix}\begin{bmatrix}0 \ 1\end{bmatrix} = 1 \end{aligned}
Transpuesta Conjugada La conversión entre bra-ket se lleva a cabo mediante el método de transposición conjugada. Sabemos que un ket (vector columna) se representa de la siguiente manera:
a=[a0 a1  an]\quad|a\rangle = \begin{bmatrix}a_0 \ a_1 \ \vdots \ a_n \end{bmatrix}

Para obtener la transpuesta conjugada, la matriz se transpone y los elementos son complejos conjugados (representados por la operación "∗") donde el complejo conjugado de un número complejo es un número con una parte real igual y una parte imaginaria igual en magnitud pero opuesta en signo. Esto da el bra correspondiente (vector fila) de la siguiente manera:

a=[a0,amp;a1,amp;amp;an]\langle a| = \begin{bmatrix}a_0^*, & a_1^*, & \dots & a_n^* \end{bmatrix}

En la ecuación anterior, x|x\rangle puede ser cualquier estado de qubit. Para encontrar la probabilidad de medir x|x\rangle, tomamos el producto interno de x|x\rangle y el estado que estamos midiendo (en este caso ψ|\psi\rangle), luego elevamos al cuadrado la magnitud. Esto puede parecer un poco complicado, pero pronto se convertirá en una segunda naturaleza.

Si observamos el estado q0|q_0\rangle anterior, podemos ver que la probabilidad de medir 0|0\rangle es de hecho 0.50.5:

q0amp;=120+i21 0q0amp;=1200+i201 amp;=121+i20 amp;=12 0q02amp;=12\begin{aligned} |q_0\rangle & = \tfrac{1}{\sqrt{2}}|0\rangle + \tfrac{i}{\sqrt{2}}|1\rangle \ \langle 0| q_0 \rangle & = \tfrac{1}{\sqrt{2}}\langle 0|0\rangle + \tfrac{i}{\sqrt{2}}\langle 0|1\rangle \ & = \tfrac{1}{\sqrt{2}}\cdot 1 + \tfrac{i}{\sqrt{2}} \cdot 0\ & = \tfrac{1}{\sqrt{2}}\ |\langle 0| q_0 \rangle|^2 & = \tfrac{1}{2} \end{aligned}

Debes verificar la probabilidad de medir 1|1\rangle como ejercicio.

Esta regla rige cómo obtenemos información de los estados cuánticos. Por lo tanto, es muy importante para todo lo que hacemos en computación cuántica. También implica inmediatamente varios hechos importantes.

2.2 Las Implicaciones de esta Regla

#1 Normalización

La regla nos muestra que las amplitudes están relacionadas con las probabilidades. Si queremos que las probabilidades sumen 1 (¡y deberían!), debemos asegurarnos de que el vector de estado esté correctamente normalizado. Específicamente, necesitamos que la magnitud del vector de estado sea 1.

ψψ=1\langle\psi|\psi\rangle = 1

Así si:

ψ=α0+β1|\psi\rangle = \alpha|0\rangle + \beta|1\rangle

Entonces:

α2+β2=1|\alpha|^2 + |\beta|^2 = 1

Esto explica los factores de 2\sqrt{2} que has visto a lo largo de este capítulo. De hecho, si intentamos darle a initialize() un vector que no está normalizado, nos dará un error:

vector = [1,1] qc.initialize(vector, 0)
--------------------------------------------------------------------------- QiskitError Traceback (most recent call last) <ipython-input-12-ddc73828b990> in <module> 1 vector = [1,1] ----> 2 qc.initialize(vector, 0) /usr/local/anaconda3/lib/python3.7/site-packages/qiskit/extensions/quantum_initializer/initializer.py in initialize(self, params, qubits) 453 454 num_qubits = None if not isinstance(params, int) else len(qubits) --> 455 return self.append(Initialize(params, num_qubits), qubits) 456 457 /usr/local/anaconda3/lib/python3.7/site-packages/qiskit/extensions/quantum_initializer/initializer.py in __init__(self, params, num_qubits) 89 if not math.isclose(sum(np.absolute(params) ** 2), 1.0, 90 abs_tol=_EPS): ---> 91 raise QiskitError("Sum of amplitudes-squared does not equal one.") 92 93 num_qubits = int(num_qubits) QiskitError: 'Sum of amplitudes-squared does not equal one.'

Ejercicio Rápido

  1. Crea un vector de estado que dé una probabilidad de 1/31/3 al medir 0|0\rangle.

  2. Crea un vector de estado diferente que proporcione las mismas probabilidades de medición.

  3. Verifica que la probabilidad de medir 1|1\rangle para estos dos estados es 2/32/3.

Puedes verificar tu respuesta en el widget a continuación (acepta respuestas con ±1% de precisión, puedes usar términos numéricos como 'pi' y 'sqrt()' en el vector):

# Ejecutar el código en esta celda para interactuar con el widget from qiskit_textbook.widgets import state_vector_exercise state_vector_exercise(target=1/3)

#2 Medición alternativa

La regla de medición nos da la probabilidad p(x)p(|x\rangle) de que un estado ψ|\psi\rangle se mida como x|x\rangle. En ninguna parte nos dice que x|x\rangle solo puede ser 0|0\rangle o 1|1\rangle.

Las mediciones que hemos considerado hasta ahora son, de hecho, solo una de las infinitas formas posibles de medir un qubit. Para cualquier par de estados ortogonales, podemos definir una medición que haga que un qubit elija entre los dos.

Esta posibilidad se explorará más en la siguiente sección. Por ahora, ten en cuenta que x|x\rangle no se limita a ser simplemente 0|0\rangle o 1|1\rangle.

#3 Fase Global

Sabemos que medir el estado 1|1\rangle nos dará el resultado 1 con certeza. Pero también podemos escribir estados como

[0 i]=i1.\begin{bmatrix}0 \ i\end{bmatrix} = i|1\rangle.

Para ver cómo se comporta esto, aplicamos la regla de medición.

x(i1)2=ix12=x12|\langle x| (i|1\rangle) |^2 = | i \langle x|1\rangle|^2 = |\langle x|1\rangle|^2

Aquí encontramos que el factor de ii desaparece una vez que tomamos la magnitud del número complejo. Este efecto es completamente independiente del estado medido x|x\rangle. No importa qué medición estemos considerando, las probabilidades para el estado i1i|1\rangle son idénticas a las de 1|1\rangle. Dado que las mediciones son la única forma en que podemos extraer información de un qubit, esto implica que estos dos estados son equivalentes en todos los aspectos físicamente relevantes.

Más generalmente, nos referimos a cualquier factor global γ\gamma en un estado para el cual γ=1|\gamma|=1 como una 'fase global'. Los estados que difieren solo por una fase global son físicamente indistinguibles.

x(γa)2=γxa2=xa2|\langle x| ( \gamma |a\rangle) |^2 = | \gamma \langle x|a\rangle|^2 = |\langle x|a\rangle|^2

Ten en cuenta que esto es distinto de la diferencia de fase entre términos en una superposición, que se conoce como 'fase relativa'. Esto se vuelve relevante una vez que consideramos diferentes tipos de mediciones y múltiples qubits.

#4 El Efecto del Observador

Sabemos que las amplitudes contienen información sobre la probabilidad de que encontremos el qubit en un estado específico, pero una vez que hemos medido el qubit, sabemos con certeza cuál es el estado del qubit. Por ejemplo, si medimos un qubit en el estado:

q=α0+β1|q\rangle = \alpha|0\rangle + \beta|1\rangle

Y encontrarlo en el estado 0|0\rangle, si volvemos a medir, hay un 100% de posibilidades de encontrar el qubit en el estado 0|0\rangle. Esto significa que el acto de medir cambia el estado de nuestros qubits.

q=[α β]Measure 0q=0=[1 0]|q\rangle = \begin{bmatrix} \alpha \ \beta \end{bmatrix} \xrightarrow{\text{Measure }|0\rangle} |q\rangle = |0\rangle = \begin{bmatrix} 1 \ 0 \end{bmatrix}

A veces nos referimos a esto como colapsar el estado del qubit. Es un efecto potente, por lo que debe usarse sabiamente. Por ejemplo, si tuviéramos que medir constantemente cada uno de nuestros qubits para realizar un seguimiento de su valor en cada punto de un cálculo, siempre estarían en un estado bien definido de 0|0\rangle o 1|1\rangle. Como tales, no serían diferentes de los bits clásicos y nuestro cálculo podría reemplazarse fácilmente por un cálculo clásico. Para lograr un cálculo verdaderamente cuántico, debemos permitir que los qubits exploren estados más complejos. Por lo tanto, las mediciones solo se usan cuando necesitamos extraer una salida. Esto significa que a menudo colocamos todas las medidas al final de nuestro circuito cuántico.

Podemos demostrar esto usando el simulador de vector de estado de Qiskit. Inicialicemos un qubit en superposición:

qc = QuantumCircuit(1) # Estamos redefiniendo qc initial_state = [0.+1.j/sqrt(2),1/sqrt(2)+0.j] qc.initialize(initial_state, 0) qc.draw()
Image in a Jupyter notebook

Esto debería inicializar nuestro qubit en el estado:

q=i20+121|q\rangle = \tfrac{i}{\sqrt{2}}|0\rangle + \tfrac{1}{\sqrt{2}}|1\rangle

Lo podemos verificar usando el simulador:

qc.save_statevector() result = sim.run(assemble(qc)).result() state = result.get_statevector() print("Qubit State = " + str(state))
Qubit State = [0. +0.70710678j 0.70710678+0.j ]

Podemos ver aquí que el qubit se inicializa en el estado [0.+0.70710678j 0.70710678+0.j], que es el estado que esperábamos.

Ahora creemos un circuito donde medimos este qubit:

qc = QuantumCircuit(1) # Estamos redefiniendo qc initial_state = [0.+1.j/sqrt(2),1/sqrt(2)+0.j] qc.initialize(initial_state, 0) qc.measure_all() qc.save_statevector() qc.draw()
Image in a Jupyter notebook

Cuando simulamos todo este circuito, podemos ver que una de las amplitudes es siempre 0:

qobj = assemble(qc) state = sim.run(qobj).result().get_statevector() print("Estado del Qubit Medido = " + str(state))
Estado del Qubit Medido = [0.+1.j 0.+0.j]

Puedes volver a ejecutar esta celda varias veces para reiniciar el qubit y medirlo nuevamente. Notarás que cualquier resultado es igualmente probable, pero que el estado del qubit nunca es una superposición de 0|0\rangle y 1|1\rangle. Curiosamente, la fase global en el estado 0|0\rangle sobrevive, pero dado que esta es una fase global, nunca podremos medirla en una computadora cuántica real.

Una Nota sobre los Simuladores Cuánticos

Podemos ver que escribir el estado de un qubit requiere realizar un seguimiento de dos números complejos, pero cuando usamos una computadora cuántica real, solo recibiremos un sí o un no (0 o 1) como respuesta para cada qubit. La salida de una computadora cuántica de 10 qubits se verá así:

0110111110

Solo 10 bits, sin superposición ni amplitudes complejas. Cuando usamos una computadora cuántica real, no podemos ver los estados de nuestros qubits en medio del cálculo, ¡ya que esto los destruiría! Este comportamiento no es ideal para el aprendizaje, por lo que Qiskit proporciona diferentes simuladores cuánticos: de forma predeterminada, el aer_simulator imita la ejecución de una computadora cuántica real, pero también te permitirá observar los estados cuánticos antes de la medición si incluimos ciertas instrucciones en nuestro circuito. Por ejemplo, aquí hemos incluido la instrucción .save_statevector(), lo que significa que podemos usar .get_statevector() en el resultado de la simulación.

3. La Esfera de Bloch

3.1 Descripción del Estado de Qubit Restringido

Vimos anteriormente en este capítulo que el estado general de un qubit (q|q\rangle) es:

q=α0+β1|q\rangle = \alpha|0\rangle + \beta|1\rangleα,βC\alpha, \beta \in \mathbb{C}

(La segunda línea nos dice que α\alpha y β\beta son números complejos). Las dos primeras implicaciones de la sección 2 nos dicen que no podemos diferenciar entre algunos de estos estados. Esto significa que podemos ser más específicos en nuestra descripción del qubit.

En primer lugar, dado que no podemos medir la fase global, solo podemos medir la diferencia de fase entre los estados 0|0\rangle y 1|1\rangle. En lugar de que α\alpha y β\beta sean complejos, podemos limitarlos a los números reales y agregar un término que nos indique la fase relativa entre ellos:

q=α0+eiϕβ1|q\rangle = \alpha|0\rangle + e^{i\phi}\beta|1\rangleα,β,ϕR\alpha, \beta, \phi \in \mathbb{R}

Finalmente, dado que el estado del qubit debe normalizarse, es decir

α2+β2=1\sqrt{\alpha^2 + \beta^2} = 1

podemos usar la identidad trigonométrica:

sin2x+cos2x=1\sqrt{\sin^2{x} + \cos^2{x}} = 1

para describir los α\alpha y β\beta reales en términos de una variable, θ\theta:

α=cosθ2,β=sinθ2\alpha = \cos{\tfrac{\theta}{2}}, \quad \beta=\sin{\tfrac{\theta}{2}}

A partir de esto podemos describir el estado de cualquier qubit usando las dos variables ϕ\phi y θ\theta:

q=cosθ20+eiϕsinθ21|q\rangle = \cos{\tfrac{\theta}{2}}|0\rangle + e^{i\phi}\sin{\tfrac{\theta}{2}}|1\rangleθ,ϕR\theta, \phi \in \mathbb{R}

3.2 Representación Visual de un Estado de Qubit

Queremos graficar nuestro estado de qubit general:

q=cosθ20+eiϕsinθ21|q\rangle = \cos{\tfrac{\theta}{2}}|0\rangle + e^{i\phi}\sin{\tfrac{\theta}{2}}|1\rangle

Si interpretamos θ\theta y ϕ\phi como coordenadas esféricas (r=1r = 1, dado que la magnitud del estado del qubit es 11), podemos representar cualquier estado de qubit en la superficie de una esfera, conocida como la esfera de Bloch.

A continuación, hemos graficado un qubit en el estado +|{+}\rangle. En este caso, θ=π/2\theta = \pi/2 y ϕ=0\phi = 0.

(Qiskit tiene una función para graficar una esfera de Bloch, plot_bloch_vector(), pero al momento de escribirla solo toma coordenadas cartesianas. Hemos incluido una función que realiza la conversión automáticamente).

También puedes probar esta demostración interactiva de la esfera de Bloch.

from qiskit_textbook.widgets import plot_bloch_vector_spherical coords = [pi/2,0,1] # [Theta, Phi, Radius] plot_bloch_vector_spherical(coords) # Vector de Bloch con coordenadas esféricas
Image in a Jupyter notebook

¡Advertencia!

Cuando se aprende por primera vez sobre los estados de los qubits, es fácil confundir el vector de estado de los qubits con su vector de Bloch. Recuerda que el vector de estado es el vector discutido en 1.1, que contiene las amplitudes de los dos estados en los que puede estar nuestro qubit. El vector de Bloch es una herramienta de visualización que mapea el vector de estado complejo en 2D en un espacio real en 3D.

Ejercicio Rápido

Usa plot_bloch_vector() o plot_bloch_sphere_spherical() para graficar un qubit en los estados:

  1. 0 |0\rangle

  2. 1 |1\rangle

  3. 12(0+1)\tfrac{1}{\sqrt{2}}(|0\rangle + |1\rangle)

  4. 12(0i1)\tfrac{1}{\sqrt{2}}(|0\rangle - i|1\rangle)

  5. ParseError: KaTeX parse error: Undefined control sequence: \1 at position 36: …begin{bmatrix}i\̲1̲\end{bmatrix}

También hemos incluido a continuación un widget que convierte de coordenadas esféricas a cartesianas, para usar con plot_bloch_vector():

from qiskit_textbook.widgets import bloch_calc bloch_calc()
import qiskit.tools.jupyter %qiskit_version_table