Introducción a la Computación Cuántica con Qiskit (Parte 1)
Aquí comienza una serie de artículos en los que se pretende hacer un recorrido por los principios básicos de la Computación Cuántica, algo que abrirá un mundo de posibilidades y logrará resolver problemas asociados con Big Data, Machine learning e Inteligencia Artificial que con la computación tradicional no es posible resolver. Y como la mejor forma de aprender es hacerlo de forma práctica, vamos a acercarnos a este paradigma empleando Qiskit, el framework que ofrece IBM para desarrollar algoritmos que se aprovechen de las particularidades que ofrece la física cuántica aplicada a la computación.Comencemos por la pregunta más obvia.¿Cuál es la principal diferencia entre la Computación Clásica y la Computación Cuántica?Para abordar esa pregunta vamos a comenzar viendo cómo se almacena la información y cómo se tratan las distribuciones de probabilidad en Computación Clásica para en un siguiente artículo confrontarlo con la forma de trabajar en Computación Cuántica.
Distribuciones de Probabilidad en Computación Clásica
Un primer aspecto diferenciador es cómo se representa la unidad mínima de información. En Computación Clásica, la que se emplea para la arquitectura y el software presente en los servidores, ordenadores de sobremesa, portátiles, dispositivos móviles, el procesamiento de información se realiza manipulando bits. De esta forma, un bit es un fragmento de información que puede tomar o bien el valor 1 o el valor 0, pero solo uno de esos dos valores.Dentro de este enfoque, vamos a tratar el tema de distribuciones de probabilidad clásica poniendo el ejemplo del lanzamiento de una moneda que está sesgada. De manera que vamos a representar el resultado de dicho lanzamiento mediante una variable aleatoria X que tomará el valor “0” cuando salga “cara” y el valor “1” cuando se obtenga “cruz”.Formalmente, por cada lanzamiento de moneda se puede decir que se obtendrá “cara” con una probabilidad P(X=0) = p0 y “cruz” con P(X=1) = p1 siendo pi >= 0 (es decir la probabilidad de obtener “cara” o de obtener “cruz” será siempre mayor o igual que 0) yDistribuciones de probabilidad
Vamos a extraer muestras de una distribución aleatoria binomial definida como:donde ‘N’ es el número de éxitos, ‘n’ es el número de intentos y ‘p’ es la probabilidad de éxito en cada intento.En el siguiente ejemplo el número de intentos será 1 y la probabilidad de éxito (prob_1) será 0.2:A continuación, podemos comprobar como la suma de las observaciones de 1’s y de 0’s suman 1:Representaciones visuales
Si queremos representar visualmente p0 y p1 veremos que estarán restringidos al cuadrante positivo. Esto es porque deben ser mayores o iguales que 0 debido al requisito de normalización. En el siguiente gráfico podemos comprobar cómo todas las distribuciones de probabilidad del lanzamiento de monedas sesgadas y no segadas caen dentro de la siguiente línea recta del cuadrante positivo:Una forma de representar probabilidades es en forma de vector columnar:De esta forma, ponemos una flecha encima del nombre de la variable ‘p’ para diferenciarlo de un escalar. En este caso tenemos un vector representando a una distribución de probabilidad y, cuando esto ocurre, recibe el nombre de vector estocástico.El requisito de normalización indica que la norma del vector está restringida a 1 en la norma l1, lo que se puede expresar como:Pero además, como p1 >= 0 estaremos restringidos al cuadrante positivo del círculo unitario. Esto se puede comprobar calculando la norma l1 del vector ‘p’ donde prob_0 = 0.8 y prob_1 = 0.2.El primer elemento del vector ‘p’ se corresponderá con la probabilidad de obtener cara (prob_0) y el segundo con la probabilidad de obtener cruz (prob_1). Si quisiéramos extraer, por ejemplo, prob_0 podríamos proyectar el vector ‘p’ sobre el primer eje. Esa proyección se corresponde con la matriz de transformaciónSi calculamos la longitud de la norma l1 del resultado de aplicar la matriz M_0 al vector ‘p’ obtendremos la probabilidad prob_0.Para obtener la probabilidad de obtener cruz tendríamos que proyectar el vector ‘p’ sobre el segundo eje de la siguiente forma:Esto nos lleva a la cuestión de cómo transformar una distribución de probabilidad en otra, por ejemplo, para cambiar el sesgo de una moneda.Transformación de una distribución de probabilidad en otra
Hemos visto que una distribución de probabilidad se puede representar como un vector estocástico y, para modificarlo, podemos multiplicar una matriz de transformación sobre dicho vector siempre que esa matriz cumpla unos requisitos:- Cada una de sus columnas debe sumar 1 (la suma de todas las probabilidades debe ser 1).
- Además debemos multiplicar esa matriz por la izquierda del vector.
Entropía
Para terminar este primer artículo, vamos a introducir el concepto de Entropía como medida de desorden o en nuestro caso, de falta de predictibilidad cuya definición formal será: En el siguiente gráfico comprobaremos cómo la Entropía será máxima en el caso de una moneda no sesgada, que se corresponde con una distribución uniforme: En siguientes artículos comenzaremos a movernos por el apasionante mundo de la Computación Cuántica haciendo paralelismos con los conceptos que acabamos de ver. ¡No te los pierdas!Introducción a la Computación Cuántica con Qiskit (Parte 2)
En el primer artículo de esta serie sobre Computación Cuántica se expuso cómo la unidad fundamental de información en sistemas de Computación Clásica era el bit y cómo se tratan las distribuciones de probabilidad en ese paradigma. El objetivo de esta nueva entrega es el de ampliar nuestra perspectiva a la hora de abordar la modelización de problemas. Comencemos.Qubits
La Computación Cuántica emplea, como se comentó anteriormente, principios presentes en física cuántica como los fenómenos de superposición y entrelazamiento, entre otros, para llevar a cabo cálculos de una forma más eficiente que con la computación tradicional. Esto lo consigue empleando como unidad de información el qubit, que es un sistema de mecánica cuántica de 2 estados pero que, cuando es observado y medido, puede tomar cualquier posible combinación de esos 2 valores.En el artículo inicial se presentó el ejemplo del lanzamiento de una moneda como un caso que podía modelizarse como una distribución de probabilidad en Computación Clásica y se representaba como un vector columnar.Primera aproximación al estado cuántico
Como primera aproximación, podemos acercarnos al concepto de estado cuántico también como una distribución de probabilidad representada a través de un vector columnar. Para identificarlo y distinguirlo del vector de Computación Clásica se empleará el denominado ket de la notación Dirac. Siguiendo esta nomenclatura, el ket que representa el estado de un qubit se escribirá de la siguiente forma:Donde a0, a1 ∈ ℂ y se denominan amplitudes de probabilidad de forma que cada amplitud estará asociada a un estado cuántico. La diferencia con el modelo clásico es que ahora el requisito de normalización es en la norma l2 en vez de en l1. Formalmente esto se traduce en que la raíz cuadrada de la suma de los cuadrados de los valores absolutos de las amplitudes será igual a 1:Profundizando en la representación del estado cuántico
Profundizando en cómo representar un estado cuántico, hay que decir que se emplean como vectores de base canónica en 2 dimensiones los kets 0 y 1 cuya notación Dirac será la siguiente:Combinando lo que hemos visto sobre cómo representar el estado de un qubit con la notación de la base canónica en computación cuántica, podemos describir el estado de dicho qubit empleando esa base canónica de la siguiente forma:La expansión del estado del qubit (|) en una base nos lleva a unos de los fenómenos más importantes en mecánica cuántica, la Superposición. Si observamos una muestra de esa distribución de probabilidad que representa el qubit y la medimos, obtendremos la salida ‘0’ con una probabilidad igual al cuadrado del valor absoluto de la amplitud que acompaña a la base canónica ket 0, es decir, |a0|2 y que obtendremos un ‘1’ con probabilidad |a1|2 (el cuadrado del valor absoluto de amplitud que acompaña al ket 1). Esta regla que nos permite calcular la probabilidad con la que se obtendrá cada uno de los estados cuánticos recibe el nombre de regla de Born.Circuitos Cuánticos con Qiskit
Como la idea es ir viendo cómo implementar estos conceptos de teoría empleando el framework Qiskit de python, vamos a comenzar simulando el ejemplo del lanzamiento de una moneda totalmente sesgada donde se obtendrá “cara” en el 100% de los lanzamientos, por lo que el ket La librería ‘BasicAer’ proporciona un framework de simulación para la pila de software de Qiskit. En concreto, mediante su método ‘get_backed’ permite definir el entorno de ejecución que podrá ser o bien un simulador o un procesador cuántico real. En este caso, se está indicando que se utilizará el simulador ‘qasm_simulator’, por lo que la ejecución no se realizará en un entorno cuántico auténtico pero tratará de imitarlo. También devolverá un diccionario con el contador de las medidas realizadas que estarán almacenadas en registros clásicos del circuito cuántico.En la variable ‘qr’ se almacenará la referencia a un registro cuántico que permitirá almacenar un qubit. Mientras que la variable ‘cr’ se empleará para manejar un registro clásico que contendrá un bit. Por último, en la variable ‘circuit’ se define un circuito cuántico que inicialmente dispondrá del registro cuántico ‘qr’ y del registro clásico ‘cr’.Hay que decir que cualquier qubit estará siempre inicializado por defecto en el ket 0, por lo que, si lo medimos, obtendremos el resultado deseado de una moneda totalmente sesgada que devuelva siempre ‘cara’. Para realizar esa medición emplearemos el método ‘measure’ del circuito cuántico que hemos definido en la variable ‘circuit’:El método ‘measure’ recibirá el qubit que hemos almacenado en el registro cuántico ‘qr’, y cuando sea ejecutado el circuito, realizará una medición mediante la observación del estado cuántico lo que provocará que dicho estado colapse y se obtenga un valor concreto que será almacenado en el registro clásico definido en la variable ‘cr’.El siguiente paso
Una vez que se ha añadido esa operación de medición al circuito procederemos a ejecutarlo 50 veces (parámetro shots=50) mediante la librería ‘execute’ de Qiskit almacenado la referencia a esa llamada en la variable ‘job’. Dicho método ‘execute’ recibirá el circuito a ejecutar y el backend de ejecución. Una vez hecho eso, se guardará en la variable ‘result’ la llamada al método ‘result’ del objeto ‘job’. Por último, como estamos empleando el ‘qasm_simulator’ dispondremos del método ‘get_counts’ para obtener un diccionario donde cada clave será un estado y su valor el número de ocurrencias del mismo durante los experimentos (shots). Podremos comprobar que las 50 veces que se repite la ejecución del circuito cuántico y se realiza su medición se obtiene siempre un ‘0’. Si estas ejecuciones se hubieran realizado en un procesador cuántico real podríamos encontrar que esos resultados no coincidirían exactamente con estas medidas debido entre otros factores al ruido.Conclusión
Acabamos de definir y ejecutar nuestro primer circuito cuántico para simular el problema del lanzamiento de una moneda sesgada. Y como probablemente os hayáis quedado con ganas de seguir jugando os emplazo al siguiente artículo de esta serie donde continuaremos profundizando en este apasionante campo.Introducción a la Computación Cuántica con Qiskit (Parte 3)
En el primer artículo de la serie vimos cómo aproximarnos a las distribuciones de probabilidad en la Computación Clásica que emplea bits como unidad básica de información. En el segundo, comenzamos a asomarnos de forma superficial a la Computación Cuántica introduciendo conceptos como qubit, base canónica, superposición, regla de Born y finalizamos viendo cómo implementar un circuito cuántico con Qiskit de python, que modelizaba el problema del lanzamiento de una moneda completamente sesgada que siempre devuelve ‘cara’ (que se corresponde con el valor de salida ‘0’).Utilizaremos ese código como punto de partida para los temas que vamos a tratar en esta ocasión:Esfera Bloch
Al realizar en el backend ‘qasm_simulator’ las 50 ejecuciones y posteriores medidas del circuito anterior formado por un qubit inicializado en el ket 0, se obtiene siempre la salida ‘0’ (cara de la moneda). Sería muy útil disponer de algún mecanismo de visualización para facilitar la comprensión de los pasos que vamos dando y aquí es donde entra en escena la Esfera Bloch. Se trata de una representación que permite proyectar un estado cuántico a una localización de la superficie de una esfera con unas características un tanto especiales.Habíamos visto que un qubit tiene 2 amplitudes de probabilidad (una correspondiente a cada base canónica). Como son números complejos (parte real y parte imaginaria) se necesitaría un espacio de 4 dimensiones. Pero, como los vectores están normalizados, esto elimina un grado de libertad, por lo que podríamos emplear una representación en 3 dimensiones, que como estaréis imaginando, será la Esfera Bloch.Peculiaridades de la esfera
Antes comentábamos que esta esfera tiene una serie de peculiaridades. Su polo norte se corresponde con el estado del ket |0> y su polo sur con el del ket |1>. Intuitivamente, esto podría extrañar, ya que en el eje Z se encuentran 2 vectores que son ortogonales. La potencia de este tipo de representación es que cualquier punto de la esfera se corresponderá con un estado cuántico. También podemos afirmar que cualquier estado cuántico puro, es decir, un estado cuántico representado por un ket (vector columnar) se podrá visualizar como un punto de la esfera. Además, podremos encontrar estados cuánticos mixtos (no descritos por un ket) que estarán representados dentro de la esfera.Visualización de la esfera
Ya es turno de volver a tocar un poco de código y ver cómo se visualiza esa Esfera Bloch. Para ello, en primer lugar vamos a emplear el backend ‘statevector_simulartor’ mediante llamada a BasicAer.get_backend(). A continuación, crearemos un circuito llamado ‘circuit’ formado por un registro cuántico (‘qr’) y por uno clásico (‘cr’). El objetivo es que el qubit almacenado en ‘qr’ se encuentre en el estado ket |0> (situación que ocurre por defecto) y visualizarlo en la Esfera Bloch. Hay que decir que para modificar el estado de los qubits emplearemos puertas cuánticas (matrices que transformarán los vectores columnares de los qubits). En este caso, no hay que realizar ninguna modificación al qubit pero aun así hay que añadir una operación llamada ‘iden’ al circuito que corresponde con la matriz identidad. Un punto a señalar es que por convenio en los registros cuánticos la posición menos significativa será la de más a la izquierda. Es decir, si se define un registro cuántico que contendrá 2 qubits:qr = QuantumRegister(2)
El qubit menos significativo, es decir qr[0], será el que esté más a la izquierda y el más significativo es de más a la derecha en la siguiente representación |00>.En el caso de los registros clásicos (en los que guardaremos los resultados de las mediciones de circuitos cuánticos) la posición menos significativa será la de más a la derecha como ocurre a la hora de representar bits.Volviendo a nuestro ejemplo, una vez añadida al circuito la operación ‘iden’ sobre el qubit se invocará al método ‘execute’ sobre el circuito indicando el backend almacenando el manejador de esa llamada en la variable ‘job’. Una vez hecho esto, se invocará al método ‘plot_bloch_multivector’ haciéndole llegar el resultado de ‘job.result().get_statevector(circuit)’.En la siguiente imagen puede verse el código completo y la visualización de la Esfera Bloch en la que aparece resaltada la flecha correspondiente al qubit en el estado del ket |0>.Superposición
Para entender el fenómeno de la Superposición vamos a seguir con el ejemplo del lanzamiento de una moneda pero ahora el objetivo es que no esté sesgada. Es decir, vamos a pasar del caso en que la moneda estaba completamente sesgada de forma que siempre se obtenía cara (ket |0>) a la situación de que en el 50% de los casos se obtenga cara y en el otro 50% se obtenga cruz que se corresponderá con el estado de superposicióndonde de los casos que según la regla de Born la salida se corresponderá con el ket |0> y el resto al ket |1>. Una forma de realizar esta transformación será empleando la Quantum Gate ‘ry’ que se corresponderá con una rotación de π/2 en el eje Y. Esa puerta se implementa mediante la matriz:En futuros artículos de esta serie veremos más tipos de puertas cuánticas y entre ellas la puerta Hadamard que nos permitirá llegar también a un estado de Superposición.Construyendo el circuito
A continuación, veremos el código para construir el circuito que parte de un qubit en el estado ket |0> , le aplica la puerta ‘ry’ para obtener una moneda no sesgada e invoca al método ‘plot_histogram’ sobre el resultado de 50 ejecuciones del circuito en el backend ‘qasm_simulator’ (almacenado en la variable ‘bk’) para poder obtener el conteo de veces en el que el lanzamiento de la moneda acaba en cada estado. Si queremos visualizar ese experimento en la Esfera Bloch el código sería el siguiente Como se puede comprobar se ha producido una rotación de 90º sobre el eje Y.En el siguiente artículo seguiremos jugando con puertas cuánticas e introduciremos conceptos como superposición e interferencia y cómo codificarlos empleando Qiskit. ¡No os lo perdáis!Introducción a la Computación Cuántica con Qiskit (Parte 4)
En el segundo artículo de esta serie se comentaba que las amplitudes de probabilidad son números complejos en contraposición con los números reales positivos que se emplean en Computación Clásica.Superposición y números complejos
Los números complejos tiene la forma de a + bi donde ‘a’ es la parte real y ‘bi’ es la parte imaginaria siendo ‘a’ y ‘b’ números reales positivos o negativos e ‘i’ se corresponde con el número imaginario de forma que:(ya que no tenemos números reales que después de elevarlos al cuadrado sigan siendo negativos, por lo que no podremos volver hacia atrás haciendo la raíz cuadrada).Los números complejos permiten representar coordenadas en un plano de manera que la parte real se asociará al eje X y la parte imaginaria con el eje Y. Por lo que:- sumar en la parte real supondrá movernos hacia la derecha
- restar en la parte real movernos hacia la izquierda
- sumar en la parte imaginaria nos permitirá desplazarnos hacia arriba y
- restar en la parte imaginaria supondrá movernos hacia abajo en el plano.
Suma / Resta de Números Complejos
(7 + 3i) + (3 – 5i) = (10 -2i)Multiplicación de Números Complejos
(7 + 3i) * (3 -5i) = 7 * 3 + 7 * (-5i) + 3i * 3 + 3i * (-5i) = 21 + (-35i) + 9i + (-15i2) = 21 -26i -15*(-1) = 36 – 26iLa razón por la que i2 simplifica a (-1) es porque División de Números Complejos
Para realizar la división de números complejos hay que introducir el concepto de conjugada de números complejos, que consiste en cambiar el signo a la parte imaginaria. Por ejemplo la conjugada del número complejo (a + bi) será (a – bi). Multiplicar un número complejo por su conjugada supone que los términos centrales se cancelan: (a + bi) * (a – bi) = a2 -abi + abi –(bi)2Para realizar la división de números complejos multiplicaremos al numerador y al denominador por la conjugada del denominador:(7 + 3i) / (3 – 5i) = ((7 + 3i) * (3 + 5i)) / ((3 – 5i) * (3 + 5i))Uso de números complejos
Para comprobar la utilidad de emplear números complejos vamos a realizar un circuito cuántico que aplique una rotación ‘ry’ de 90º pero ahora al ket |1>.Hemos visto que todo qubit comienza inicializado en el estado ket |0> por lo que tendremos que aplicar la puerta cuántica ‘x’ (que se correspondería con una puerta lógica NOT) sobre el qubit para que pase a estar en estado |1>. La puerta cuántica ‘x’ se corresponderá con la matriz: Una vez que el qubit se encuentre en el |1> aplicaremos la puerta ‘ry’ con un ángulo de 90º para realizar dicha rotación:En el tercer artículo de esta serie se aplicó la puerta ‘x’ sobre el qubit en el estado |0> y el resultado fue:Se puede comprobar que cuando se aplica la rotación ‘ry’ sobre el ket |1> el resultado es similar al anterior pero con signo opuesto, por lo que tendremos una amplitud de probabilidad negativa. El estado obtenido será:Uso de números complejos para representar amplitudes de probabilidad en estados cuánticos
La utilidad de disponer de números complejos para representar las amplitudes de probabilidad de los estados cuánticos se hace patente cuando se comprueba que el signo negativo del ket |0> anterior no puede observarse al realizar la medición de las estadísticas de la ejecución del circuito cuántico. Para obtener dichas estadísticas de las frecuencias de cada resultado se ha empleado el backend ‘qasm_simulator’:Se puede comprobar que prácticamente se han producido el mismo número de caras (‘0s’) que de cruces (‘1s’). La utilización de números complejos permite modelar un fenómeno de mecánica cuántica conocido como ‘interferencia’ según el cual las amplitudes de probabilidad puede interactuar unas veces constructiva y otras destructivamente. Una forma de comprobarlo es aplicar sobre un qubit en el estado |0> dos rotaciones ‘ry’ consecutivas de 90º. Al realizarlo obtendremos el ket |1> aunque durante el proceso hubo cierta superposición.El código para realizar este experimento en el que se realizarán 50 ejecuciones del circuito cuántico sobre el backend ‘qasm_simulator’ y se obtendrá el histograma de los resultados es el siguiente:En próximos artículos seguiremos avanzando tratando más propiedades presentes en mecánica cuántica como por ejemplo el ‘Entanglement’ y viendo cómo implementarlas empleando el framework Qiskit. ¡Os esperamos!Introducción a la Computación Cuántica con Qiskit (Parte 6)
En el quinto artículo de esta serie hicimos un repaso general de los conceptos más importantes desarrollados hasta ese momento, poniendo especial foco en cómo codificar 1 qubit. Eso nos llevó a plantearnos cómo se conseguiría llevar a cabo la representación de estados cuánticos compuestos por varios qubits. Eso, a su vez, abrió el camino para el tema en el que vamos a centrarnos en esta publicación: el fenómeno conocido como entanglement. Vamos a incorporar un concepto más a nuestra mochila. ¡Pero tranquilos que no será nada pesada!Entanglement
Vamos a comenzar de la misma forma que lo hicimos en el artículo anterior, recapitulando los puntos claves que se trataron en él. El primer tema que pudimos comprobar fue que la forma de construir estados cuánticos formados por varios qubits era mediante la operación del producto de tensores o producto Kronecker de los qubits individuales. Suponiendo que tenemos 2 qubits llamados |(|)> y |(|)‘>:El resultado de realizar el producto de tensores o producto Kronecker de esos 2 qubits será:
Si estamos trabajando con estados cuánticos compuestos por 2 qubits entonces tendremos los siguientes vectores de base canónica: |00>, |01>, |10> y |11> en un espacio de números complejos de 4 dimensiones
Espacios de alta dimensionalidad
También introdujimos en el artículo anterior la idea de que cuando construimos espacios de alta dimensionalidad empleando la operación del producto de tensores de los qubits individuales no todos los vectores de ese espacio resultante pueden ser obtenidos mediante el producto Kronecker de sus componentes.La mejor forma de entender algo es mediante ejemplos. Por ello, vamos a intentar demostrar ese concepto partiendo del siguiente estado de superposición de los kets |00> y |11>:
Como el vector resultante es una combinación lineal de 2 de los vectores canónicos (|00> y |11>) del espacio de los números complejos de 4 dimensiones, podemos decir que este vector pertenece a dicho espacio de . El problema es que esto no puede ser escrito como el producto Kronecker |(|)>⊕|(|)‘> para cualesquiera .
Para demostrarlo, vamos a escribir como un producto Kronecker de sus componentes el estado cuántico
Posteriormente, vamos a expandir el resultado sobre los vectores de base canónica de los complejos de 4 dimensiones:
Podemos ver que no aparecen los kets |01> ni |10> en esta parte de la expresión:
Por lo que llegamos a la conclusión de que a0b1=0 y a1b0=0. El problema es que eso lleva a una contradicción, ya que, como a1b1=1 de ahí extraemos que a1 no puede ser 0 por lo que deducimos que b0 debe ser 0. Pero eso tampoco puede ser posible debido a que como a0b0=1 entonces b0 no podría ser
https://www.datahack.es/introduccion-a-la-computacion-cuantica-con-qiskit-parte-1/
No hay comentarios:
Publicar un comentario