Computación Cuántica: Mi primer qbit
Hace un 8 meses salía «Quatum Computing – Program Next-Gen Computers for Hard, Real-World Applications«, en un eBook escrito por Nihal Mehta, de la editorial Pragmatic Bookshelf, podría decir que colecciono los libros de esta editorial :P. Me llamó la atención, por que ya había estado cacharreando un poco por IBM Q Exp, pero me faltaba una primera pincelada para ingenieros de sowa y no le presté mayor atención en su momento.
De esta primera lectura, con qASM, nada de python, C o similares; me quedé con una primera impresión, el manejo de las puertas cuánticas y las bases de lo que es la programación cuántica; es decir, la parte física/mecánica, aun que se referencia en el libro, me faltaba entrar un poco en el detalle, humanamente entendible.
En este artículo voy a intentar explicar lo hasta ahora aprendido, para poder entender y manipular un cúbit (qubit o qbit), como imaginamos es un bit cuántico, y hasta casi mágico. Antes de nada, y esto me gustaría que quedase claro, soy un ingeniero de software, ni físico, ni científico, pero esto ha llegado a terreno, el software,y me encanta jugar con estas cosas, cualquier error de concepto, por favor, estaré más que agradecido por la corrección.
Que es la programación cuántica?
La programación cuántica, no es más que el proceso de ensamblar una secuencia de instrucciones; el conjunto de secuencias (lo digo ya, circuitos) forman un programa cuántico, capaz de ejecutarse en un ordenador cuántico.
Nada nuevo hasta aquí. Empezamos por lo fácil.
Que es la computación cuántica?
La computación cuántica, es el uso de una serie de fenómenos de la mecánica cuántica, como la super-posición y el entrelazamiento (entre partículas) de los que nos podemos beneficiar para realizar cálculos.
Fuera de un simulador, solo los computadores cuánticos son capaces de ejecutar estos programas. Estos ordenadores, operan bajo el «paradigma» de la mecánica cuántica, y la principal diferencia reside es la naturaleza más básica de unidad de información.
Si en computación clásica un bit puede tener dos estados, 1 o 0, un qbit, puede tener ambos a la vez…
Un qbit, por el principio de super-posición cuántico puede representar al mismo tiempo un 1 y un 0. Solo, y aquí entra el gato de Schrödinger, cuando hagamos la lectura, los diferentes estados colapsarán por el principio de decoherencia cuántica, en uno solo, lo que no impide el diseño de circuitos que puedan representar todos los valores de una clave RSA de una sola tocada, y obtener una lectura final sobre el estado de super-posición de mayor probabilidad.
Llevamos ya muchos palabras raras… no es mucho rollo para programar?
Y no falta razón, por eso mismo al principio comentaba que el primer libro me dejó a medias, sabiendo que es el entrelazamiento o la super-posición, que es eso de colapsar… Sin entrar en detalle, ya me meteré más en otros artículos, es importante saber:
- Los qbits se crean de forma física a partir de electrones, fotones, o protones, depende del modelo escogido. Ambas partículas sub-atómicas se usan a día de hoy, junto con otros modelos de cuasi-partículas, que la verdad no entiendo :D.
- Entrelazamiento cuántico: Así, en bruto, a lo bestia, es un fenómeno por el que dos partículas se enlazan entre sí y el cambio de estado en una se ve reflejado en la otra. Magia… con soporte físico/matemático.
- Super-posición de estados: Igual que antes, es un fenómeno por el cual una partícula puede estar en dos estados a la vez, 1 y/o 0. Esto se debe la capacidad de las partículas sub-atómicas de lidiar con la incertidumbre. Mientras que la computación clásica 2bits puede estar en 1 estado a la vez, un qbit pude estar en 00, 01, 10, 00 a la vez. En la universidad de Waterloo se consiguió trabajar con 12 qbits con una equivalencia de unos 1000 bits. De entrada cabría esperar un poco más… La supremacía cuántica está en la barrera de los 54qbits (momento en el que se supera la potencia de computo global) ya fue reclamada por google con su controversia, pero para el dato, en 200 segundos se resolvió el problema de randomización de cadenas que le llevaría a el super computador más potente del mundo 10.000 años.
- Decoherencia cuántica (colapso): Es el fenómeno por el cual una partícula pierde su coherencia cuántica, sus propiedad, y colapsa en un único valor. Esto parece una tontería, pero es lo que traslada el estado cuántico, a un estado físico que pueda «entendible» por nosotros. Lo común es realizar medidas sobre los qbits y obtener los porcentajes de las posibles combinaciones de estado… aquí se empieza a enturbiar el tema.

