Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
Lenguajes de Programación Cuántico Brandon Prieto September 2018 Índice general 1. Introducción 2 2. Estado del Arte y Marco Teórico 4 2.1. Lenguaje de programación . . . . . . . . . . . . . . . . . . . . 4 2.2. IBM Experiencia Cuántica . . . . . . . . . . . . . . . . . . . . 4 2.2.1. Quantum Computer Information Software Kit . . . . . 5 2.3. Lenguaje de Programación Imperativo . . . . . . . . . . . . . 8 2.4. Quantum Computation Language (QCL) . . . . . . . . . . . . 8 2.5. Lenguaje Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.6. Programación Cuántica . . . . . . . . . . . . . . . . . . . . . . 9 2.6.1. Lenguaje Ensamblador Cuántico . . . . . . . . . . . . . 9 2.7. QRAM y Lenguaje Ensamblador Cuántico . . . . . . . . . . . 11 2.8. Comparación de QCL y Q . . . . . . . . . . . . . . . . . . . . 17 2.8.1. Deutsch en QCL . . . . . . . . . . . . . . . . . . . . . 17 2.8.2. Deutsch en Q . . . . . . . . . . . . . . . . . . . . . . . 18 3. Compilador Lenguaje Cuántico Ensamblador (Compilador LQE) 19 3.1. Compilador LQE . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.1. BNF . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.1.2. EBNF . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.1.3. JavaCC QuantumAssembly.jj . . . . . . . . . . . . . . 23 3.1.4. Algorimo de Deutsch LQE . . . . . . . . . . . . . . . . 24 4. Conclusiones 26 1 Caṕıtulo 1 Introducción Para hablar de lenguajes de programación debemos remontarnos aproxi- madamente al año 1800 donde Charles Baggage definió la máquina anaĺıtica, cuyo diseño se basaba en el telar de Joseph Marie Jacquard, el cual usaba tarjetas perforadas para realizar diseños en el tejido. Charles Babbage adaptó su diseño para conseguir calcular funciones anaĺıticas, con él trabajaba como colaboradora Ada Lovedby, la cual es considerada como la primera programa- dora de la historia, pues realizo programas para aquélla supuesta máquina de Babagge, en tarjetas perforadas, aunque como la máquina pudo construirse hasta después de un siglo. En 1943 apareció ENIAC (Electronic Numeri- cal Integrator And Calculator), su programación se basaba en el cambio de componentes f́ısicos, es decir, que se programaba, cambiando directamente el Hardware de la máquina, exactamente lo que sé hacia era cambiar cables de sitio para conseguir aśı la programación de la máquina. La entrada y salida de datos se realizaba mediante tarjetas perforadas. Un Lenguaje de Programación es un conjunto estructurado de reglas, notaciones, śımbolos y caracteres que permiten a un programador poder expresar el procesamiento de datos y sus resultados por medio del uso de computadores. Cada lenguaje posee una sintaxis propia, lo cual los hace muy diferentes entre si. Se usan para crear programas que contengan algorit- mos por los cuales, el programador puede comunicarse con la computadora y aśı controlar las acciones a realizar por está, existen varios tipos de para- digmas de programación, por ejemplo, imperativos, funcionales, declarativos, orientado a objetos. Donde se puede encontrar una gran variedad de lengua- jes mencionando algunos, Java, Python, C , C++, Pascal, Javascript, C#, PHP. 2 Hay lenguajes de programación de alto nivel y de bajo nivel, donde los de alto nivel permiten que se pueda escribir y leer de una forma más sencilla, ya que, son muy parecidos al lenguaje humano simplificando su entendimiento. Permiten expresarse en un nivel y estilo de escritura fácilmente legible y com- prensible por otros programadores, además no dependen del tipo de máquina. Y los de bajo nivel son lenguajes totalmente dependientes de la máquina, es decir que el programa que se realiza con este tipo de lenguajes no se pueden migrar o utilizar en otras maquinas. Acá se encuentra el lenguaje de máquina el usa operaciones fundamentales para su funcionamiento de la máquina, y el lenguaje ensamblador el cual es un derivado del lenguaje máquina y esta formado por abreviaturas de letras y números llamadas mnemotécnicos. Con la aparición de este lenguaje se crearon los programas traductores para poder pasar los programas escritos en lenguaje ensamblador a lenguaje máquina. La computación cuántica comenzó a surgir a partir del año 1980 donde se comenzó a proponer el uso de f́ısica cuántica para realizar cálculos compu- taciones, y David Deutsch describiera el primer computador cuántico, de aqúı se empezó la idea de generar algoritmos para este mismo, en 2017 IBM presentó el primer computador cuántico, el cuál puede ser usado por medio de la nube, el cual permite crear circuitos cuánticos a través del modelo de arrastrar y soltar compuertas cuánticas, para más información sobre está vea [1] caṕıtulo 5, o también a través de su lenguaje ensamblador OpenQASM [2], y para programadores más avanzados pueden realizar uso de uso API desarrollada en Python. En el siguiente documento se mostrará las funciones del lenguaje ensamblador cuántico, el modelo de computación QRAM, el cual usa el poder de una computadora clásica y el lenguaje ensamblador cuántico para añadir más potencia al momento de resolver problemas, y se tocarán las diferencias de dos lenguajes de programación cuánticos QCL [3] y Q [4]. 3 Caṕıtulo 2 Estado del Arte y Marco Teórico 2.1. Lenguaje de programación Un Lenguaje de Programación es un conjunto estructurado de reglas, notaciones, śımbolos y caracteres que permiten a un programador poder expresar el procesamiento de datos y sus resultados por medio del uso de computadores. Cada lenguaje posee una sintaxis propia, lo cual los hace muy diferentes entre si. Se usan para crear programas que contengan algoritmos por los cuales, el programador puede comunicarse con la computadora y aśı controlar las acciones a realizar por está. 2.2. IBM Experiencia Cuántica IBM Q Experience es una plataforma en ĺınea que brinda a los usuarios del público en general acceso a un conjunto de prototipos de procesadores cuánticos de IBM a través de la nube. Se puede decir que es computación cuántica basada en la nube. A partir de mayo de 2018, hay tres procesadores en la experiencia IBM Q: dos procesadores de 5 cúbits y un procesador de 16 cúbit. Este servicio se puede utilizar para ejecutar algoritmos y experimentos, y explorar tutoriales y simulaciones sobre lo que podŕıa ser posible con la computación cuántica. Se puede realizar construcción de circuitos cuánticos a tráves del Quan- tum Composer, el cuál es una herramienta de interfaz gráfica en la que puede 4 arrastrar y soltar diferentes operaciones para controlar cúbits. El Quantum Composer le permite desarrollar sus propios algoritmos cuánticos, que llama- mos puntuaciones cuánticas. También posee el Quantum Score, el cual es el conjunto de instrucciones, o algoritmo, para una computadora cuántica. Es una serie de puertas contra el tiempo jugadas en diferentes cúbits, muy parecido a una partitura musical. También se le llama un circuito cuántico. Los usuarios interactúan con un procesador cuántico a través del modelo de circuito cuántico de cálculo, aplicando puertas cuánticas en los qubits utilizando una GUI llamada el compositor cuántico, escribiendo código de lenguaje de ensamblador cuántico o mediante QISKit. 2.2.1. Quantum Computer Information Software Kit Quantum Computer Information Software Kit (QISkit) es el framework de código abierto para computación cuántica publicado por IBM bajo la li- cencia apache desarrollado en Python, está diseñado teniendo en cuenta la modularidad y la extensibilidad. basado en circuitos especificados a través del lenguaje intermediario OpenQASM, compila y ejecuta el SDK en varios backends por medio del procesador de 16 bits cuánticos o un simulador lo- cal y en ĺınea ambos desarrollados también por IBM. Para el backend de QISKIT en ĺınea, se usa como puente el API conector de a IBM Quantum Experience. QISKit permite a los desarrolladoresrealizar exploraciones en la Experiencia Quantum de IBM usando una interfaz Python. Esta interfaz le permite trabajar con circuitos cuánticos y ejecutar múltiples circuitos en un lote eficiente de experimentos. QISKit está compuesto de cuatro elementos fundamentales: QISKit Terra QISKit Aqua QISKit Ignis QISKit Aer QISKit Terra: Es la base sobre la que se basa el resto del software. Terra proporciona una base para la composición de programas cuánticos a nivel de circuitos y pulsos, para optimizarlos en base a las restricciones de un dispositivo en particular, y para administrar la ejecución de lotes de experi- mentos en dispositivos de acceso remoto. Terra define las interfaces para una 5 experiencia deseable para el usuario final, aśı como el manejo eficiente de las capas de optimización, programación de pulsos y comunicación backend. QISKit Aqua: Aqua, es el elemento de la vida. Para hacer que la compu- tación cuántica esté a la altura de sus expectativas, necesitamos encontrar aplicaciones del mundo real. Aqua es donde los algoritmos para NISQ son realizados. Estos algoritmos se pueden utilizar para crear aplicaciones para la computación cuántica. Aqua es accesible para expertos en dominios de qúımica, optimización o inteligencia artificial, donde van a poder explorar los beneficios de usar computadoras cuánticas como aceleradores para tareas computacionales espećıficas, sin tener que preocuparse de cómo traducir el problema al lenguaje de las máquinas cuánticas. Nota: Noisy Intermediate-Scale Quantum (NISQ) es un termino introdu- cido por John Preskil donde dice, ”las computadoras cuánticas puede realizar tareas que superan las capacidades de las computadoras digitales clásicas de hoy, pero el ruido en las puertas cuánticas limitará el tamaño de los circuitos cuánticos que pueden ejecutarse de manera confiable”. Para más información vea [7]. QISKit Ignis: Ignis, está dedicado a combatir el ruido y los errores. Mejora la caracterización de errores, de las compuertas, y la computación en presencia de ruido. Ignis está destinado a aquellos que desean diseñar códigos de corrección de errores cuánticos, o que deseen estudiar formas de caracterizar errores a través de métodos como la tomograf́ıa, o incluso en- contrar una mejor manera de usar las compuertas lógicas cuánticas mediante la exploración del desacoplamiento dinámico y el control óptimo. QISKit Aer: Aer, impregna todos los elementos de Qiskit. Para acelerar realmente el desarrollo de las computadoras cuánticas necesitamos mejores simuladores, emuladores y depuradores. Aer ayuda a comprender los ĺımites de los procesadores clásicos al demostrar en qué medida pueden imitar el cálculo cuántico. Además, Aer se puede usar para verificar que las compu- tadoras cuánticas actuales y futuras funcionen correctamente. Esto se puede hacer estirando los ĺımites de la simulación para acomodar más de 50 bits cuánticos con una profundidad razonablemente alta, y simulando los efectos del ruido realista en el cálculo. En resumen, QISKit Terra es la base del código, para componer progra- mas cuánticos a nivel de circuitos y pulsos, Aqua esta para algoritmos y apli- caciones de construcción, Ignis para tratar el ruido y los errores y Aer sirve 6 para acelerar el desarrollo a través de simuladores, emuladores y depuradores. 2.2.1.1. Open Quantum Assembly Languague QISKit OpenQASM o ”Quantum Assembly Languague.es uno de los pro- yectos de código abierto que componen QISKit, básicamente un lenguaje ensamblador cuántico el cual permite hacer la representación de circuitos cuánticas simples. Además dispone de un articulo públicado en enero del 2017 donde se especifica el lenguaje, y un repositorio en github. Para más información de uso de OpenQASM revise [8]. Ejemplo 2.1.1.1.1 Algoritmo de Deutsch para f(x) = x en OpenQASM para dos bits cuánticos. ... include "qelib1.inc"; qreg q[2]; creg c[2]; x q[1]; h q[0]; h q[1]; cx q[0],q[1]; h q[0]; measure q[0] ->c[0]; ... 2.2.1.2. Software Developer’s Kit El Software Developer’s Kit o SDK proporciona soporte para la fase de generación de circuitos de en IBM Quantum Experience y utiliza la API de QISKit para acceder al hardware y simuladores de IBM Quantum Experience. 2.2.1.3. QISKit API Es un wrapper de Python alrededor de la API HTTP de Quantum Ex- perience que le permite conectarse y ejecutar el código OpenQASM. Los 7 desarrolladores pueden interactuar directamente con el experimento y los si- muladores de Quantum Experience. La API utiliza OpenQASM, que admite un conjunto de herramientas de circuitos cuánticos, lo que abre más capaci- dades para el hardware cuántico subyacente en las versiones posteriores 2.3. Lenguaje de Programación Imperativo Los lenguajes de programación imperativos pueden ser definidos como un conjunto de instrucciones, por los cuales el programador puede indicar a la computadora la manera en que este mismo desea que resuelva un problema, las instrucciones definidas se ejecutan de manera secuencial, es decir, una a una, existen varios tipos de lenguajes, por ejempo, Java, Python, C, C++. 2.4. Quantum Computation Language (QCL) QCL fue el primer lenguaje de cuántico de programación. Creado por Bernhard Ömer, quien queŕıa que este fuera parecido a C y Pascal. QCL contiene todas las caracteŕısticas de un lenguaje de programación clásico tales como, variables, ciclos, condicionales, lo cual va a facilitar la transición de los lenguajes de programación clásicos a los lenguajes de programación cuánticos. También cuenta con soporte para funciones ya construidas, algunas de estas son cos, sin, print. También cuenta con todos los operadores aritméticos conocidos. Para toda la explicación se supone que el lector ya tiene conocimientos de C, ya que tienen una sintaxis parecida y facilitará la tarea de entender el código. Para más información vea [3] 2.5. Lenguaje Q Este lenguaje puede expresar de forma compacta los algoritmos cuánti- cos existentes y reducirlos a secuencias de operaciones elementales; También se presta fácilmente a sistemas automáticos, independientes de hardware, simplificación del circuito. Para más información vea [4] 8 2.6. Programación Cuántica Programar un computador significa hacer que la computadora lleve acabo ciertas acciones en un lenguaje espećıfico, ya sea directamente o través de un interprete intermediario. La manera básica de como manejar datos esta representada de la siguiente manera, con una entrada de datos y un control. DATOS + CONTROL = PROGRAMACIÓN Control significa que el programa está construido por un conjunto de ins- trucciones básicas y un conjunto de estructuras tales como condicionales, ciclos, saltos. Todo esto se transpone al mundo cuántico, primero se debe suponer que la computadora consiste de un dispositivo cuántico, con una en- trada de datos cuántica, la cual es representada por un conjunto direccionable de cúbits, junto a un conjunto de operaciones ya construido que permiten la manipulación de datos, operaciones que son de dos tipos: 1. Unitarias las cuales evolucionaran los datos cuánticos. 2. Medición las cuales inspeccionaran el valor de los datos. También se asumirá que se pueden ensamblar más operaciones fuera de las básicas. Esto se representará de la siguiente manera: DATOS CUÁNTICOS + CONTROL = PROGRAMACIÓN CUÁNTICA Sabiendo esto ahora nos podemos enfocar en abordar uno de los temas más importarte para los lenguajes de programación cuánticos, el lenguaje emsablador cuántico, en donde la programación cuántica se realizará a bajo nivel. 2.6.1. Lenguaje Ensamblador Cuántico Hoy un d́ıa existen múltiples lenguajes de programación para las compu- tadoras clásicas, donde los desarrolladores no tienen preocupación alguna sobre la arquitectura sobre la máquina en la que están trabajando, aqúı el compilador se ocupa de todo el trabajo, pero alguien tuvoque preocuparse de esto en algún momento por como construir estos interpretes, hace unas décadas el lenguaje ensamblador era el único lenguaje existente. Ahora no nos preocuparemos por esto ya que se espera que un programador en cuántica 9 tenga una gran experiencia, aśı como el programador de hoy en d́ıa no tiene un amplio conocimiento sobre hardware. Para especificar los algoritmos cuánticos existentes se necesita al menos un ensamblador cuántico. Aunque no se necesita conocer espećıficamente el hardware cuántico por el cual la computadora esta compuesta, pero si se necesita saber cual es su tipo de arquitectura. Existen tres tipos diferentes de modelos de computación cuántica que pueden ser equivalentes entre si. Modelo de circuitos cuánticos. Máquina de Turing cuántica. Modelo de memoria cuántica de acceso aleatorio (Modelo QRAM). Estos modelos serán explicados a continuación en el orden en el que han sido nombrados anteriormente. Empezando por el modelo de circuitos cuánti- cos, el cuál es un circuito que opera con bits cuánticos haciendo uso de compuertas lógicas cuánticas, las cuales son representadas mediante matri- ces unitarias. Este modelo requiere tres elementos que son necesario para su funcionamiento. Un dispositivo de entrada el cual recibirá datos cuánticos. Un conjunto básico de compuertas, que pueden usarse paralelamente y secuencialmente. Un dispositivo el cual permite realizar mediciones. Normalmente en el mundo clásico el programador revisa ver las variables en cualquier lugar durante la computación, pero en la parte cuántica las me- diciones se realizan al final por lo cual puede resultar extraño. El segundo modelo es la máquina de Turing cuántica, este es una analoǵıa de la máquina de Turing clásica, este modelo es ideal para tratar problemas de complejidad de clases, pero no cuando se trata de diseño de algoritmos o de lenguajes de programación. Este modelo consta de tres elementos. Una cinta de memoria infinita en donde cada elemento es un cúbit. Un procesador finito. Un cabezal. 10 Cada conjunto de instrucciones se aplica sobre el elemento de la cinta señala- do por el cabezal. El resultado va a depender del cúbit en la cinta y el estado en cual este el procesador en el momento de medición. El tercer modelo es el más conveniente para nosotros, es conocido como el modelo QRAM (Modelo de memoria cuántica de acceso aleatorio), este modelo esta compuesto de dos partes. Un computador clásico que juega el rol de maestro. Un dispositivo cuántico, que pueda ser accedido por el maestro en el momento que lo requiera. 2.7. QRAM y Lenguaje Ensamblador Cuánti- co El objetivo del modelo QRAM, es que cualquier programador pueda es- cribir código clásico en cualquier lenguaje, por ejemplo, Python, y cuando requiere de poder adicional de la máquina para lograr resolver un problema, sea capaz de añadir algunas lineas de código ensamblador cuántico. El ensam- blador cuántico va a ser el puente para poder acceder y hacer uso de nuestro dispositivo cuántico. Por cierto, como ya pudo haber notado el programa- dor no requiere tener conocimiento alguno sobre la composición interna del dispositivo cuántico, y además, tampoco necesita saber la manera de como almacenan, inicializan o se miden los bits cuánticos. Solo debeŕıa preocuparse por cosas como la capacidad de almacenamiento, el tamaño de la memoria cuántica. Todo lo demás va a pasar a través de la Interfaz de Hardware Cuántico, la cuál va a encargarse de traducir los comandos de ensamblador cuántico introducidos en acciones explicitas que va realizar el dispositivo 2 cuántico. Resumiendo el modelo QRAM puede explotar recursos cuánticos y, al mismo tiempo, pueden ser utilizados. Para realizar cualquier tipo de compu- tación clásica. Nos permite controlar las operaciones realizadas en registros cuánticos. y proporciona el conjunto de instrucciones para su definición. 11 Figura 2.1: Representación básica del modelo QRAM. Observado la Figura 2.1 Tenemos dos dispositivos el primero es una computadora clásica, dentro de la computadora maestra, el registro de control se utilizará para almacenar la instrucción en lenguaje ensamblador cuántico, note que las propias instrucciones son codificables como secuencias de bits. Cuando el puntero de control se encuentra en una u otra de las instrucciones cuánticas, el maestro utilizará la interfaz de hardware cuántica para enviarla al dispositivo cuántico. En el segundo dispositivo hay dos cosas: un conjunto de registros de almacenamiento de datos cuánticos y las utilidades que apli- can operaciones en el almacenamiento. Lo primero que hará el programador es pedirle al dispositivo cuántico a través de la interfaz de hardware cuántica que inicie una secuencia direccionable de bits cuánticos. Estas transaccio- nes se realizan a través de una interfaz conocida como el registro cuántico o registro-q. Ya que la anterior explicación puede no haber sido lo suficientemente clara vamos a definir un registro cuántico. Un registro cuántico es una interfaz para una secuencia direccionable de bits cuánticos. Cada registro q tiene un identificador único por el cual es referido. En el teorema de no clonación: El teorema de no clonación evitará que el ensamblador cuántico tenga instrucciones de copia. No hay forma de copiar el contenido de un registro a otro, una operación familiar y generalizada en los ensambladores ordinarios. Por ahora vamos a pensar en un registro cuántico como un arreglo ad- yacente de cúbits. Tampoco es necesario preocuparse por donde o como se almacenan los bits cuánticos. Después de que un registro cuántico ha sido inicializado y manipulado por el programador, esté puede emitir un coman- do que medirá las partes seleccionadas del mismo. El dispositivo cuántico va a realizar la medición solicitada y devolverá un valor clásico que se puede mostrar y almacenar en algún lugar del programa principal. En este modelo, la medición se intercala con otros comandos: el programador puede solicitar en cualquier momento después de la inicialización el valor de una sección 12 arbitraria del registro. Todo esto puede verse en la Figura 2.2 Figura 2.2: Control Cuántico. Ahora vamos usar el lenguaje básico basado en lenguaje ensamblador propuesto por [1] el cual no es un estándar, pero nos va a permitir mostrar de manera sencilla como son las instrucciones del lenguaje ensamblador, dado que un lenguaje ensamblador que tenga propósitos de uso en la vida real puede ser más complejo revise [13]. Los identificadores de los registros cuánticos se van a nombrar R1,R2,. . . ,Rn. También supondremos, para una mejor comodidad, que todos los registros son de tamaño 8, es decir, pueden almacenar el análogo cuántico de un byte, un qubyte. El prefijo R representará el código de un registro q no especifica- do. Dicho lo anterior comencemos a enumerar las instrucciones del lenguaje ensamblador propuesto. La arquitectura QRAM permite que el programa de llamada transfiera cada instrucción individual al procesador cuántico de una en una. Ya hablamos de como identificar los registros cuánticos, pero ahora necesitamos una forma de inicializarlos. Más espećıficamente, necesi- tamos pasar una matriz de bits del programa principal a un registro q dado, y pedirle al dispositivo cuántico que lo inicie. Inicializar el registro R INITIALIZE R [INPUT] El [INPUT] opcional es un arreglo clásico de bits, cuyo tamaño coincide con el tamaño de la registro, que como hab́ıamos dicho antes es de un byte. Además si no se especifica, se va supone que se rellena automáticamente con ceros. Ejemplo 2.6.1 El siguiente ejemplo inicializa un registro R1 de ocho bits cuánticos, el cual que daŕıa inicializado aśı [00000000], pero entonces se 13 vuelve a inicializar usando como entrada el arreglo de bits G = [11011011]. ... var G = [11011011] ... INITIALIZE R1 INITIALIZER1 B ... Como se suposición se tendrá que la inicialización env́ıa todos los bits cuánticos a su estado fundamental |0〉. Es decir, si inicializamos un registro cuántico de tamaño 5, el estado conjunto es |00000〉. Si, por otro lado, pro- porcionamos un INPUT tal como [00101], el sistema se encargará de inicializar nuestro registro a |00101〉. Una vez que tenemos un registro inicializado, podemos acceder a sus cúbits individuales para la manipulación. Por ejemplo, R [0] indicará su pri- mer cúbit, y aśı sucesivamente. Ahora se expandirá el ensamblador con la capacidad de seleccionar una variable de subregistro, se denotará con la letra s del prefijo S. Seleccionar del subregistro R compuesto por un número qubits NUM- QUBIT a partir de R[OFFSET]. Almacenando la dirección en la varia- ble S. SELECT S R OFFSET NUMQUBIT Ejemplo 2.6.2 Se inicializa un registro cuántico R1, y se extrae un su- bregistro formado por los ı́ndices 2 y 3 representados por la variable S. ... INITIALIZE R1 SELECT S R1 2 3 ... Ejemplo 2.6.3 Se inicializa un registro cuántico R1, y se extrae un su- bregistro formado por los ı́ndices 2 y 4 representados por la variable S1, y luego se extraen los ı́ndices 0 y 2 representados por la variable S2. ... INITIALIZE R1 [01110001] SELECT S1 R1 2 4 SELECT S2 S1 0 2 14 ... ¿Cuáles cúbits de R1 seleccionamos en S2? Para responder está pregunta revisemos las instrucciones paso a paso. Primero inicializamos el registro R1 con [01110001]. Luego seleccionamos los ı́ndices 2 y 4, es decir, los cúbits 1 y 0, respectivamente, para que se entien- da mejor ya que nuestro arreglo está compuesto de 0’s y 1’s seleccionamos [00110001], ahora tenemos en S1 el registro cuántico [10000000], para esto estamos suponiendo que los demás números del registro se rellenan con 0’s. Ahora almacenamos en S2 los ı́ndices 0 y 2, es decir, 1 y 0, [1000000], note que al final solo permanecerá 1 del registro R1 ya que los 0’s son diferentes, aśı que no se confunda. Ahora volvemos a las compuertas cuánticas las cuales ya se hab́ıan nom- brado anteriormente. GATES = [G0, G1, . . . , Gn] Se pueden realizar diferentes elecciones de compuertas cuánticas básicas, siempre que el conjunto GATES sea un conjunto universal de compuer- tas, es decir, genere todas las transformaciones unitarias de dimensión finita mediante aplicaciones sucesivas de composición y producto tensor. En la práctica. Algunos ejemplos de compuertas cuánticas que se podŕıan usar del conjunto. GATES = [H,Rθ, In, CNOT ] donde H,Rθ, In y CNOT denotan el Hadamard, el cambio de fase en un ángulo θ,la matriz de identidad n × n, y la compuerta NOT controlado, respectivamente. La instrucción básica para aplicar una compuerta se ve de la siguiente forma. APPLY U R Donde U es la compuerta a aplicar y R el registro cuántico. Ejemplo 2.6.4 Se inicializa un registro cuántico R1, y se aplica la com- puerta de Hadamard. ... 15 INITIALIZE R1 APPLY H R1 ... También tenemos instrucciones para realizar concatenación, producto tensor e inversa. La operación de composición, que se ejecuta secuencialmente de dere- cha a izquierda dos transformaciones unitarias U1 y U2, y guarda el resultado en una variable U . U CONCAT U1 U2 U es el resultado de realizar producto tensor de U1 y U2. U TENSOR U1 U2 El inverso: U es el resultado de tomar el inverso de U1, es decir, la transformación que ”deshace”U1. U INVERSE U1 Hasta aqúı hemos hablado de varias instrucciones pero como se supone que vamos obtener nuestra respuesta, para esto vamos a usar la instrucción de medición. Medición del registro R1 y guardado del resultado en la variable clásica RES. MEASURE R RE Hasta ahora, no se ha hablado de estructuras de control, como los saltos, condicionales. La razón es que son prescindibles. Si el programador desea implementar un if - then - else, entonces podŕıa emitir una declaración de medición, recuperar una matriz de bits y usar una estructura condicional clásica (if, while, case). Y podŕıa escribir un comando aśı por ejemplo: IF(RES==[01]) THEN APPLY H R ELSE TENSOR H R WHILE(ANS<=[01]) APPLY H R El lenguaje propuesto hasta el momento, está compuesto por nada más que cadenas binarias, pero es de utilidad para expresar algunos algoritmos 16 cuánticos. Ejemplo 2.6.5 Algoritmo de Deutsch para f(x) = x. ... INITIALIZE R1 [01000000] SELECT S1 R1 0 SELECT S2 R1 1 TENSOR S S1 S2 APPLY H S APPLY CNOT S APPLY H S MEASURE S ANS ... 2.8. Comparación de QCL y Q Para realizar la comparación de ambos lenguajes se va a mostrar la im- plementación del algoritmo de Deutsch para f(x) = x, el cual es sencillo pero nos va a permitir ver la esencia de ambos lenguajes. Para más información sobre el algoritmo de Deutsch ver [1] caṕıtulo 6. 2.8.1. Deutsch en QCL operator Uf(qureg x,qureg y){ //Para f(x) no hay necesidad de un uf } procedure deutsch() { qureg registro1[1]; qureg registro2[1]; int m; CNot(registro2); H(registro1); H(registro2); Uf(registro1,registro2); H(registro1); 17 measure registro1,m; } 2.8.2. Deutsch en Q Qop Uf(qureg x,qureg y){ //Para f(x) no hay necesidad de un uf } int Deutsch() { Qreg registro1(1,0); Qreg registro2(1,1); Qop h1 = QHadamard(registro1); Qop h2 = QHadamard(registro2); Uf(registro1, registro2); h1.QHadarmard(); int m = h1.measure(); return m; } En QCL las operaciones unitarias son funciones (qufunct u operator) y en Q son objetos, por lo que en QCL su manipulación está sujeta a la sintaxis de la función llamada; por lo tanto, la simplificación son más complicadas de implementar, en Q esto se facilita por el mismo hecho de que son objetos. Aunque en ambos lenguajes los registros cuánticos se manejan de manera parecida, en QCL además del qureg, existen otros dos tipos de registro, qu- void y quscratch, que, para una correcta verificación de tipos, requieren el conocimiento del estado del dispositivo cuántico. Su sintaxis puede ser dife- rir ya que QCL esta basado en C y Q en C++. Y por ultimo Q está más enfocado en el paradigma orientado a objetos, por lo cual al hacer el uso de compuertas cuánticas las funciones propuestas van a ser diferentes. 18 Caṕıtulo 3 Compilador Lenguaje Cuántico Ensamblador (Compilador LQE) 3.1. Compilador LQE Este compilador ha sido construido usando javacc y está basado en el lenguaje propuesto en [1], haciendo uso de la clase QuantumAssembly.jj la cual contiene los tokens básicos del ensamblador. Si se realizan cambios a este archivo se deberan ejecutar los siguientes comandos. $javacc QuantumAssembly.jj $javac *.java $java QuantumAssembly 〈 codigoEnsamblador.txt No se debe preocupara por la primera y la segunda linea, estas solo generar error, si no se maneja la sintaxis de javacc y de java. La tercera linea generara el código apartir del lenguaje ensamblador del archivo txt en java creado un nuevo archivo Main.java INITIALIZE registerName [qubitNumber] SELECT varName registerName indexMin:indexMax TENSOR tensorAnswer register1 register2 APPLY GATE registerName 19 INVERSE varAnswerName registerName CONCAT varAnswerName register1 register2 MEASURE registerName varAnswer Se tienen matrices predeterminadas de Hadarmard, Not Controlado, Iden- tidad. Hada -〉 Hadamard Iden -〉 Identidad Cnot -〉 Not Controlado 3.1.0.1. Initialize Permite inicializar un registro de bits cuánticos de la siguiente manera, donde el usuario deberá tomar cada el registro como un arreglo para mayor comodidad, por debajo se crearán ArrayList¡ComplexNumber[]¿para alma- cenar los cúbits. INITIALIZE myQubitRegister [0010101] Donde cada número en el arreglos representa un bit cuántico y estado, por tal si solo requiere usar un cúbit, por ejemplo, debeŕıa hacer esto. INITIALIZE myQubitRegister [1] 3.1.0.2. Select Permite inicializar un registro tomando los bits cuánticos de un registro creado con anterioridad, seleccionando los ı́ndices en los que desea sacar el subregistro, tenga en cuentaque primero va el ı́ndice menor y luego el mayor, y van separados por ”:”para mayor comodidad y no crear confunciones, por debajo se crearán ArrayList〈ComplexNumber[]〉 para almacenar los cúbits. INITIALIZE myQubitRegister [00001111] SELECT mySelectVar myQubitRegister 0:3 Al realizar esto la variable myQubitRegister que quedaŕıa igual, es decir, con un registro [00001111], la variable mySelectVar quedaŕıa con [0000] 20 3.1.0.3. Apply Permite aplicar las siguientes compuertas H (Hadamard),CNOT (Not Controllado),NOT (Negación),I (Identity) a un registro de cúbits, tenga en cuenta que la compuerta se aplicará a cada cúbit del registro, si requiere apli- car a un solo cúbit deberá usar SELECT, aplicar la compuerta con APPLY, y luego CONCAT para volverla a concatenar al registro, el simulador multipli- cara el cúbit por la matriz correspondiente a la compuerta para aśı aplicara. INITIALIZE myQubitRegister [10001111] APPLY H myQubitRegister 3.1.0.4. Inverse Almacena la inversa de la variable requerida por el usuario, se hace apli- cando la operacion inverse definida el simulador, INVERSE myInverse Q Guardando la inversa de la Q en la variable myInverse, tenga en cuenta que la inversa se aplicara a todos los bits cuánticos dentro del registro. 3.1.0.5. Tensor Guarda el resultado de realizar producto tensor, entre 2 registros, o ma- trices especiales, Hada (Hadamard), Iden (Identity), Cnot (Controlled Not). Se realiza producto tensor de los cada cúbit de los registros en orden. Recuer- de que se realiza producto tensor entre matrices o entre registros que seŕıan arreglos, por lo cual deberian ser del mismo tamaño. TENSOR myTensor R1 R2 Almacena en myTensor un nuevo registro el resultado de realizar producto tensor de R1 y R2. 3.1.0.6. Measure Almacena el resultado de realizar una medición de un determinado regis- tro en una nueva variable. 21 MEASURE Q answer Almacena en la varible answer el resultado de realizar la medición de Q. 3.1.1. BNF Notación en Backus-Naur Form usada para definir la sintaxis del lenguaje ensamblador. <start>::= <reg><eol> | <reg><expr><eol> <expr>::= <reg>|<sel>|<apply>|<tensor>|<concat>|<inv>|<measure> <reg>::= ‘initialize’ <identifier> ..............| ‘initialize’ <identifier><size> ..............| ‘initialize’ <identifier><expr> ..............| ‘initialize’ <identifier><size><expr> <sel>::= ‘select’ <identifier><identifier><index>‘:’<index> | ..............‘select’ <identifier><identifier><index>‘:’<index> <expr> <apply>::= ‘apply’ <gate><identifier> ..............| ‘apply’ <gate><identifier><expr> <tensor>::= ‘tensor’ <identifier><identifier><identifier> ............. | ‘tensor’ <identifier><identifier><identifier><expr> <concat>::= ‘concat’ <identifier><identifier><identifier> ............. | ‘concat’ <identifier><identifier><identifier><expr> <inv>::= ‘inverse’ <identifier><identifier> ............. | ‘inverse’ <identifier><identifier><expr> <measure>::= ‘measure’ <identifier><identifier> ............. | ‘measure’ <identifier><identifier><expr> <gate>::= ‘h’ | ‘phase’ | ‘identity’ | ‘cnot’ | ‘not’ <identifier>::= | <letter> <identifier> | <letter> <digit> <identifier> <size>::= ‘[’ <qubit>‘]’ | ‘[’ <qubit><multisize>‘]’ <multisize>::= <qubit> | <qubit><multisize> <qubit>::= ‘0’ | ‘1’ <letter>::= ‘A’ | ‘B’ | ‘C’ | ‘D’ | ‘E’ | ‘F’ | ‘G’ | ‘H’ | ‘I’ | ‘J’ | ‘K’ ...............| ‘L’ | ‘M’ | ‘N’ | ‘O’ | ‘P’ | ‘Q’ | ‘R’ | ‘S’ | ‘T’ | ‘U’ | ‘V’ ...............| ‘W’ | ‘X’ | ‘Y’ | ‘Z’ | ‘a’ | ‘b’ | ‘c’ | ‘d’ | ‘e’ | ‘f’ | ‘g’ ...............| ‘h’ | ‘i’ | ‘j’ | ‘k’ | ‘l’ | ‘m’ | ‘n’ | ‘o’ | ‘p’ | ‘q’ | ‘r’ ...............| ‘s’ | ‘t’ | ‘u’ | ‘v’ | ‘w’ | ‘x’ | ‘y’ | ‘z’ 22 <digit>::= ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’ <index>::= ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ 3.1.2. EBNF Notación en Extended Backus-Naur Form usada para definir la sintaxis del lenguaje ensamblador. start = reg [expr] EOL expr = reg | sel | apply | tensor | concat | inv | measure reg = ‘initialize’ identifier [size] [expr] sel = ‘select’ identifier identifier index‘:’index [expr] apply = ‘apply’ gate identifier [expr] tensor= ‘tensor’ identifier identifier identifier [expr] concat= ‘concat’ identifier identifier identifier [expr] inv = ‘inverse’ identifier identifier [expr] measure = ‘measure’ identifier identifier [expr] gate = ‘h’ | ‘phase’ | ‘identity’ | ‘cnot’ | ‘not’ identifier = letter {letter} {digit} size = ‘[’ qubit {qubit} ‘]’ qubit = ‘0’ | ‘1’ letter = ‘A’ | ‘B’ | ‘C’ | ‘D’ | ‘E’ | ‘F’ | ‘G’ | ‘H’ | ‘I’ | ‘J’ | ‘K’ | ‘L’ .......... | ‘M’ | ‘N’ | ‘O’ | ‘P’ | ‘Q’ | ‘R’ | ‘S’ | ‘T’ | ‘U’ | ‘V’ | ‘W’ | ‘X’ .......... | ‘Y’ | ‘Z’ | ‘a’ | ‘b’ | ‘c’ | ‘d’ | ‘e’ | ‘f’ | ‘g’ | ‘h’ | ‘i’ | ‘j’ .......... | ‘k’ | ‘l’ | ‘m’ | ‘n’ | ‘o’ | ‘p’ | ‘q’ | ‘r’ | ‘s’ | ‘t’| ‘u’ | ‘v’ .......... | ‘w’ | ‘x’ | ‘y’ | ‘z’ digit = ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’ index = ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ 3.1.3. JavaCC QuantumAssembly.jj Esta es la clase que se usar para cambiar los tokens, añadir nuevas com- puertas, además la cuál genera el código en java aplicado al simulador cuánti- co. El código escrito en formato java se encarga de crear un archivo Main.java a partir de la entrada con formato txt. Y en javacc se definen los tokens con los comandos especiales, compuertas, tamaño de los registros, caracte- res que pueden llevar como nombre las variables teniendo en cuenta que sea un carácter o una cadena. Para modificaciones hay que tener en cuenta la estructura del EBNF para aśı no dañar la estructura principal del lenguaje. 23 La representación en javacc es exactamente la misma propuesta en ebnf, por supuesto teniendo en cuenta que la sintaxis de ambas partes es diferente. 3.1.4. Algorimo de Deutsch LQE En esta implematación del algoritmo de Deutsch en LQE para f(x) = x, se crean ambos bits cuánticos, se entrelazan realizando producto tensor, se crea la matriz de hadamard del tamaño para poderlos poner en superposición, se hace tensor de hadamard identidad para que la matriz alcance el tamaño indicando, luego se realiza tensor de hadamard y los qubits entrelazados para ponerlos en estado de superposición, se aplica CNOT a los qubits en super- posición en este caso este seria nuestra matriz uf por lo cual es menos cosos usar CNOT y no crearla manualmente, y tensor de de este y la identidad, y luego medimos. INITIALIZE R1 [0] INITIALIZE R2 [1] TENSOR QUBIT R2 R1 TENSOR Thada Hada Hada TENSOR Tiden Hada Iden TENSOR R0 Thada QUBIT TENSOR RE1 Cnot R0 TENSOR RE2 Tiden RE1 MEASURE RE2 ANS Código gerado en java 1 ArrayList <?> hadamardMatrix = QuantumCompilerMethods. createHadamardMatrix (); 2 ArrayList <?> controlledNotMatrix = QuantumCompilerMethods. createControlledNotMatrix (); 3 ArrayList <?> identityMatrix = QuantumCompilerMethods. createIdentityMatrix (); 4 ArrayList <ComplexNumber []> R1 = new ArrayList (); 5 R1 = QuantumCompilerMethods.createQubitRegister("0"); 6 ArrayList <ComplexNumber []> R2 = new ArrayList (); 7 R2 = QuantumCompilerMethods.createQubitRegister("1"); 8 ArrayList <?> QUBIT = QuantumCompilerMethods.tensorProduct( R2 ,R1); 9 ArrayList <ComplexNumber []> applyR2H = QuantumCompilerMethods.quantumApply (( ComplexNumber [][]) 24 hadamardMatrix.get (0),R2); 10 ArrayList <?> Thada = QuantumCompilerMethods.tensorProduct (( ComplexNumber [][]) hadamardMatrix.get(0) ,(ComplexNumber [][]) hadamardMatrix.get(0)); 11 ArrayList <?> Tiden = QuantumCompilerMethods.tensorProduct (( ComplexNumber [][]) hadamardMatrix.get(0) ,(ComplexNumber [][]) identityMatrix.get(0)); 12 ArrayList <?> R0 = QuantumCompilerMethods.tensorProduct( Thada ,QUBIT); 13 ArrayList <?> RE1 = QuantumCompilerMethods.tensorProduct( controlledNotMatrix ,R0); 14 ArrayList <?> RE2 = QuantumCompilerMethods.tensorProduct( Tiden ,RE1); 15 double ANS = QuantumCompilerMethods.measure(RE2); Ya que un registro de cúbits se ve como un arreglo en estecaso, se mane- jara usando ArrayList, el tipo es ? debido a que al realizar producto tensor se puede realizar entre 2 vectores o entre 2 matrices, usando instanceof y por dentro se identifica cual es el tipo de ambas entradas para realizar el producto tensor correspondiente, ya que el código varia entre ambos, para aplicar las compuertas se multiplican las matrices por dentro, al crear el co- digo se inicializan automaticamente las matrices de hadamard, identidad y not controlado. 25 Caṕıtulo 4 Conclusiones Aún falta bastante tiempo para poder ver un lenguaje de programación imperativo cuántico, debido a la falta de disponibilidad de computadores cuánticos, los avances de implementación de lenguajes ensambladores cuánti- cos son muy grandes, y ya se puede usar al menos uno con un computador cuántico real, el QASM. Hay bastantes simuladores de computadores cuánticos, pero nunca serán tan eficiente como uno real, debido a la inmensa capacidad de recursos re- querida para la creación bits cuánticos. Se ha implementado el compilador básico usando javacc, haciendo el análi- sis léxico, y creando una clase la cual puede ser usado por el simulador cuánti- co construido en java, creando una clase Main que ejecutara los métodos ya definidos en este, solo con que el usuario sea capaz de entender y usar el LQE básico. 26 Bibliograf́ıa [1] Mirco A Mannucci Noson S. Yanofsky. Quantum Computing for Com- puter Scientists. Cambridge University Press, 2008. [2] IBM Developer. Qiskit openqasm, November 2018. URL https://developer.ibm.com/code/open/projects/qiskit/ qiskit-openqasm. [3] Bernhard Ömer. Quantum programming in qcl, May 2003. URL http: //tph.tuwien.ac.at/~oemer/doc/quprog.pdf. [4] T. Calarco S. Bettelli, L. Serafini. Toward an architecture for quantum programming, March 2001. URL arXiv:cs/0103009v3. [5] Paola Camacho. Historia y definición de los lenguajes de programación. URL https://www.monografias.com/ trabajos99/historia-y-definicion-lenguajes-programacion/ historia-y-definicion-lenguajes-programacion.shtml. [6] Sara Alvarez. Tipos de lenguajes de programación, February 2006. URL https://desarrolloweb.com/articulos/2358.php. [7] John Preskill. Quantum computing in the nisq era and beyond, July 2018. URL arXiv:1801.00862v3. [8] John A. Smolin Jay M. Gambetta Andrew W. Cross, Lev S. Bishop. Open quantum assembly language, July 2017. URL https://arxiv. org/abs/1707.03429. [9] Jay M. Gambetta Ali Javadi-Abhari. Qiskit and its funda- mental elements, July 2018. URL https://medium.com/qiskit/ qiskit-and-its-fundamental-elements-bcd7ead80492. 27 [10] IBM Research and the IBM QX team. Ibm experience documenta- tion, 2017. URL https://quantumexperience.ng.bluemix.net/qx/ tutorial?sectionId=beginners-guide&page=introduction. [11] Bernhard Ömer. Classical concepts in quantum programming, April 2003. URL https://arxiv.org/pdf/quant-ph/0211100.pdf. [12] IBM Research and the IBM QX team. Ibm experience documenta- tion, 2017. URL https://quantumexperience.ng.bluemix.net/qx/ tutorial?sectionId=full-user-guide&page=introduction. [13] David William Rajagopal Nagarajan, Nikolaos Papanikolaou. Simula- ting and Compiling Code for the Sequential Quantum Random Access Machine. 170:101–124, 2007. doi: https://doi.org/10.1016/j.entcs.2006. 12.014. [14] JavaCC Oracle. Javacc documentation, October 1996. URL https: //javacc.org/doc. 28
Compartir