Estos conceptos son una punta ínfima de todo lo que esconden los fenómenos cuánticos. Con tiempo, me gustaría entrar más en detalle, pero ahora toca que saltemos a la chicha. Trabajar con qbuit.
Mi primer programa (circuito) cuántico
Empecemos el viaje, como siempre, vamos a necesitar una serie de requisitos:
- Una cuenta en IBM Q Experience
- Chapurrear Python, usaremos Qiskit como librería en vez de qASM.
- Crearnos un notebook para poder tirar las líneas y ejecutar nuestro circuito
- Álgebra lineal… hoy aun no… ya llegaremos a temas turbios como los espacios de Hilbert, orto-normalidad, matrices unitarias y cosas aun más interesantes.
IBM Q Experience y Jupyter Notebooks
Q Experience es una plataforma diseñada por IBM, en la que si no me equivocó, hay algunos gallegos trabajando en ella; y si me están leyendo, encantado de tomar un café aun que sea virtual 🙂 para ser menos pulpo en el desierto.
Q Experience, tiene dos servicios muy interesantes para iniciarte en este mundo.
Circuit Composer
Nos permite diseñar circuitos cuánticos casi en modo drag and drop. Personalmente lo encuentro muy útil a la hora de estudiar las puertas y poder ver como se comportan. Quiero recordar en este punto la importancia de dejar de pensar en POO y más en tarjetas perforadas.
El Composer nos permite agregar tantos qbits como necesitemos, aplicar puertas lógicas (si, pero cuánticas) y obtener los resultados de una forma sencilla. Tampoco es que podamos hacer algo muy potente, y es mejor bajarse a notebook en Jupyter o un IDE normal.

En captura de arriba sale un resultado ya calculado por el simulador. Recodáis que los simuladores no cuánticos… la gran diferencia viene a la hora de sacar los resultados. Con dos puertas de Hadamard después de aplicar la de puerta X de Pauli, deberíamos de obtener un 1, pero la realidad es que es un %1 y %0. A la hora de ejecutar los circuitos se indica el número de lecturas que se hacen y en base a eso se obtienen una probabilidad sobre el posible valor del qbit.
El registro c es un bit normal al que bajamos la medida para poder tratarla en el mundo «determinista».

De la imagen superior hay dos cosas interesantes, la primera es que la aplicación de esas tres puertas seguidas es equivalente a usar una U3. Pero lo importante es que como podemos ver no es 0 o 1, durante las 1024 lecturas un 4% de las veces el qbit estaba en un valor 0 y en 1 el 96%.
Jupyter Notebooks (versión IBM)
Desde hace unos años soy un fan, evangelista, predicador… lo que queráis, de notebooks de programación. Para el mundo de trabajar con datos, ML, o simplemente explicar algoritmos, son una maravilla.
La combinación de código (Python, R o algunos kernels más en modo experimental que hay) con plots, widgets y texto perfectamente formateados hace de ellos una herramienta indispensable para mi. Google tiene Colab, un clon de Jupyter Notebooks integrado con Drive y más servicios. Se pueden tirar una lineas para conectar con el servicio de IBM, pero IBM nos da Jupyter Notebooks también en la nube.

Puertas básica
A modo de introducción voy a habla solo de las puertas de Pauli y la de Hadamard. Vamos poco a poco.
Las puertas de Pauli (X, Y, Z) se encargan de «mover» el vector que representa el estado, ya sea mediante flips, o cambios de fase. Chino chino chino… pero una imagen vale más que mil palabras.

Como se puede ver, le da la vuelta al estado, pasamos de |0> a |1> (esta es la notación del estado de un qbit, con dos tendríamos algo parecido a |01>)


No me voy a meter en las matemáticas, tengo pensado, pero como pincela comentar que cada uno de estos vectores tiene tres coordenadas (3-D + 1-D, si ya contamos el tiempo), y tiene un impacto en el estado de cada qbit sobre el que se aplica. Si esta resultó estar entrelazado, su par se verá afectado de la misma forma.
Las puertas R, más simplonas ellas, son rotaciones puras que tiene una relación con las puertas de Pauli. Podemos decir que X(0) = Rx(π) = |1>. En la documentación de IBM hay buenos ejemplos sobre como se comportan estas.
La puerta de Hadamard
Ains…, que bonita la jodida, no solo por las matemáticas que tiene detrás, también por que es una de las puertas que nos permite movernos a un estado de súper-posición. Para hacer una idea hace el flip y cambio de fase, permitiendo alejarnos de los polos en la esfera de Bloch. Dicho de otro modo, nos permite mover información entre las bases x, z.

Vale, ahora si, programemos un poco
Más adelante empezaremos con cosas de más chicha. El primero problema que veremos es una simplificación de la gestión de horarios. Pero para el proposito de este artículo vamos a trabajar con un único qbuit y una puerta X y otra H.
# Primero importamos los paquetes que vamos a usar de qiskit
# NOTA IMPORTANTE, está pensado para correr en IBM Q Exp
# en otros notebooks fuera de IBM Q Exp hay que abrir una sesión de trabajo
%matplotlib inline
from qiskit import QuantumCircuit, execute, Aer, IBMQ
from qiskit.compiler import transpile, assemble
from qiskit.tools.jupyter import *
from qiskit.visualization import *
# Abre la session con IBM Q, no lleva credenciales al estar dentro del entorno.
provider = IBMQ.load_account()
# Creamos un circuito, que recibe el número de qbits
qc = QuantumCircuit(1)
qc.x(0)
qc.h(0)
qc.measure_all()
qc.draw()

Como salida tenemos el circuito de arriba, y como resultado dela medición un 0. Esto mismo lo podemos ver en esfera con el siguiente snippet. Lo único que hace es simular un backend para recoger un vector de estados y pintarlo.
backend = Aer.get_backend('statevector_simulator')
state = execute(qc, backend).result().get_statevector()
plot_bloch_multivector(state)

Pero aquí hay una pequeña trampa. Si hemos aplicado superposición, no debería de estar en un estado indeterminado… si, pero al medir, colapsa por el principio de decoherencia. Veamos el mismo código sin la barrera y la medida 🙂
qc = QuantumCircuit(1)
qc.x(0)
qc.h(0)
backend = Aer.get_backend('statevector_simulator')
state = execute(qc, backend).result().get_statevector()
plot_bloch_multivector(state)
En esta situación, el valor del qubit aun no ha colapsado y lo tenemos en el estado|-> , que no es ni 0 ni 1. Como el gato, hasta que abramos la caja (midamos) no sabremos como está.

Y creo que hasta aquí. Siento mucho las posibles faltas de concepto, y lo vago de las explicaciones, no pretende ser súper estricto, simplemente un pequeño aporte, para perder el miedo las maravillas y complejidades de la programación Q.
El siguiente se lo dedicaré más en profundidad a las puertas y a resolver problema reales sencillos. Sobre mecánica y filosofía cuántica vamos a tener tiempo de hablar.
… sobre como fue cogiendo forma todo, es bueno echar la vista atrás, a los Congresos de Solvay. No es magia, es ciencia.