├── lcu.jpeg ├── qpe_ketg.jpeg ├── hhl_model.jpeg ├── Challenge Ket.G ├── balance.jpeg └── Problem 1.ipynb ├── QuantumCounting ├── IMG_2077.jpg ├── IMG_2078.jpg ├── IMG_2079.jpg └── CountingSolutions.ipynb ├── DescomposicionToffoli ├── toffoli1.jpeg ├── toffoli2.jpeg ├── toffoli3.jpeg ├── toffoli4.jpeg ├── toffoli5.jpeg ├── toffoli6.jpeg └── DescomposicionToffoli.ipynb ├── N-Queens Problem ├── Imágenes │ ├── ReinaColocada.png │ └── TableroInicial.png └── N-Reinas 2.0.ipynb ├── MisProyectos ├── hamiltoniano.py ├── MaxCut.ipynb └── Hamiltoniano.ipynb ├── DiagramComputer.ipynb ├── FinalProblem.ipynb ├── CircuitTransform.ipynb ├── knapsackproblem.py ├── DivisionEntera.ipynb ├── .ipynb_checkpoints └── Mochila - Knapsack problem-checkpoint.ipynb ├── vqe_casero.ipynb ├── Mochila - Knapsack problem.ipynb ├── QuantumPhaseEstimation.ipynb ├── EstimandoPi.ipynb ├── ClasificadorKernel.ipynb ├── Quantum KNN.ipynb ├── QPE_Energy.ipynb ├── LCU.ipynb └── HHL.ipynb /lcu.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/lcu.jpeg -------------------------------------------------------------------------------- /qpe_ketg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/qpe_ketg.jpeg -------------------------------------------------------------------------------- /hhl_model.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/hhl_model.jpeg -------------------------------------------------------------------------------- /Challenge Ket.G/balance.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/Challenge Ket.G/balance.jpeg -------------------------------------------------------------------------------- /QuantumCounting/IMG_2077.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/QuantumCounting/IMG_2077.jpg -------------------------------------------------------------------------------- /QuantumCounting/IMG_2078.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/QuantumCounting/IMG_2078.jpg -------------------------------------------------------------------------------- /QuantumCounting/IMG_2079.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/QuantumCounting/IMG_2079.jpg -------------------------------------------------------------------------------- /DescomposicionToffoli/toffoli1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/DescomposicionToffoli/toffoli1.jpeg -------------------------------------------------------------------------------- /DescomposicionToffoli/toffoli2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/DescomposicionToffoli/toffoli2.jpeg -------------------------------------------------------------------------------- /DescomposicionToffoli/toffoli3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/DescomposicionToffoli/toffoli3.jpeg -------------------------------------------------------------------------------- /DescomposicionToffoli/toffoli4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/DescomposicionToffoli/toffoli4.jpeg -------------------------------------------------------------------------------- /DescomposicionToffoli/toffoli5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/DescomposicionToffoli/toffoli5.jpeg -------------------------------------------------------------------------------- /DescomposicionToffoli/toffoli6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/DescomposicionToffoli/toffoli6.jpeg -------------------------------------------------------------------------------- /N-Queens Problem/Imágenes/ReinaColocada.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/N-Queens Problem/Imágenes/ReinaColocada.png -------------------------------------------------------------------------------- /N-Queens Problem/Imágenes/TableroInicial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KetpuntoG/Notebooks-del-canal/master/N-Queens Problem/Imágenes/TableroInicial.png -------------------------------------------------------------------------------- /MisProyectos/hamiltoniano.py: -------------------------------------------------------------------------------- 1 | from qiskit import * 2 | 3 | class Termino_hamiltoniano(): 4 | 5 | def __init__(self, paulis, n_qubits, constante = 1): 6 | 7 | self.paulis = paulis 8 | self.n_qubits = n_qubits 9 | self.constante = constante 10 | 11 | def simplificar_termino(self): 12 | 13 | simplificacion = [] 14 | qubits_recorridos = [] 15 | 16 | for pauli, qubit in self.paulis: 17 | 18 | if qubit not in qubits_recorridos: 19 | 20 | qubits_recorridos.append(qubit) 21 | simplificacion.append([pauli, qubit]) 22 | 23 | else: 24 | 25 | pauli_actual = simplificacion[qubits_recorridos.index(qubit)][0] 26 | nueva_pauli, constante = self.reducir_paulis(pauli_actual, pauli) 27 | 28 | if nueva_pauli == 'I': 29 | 30 | simplificacion.remove([pauli_actual, qubit]) 31 | qubits_recorridos.remove(qubit) 32 | 33 | else: 34 | 35 | simplificacion[qubits_recorridos.index(qubit)][0] = nueva_pauli 36 | self.constante *= constante 37 | 38 | return simplificacion 39 | 40 | def reducir_paulis(self, pauli1, pauli2): 41 | 42 | paulis = ['X', 'Y', 'Z'] 43 | 44 | if paulis.index(pauli1) < paulis.index(pauli2): 45 | return set(paulis).difference(set([pauli1, pauli2])).pop(), complex('j') 46 | 47 | elif paulis.index(pauli1) > paulis.index(pauli2): 48 | return set(paulis).difference(set([pauli1, pauli2])).pop(), complex('-j') 49 | 50 | else: 51 | return 'I', 1 52 | 53 | def calcular_valor_esperado(self, circ_estado): 54 | 55 | puerta_estado = circ_estado.to_gate() 56 | 57 | termino_simp = self.simplificar_termino() 58 | qubits_interes = len(termino_simp) 59 | 60 | circuito = QuantumCircuit(self.n_qubits, qubits_interes) 61 | circuito.append(puerta_estado, range(self.n_qubits)) 62 | 63 | for i, termino in enumerate(termino_simp): 64 | 65 | pauli, qubit = termino 66 | 67 | if pauli == 'X': 68 | circuito.h(qubit) 69 | 70 | 71 | elif pauli == 'Y': 72 | circuito.sdg(i) 73 | circuito.h(i) 74 | 75 | circuito.measure(qubit, i) 76 | 77 | conteo = self.ejecutar_circuito(circuito) 78 | solucion = 0 79 | for num in conteo: 80 | solucion += conteo[num] * (-1) ** (num.count('1')) 81 | return solucion * self.constante 82 | 83 | def ejecutar_circuito(self, circ): 84 | 85 | # devuelve la probabilidad de cada estado 86 | 87 | shots = 5000 88 | backend = Aer.get_backend("qasm_simulator") 89 | job = execute(circ, backend, shots = shots) 90 | counts = job.result().get_counts() 91 | 92 | for clave in counts: 93 | counts[clave] /= shots 94 | 95 | return counts 96 | 97 | 98 | class Hamiltoniano(): 99 | 100 | def __init__(self, n_qubits): 101 | 102 | self.terminos = [] 103 | self.n_qubits = n_qubits 104 | 105 | def incluir_termino(self, termino): 106 | self.terminos.append(termino) 107 | 108 | def calcular_valor_esperado(self, circuito_estado): 109 | 110 | solucion = 0 111 | 112 | for termino in self.terminos: 113 | 114 | solucion += termino.calcular_valor_esperado(circuito_estado) 115 | 116 | return solucion 117 | -------------------------------------------------------------------------------- /DiagramComputer.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "https://csacademy.com/app/graph_editor/" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "from qiskit import *\n", 17 | "IBMQ.load_account()\n", 18 | "provider = IBMQ.get_provider(hub='ibm-q')" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "def media_gate(ns, couplingMap):\n", 28 | "\n", 29 | " \n", 30 | " import itertools\n", 31 | "\n", 32 | " total_counts = 0\n", 33 | " nq = couplingMap.size()\n", 34 | " \n", 35 | " for k in range(ns):\n", 36 | " ni = 0 # numero de iteraciones\n", 37 | " for i,j in itertools.permutations(range(nq), 2):\n", 38 | " qc = QuantumCircuit(nq,nq)\n", 39 | " qc.cx(i,j)\n", 40 | " total_counts += transpile(qc, coupling_map=couplingMap, \n", 41 | " basis_gates=['u1', 'u2', 'u3', 'cx'], \n", 42 | " optimization_level= 0).count_ops()['cx']\n", 43 | " ni += 1\n", 44 | "\n", 45 | " \n", 46 | " \n", 47 | " media = total_counts / ns\n", 48 | " return media / ni\n" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "def str_to_list(string):\n", 58 | " div = string.split()\n", 59 | " lista = []\n", 60 | " for i in range(0, len(div), 2):\n", 61 | " lista.append([int(div[i]), int(div[i+1])])\n", 62 | " return lista" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "def check_diagram(string, ns):\n", 72 | " from qiskit.transpiler import CouplingMap\n", 73 | " lista = str_to_list(string)\n", 74 | " return media_gate(ns,CouplingMap(lista))" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 5, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "def nodes_degree(string):\n", 84 | " numeros = string.split()\n", 85 | " n_dif = set(numeros)\n", 86 | " lista = []\n", 87 | " for n in n_dif:\n", 88 | " lista.append(numeros.count(n))\n", 89 | " for e in set(lista):\n", 90 | " print(\"enlaces de orden \", e, \" : \", lista.count(e))\n", 91 | " " 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 14, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "cada cx ejecuta realmente 2.56 cx\n", 104 | "enlaces de orden 2 : 4\n", 105 | "enlaces de orden 4 : 1\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | "a = \"\"\"\n", 111 | "4 1\n", 112 | "1 0\n", 113 | "1 2\n", 114 | "1 3\n", 115 | "3 0\n", 116 | "2 4\n", 117 | " \"\"\"\n", 118 | "\n", 119 | "print(\"cada cx ejecuta realmente {0} cx\".format(check_diagram(a,10)))\n", 120 | "nodes_degree(a)" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "metadata": {}, 127 | "outputs": [], 128 | "source": [] 129 | } 130 | ], 131 | "metadata": { 132 | "kernelspec": { 133 | "display_name": "Python 3", 134 | "language": "python", 135 | "name": "python3" 136 | }, 137 | "language_info": { 138 | "codemirror_mode": { 139 | "name": "ipython", 140 | "version": 3 141 | }, 142 | "file_extension": ".py", 143 | "mimetype": "text/x-python", 144 | "name": "python", 145 | "nbconvert_exporter": "python", 146 | "pygments_lexer": "ipython3", 147 | "version": "3.6.9" 148 | } 149 | }, 150 | "nbformat": 4, 151 | "nbformat_minor": 2 152 | } 153 | -------------------------------------------------------------------------------- /DescomposicionToffoli/DescomposicionToffoli.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d9e4b608", 6 | "metadata": {}, 7 | "source": [ 8 | "# Descomposición de la puerta Toffoli\n", 9 | "\n", 10 | "La puerta de Toffoli es una de las más importantes que utilizamos dentro de la computación cuántica. Se define a partir de dos qubits de control y un qubit objetivo tal y como se muestra en la imagen:\n", 11 | "\n", 12 | "\"drawing\"\n", 13 | "\n", 14 | "Su comportamiento sigue una regla muy sencilla: si en todos los qubits de control tenemos el estado $|1\\rangle$, entonces aplicamos una puerta $X$ sobre el qubit objetivo. Esta puerta puede ser construida a partir de puertas que afectan a un único qubit y la puerta CNOT por lo que a lo largo de este notebook desarrollaremos dicha equivalencia. Para ello mostraremos una serie de equivalencias que nos serán de gran utilidad.\n", 15 | "\n", 16 | "La primera de las equivalencias probablemente sea las más conocida: podemos utilizar la puerta Hadamard para transformar la puerta $X$ en una puerta $Z$:\n", 17 | "\n", 18 | "\"drawing\"\n", 19 | "\n", 20 | "Por lo tanto, si somos capaces de descomponer la puerta $CCZ$, sabremos descomponer la puerta de Toffoli. Realmente nos será más fácil trabajar con $CCZ$ por ser una matriz diagonal así que seguiremos por esta linea.\n", 21 | "La siguiente propiedad es menos conocida pero no por ello menos interesante: La construcción de **Sleator-Weinfurter** , que establece una equivalencia capaz de descomponer $CCU$ para cualquier puerta $U$ unitaria. Para ello jugará con una puerta $V$ que cumpla que $V^2 = U$:\n", 22 | "\n", 23 | "\"drawing\"\n", 24 | "\n", 25 | "Aunque puede parecer complicado, la demostración se hace de forma muy sencilla. Solo habría que estudiar cada uno de los estados básicos y ver que realmente se comporta como queremos. Por ver un ejemplo de cómo se haría esto, veamos que efectivamente el estado $|11\\rangle|\\phi\\rangle$ se transforma en el estado $|11\\rangle U|\\phi\\rangle$:\n", 26 | "\n", 27 | "\"drawing\"\n", 28 | "\n", 29 | "Si comprobásemos para el resto de estados iniciales veríamos que se cumple la igualdad esperada con la puerta $CCU$. En nuestro caso particular, al estar trabajando con $U = Z$ tan solo tendríamos que aplicar la construcción anterior para $V = S$ ya que es la raiz cuadrada de $Z$. Sin embargo, con esto no hemos terminado todavía, la puerta $CS$ es una puerta que no hemos definido, por lo que debemos ser capaces de descomponerla como puertas de un único qubit y la CNOT. Es por ello que haremos uso de la última equivalencia necesaria:\n", 30 | "\n", 31 | "\"drawing\"\n", 32 | "\n", 33 | "\n", 34 | "De primeras estas equivalencias que hemos estado usando pueden parecer complicadas pero se deducen de forma similar. Juegan con puertas raiz que se anulan o no en función de si los qubits tienen el estado $|0\\rangle$ o el estado $|1\\rangle$. Juntando todas estas piezas podemos llegar a expresar la puerta de Toffoli únicamente con puertas $T$, Hadamard y CNOT:\n", 35 | "\n", 36 | "\"drawing\"\n", 37 | "\n", 38 | "¿Serías capaz de simplificarlo más? 😃\n", 39 | "\n", 40 | "Para cualquier duda que surja:\n", 41 | "\n", 42 | "Gmail: canalket.g@gmail.com\n", 43 | "\n", 44 | "Twitter: @KetPuntoG" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "3302a7a7", 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [] 54 | } 55 | ], 56 | "metadata": { 57 | "kernelspec": { 58 | "display_name": "Python 3", 59 | "language": "python", 60 | "name": "python3" 61 | }, 62 | "language_info": { 63 | "codemirror_mode": { 64 | "name": "ipython", 65 | "version": 3 66 | }, 67 | "file_extension": ".py", 68 | "mimetype": "text/x-python", 69 | "name": "python", 70 | "nbconvert_exporter": "python", 71 | "pygments_lexer": "ipython3", 72 | "version": "3.8.8" 73 | } 74 | }, 75 | "nbformat": 4, 76 | "nbformat_minor": 5 77 | } 78 | -------------------------------------------------------------------------------- /FinalProblem.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from qiskit import *" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 3, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "data": { 19 | "text/plain": [ 20 | "{'0': 90, '1': 910}" 21 | ] 22 | }, 23 | "execution_count": 3, 24 | "metadata": {}, 25 | "output_type": "execute_result" 26 | } 27 | ], 28 | "source": [ 29 | "tablero = \"1000010000010010\"\n", 30 | "\n", 31 | "# 0 1 2 3\n", 32 | "# 4 5 6 7\n", 33 | "# 8 9 10 11\n", 34 | "# 12 13 14 15\n", 35 | "\n", 36 | "qc = QuantumCircuit(16 + 6 + 1, 1)\n", 37 | "\n", 38 | "def añadir_tablero(qc, tablero):\n", 39 | " for ind, i in enumerate(tablero):\n", 40 | " if i == \"1\":\n", 41 | " qc.x(ind)\n", 42 | " return qc\n", 43 | " \n", 44 | "qc = añadir_tablero(qc, tablero)\n", 45 | "\n", 46 | "def añadir_cswap(qc, control, columna1, columna2):\n", 47 | " for i in range(len(columna1)):\n", 48 | " qc.cswap(control, columna1[i], columna2[i])\n", 49 | " return qc\n", 50 | "\n", 51 | "def añadir_permutaciones(qc):\n", 52 | " \n", 53 | " qc = añadir_cswap(qc, 16, [0,4,8,12], [1,5,9,13])\n", 54 | " qc = añadir_cswap(qc, 17, [0,4,8,12], [2,6,10,14])\n", 55 | " qc = añadir_cswap(qc, 18, [0,4,8,12], [3,7,11,15])\n", 56 | " qc = añadir_cswap(qc, 19, [1,5,9,13], [2,6,10,14])\n", 57 | " qc = añadir_cswap(qc, 20, [1,5,9,13], [3,7,11,15])\n", 58 | " qc = añadir_cswap(qc, 21, [2,6,10,14], [3,7,11,15])\n", 59 | " return qc\n", 60 | "\n", 61 | "def deshacer_permutaciones(qc):\n", 62 | " \n", 63 | " qc = añadir_cswap(qc, 21, [2,6,10,14], [3,7,11,15])\n", 64 | " qc = añadir_cswap(qc, 20, [1,5,9,13], [3,7,11,15])\n", 65 | " qc = añadir_cswap(qc, 19, [1,5,9,13], [2,6,10,14])\n", 66 | " qc = añadir_cswap(qc, 18, [0,4,8,12], [3,7,11,15])\n", 67 | " qc = añadir_cswap(qc, 17, [0,4,8,12], [2,6,10,14])\n", 68 | " qc = añadir_cswap(qc, 16, [0,4,8,12], [1,5,9,13])\n", 69 | " return qc\n", 70 | " \n", 71 | "\n", 72 | "def añadir_oraculo(qc):\n", 73 | " \n", 74 | " qc.h(12)\n", 75 | " qc.mct([3,6,9], 12)\n", 76 | " qc.h(12)\n", 77 | "\n", 78 | " return qc\n", 79 | "\n", 80 | "\n", 81 | "def añadir_grover(qc):\n", 82 | " qc.h(range(16,22))\n", 83 | " qc.x(range(16,22))\n", 84 | " qc.h(21)\n", 85 | " qc.mct(list(range(16,21)),21)\n", 86 | " qc.h(21)\n", 87 | " qc.x(range(16,22))\n", 88 | " qc.h(range(16,22))\n", 89 | " return qc\n", 90 | "\n", 91 | "\n", 92 | "\n", 93 | "qc.h(range(16,22))\n", 94 | "\n", 95 | "for _ in range(2):\n", 96 | " \n", 97 | " qc = añadir_permutaciones(qc)\n", 98 | " qc = añadir_oraculo(qc)\n", 99 | " qc = deshacer_permutaciones(qc)\n", 100 | " qc = añadir_grover(qc)\n", 101 | "\n", 102 | "qc = añadir_permutaciones(qc)\n", 103 | "qc.mct([3,6,9,12], 22)\n", 104 | "qc = deshacer_permutaciones(qc)\n", 105 | "qc.measure(22,0)\n", 106 | "\n", 107 | "backend = Aer.get_backend(\"qasm_simulator\")\n", 108 | "job = execute(qc, backend, shots = 1000)\n", 109 | "job.result().get_counts()\n", 110 | "#qc.draw(output = \"mpl\")\n", 111 | "\n", 112 | "# 1 no tiene solución, 0 tiene solución" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [] 121 | } 122 | ], 123 | "metadata": { 124 | "kernelspec": { 125 | "display_name": "Python 3", 126 | "language": "python", 127 | "name": "python3" 128 | }, 129 | "language_info": { 130 | "codemirror_mode": { 131 | "name": "ipython", 132 | "version": 3 133 | }, 134 | "file_extension": ".py", 135 | "mimetype": "text/x-python", 136 | "name": "python", 137 | "nbconvert_exporter": "python", 138 | "pygments_lexer": "ipython3", 139 | "version": "3.8.3" 140 | } 141 | }, 142 | "nbformat": 4, 143 | "nbformat_minor": 4 144 | } 145 | -------------------------------------------------------------------------------- /CircuitTransform.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d09da19a", 6 | "metadata": {}, 7 | "source": [ 8 | "El objetivo de este notebook es mostrar como podemos aplicar una transformación a un QNodo. Para ello crearemos un circuito inicial y posteriormente veremos como aplicar una transformación para sustituir las puertas X por la concatenación de una puerta Y y una puerta Z." 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "47409d48", 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | " 0: ──X─────╭SWAP──────────╭┤ State \n", 22 | " 1: ──H──X──│──────╭C──────├┤ State \n", 23 | " 2: ────────╰SWAP──╰RZ(2)──╰┤ State \n", 24 | "\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "import pennylane as qml\n", 30 | "\n", 31 | "dev = qml.device(\"default.qubit\", wires = 3)\n", 32 | "\n", 33 | "@qml.qnode(dev)\n", 34 | "def circuit():\n", 35 | " qml.PauliX(wires = 0)\n", 36 | " qml.SWAP(wires = [0,2])\n", 37 | " qml.Hadamard(wires = 1)\n", 38 | " qml.PauliX(wires = 1)\n", 39 | " qml.CRZ(2, wires = [1,2])\n", 40 | " return qml.state()\n", 41 | " \n", 42 | "circuit()\n", 43 | "\n", 44 | "print(qml.draw(circuit)())" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "id": "dad848b4", 50 | "metadata": {}, 51 | "source": [ 52 | "La transformación recorrerá las operaciones de una lista y hará la sustitución correspondiente." 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 2, 58 | "id": "a8695263", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "@qml.qfunc_transform\n", 63 | "def remove_X(tape):\n", 64 | " \n", 65 | " for op in tape.operations:\n", 66 | " if op.name != \"PauliX\":\n", 67 | " qml.apply(op)\n", 68 | " \n", 69 | " else:\n", 70 | " qml.PauliY(wires = op.wires)\n", 71 | " qml.PauliZ(wires = op.wires)\n", 72 | " \n", 73 | " \n", 74 | " for ms in tape.measurements:\n", 75 | " qml.apply(ms)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "id": "d31508c4", 81 | "metadata": {}, 82 | "source": [ 83 | "Finalmente, utilizando el propio nombre de la función como decorador aplicaremos la función al qnodo en cuestión." 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 3, 89 | "id": "618db91b", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | " 0: ──Y──Z─────╭SWAP──────────╭┤ State \n", 97 | " 1: ──H──Y──Z──│──────╭C──────├┤ State \n", 98 | " 2: ───────────╰SWAP──╰RZ(2)──╰┤ State \n", 99 | "\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | "import pennylane as qml\n", 105 | "\n", 106 | "dev = qml.device(\"default.qubit\", wires = 3)\n", 107 | "\n", 108 | "@qml.qnode(dev)\n", 109 | "@remove_X\n", 110 | "def circuit():\n", 111 | " qml.PauliX(wires = 0)\n", 112 | " qml.SWAP(wires = [0,2])\n", 113 | " qml.Hadamard(wires = 1)\n", 114 | " qml.PauliX(wires = 1)\n", 115 | " qml.CRZ(2, wires = [1,2])\n", 116 | " return qml.state()\n", 117 | " \n", 118 | "circuit()\n", 119 | "\n", 120 | "print(qml.draw(circuit)())" 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "id": "ee2668d9", 126 | "metadata": {}, 127 | "source": [ 128 | "Como podemos comprobar las puertas X han sido remplazadas correctamente." 129 | ] 130 | } 131 | ], 132 | "metadata": { 133 | "kernelspec": { 134 | "display_name": "Python 3", 135 | "language": "python", 136 | "name": "python3" 137 | }, 138 | "language_info": { 139 | "codemirror_mode": { 140 | "name": "ipython", 141 | "version": 3 142 | }, 143 | "file_extension": ".py", 144 | "mimetype": "text/x-python", 145 | "name": "python", 146 | "nbconvert_exporter": "python", 147 | "pygments_lexer": "ipython3", 148 | "version": "3.8.8" 149 | } 150 | }, 151 | "nbformat": 4, 152 | "nbformat_minor": 5 153 | } 154 | -------------------------------------------------------------------------------- /knapsackproblem.py: -------------------------------------------------------------------------------- 1 | import cirq 2 | import numpy as np 3 | import scipy 4 | import operator 5 | 6 | # Input parameters. Feel free to change them. 7 | L = 100 # Limit value 8 | objs = [60, 35, 23, 55, 70, 13] # weights of the items 9 | layers = 5 # number of layers 10 | initial = 0 # inizialization value 11 | methods = ['COBYLA'] # list of methods that you want to use 12 | # See https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize for available methods 13 | 14 | n = len(objs) 15 | gamma = 2 / (n*L) 16 | 17 | """ 18 | Clarification: (2*pi)/(n*L) appears on the paper 19 | In this case there is no pi for how gate R is constructed. 20 | To rotate pi degrees, we write z ** 1, 21 | so intuitively, we have to divide by pi. 22 | 23 | """ 24 | class ParametrizedGate(cirq.Gate): 25 | 26 | def _decompose_(self, qs): 27 | for i in range(n): 28 | Rz = cirq.Z(qs[n]) ** (gamma * objs[i]) 29 | yield Rz.controlled_by(qs[i]) 30 | 31 | def _num_qubits_(self): 32 | return n + 1 33 | 34 | def _unitary_(self): 35 | return cirq.unitary( 36 | cirq.Circuit(self._decompose_(cirq.LineQubit.range(n + 1)))) 37 | 38 | def ansatz(params): 39 | 40 | qs = cirq.LineQubit.range(n + 2) 41 | ansatz = cirq.Circuit() 42 | 43 | for j in range(layers): 44 | 45 | ansatz.append([cirq.X(qs[i]) ** params[i + 2*j*n] for i in range(n)]) 46 | ansatz.append([cirq.CX(qs[aux[0]], qs[aux[1]]) 47 | for aux in [[i,i+1] for i in range(n - 1)]]) 48 | ansatz.append([cirq.Z(qs[i]) ** params[i + (2*j+1)*n] for i in range(n)]) 49 | ansatz.append([cirq.CX(qs[aux[0]], qs[aux[1]]) 50 | for aux in [[i,i+1] for i in range(n - 1)]]) 51 | 52 | return ansatz 53 | 54 | def expected_values(params): 55 | 56 | sol = [] 57 | 58 | for i in range(2): 59 | 60 | qs = cirq.LineQubit.range(n + 2) 61 | circuit = cirq.Circuit() 62 | circuit.append(cirq.X(qs[n])) 63 | cg = cirq.ControlledGate(ParametrizedGate()) 64 | circuit.append(cirq.H(qs[n + 1])) 65 | circuit.append(cirq.S(qs[n + 1]) ** i) 66 | circuit.append(cg(qs[n + 1], *[qs[i] for i in range(n + 1)])) 67 | circuit.append(cirq.H(qs[n + 1])) 68 | 69 | circuit.append(cirq.measure(qs[n + 1])) 70 | circuit = ansatz(params) + circuit 71 | s = cirq.Simulator() 72 | rep = 1000 73 | sol.append(s.run(circuit, repetitions = rep)) 74 | 75 | real = 2 * int(str(sol[0]).count('0')) / rep - 1 76 | img = - 2 * int(str(sol[1]).count('0')) / rep + 1 77 | 78 | if np.sin(L * gamma * np.pi) - img < 0: 79 | return 3 80 | else: 81 | return np.abs(np.cos(L * gamma * np.pi) - real) 82 | 83 | 84 | def solution(method,n): 85 | 86 | initial_params = np.array([initial]*(2*layers*n)) 87 | minimum = scipy.optimize.minimize(expected_values, 88 | initial_params, method=method) 89 | final = cirq.Circuit() 90 | qs = cirq.LineQubit.range(n + 2) 91 | final =ansatz(minimum.x) 92 | final.append(cirq.measure(*[qs[i] for i in range(n)] , key = 'm')) 93 | 94 | s = cirq.Simulator() 95 | rep = 10000 96 | sol = s.run(final, repetitions = rep) 97 | 98 | result = max(sol.histogram(key = 'm').items(), 99 | key=operator.itemgetter(1))[0] 100 | times = max(sol.histogram(key = 'm').items(), 101 | key=operator.itemgetter(1))[1] 102 | 103 | sum = 0 104 | print("to approach the value ", L, " without going over, we must take: ") 105 | for i, n in enumerate(np.binary_repr(result,n)): 106 | sum += int(n) * objs[i] 107 | if int(n) == 1: 108 | print("obj ", i + 1, " with value ", objs[i]) 109 | 110 | print("METHOD: ", method) 111 | print("sum: ",sum, "percentage: ", 100* times / rep , "%") 112 | 113 | 114 | 115 | for method in methods: 116 | try: 117 | solution(method,n) 118 | except Exception as e: 119 | print(method, " does not work") 120 | print('Exception: ' + str(e)) # Printing exact error for debugging if necessary 121 | -------------------------------------------------------------------------------- /N-Queens Problem/N-Reinas 2.0.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Problema de las N-Reinas 2.0" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Explicación del problema: https://youtu.be/ZGKSoTUaphU\n", 15 | "\n", 16 | "\n", 17 | "Explicación del código: https://youtu.be/3wVwpPzoyDs\n", 18 | "\n", 19 | "\n", 20 | "Nuestra función a minimizar será:\n", 21 | "\n", 22 | "\n", 23 | "$\\begin{equation}\n", 24 | "f(x) = -\\sum_i^n \\sum_j^n x_{i,j} + \\lambda\\sum_{i_1}^n \\sum_{i_2}^n \\sum_{i_3}^n \\sum_{i_4}^n J_{i_1,i_2,i_3,i_4}x_{i_1,i_2}x_{i_3,i_4}\n", 25 | "\\end{equation}$\n", 26 | "\n", 27 | "donde $x_{ij}$ valdrá 1 si en la casilla (i,j) hay una dama y 0 si no.\n", 28 | "\n", 29 | "Daremos además a $J_{i_1,i_2,i_3,i_4}$ el valor 1 si las casillas $(i_1,i_2)$ y $(i_3, i_4)$ están conectadas y 0 en otro caso." 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 1, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "import qubovert\n", 39 | "\n", 40 | "size = 6\n", 41 | "lagrange = size ** 2\n", 42 | "\n", 43 | "# Creamos las variables de nuestro modelo\n", 44 | "Q = qubovert.QUBO()\n", 45 | "for i in range(size):\n", 46 | " for j in range(size):\n", 47 | " Q.create_var(f\"x_{i}_{j}\")\n", 48 | " \n", 49 | "# Añadimos el primer bloque de la función objetivo\n", 50 | "for i in range(size):\n", 51 | " for j in range(size):\n", 52 | " Q[(f\"x_{i}_{j}\",)] = -1\n", 53 | " \n", 54 | "# Incluimos las restricciones finales\n", 55 | "for i1 in range(size):\n", 56 | " for i2 in range(size):\n", 57 | " for i3 in range(size):\n", 58 | " for i4 in range(size):\n", 59 | " if i1 == i3 or i2 == i4 or i1 - i3 == i2 - i4 or i1 - i3 == i4 - i2:\n", 60 | " if not (i1 == i3 and i2 == i4):\n", 61 | " Q[(f\"x_{i1}_{i2}\", f\"x_{i3}_{i4}\")] = lagrange\n", 62 | " " 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "dwave_dic = {}\n", 72 | "for i in Q:\n", 73 | " if len(i) == 1:\n", 74 | " dwave_dic[(i[0],i[0])] = Q[i]\n", 75 | " else:\n", 76 | " dwave_dic[i] = Q[i]" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 5, 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "from neal import SimulatedAnnealingSampler\n", 86 | "#from dwave.system import DWaveSampler, EmbeddingComposite\n", 87 | "\n", 88 | "\n", 89 | "n_samples = 2000 # número de veces que ejecutamos el sistema\n", 90 | "\n", 91 | "\n", 92 | "sampler = SimulatedAnnealingSampler()\n", 93 | "#sampler = EmbeddingComposite(DWaveSampler())\n", 94 | "\n", 95 | "sampleset = sampler.sample_qubo(dwave_dic, num_reads = n_samples)\n", 96 | "solution = sampleset.first.sample" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 6, 102 | "metadata": {}, 103 | "outputs": [ 104 | { 105 | "name": "stdout", 106 | "output_type": "stream", 107 | "text": [ 108 | "O O O X O O \n", 109 | "X O O O O O \n", 110 | "O O O O X O \n", 111 | "O X O O O O \n", 112 | "O O O O O X \n", 113 | "O O X O O O \n" 114 | ] 115 | } 116 | ], 117 | "source": [ 118 | "for i in range(size):\n", 119 | " for j in range(size):\n", 120 | " if solution[f\"x_{i}_{j}\"] == 0:\n", 121 | " print(\"O\", end = \" \")\n", 122 | " else:\n", 123 | " print(\"X\", end = \" \")\n", 124 | " print()" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [] 133 | } 134 | ], 135 | "metadata": { 136 | "kernelspec": { 137 | "display_name": "Python 3", 138 | "language": "python", 139 | "name": "python3" 140 | }, 141 | "language_info": { 142 | "codemirror_mode": { 143 | "name": "ipython", 144 | "version": 3 145 | }, 146 | "file_extension": ".py", 147 | "mimetype": "text/x-python", 148 | "name": "python", 149 | "nbconvert_exporter": "python", 150 | "pygments_lexer": "ipython3", 151 | "version": "3.8.3" 152 | } 153 | }, 154 | "nbformat": 4, 155 | "nbformat_minor": 4 156 | } 157 | -------------------------------------------------------------------------------- /MisProyectos/MaxCut.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 8, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "def crear_ansantz(n, parametros):\n", 10 | " \n", 11 | " ansantz = QuantumCircuit(n)\n", 12 | " \n", 13 | " for i in range(n):\n", 14 | " \n", 15 | " ansantz.ry(parametros[i], i)\n", 16 | " \n", 17 | " for i in range(n-1, 0, -1):\n", 18 | " \n", 19 | " ansantz.cx(i, i-1)\n", 20 | " \n", 21 | " for i in range(n):\n", 22 | " \n", 23 | " ansantz.ry(parametros[i + n], i)\n", 24 | " \n", 25 | " return ansantz\n", 26 | " \n", 27 | " " 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "def resolver(H, crear_ansantz):\n", 37 | " \n", 38 | " params = np.random.rand(H.n_qubits * 2) * np.pi\n", 39 | " \n", 40 | " def func(params):\n", 41 | " return H.calcular_valor_esperado(crear_ansantz(H.n_qubits, params))\n", 42 | " \n", 43 | " solucion = scipy.optimize.minimize(fun = func, method = \"COBYLA\", x0 = params)\n", 44 | " \n", 45 | " circ = QuantumCircuit(H.n_qubits, H.n_qubits)\n", 46 | " circ += crear_ansantz(H.n_qubits, solucion['x'])\n", 47 | " circ.measure(range(H.n_qubits), range(H.n_qubits))\n", 48 | " \n", 49 | " backend = Aer.get_backend('qasm_simulator')\n", 50 | " job = execute(circ, backend, shots = 1)\n", 51 | " result = job.result().get_counts()\n", 52 | " return list(result.keys())[0]\n", 53 | " \n", 54 | " " 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 3, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "def aclarar_solucion(solucion):\n", 64 | " \n", 65 | " for i, color in enumerate(solucion):\n", 66 | " \n", 67 | " if color == '0':\n", 68 | " print(nodos[i], \"es de color rojo\")\n", 69 | " else:\n", 70 | " print(nodos[i], \"es de color azul\")" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 16, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "A es de color rojo\n", 83 | "B es de color azul\n", 84 | "C es de color azul\n", 85 | "D es de color azul\n", 86 | "E es de color rojo\n", 87 | "con un coste de 13.0\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "import hamiltoniano as hmt\n", 93 | "from qiskit import *\n", 94 | "import scipy\n", 95 | "import matplotlib.pyplot as plt\n", 96 | "import numpy as np\n", 97 | "\n", 98 | "nodos = ['A', 'B', 'C', 'D', 'E']\n", 99 | "\n", 100 | "\n", 101 | "pesos = {\n", 102 | " 'AB': 1,\n", 103 | " 'BA': 1,\n", 104 | " 'AC': 4,\n", 105 | " 'CA': 4,\n", 106 | " 'AD': 2,\n", 107 | " 'DA': 2,\n", 108 | " 'BE': 3,\n", 109 | " 'EB': 3,\n", 110 | " 'CD': 2,\n", 111 | " 'DC': 2,\n", 112 | " 'DE': 5,\n", 113 | " 'ED': 5\n", 114 | "}\n", 115 | "\n", 116 | "n_qubits = len(nodos)\n", 117 | "\n", 118 | "H = hmt.Hamiltoniano(n_qubits)\n", 119 | "for peso in pesos:\n", 120 | " \n", 121 | " termino1 = hmt.Termino_hamiltoniano([['Z', nodos.index(peso[0])],['Z', nodos.index(peso[1])]], \n", 122 | " n_qubits, pesos[peso]/2)\n", 123 | " \n", 124 | " H.incluir_termino(termino1)\n", 125 | "\n", 126 | " \n", 127 | "solucion = resolver(H, crear_ansantz)\n", 128 | "\n", 129 | "aclarar_solucion(solucion)\n", 130 | "\n", 131 | "circ_valor = QuantumCircuit(n_qubits)\n", 132 | "\n", 133 | "for i, color in enumerate(solucion):\n", 134 | " \n", 135 | " if color == '0':\n", 136 | " \n", 137 | " circ_valor.x(i)\n", 138 | " \n", 139 | "print(\"con un coste de\", -H.calcular_valor_esperado(circ_valor))" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [] 148 | } 149 | ], 150 | "metadata": { 151 | "kernelspec": { 152 | "display_name": "Python 3", 153 | "language": "python", 154 | "name": "python3" 155 | }, 156 | "language_info": { 157 | "codemirror_mode": { 158 | "name": "ipython", 159 | "version": 3 160 | }, 161 | "file_extension": ".py", 162 | "mimetype": "text/x-python", 163 | "name": "python", 164 | "nbconvert_exporter": "python", 165 | "pygments_lexer": "ipython3", 166 | "version": "3.8.3" 167 | } 168 | }, 169 | "nbformat": 4, 170 | "nbformat_minor": 4 171 | } 172 | -------------------------------------------------------------------------------- /DivisionEntera.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "id": "a71acecf", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "data": { 11 | "text/plain": [ 12 | "tensor([0, 1, 0], requires_grad=True)" 13 | ] 14 | }, 15 | "execution_count": 2, 16 | "metadata": {}, 17 | "output_type": "execute_result" 18 | } 19 | ], 20 | "source": [ 21 | "import pennylane as qml\n", 22 | "from pennylane import numpy as np\n", 23 | "\n", 24 | "\n", 25 | "def add_k_fourier(k, wires):\n", 26 | " for j in range(len(wires)):\n", 27 | " qml.RZ(k * np.pi / (2**j), wires=wires[j])\n", 28 | " \n", 29 | "def substract_m_n(wires_m, wires_n):\n", 30 | " # |m>|n> -> |m - n> |n>\n", 31 | " \n", 32 | " qml.QFT(wires = wires_m)\n", 33 | " \n", 34 | " \n", 35 | " for i in range(len(wires_n)):\n", 36 | " qml.ctrl(add_k_fourier, control=wires_n[i])(-2 **(len(wires_n) - i - 1), wires_m)\n", 37 | " \n", 38 | " qml.adjoint(qml.QFT)(wires = wires_m)\n", 39 | "\n", 40 | "dev = qml.device(\"default.qubit\", wires = 6, shots = 1)\n", 41 | "\n", 42 | "@qml.qnode(dev)\n", 43 | "def circuit():\n", 44 | " qml.BasisEmbedding(4, wires = range(3))\n", 45 | " qml.BasisEmbedding(2, wires = range(3,6))\n", 46 | " substract_m_n(range(3), range(3,6))\n", 47 | " return qml.sample(wires = range(3))\n", 48 | "\n", 49 | "circuit()" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "id": "ca846e2f", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "id": "b06e8f05", 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "data": { 68 | "text/plain": [ 69 | "tensor(1, requires_grad=True)" 70 | ] 71 | }, 72 | "execution_count": 3, 73 | "metadata": {}, 74 | "output_type": "execute_result" 75 | } 76 | ], 77 | "source": [ 78 | "def is_greater(wires_m, wires_n, wires_aux, wires_target):\n", 79 | " \n", 80 | " wires_m_aux = [wires_aux] + list(wires_m)\n", 81 | " substract_m_n(wires_m_aux, wires_n)\n", 82 | " \n", 83 | " qml.PauliX(wires = wires_aux)\n", 84 | " qml.CNOT(wires = [wires_aux, wires_target])\n", 85 | " qml.PauliX(wires = wires_aux)\n", 86 | " \n", 87 | " qml.adjoint(substract_m_n)(wires_m_aux, wires_n)\n", 88 | " \n", 89 | "dev = qml.device(\"default.qubit\", wires = 8, shots = 1)\n", 90 | "\n", 91 | "@qml.qnode(dev)\n", 92 | "def circuit():\n", 93 | " qml.BasisEmbedding(3, wires = range(3))\n", 94 | " qml.BasisEmbedding(3, wires = range(3,6))\n", 95 | " is_greater(range(3), range(3,6), 6, 7)\n", 96 | " return qml.sample(wires = 7)\n", 97 | "\n", 98 | "circuit()" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 4, 104 | "id": "44a0f6b3", 105 | "metadata": {}, 106 | "outputs": [ 107 | { 108 | "data": { 109 | "text/plain": [ 110 | "tensor([0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0], requires_grad=True)" 111 | ] 112 | }, 113 | "execution_count": 4, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "wires_dividendo = [0,1,2,3,4,5]\n", 120 | "wires_divisor = [6,7,8,9]\n", 121 | "wires_aux_dividendo = [10,11,12]\n", 122 | "wires_solucion = [13,14,15,16,17,18]\n", 123 | "wires_aux = 19\n", 124 | "\n", 125 | "def division(wires_dividendo, wires_divisor, wires_aux_dividendo, wires_solucion, wires_aux):\n", 126 | " \n", 127 | " wires_dividendo_totales = wires_aux_dividendo + wires_dividendo\n", 128 | " \n", 129 | " for i in range(len(wires_solucion)):\n", 130 | " window = wires_dividendo_totales[i - 1: len(wires_divisor)+ i]\n", 131 | " if i == 0:\n", 132 | " window = wires_dividendo_totales[0: len(wires_divisor)]\n", 133 | " is_greater(window, wires_divisor, wires_aux, wires_solucion[i])\n", 134 | " qml.ctrl(substract_m_n, control = wires_solucion[i])(window, wires_divisor)\n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | "dev = qml.device(\"default.qubit\", wires = 20, shots = 1)\n", 139 | "\n", 140 | "@qml.qnode(dev)\n", 141 | "def circuit():\n", 142 | " qml.BasisEmbedding(32, wires = wires_dividendo)\n", 143 | " qml.BasisEmbedding(13, wires = wires_divisor)\n", 144 | " division(wires_dividendo, wires_divisor, wires_aux_dividendo, wires_solucion, wires_aux)\n", 145 | " \n", 146 | " \n", 147 | " return qml.sample(wires = wires_dividendo + wires_divisor + wires_solucion)\n", 148 | "\n", 149 | "circuit()" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": null, 155 | "id": "044de658", 156 | "metadata": {}, 157 | "outputs": [], 158 | "source": [] 159 | } 160 | ], 161 | "metadata": { 162 | "kernelspec": { 163 | "display_name": "Python 3 (ipykernel)", 164 | "language": "python", 165 | "name": "python3" 166 | }, 167 | "language_info": { 168 | "codemirror_mode": { 169 | "name": "ipython", 170 | "version": 3 171 | }, 172 | "file_extension": ".py", 173 | "mimetype": "text/x-python", 174 | "name": "python", 175 | "nbconvert_exporter": "python", 176 | "pygments_lexer": "ipython3", 177 | "version": "3.11.1" 178 | } 179 | }, 180 | "nbformat": 4, 181 | "nbformat_minor": 5 182 | } 183 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/Mochila - Knapsack problem-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "COBYLA does not work\n" 13 | ] 14 | } 15 | ], 16 | "source": [ 17 | "import cirq\n", 18 | "import numpy as np\n", 19 | "import scipy\n", 20 | "import operator\n", 21 | "\n", 22 | "#Feel free to change these parameters\n", 23 | "\n", 24 | "L = 100 # Limit value\n", 25 | "objs = [60, 35, 23, 55, 70, 13] # weights of the items\n", 26 | "capas = 5 # number of layers\n", 27 | "initial = 0 # inizialization value\n", 28 | "methods = ['COBYLA'] # methods that you want to use\n", 29 | "\n", 30 | "\n", 31 | "\n", 32 | "\n", 33 | "n = len(objs) \n", 34 | "gamma = 2 / (n*L) \n", 35 | "\n", 36 | "class MyGate(cirq.Gate):\n", 37 | " \n", 38 | " def _descompose_(self, qs): \n", 39 | "\n", 40 | " \n", 41 | " for i in range(n):\n", 42 | " \n", 43 | " Rz = cirq.Z(qs[n]) ** (gamma * objs[i])\n", 44 | " yield Rz.controlled_by(qs[i])\n", 45 | "\n", 46 | " def _num_qubits_(self):\n", 47 | " return n + 1\n", 48 | " \n", 49 | " def num_qubits(self):\n", 50 | " return n + 1\n", 51 | " \n", 52 | " def _unitary_(self):\n", 53 | " return cirq.unitary(\n", 54 | " cirq.Circuit(self._descompose_(\n", 55 | " cirq.LineQubit.range(n + 1)))) \n", 56 | " \n", 57 | "def ansatz(params):\n", 58 | " \n", 59 | " qs = cirq.LineQubit.range(n + 2)\n", 60 | " ansatz = cirq.Circuit()\n", 61 | " \n", 62 | " for j in range(capas):\n", 63 | " \n", 64 | " ansatz.append([cirq.X(qs[i]) ** params[i + 2*j*n] for i in range(n)])\n", 65 | " ansatz.append([cirq.CX(qs[aux[0]], qs[aux[1]]) \n", 66 | " for aux in [[i,i+1] for i in range(n - 1)]])\n", 67 | " ansatz.append([cirq.Z(qs[i]) ** params[i + (2*j+1)*n] for i in range(n)])\n", 68 | " ansatz.append([cirq.CX(qs[aux[0]], qs[aux[1]]) \n", 69 | " for aux in [[i,i+1] for i in range(n - 1)]])\n", 70 | " \n", 71 | "\n", 72 | "\n", 73 | " return ansatz\n", 74 | "\n", 75 | "def expected_values(params):\n", 76 | " \n", 77 | " sol = []\n", 78 | " \n", 79 | " for i in range(2):\n", 80 | "\n", 81 | " qs = cirq.LineQubit.range(n + 2)\n", 82 | " circuit = cirq.Circuit()\n", 83 | " circuit.append(cirq.X(qs[n]))\n", 84 | " cg = cirq.ControlledGate(MyGate())\n", 85 | " circuit.append(cirq.H(qs[n + 1]))\n", 86 | " circuit.append(cirq.S(qs[n + 1]) ** i)\n", 87 | " circuit.append(cg(qs[n + 1], *[qs[i] for i in range(n + 1)])) \n", 88 | " circuit.append(cirq.H(qs[n + 1]))\n", 89 | "\n", 90 | " circuit.append(cirq.measure(qs[n + 1]))\n", 91 | " circuit = ansatz(params) + circuit\n", 92 | " s = cirq.Simulator()\n", 93 | " rep = 1000\n", 94 | " sol.append(s.run(circuit, repetitions = rep))\n", 95 | "\n", 96 | " real = 2 * int(str(sol[0]).count('0')) / rep - 1\n", 97 | " img = - 2 * int(str(sol[1]).count('0')) / rep + 1\n", 98 | " \n", 99 | " if np.sin(L * gamma * np.pi) - img < 0:\n", 100 | " return 3\n", 101 | " else:\n", 102 | " return np.abs(np.cos(L * gamma * np.pi) - real) \n", 103 | " \n", 104 | " \n", 105 | "def solucion(method,n):\n", 106 | " \n", 107 | " initial_params = np.array([initial]*(2*capas*n))\n", 108 | " minimum = scipy.optimize.minimize(expected_values,\n", 109 | " initial_params, method=metodo)\n", 110 | " final = cirq.Circuit()\n", 111 | " qs = cirq.LineQubit.range(n + 2)\n", 112 | " final =ansatz(minimum.x)\n", 113 | " final.append(cirq.measure(*[qs[i] for i in range(n)] , key = 'm'))\n", 114 | "\n", 115 | " s = cirq.Simulator()\n", 116 | " rep = 10000\n", 117 | " sol = s.run(final, repetitions = rep)\n", 118 | "\n", 119 | " solucion = max(sol.histogram(key = 'm').items(),\n", 120 | " key=operator.itemgetter(1))[0]\n", 121 | " times = max(sol.histogram(key = 'm').items(), \n", 122 | " key=operator.itemgetter(1))[1]\n", 123 | "\n", 124 | " suma = 0\n", 125 | "\n", 126 | " print(\"to approach the value \", L, \" without going over, we must take: \")\n", 127 | " for i, n in enumerate(np.binary_repr(solucion,n)):\n", 128 | " suma += int(n)*objs[i]\n", 129 | " if int(n) == 1:\n", 130 | " print(\"obj \", i + 1, \" with value \",objs[i])\n", 131 | "\n", 132 | " print(\"METHOD: \", method)\n", 133 | " print(\"sum: \",suma, \"percentage: \", 100* times / rep , \"%\")\n", 134 | "\n", 135 | " \n", 136 | "\n", 137 | "for method in methods:\n", 138 | " try:\n", 139 | " solucion(method,n)\n", 140 | " except:\n", 141 | " print(method, \" does not work\")\n", 142 | " \n" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [] 151 | } 152 | ], 153 | "metadata": { 154 | "kernelspec": { 155 | "display_name": "Python 3", 156 | "language": "python", 157 | "name": "python3" 158 | }, 159 | "language_info": { 160 | "codemirror_mode": { 161 | "name": "ipython", 162 | "version": 3 163 | }, 164 | "file_extension": ".py", 165 | "mimetype": "text/x-python", 166 | "name": "python", 167 | "nbconvert_exporter": "python", 168 | "pygments_lexer": "ipython3", 169 | "version": "3.7.6" 170 | } 171 | }, 172 | "nbformat": 4, 173 | "nbformat_minor": 2 174 | } 175 | -------------------------------------------------------------------------------- /vqe_casero.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# objetivo: minimizar f(x0, x1, x2) = 2.x0 -4.x0.x1 + 3.x1.x2\n", 10 | "\n", 11 | "# haciendo el cambio xi = (1-zi)/2 llegamos a que queremos minimizar:\n", 12 | "\n", 13 | "# g(z0, z1, z2) = 3/4 + z1/4 -3.z2/4 - z0.z1 + 3.z1.z2/4\n", 14 | "\n", 15 | "#solución óptima:\n", 16 | " # 1 1 0 en QUBO\n", 17 | " # -1 -1 1 en Ising" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# creamos cada uno de los circuitos\n", 27 | "\n", 28 | "import pennylane as qml\n", 29 | "\n", 30 | "variables = 3\n", 31 | "dev = qml.device(\"default.qubit\", wires = variables, shots = 1000)\n", 32 | "\n", 33 | "def phi():\n", 34 | " qml.PauliX(wires = 1) \n", 35 | " qml.PauliX(wires = 2)\n", 36 | " \n", 37 | "@qml.qnode(dev)\n", 38 | "def circ1():\n", 39 | " phi()\n", 40 | " return qml.expval(qml.Identity(wires = 0) @ qml.Identity(wires = 1) @ qml.Identity(wires = 2))\n", 41 | "\n", 42 | "@qml.qnode(dev)\n", 43 | "def circ2():\n", 44 | " phi()\n", 45 | " #return qml.expval(qml.PauliZ(wires = 1))\n", 46 | " return qml.expval(qml.Identity(wires = 0) @ qml.PauliZ(wires = 1) @ qml.Identity(wires = 2))\n", 47 | "\n", 48 | "@qml.qnode(dev)\n", 49 | "def circ3():\n", 50 | " phi()\n", 51 | " return qml.expval(qml.Identity(wires = 0) @ qml.Identity(wires = 1) @ qml.PauliZ(wires = 2))\n", 52 | "\n", 53 | "@qml.qnode(dev)\n", 54 | "def circ4():\n", 55 | " phi()\n", 56 | " return qml.expval(qml.PauliZ(wires = 0) @ qml.PauliZ(wires = 1) @ qml.Identity(wires = 2))\n", 57 | "\n", 58 | "@qml.qnode(dev)\n", 59 | "def circ5():\n", 60 | " phi()\n", 61 | " return qml.expval(qml.Identity(wires = 0) @ qml.PauliZ(wires = 1) @ qml.PauliZ(wires = 2))\n", 62 | "\n", 63 | "\n", 64 | "def value():\n", 65 | " return 3*circ1()/4 + circ2()/4 - 3*circ3()/4 - circ4() + 3*circ5()/4\n", 66 | "\n", 67 | "value()" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 17, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "epoch 0 loss -0.351\n", 80 | "epoch 50 loss -0.6324999999999998\n", 81 | "epoch 100 loss -0.9185\n", 82 | "epoch 150 loss -1.294\n", 83 | "epoch 200 loss -1.5235\n", 84 | "epoch 250 loss -1.72\n", 85 | "epoch 300 loss -1.8314999999999997\n", 86 | "epoch 350 loss -1.8990000000000002\n", 87 | "epoch 400 loss -1.9409999999999998\n", 88 | "epoch 450 loss -1.962\n", 89 | "epoch 500 loss -1.968\n" 90 | ] 91 | }, 92 | { 93 | "data": { 94 | "text/plain": [ 95 | "array([[-1],\n", 96 | " [-1],\n", 97 | " [ 1]])" 98 | ] 99 | }, 100 | "execution_count": 17, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "# creamos cada uno de los circuitos\n", 107 | "\n", 108 | "import pennylane as qml\n", 109 | "\n", 110 | "variables = 3\n", 111 | "dev = qml.device(\"default.qubit\", wires = variables, shots = 1000)\n", 112 | "\n", 113 | "@qml.template\n", 114 | "def phi(w):\n", 115 | " qml.RX(w[0], wires = 0)\n", 116 | " qml.RX(w[1], wires = 1)\n", 117 | " qml.RX(w[2], wires = 2)\n", 118 | " \n", 119 | "@qml.qnode(dev)\n", 120 | "def circ1(w):\n", 121 | " phi(w)\n", 122 | " return qml.expval(qml.Identity(wires = 0) @ qml.Identity(wires = 1) @ qml.Identity(wires = 2))\n", 123 | "\n", 124 | "@qml.qnode(dev)\n", 125 | "def circ2(w):\n", 126 | " phi(w)\n", 127 | " #return qml.expval(qml.PauliZ(wires = 1))\n", 128 | " return qml.expval(qml.Identity(wires = 0) @ qml.PauliZ(wires = 1) @ qml.Identity(wires = 2))\n", 129 | "\n", 130 | "@qml.qnode(dev)\n", 131 | "def circ3(w):\n", 132 | " phi(w)\n", 133 | " return qml.expval(qml.Identity(wires = 0) @ qml.Identity(wires = 1) @ qml.PauliZ(wires = 2))\n", 134 | "\n", 135 | "@qml.qnode(dev)\n", 136 | "def circ4(w):\n", 137 | " phi(w)\n", 138 | " return qml.expval(qml.PauliZ(wires = 0) @ qml.PauliZ(wires = 1) @ qml.Identity(wires = 2))\n", 139 | "\n", 140 | "@qml.qnode(dev)\n", 141 | "def circ5(w):\n", 142 | " phi(w)\n", 143 | " return qml.expval(qml.Identity(wires = 0) @ qml.PauliZ(wires = 1) @ qml.PauliZ(wires = 2))\n", 144 | "\n", 145 | "\n", 146 | "def value(w):\n", 147 | " return 3*circ1(w)/4 + circ2(w)/4 - 3*circ3(w)/4 - circ4(w) + 3*circ5(w)/4\n", 148 | "\n", 149 | "w = qml.numpy.random.rand(3) * 2*3.14\n", 150 | "\n", 151 | "gradient_fn_w = qml.grad(value, argnum=0)\n", 152 | "\n", 153 | "lr = 0.005\n", 154 | "for epoch in range(501):\n", 155 | " w = w - lr*gradient_fn_w(w)\n", 156 | " if epoch % 50 == 0:\n", 157 | " print(\"epoch\", epoch, \"loss\", value(w))\n", 158 | "\n", 159 | "@qml.qnode(qml.device(\"default.qubit\", wires = variables, shots = 1)\n", 160 | ")\n", 161 | "def solucion(w):\n", 162 | " phi(w)\n", 163 | " return [qml.sample(qml.PauliZ(i)) for i in range(3)]\n", 164 | "\n", 165 | "solucion(w)" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": null, 171 | "metadata": {}, 172 | "outputs": [], 173 | "source": [] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": null, 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": null, 185 | "metadata": {}, 186 | "outputs": [], 187 | "source": [] 188 | } 189 | ], 190 | "metadata": { 191 | "kernelspec": { 192 | "display_name": "Python 3 (ipykernel)", 193 | "language": "python", 194 | "name": "python3" 195 | }, 196 | "language_info": { 197 | "codemirror_mode": { 198 | "name": "ipython", 199 | "version": 3 200 | }, 201 | "file_extension": ".py", 202 | "mimetype": "text/x-python", 203 | "name": "python", 204 | "nbconvert_exporter": "python", 205 | "pygments_lexer": "ipython3", 206 | "version": "3.8.3" 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 4 211 | } 212 | -------------------------------------------------------------------------------- /Mochila - Knapsack problem.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 6, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "to approach the value 100 without going over, we must take: \n", 13 | "obj 3 with value 23\n", 14 | "obj 5 with value 70\n", 15 | "METHOD: COBYLA\n", 16 | "sum: 93 percentage: 48.06 %\n", 17 | "to approach the value 100 without going over, we must take: \n", 18 | "METHOD: SLSQP\n", 19 | "sum: 0 percentage: 100.0 %\n", 20 | "to approach the value 100 without going over, we must take: \n", 21 | "METHOD: BFGS\n", 22 | "sum: 0 percentage: 100.0 %\n" 23 | ] 24 | } 25 | ], 26 | "source": [ 27 | "import cirq\n", 28 | "import numpy as np\n", 29 | "import scipy\n", 30 | "import operator\n", 31 | "\n", 32 | "# Input parameters. Feel free to change them.\n", 33 | "L = 100 # Limit value\n", 34 | "objs = [60, 35, 23, 55, 70, 13] # weights of the items\n", 35 | "capas = 5 # number of layers\n", 36 | "initial = 0 # inizialization value\n", 37 | "methods = ['COBYLA','SLSQP','BFGS'] # methods that you want to use\n", 38 | "# See https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize for available methods\n", 39 | "\n", 40 | "n = len(objs) \n", 41 | "gamma = 2 / (n*L) \n", 42 | "\n", 43 | "class ParametrizedGate(cirq.Gate):\n", 44 | " \n", 45 | " def _decompose_(self, qs): \n", 46 | " for i in range(n):\n", 47 | " Rz = cirq.Z(qs[n]) ** (gamma * objs[i])\n", 48 | " yield Rz.controlled_by(qs[i])\n", 49 | "\n", 50 | " def _num_qubits_(self):\n", 51 | " return n + 1\n", 52 | " \n", 53 | " def _unitary_(self):\n", 54 | " return cirq.unitary(\n", 55 | " cirq.Circuit(self._decompose_(cirq.LineQubit.range(n + 1)))) \n", 56 | " \n", 57 | "def ansatz(params):\n", 58 | " \n", 59 | " qs = cirq.LineQubit.range(n + 2)\n", 60 | " ansatz = cirq.Circuit()\n", 61 | " \n", 62 | " for j in range(capas):\n", 63 | " \n", 64 | " ansatz.append([cirq.X(qs[i]) ** params[i + 2*j*n] for i in range(n)])\n", 65 | " ansatz.append([cirq.CX(qs[aux[0]], qs[aux[1]]) \n", 66 | " for aux in [[i,i+1] for i in range(n - 1)]])\n", 67 | " ansatz.append([cirq.Z(qs[i]) ** params[i + (2*j+1)*n] for i in range(n)])\n", 68 | " ansatz.append([cirq.CX(qs[aux[0]], qs[aux[1]]) \n", 69 | " for aux in [[i,i+1] for i in range(n - 1)]])\n", 70 | "\n", 71 | " return ansatz\n", 72 | "\n", 73 | "def expected_values(params):\n", 74 | " \n", 75 | " sol = []\n", 76 | " \n", 77 | " for i in range(2):\n", 78 | "\n", 79 | " qs = cirq.LineQubit.range(n + 2)\n", 80 | " circuit = cirq.Circuit()\n", 81 | " circuit.append(cirq.X(qs[n]))\n", 82 | " cg = cirq.ControlledGate(ParametrizedGate())\n", 83 | " circuit.append(cirq.H(qs[n + 1]))\n", 84 | " circuit.append(cirq.S(qs[n + 1]) ** i)\n", 85 | " circuit.append(cg(qs[n + 1], *[qs[i] for i in range(n + 1)])) \n", 86 | " circuit.append(cirq.H(qs[n + 1]))\n", 87 | "\n", 88 | " circuit.append(cirq.measure(qs[n + 1]))\n", 89 | " circuit = ansatz(params) + circuit\n", 90 | " s = cirq.Simulator()\n", 91 | " rep = 1000\n", 92 | " sol.append(s.run(circuit, repetitions = rep))\n", 93 | "\n", 94 | " real = 2 * int(str(sol[0]).count('0')) / rep - 1\n", 95 | " img = - 2 * int(str(sol[1]).count('0')) / rep + 1\n", 96 | " \n", 97 | " if np.sin(L * gamma * np.pi) - img < 0:\n", 98 | " return 3\n", 99 | " else:\n", 100 | " return np.abs(np.cos(L * gamma * np.pi) - real) \n", 101 | " \n", 102 | " \n", 103 | "def solution(method,n):\n", 104 | " \n", 105 | " initial_params = np.array([initial]*(2*capas*n))\n", 106 | " minimum = scipy.optimize.minimize(expected_values,\n", 107 | " initial_params, method=method)\n", 108 | " final = cirq.Circuit()\n", 109 | " qs = cirq.LineQubit.range(n + 2)\n", 110 | " final =ansatz(minimum.x)\n", 111 | " final.append(cirq.measure(*[qs[i] for i in range(n)] , key = 'm'))\n", 112 | "\n", 113 | " s = cirq.Simulator()\n", 114 | " rep = 10000\n", 115 | " sol = s.run(final, repetitions = rep)\n", 116 | "\n", 117 | " result = max(sol.histogram(key = 'm').items(),\n", 118 | " key=operator.itemgetter(1))[0]\n", 119 | " times = max(sol.histogram(key = 'm').items(), \n", 120 | " key=operator.itemgetter(1))[1]\n", 121 | "\n", 122 | " sum = 0\n", 123 | " print(\"to approach the value \", L, \" without going over, we must take: \")\n", 124 | " for i, n in enumerate(np.binary_repr(result,n)):\n", 125 | " sum += int(n) * objs[i]\n", 126 | " if int(n) == 1:\n", 127 | " print(\"obj \", i + 1, \" with value \", objs[i])\n", 128 | "\n", 129 | " print(\"METHOD: \", method)\n", 130 | " print(\"sum: \",sum, \"percentage: \", 100* times / rep , \"%\")\n", 131 | "\n", 132 | " \n", 133 | "\n", 134 | "for method in methods:\n", 135 | " try:\n", 136 | " solution(method,n)\n", 137 | " except Exception as e:\n", 138 | " print(method, \" does not work\")\n", 139 | " print('Exception: ' + str(e)) # Printing exact error for debugging if necessary\n", 140 | " \n" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [] 147 | } 148 | ], 149 | "metadata": { 150 | "kernelspec": { 151 | "display_name": "Python 3", 152 | "language": "python", 153 | "name": "python3" 154 | }, 155 | "language_info": { 156 | "codemirror_mode": { 157 | "name": "ipython", 158 | "version": 3 159 | }, 160 | "file_extension": ".py", 161 | "mimetype": "text/x-python", 162 | "name": "python", 163 | "nbconvert_exporter": "python", 164 | "pygments_lexer": "ipython3", 165 | "version": "3.7.6" 166 | } 167 | }, 168 | "nbformat": 4, 169 | "nbformat_minor": 2 170 | } 171 | -------------------------------------------------------------------------------- /MisProyectos/Hamiltoniano.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 146, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "from qiskit import *\n", 17 | "\n", 18 | "class Termino_hamiltoniano():\n", 19 | " \n", 20 | " def __init__(self, paulis, n_qubits, constante = 1):\n", 21 | " \n", 22 | " self.paulis = paulis\n", 23 | " self.n_qubits = n_qubits\n", 24 | " self.constante = constante\n", 25 | " \n", 26 | " def simplificar_termino(self):\n", 27 | " \n", 28 | " simplificacion = []\n", 29 | " qubits_recorridos = []\n", 30 | " \n", 31 | " for pauli, qubit in self.paulis:\n", 32 | "\n", 33 | " if qubit not in qubits_recorridos:\n", 34 | " \n", 35 | " qubits_recorridos.append(qubit)\n", 36 | " simplificacion.append([pauli, qubit])\n", 37 | "\n", 38 | " else:\n", 39 | " \n", 40 | " pauli_actual = simplificacion[qubits_recorridos.index(qubit)][0]\n", 41 | " nueva_pauli, constante = self.reducir_paulis(pauli_actual, pauli)\n", 42 | " \n", 43 | " if nueva_pauli == 'I':\n", 44 | " \n", 45 | " simplificacion.remove([pauli_actual, qubit])\n", 46 | " qubits_recorridos.remove(qubit)\n", 47 | " \n", 48 | " else:\n", 49 | " \n", 50 | " simplificacion[qubits_recorridos.index(qubit)][0] = nueva_pauli\n", 51 | " self.constante *= constante\n", 52 | " \n", 53 | " return simplificacion\n", 54 | " \n", 55 | " def reducir_paulis(self, pauli1, pauli2):\n", 56 | " \n", 57 | " paulis = ['X', 'Y', 'Z']\n", 58 | " \n", 59 | " if paulis.index(pauli1) < paulis.index(pauli2):\n", 60 | " return set(paulis).difference(set([pauli1, pauli2])).pop(), complex('j')\n", 61 | " \n", 62 | " elif paulis.index(pauli1) > paulis.index(pauli2):\n", 63 | " return set(paulis).difference(set([pauli1, pauli2])).pop(), complex('-j')\n", 64 | " \n", 65 | " else:\n", 66 | " return 'I', 1\n", 67 | " \n", 68 | " def calcular_valor_esperado(self, circ_estado):\n", 69 | " \n", 70 | " puerta_estado = circ_estado.to_gate()\n", 71 | " \n", 72 | " termino_simp = self.simplificar_termino()\n", 73 | " qubits_interes = len(termino_simp)\n", 74 | " \n", 75 | " circuito = QuantumCircuit(self.n_qubits, qubits_interes)\n", 76 | " circuito.append(puerta_estado, range(self.n_qubits))\n", 77 | " \n", 78 | " for i, termino in enumerate(termino_simp):\n", 79 | " \n", 80 | " pauli, qubit = termino\n", 81 | " \n", 82 | " if pauli == 'X':\n", 83 | " circuito.h(qubit)\n", 84 | " \n", 85 | " \n", 86 | " elif pauli == 'Y':\n", 87 | " circuito.sdg(i)\n", 88 | " circuito.h(i)\n", 89 | " \n", 90 | " circuito.measure(qubit, i)\n", 91 | " \n", 92 | " conteo = self.ejecutar_circuito(circuito)\n", 93 | " solucion = 0\n", 94 | " for num in conteo:\n", 95 | " solucion += conteo[num] * (-1) ** (num.count('1'))\n", 96 | " return solucion * self.constante\n", 97 | " \n", 98 | " def ejecutar_circuito(self, circ):\n", 99 | " \n", 100 | " # devuelve la probabilidad de cada estado\n", 101 | " \n", 102 | " shots = 10000\n", 103 | " backend = Aer.get_backend(\"qasm_simulator\")\n", 104 | " job = execute(circ, backend, shots = shots)\n", 105 | " counts = job.result().get_counts()\n", 106 | " \n", 107 | " for clave in counts:\n", 108 | " counts[clave] /= shots\n", 109 | " \n", 110 | " return counts" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 147, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "class Hamiltoniano():\n", 120 | " \n", 121 | " def __init__(self):\n", 122 | " \n", 123 | " self.terminos = []\n", 124 | " \n", 125 | " def incluir_termino(self, termino):\n", 126 | " self.terminos.append(termino)\n", 127 | " \n", 128 | " def calcular_valor_esperado(self, circuito_estado):\n", 129 | " \n", 130 | " solucion = 0\n", 131 | " \n", 132 | " for termino in self.terminos:\n", 133 | " \n", 134 | " solucion += termino.calcular_valor_esperado(circuito_estado)\n", 135 | " \n", 136 | " return solucion" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 190, 142 | "metadata": {}, 143 | "outputs": [ 144 | { 145 | "data": { 146 | "text/plain": [ 147 | "(1.9796+0j)" 148 | ] 149 | }, 150 | "execution_count": 190, 151 | "metadata": {}, 152 | "output_type": "execute_result" 153 | } 154 | ], 155 | "source": [ 156 | "n_qubits = 4\n", 157 | "\n", 158 | "ansantz = QuantumCircuit(n_qubits)\n", 159 | "\n", 160 | "\n", 161 | "H = Hamiltoniano()\n", 162 | "\n", 163 | "# un término consta de una lista con las puertas de pauli y \n", 164 | "# el qubit que ocupan, el nº de qubits y el coeficiente de este término\n", 165 | "\n", 166 | "H.incluir_termino(Termino_hamiltoniano([['Z', 0], ['X', 0], ['Y', 1], ['Z', 2], ['Y', 2]], n_qubits, 3))\n", 167 | "H.incluir_termino(Termino_hamiltoniano([['Z', 0], ['Z', 1], ['X', 1], ['Z', 2], ['X', 2]], n_qubits, 0))\n", 168 | "H.incluir_termino(Termino_hamiltoniano([['Z', 0]], n_qubits, 2))\n", 169 | "\n", 170 | "H.calcular_valor_esperado(ansantz)" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 3", 184 | "language": "python", 185 | "name": "python3" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.8.3" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 4 202 | } 203 | -------------------------------------------------------------------------------- /QuantumPhaseEstimation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "fafb0933", 6 | "metadata": {}, 7 | "source": [ 8 | "# Estimación de Fase Cuántica\n", 9 | "\n", 10 | "![img](qpe_ketg.jpeg)" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "id": "e4cec683", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import pennylane as qml\n", 21 | "import numpy as np\n", 22 | "\n", 23 | "target_wires = [0]\n", 24 | "estimation_wires = [1,2,3]\n", 25 | "\n", 26 | "\n", 27 | "dev = qml.device(\"default.qubit\", wires = target_wires + estimation_wires)\n", 28 | "\n", 29 | "@qml.qnode(dev)\n", 30 | "def qpe():\n", 31 | " \n", 32 | " \n", 33 | " # Codificamos el autovector\n", 34 | " qml.PauliX(wires = target_wires)\n", 35 | "\n", 36 | " # Aplicamos Hadamards y controls\n", 37 | " \n", 38 | " for wire in estimation_wires:\n", 39 | " qml.Hadamard(wires = wire)\n", 40 | " \n", 41 | " for ind, wire in enumerate(estimation_wires):\n", 42 | " qml.ctrl(qml.PhaseShift, control = wire)(2 * np.pi * 0.3 * 2 ** (len(estimation_wires) - ind -1), wires = target_wires)\n", 43 | " \n", 44 | " # Aplicamos QFT inversa\n", 45 | " \n", 46 | " qml.adjoint(qml.QFT)(wires = estimation_wires)\n", 47 | " \n", 48 | " return qml.probs(wires = estimation_wires)\n", 49 | " \n" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 2, 55 | "id": "215d4ef1", 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "data": { 60 | "text/plain": [ 61 | "" 62 | ] 63 | }, 64 | "execution_count": 2, 65 | "metadata": {}, 66 | "output_type": "execute_result" 67 | }, 68 | { 69 | "data": { 70 | "image/png": "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\n", 71 | "text/plain": [ 72 | "
" 73 | ] 74 | }, 75 | "metadata": { 76 | "needs_background": "light" 77 | }, 78 | "output_type": "display_data" 79 | } 80 | ], 81 | "source": [ 82 | "import matplotlib.pyplot as plt\n", 83 | "\n", 84 | "output = qpe()\n", 85 | "plt.bar(range(len(output)), output)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 3, 91 | "id": "beeefe81", 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "estimación: 0.25\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "print(\"estimación: \", np.argmax(output) / 2 ** len(estimation_wires))" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "id": "b541a775", 110 | "metadata": {}, 111 | "outputs": [], 112 | "source": [] 113 | } 114 | ], 115 | "metadata": { 116 | "kernelspec": { 117 | "display_name": "Python 3 (ipykernel)", 118 | "language": "python", 119 | "name": "python3" 120 | }, 121 | "language_info": { 122 | "codemirror_mode": { 123 | "name": "ipython", 124 | "version": 3 125 | }, 126 | "file_extension": ".py", 127 | "mimetype": "text/x-python", 128 | "name": "python", 129 | "nbconvert_exporter": "python", 130 | "pygments_lexer": "ipython3", 131 | "version": "3.8.9" 132 | } 133 | }, 134 | "nbformat": 4, 135 | "nbformat_minor": 5 136 | } 137 | -------------------------------------------------------------------------------- /EstimandoPi.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "id": "00f205ed", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import pennylane as qml\n", 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 7, 17 | "id": "47f9682a", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "dev = qml.device(\"default.qubit\", wires = 1)\n", 22 | "\n", 23 | "@qml.qnode(dev)\n", 24 | "def circuit(theta):\n", 25 | " qml.RX(theta, wires = 0)\n", 26 | " return qml.probs(wires = 0)\n", 27 | "\n", 28 | "def probs_0(theta):\n", 29 | " return circuit(theta)[0]\n", 30 | "\n", 31 | "opt = qml.GradientDescentOptimizer(stepsize = 0.2)\n", 32 | "\n", 33 | "epochs = 150\n", 34 | "\n", 35 | "sols = []\n", 36 | "theta = np.random.rand()\n", 37 | "for epoch in range(epochs):\n", 38 | " theta = opt.step(probs_0, theta)\n", 39 | " sols.append(theta)\n", 40 | " " 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 9, 46 | "id": "79232d82", 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "data": { 51 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAhn0lEQVR4nO3deXxV9Z3/8dcnGwHCEnYlQACRRWSNgLih1QqWQu1oq3WprRZ07Iz9TTtW245O23nMrzP153SsU3z4qLbi7rhQdcQFdx0Q2QkEZCcJZMUEwpL18/vjXmjEhFzITc69N+/n43HNveece+6bYN6cfO8532vujoiIxL+koAOIiEh0qNBFRBKECl1EJEGo0EVEEoQKXUQkQaQE9cJ9+vTx7OzsoF5eRCQurVy5sszd+za1LrBCz87OZsWKFUG9vIhIXDKzXc2t05CLiEiCUKGLiCQIFbqISIJQoYuIJAgVuohIglChi4gkCBW6iEiCCOw89FO2+C4oWh90CukAHMcdHHB3GrzRMg8tc6DBQ8tCzwn9J7SG5pcfexxe32gaa2/0vOMT/fW/je80t+UJ1rc4a/Zxr9XMjjX59qmx08aRde1/Rn2/8VfoIsdxnLoGp77BqasPfa1vaPjrsvDXhnApN4Tv17vT0EB4eaN1eASFJ3LqUrocJqst9tsG+2xbs34TdAJpJ+5OWVUNhRWHKfz8MIUVhyjeX01ZVehWXlVDWVU1+w7W0NBCAWd0SqFzWjKdU5Pp3CmZ9LRk0lOS/ros9eiyZFJTjNSkJFKSjdTkJFKTjZSk0NfU5CRSmlxmJCcZSXb0BklJje6bYUajbcDC2yaH14W259g+zMDC+c1C9/76OPyVY3caLYvsOUcf08L6Fvd3/I4kMPFX6JJwDhypZWtJFVuKq9hScoAtJVXsKj9EYcVhauoavrBtl7Rk+mR0ondGGoN6dWHi4Ez6ZKSR2SWNHp1T6d45lW7pKXRPT6V75xS6d04lIy2FpCSVjiQ+Fbq0q4pDNazJr2BNfgVr8yvYXHSAPZVHjq3vlJLE8L4ZjDmtO5eN6c/Anp0Z2LMzp/fszMDMzvTonBpgepHYpkKXNlV5uJal28r5eGsZH28rY3vpQSD06/qIfhlMHdabM/plcGb/bozol8GgXl1I1tG0yClRoUvU7So/yOLcIl7PLWJdQQUNHhoqmTq0F38zKYuJg3pydlYPuqXraFskmlToEhV7Kw/z4qpCXlu/lw179gMwLqsHf3fJCM4f0YfxWT1JS9FlDyJtqcVCN7N04AOgU3j759393uO2MeA/gSuAQ8BN7r4q+nElltQ3OB9sKeXJZbt5Z1MxDQ6TBvfkF18bzcyxA8jK7BJ0RJEOJZIj9GrgEnevMrNU4CMzW+zuyxptMwsYEb5NBRaEv0oCOlJbz3Mr8nn4g+0UfH6YPhlpzL9oONeeM5jBvVXiIkFpsdA9dAlbVfhhavh2/Fm/c4GF4W2XmVlPMzvN3fdGNa0E6khtPc8s382C97dRvL+anCGZ3D1rNJeN6a/hFJEYENEYupklAyuBM4D/cvdPjttkIJDf6HFBeNkXCt3M5gHzAAYPHnyKkaW9uTsvrirk39/YRPH+aqYM7cV/fGsC5w7vrYtKRGJIRIXu7vXABDPrCbxkZmPdPbfRJk39VH95Ggj3h4GHAXJycnRxdRz4rPgAv1iUy/Id+5g4uCe/+/ZEzh3eO+hYItKEkzrLxd0rzOw9YCbQuNALgEGNHmcBe1qdTgJzuKae3739GY98uIOM9BR+882z+VbOIF1xKRLDIjnLpS9QGy7zzsClwL8dt9nLwA/N7BlCb4ZWavw8fuUWVvL3z6xme+lBrp6cxV2zRtE7o1PQsUSkBZEcoZ8GPBYeR08CnnP3V83sVgB3fwh4jdApi1sJnbb4vTbKK23I3fnz/+7kX1/Lo1fXNJ68ZSrnndEn6FgiEqFIznJZB0xsYvlDje47cHt0o0l7OlxTz90vrmPRmj1cOrofv71qPJld04KOJSInQVeKCqUHqrn5sU9ZX1jJjy87k9svPkNj5SJxSIXewW0rreK7jy6nrKqah2/I4bIx/YOOJCKnSIXegW0q2s/1f/wEd3h23rmMH9Qz6Egi0goq9A4qt7CS6x/5hPSUZJ78wVSG980IOpKItJIKvQPaUnyAGx75hK5pKTz1g6kM6d016EgiEgWagKODyd93iBseWU5yUhJP3qIyF0kkKvQOpPJwLTf9aTmHaup4/OYpZPdRmYskEg25dBC19Q387ZMr2b3vEE/cPJXRp3UPOpKIRJkKvYP41Ssb+XhrOfddPZ6pwzS5lkgi0pBLB/DS6gIeX7aLeRcO46rJWUHHEZE2okJPcJuLDvCzF3OZMrQXd14+Mug4ItKGVOgJ7EhtPT98ahVdO6Xw4LUTSUnWX7dIItMYegL7zeJNbCmpYuH3p9Cve3rQcUSkjemQLUF9uKWUP//vTm6ans2FZ/YNOo6ItAMVegKqqq7jp8+v44x+Gdw1a1TQcUSknWjIJQHd98Zm9u4/wgu3TSc9NTnoOCLSTnSEnmBW7/6cx5bu5MZpQ5g0ODPoOCLSjlToCaSuvoGfvZTLgO7p/ONMDbWIdDQq9ATy9Kf55O3dzz/NHkNGJ42miXQ0KvQEUXGohvvf3My0Yb2YNXZA0HFEJAAq9ATxuyVbqDxcy71fPwszfR6oSEekQk8AO8oO8viyXVw7ZbBmURTpwFToCeD+tz4jLTmJOy4dEXQUEQmQCj3O5RZW8sraPdx8/lD6ddPl/SIdmQo9zv32jc307JLKvIuGBR1FRALWYqGb2SAze9fM8sxsg5nd0cQ2M8ys0szWhG/3tE1caWz17s95/7NSbr1oON3TU4OOIyIBi+Rk5Trgx+6+ysy6ASvN7C1333jcdh+6++zoR5Tm/P6drWR2SeWGaUOCjiIiMaDFI3R33+vuq8L3DwB5wMC2DiYnlltYyTubSrj5/KF01UVEIsJJjqGbWTYwEfikidXnmtlaM1tsZmc18/x5ZrbCzFaUlpaefFo55vfvbKFbego3Ts8OOoqIxIiIC93MMoAXgB+5+/7jVq8Chrj7eOD3wKKm9uHuD7t7jrvn9O2rObpP1daSKt7YUMxN07M1di4ix0RU6GaWSqjMn3T3F49f7+773b0qfP81INXM+kQ1qRzzyEc7SEtJ4rs6OheRRiI5y8WAR4A8d7+/mW0GhLfDzKaE91sezaASUlZVzYurCvibSQPpk9Ep6DgiEkMieTftPOAGYL2ZrQkv+xkwGMDdHwKuAm4zszrgMHCNu3v048rjS3dRXdfAzefrvHMR+aIWC93dPwJOONuTuz8IPBitUNK0I7X1PLFsF18Z1Y8z+mUEHUdEYoyuFI0j/7NuL+UHa/j++UODjiIiMUiFHkcWLtvF8L5dmT68d9BRRCQGqdDjxLqCCtbmV3DDtCGa71xEmqRCjxMLl+6iS1oy35ycFXQUEYlRKvQ4UHGohlfW7uHKiQN1IZGINEuFHgcWrS6kuq6B66ZqEi4RaZ4KPca5O898ms+4rB6MOV0fLycizVOhx7h1BZVsKjrAt88ZFHQUEYlxKvQY98yn+aSnJvH18acHHUVEYpwKPYYdqqnjlbV7+NrZp+vNUBFpkQo9hr21sZiq6jqu0qmKIhIBFXoMW7S6kNN7pDN1aK+go4hIHFChx6jyqmo+2FLG1yecTlKSrgwVkZap0GPU/6zfS32D840J+vhWEYmMCj1GLVpdyKgB3Rh9ms49F5HIqNBj0O7yQ6zaXcFcHZ2LyElQocegv6wpBGDOBJ17LiKRU6HHGHfnpTWFTBnai4E9OwcdR0TiiAo9xuQW7md76UG9GSoiJ02FHmMWrSkkNdm44uwBQUcRkTijQo8h9Q3OK2v3MGNkP3p2SQs6jojEGRV6DPlkRzklB6o13CIip0SFHkNezy0iPTWJi0f1DTqKiMQhFXqMaGhwXs8t4qIz+9IlLSXoOCISh1ToMWJ1/ueUHKhm1tjTgo4iInGqxUI3s0Fm9q6Z5ZnZBjO7o4ltzMweMLOtZrbOzCa1TdzEtXh9EanJxiWj+wUdRUTiVCS/29cBP3b3VWbWDVhpZm+5+8ZG28wCRoRvU4EF4a8SAXdncW4R55/RRx9kISKnrMUjdHff6+6rwvcPAHnA8adhzAUWesgyoKeZaewgQrmF+ymsOKzhFhFplZMaQzezbGAi8MlxqwYC+Y0eF/Dl0sfM5pnZCjNbUVpaepJRE9fi3L0kJxmXjekfdBQRiWMRF7qZZQAvAD9y9/3Hr27iKf6lBe4Pu3uOu+f07atT8yA03PJ6bhHThvUis6suJhKRUxdRoZtZKqEyf9LdX2xikwJgUKPHWcCe1sdLfJ8VV7G97CAzNdwiIq0UyVkuBjwC5Ln7/c1s9jJwY/hsl2lApbvvjWLOhLU4dy9mcLmGW0SklSI5y+U84AZgvZmtCS/7GTAYwN0fAl4DrgC2AoeA70U9aYJ6PbeIyYMz6dc9PegoIhLnWix0d/+IpsfIG2/jwO3RCtVR7Cw7yKaiA/zia6ODjiIiCUBXigborY3FAFx+lqbKFZHWU6EH6K28YkYN6MagXl2CjiIiCUCFHpDPD9awctfnXDpab4aKSHSo0APy3mcl1Dc4l+rsFhGJEhV6QJZsLKFvt06MG9gj6CgikiBU6AGoqWvg/c9K+cqofiQlnfAEIhGRiKnQA/DJjnKqqus0fi4iUaVCD8CSjcWkpyZx3hl9go4iIglEhd7O3J0leSWcf0YfOqclBx1HRBKICr2dbSo6QGHFYQ23iEjUqdDb2dt5oatD9VFzIhJtKvR29lZeCeMH9aRfN03GJSLRpUJvRyX7j7A2v4LLdHQuIm1Ahd6O3tlUAqCrQ0WkTajQ29GSvGIG9uzMyP7dgo4iIglIhd5ODtfU8+GWMi4b05/Qh0CJiESXCr2dfLy1jOq6Bp2uKCJtRoXeTpbkFdOtUwpThvYKOoqIJCgVejtoaAhdHXrhyL6kpehbLiJtQ+3SDtYVVlJWVc1lGm4RkTakQm8HSzYWk5xkzBjZN+goIpLAVOjtYEleMTlDMunZJS3oKCKSwFTobSx/3yE2FR3gMl1MJCJtTIXexo5OxvUVjZ+LSBtTobextzeVMLxvV4b26Rp0FBFJcC0Wupk9amYlZpbbzPoZZlZpZmvCt3uiHzM+7T9Sy7Lt5Zq7RUTaRUoE2/wZeBBYeIJtPnT32VFJlEA++KyU2nrX1aEi0i5aPEJ39w+Afe2QJeG8nVdCZpdUJg3ODDqKiHQA0RpDP9fM1prZYjM7q7mNzGyema0wsxWlpaVReunYVFffwDubSrhkVH+SkzQZl4i0vWgU+ipgiLuPB34PLGpuQ3d/2N1z3D2nb9/Evshm5a7PqTxcy6X6MAsRaSetLnR33+/uVeH7rwGpZtan1cni3JK8YtKSk7jgzMT+h0tEYkerC93MBlh4gm8zmxLeZ3lr9xvvluSVMG14bzI6RfK+s4hI67XYNmb2NDAD6GNmBcC9QCqAuz8EXAXcZmZ1wGHgGnf3NkscB7aVVrGj7CDfPy876Cgi0oG0WOjufm0L6x8kdFqjhC3ZqKtDRaT96UrRNrAkr5gxp3Xn9J6dg44iIh2ICj3K9h2sYeWuz3V1qIi0OxV6lL27qYQGRx9mISLtToUeZW9vKqZ/906MHdg96Cgi0sGo0KOouq6e9zeX8pXR/QmfySki0m5U6FG0bPs+DtbU6+pQEQmECj2K3tpYROfUZKYP7/AXyopIAFToUdLQ4LyxoZiLR/UlPTU56Dgi0gGp0KNk5e7PKT1QzcyxpwUdRUQ6KBV6lLyeW0RachIXj9RkXCISDBV6FLg7r+cWccGIPnRLTw06joh0UCr0KFhfWElhxWFmjh0QdBQR6cBU6FGwOLeI5CTTZ4eKSKBU6K10dLjl3GG9yeyaFnQcEenAVOit9FlxaO5zDbeISNBU6K20OHcvZvDVszTcIiLBUqG30uu5ReQMyaRft/Sgo4hIB6dCb4UdZQfZVHRAFxOJSExQobfC67lFABo/F5GYoEJvhVfW7mH8oJ4M1EfNiUgMUKGfoi3FB9i4dz9zx58edBQREUCFfsr+smYPSQazx2v8XERigwr9FLg7f1lbyHln9NHZLSISM1Top2B1fgX5+w4zd8LAoKOIiByjQj8Ff1ldSKeUJC7XxUQiEkNaLHQze9TMSswst5n1ZmYPmNlWM1tnZpOiHzN21NU38Oq6vVw6ur+myhWRmBLJEfqfgZknWD8LGBG+zQMWtD5W7PpoaxnlB2uYM0Fnt4hIbGmx0N39A2DfCTaZCyz0kGVATzNL2FM/Xl6zh+7pKczQJxOJSIyJxhj6QCC/0eOC8LKEc7imnjc2FHHF2afRKUUfBC0isSUahW5NLPMmNzSbZ2YrzGxFaWlpFF66fS3JK+ZgTb2GW0QkJkWj0AuAQY0eZwF7mtrQ3R929xx3z+nbN/6GLBatLmRA93SmDu0ddBQRkS+JRqG/DNwYPttlGlDp7nujsN+YUrL/CO99VsqVkwaSnNTULyUiIsFKaWkDM3samAH0MbMC4F4gFcDdHwJeA64AtgKHgO+1VdggvbCqkPoG5+rJWUFHERFpUouF7u7XtrDegdujligGuTv/vSKfKdm9GNY3I+g4IiJN0pWiEVi563O2lx3k6hwdnYtI7FKhR+DZT/PpmpbMFWcn7On1IpIAVOgtqDxUyyvr9jBnwul07dTiCJWISGBU6C14YVUBR2obuG7qkKCjiIickAr9BNydJz/ZxYRBPRk7sEfQcURETkiFfgJLt5ezrfQg100dHHQUEZEWqdBP4Mllu+nROZWv63NDRSQOqNCbUVhxmNc3FPGtnCzSUzURl4jEPhV6MxYu3Ym7893p2UFHERGJiAq9CYdq6nj6k93MHDuArMwuQccREYmICr0JL6wqZP+ROr5/3tCgo4iIREyFfpz6BudPH+1gXFYPJg/JDDqOiEjEVOjHeWNDEdvLDjLvwmGYaZpcEYkfKvRG3J0F721jaJ+uzBqreVtEJL6o0Bv5aGsZ6wsrmX/hMH2IhYjEHRV6I394dxv9u3fiykkJ+RnXIpLgVOhhy7aXs3R7OT+4YBidUnQhkYjEHxU6obHz+9/6jH7dOnH9NM2qKCLxSRN8A/+7rZzlO/bxyzln6TJ/kTZUW1tLQUEBR44cCTpKzEtPTycrK4vU1NSIn9PhC93d+X9vbua0Hul8+5xBQccRSWgFBQV069aN7OxsnRZ8Au5OeXk5BQUFDB0a+QWOHX7I5Y0NxazaXcHfXTJCR+cibezIkSP07t1bZd4CM6N3794n/ZtMhy702voG/u31TZzRL4Nv6QOgRdqFyjwyp/J96tCF/vTy3ewoO8jds0aRktyhvxUikgA6bItVHqrld0u2MG1YLy4Z1S/oOCLSgd1yyy1s3Lix1fvpsG+K3v/WZioO1fBPs8foV0ARiUhdXR0pKdGvzT/+8Y9R2U+HLPQNeyp5fNkurp82hLNO14c/iwThl69sYOOe/VHd55jTu3Pv18864Tbf+MY3yM/P58iRI9xxxx3MmzcPgIyMDObPn8+7775LZmYmzzzzDH379mXGjBlMnz6djz/+mDlz5jBhwgR+8pOfUFdXxznnnMOCBQtYt24dN998M8uXL6e+vp4pU6bw7LPPMnbs2GOvu3PnTmbOnMnUqVNZvXo1Z555JgsXLqRLly7MmDGD++67j5ycnFb9+SMacjGzmWa22cy2mtldTayfYWaVZrYmfLunVanaUEODc+9fNpDZJY0fXzYy6Dgi0s4effRRVq5cyYoVK3jggQcoLy8H4ODBg0yaNIlVq1Zx0UUX8ctf/vLYcyoqKnj//fe5/fbbuemmm3j22WdZv349dXV1LFiwgHPOOYc5c+bwi1/8gjvvvJPrr7/+C2V+1ObNm5k3bx7r1q2je/fu/OEPf4juH87dT3gDkoFtwDAgDVgLjDlumxnAqy3tq/Ft8uTJHoSFS3f6kJ++6s99ujuQ1xfpyDZu3Bh0BL/33nt93LhxPm7cOO/evbsvXbrU3d2TkpK8trbW3d23bdvm48ePd3f3iy66yN977z13d1+zZo1fcMEFx/a1ZMkSv/LKK93dvbq62seNG+dTpkzxurq6L73ujh07fNCgQccev/322z537txjr/Hpp59+6TlNfb+AFd5Mr0Yy5DIF2Oru2wHM7BlgLtD6Efx2VlhxmN+8lscFI/pw1WSdpijS0bz33nssWbKEpUuXHhvqaO5c78bvrXXt2hXg6AFsk/bt20dVVRW1tbUcOXLk2HOa22dTj1srkiGXgUB+o8cF4WXHO9fM1prZYjNrchDLzOaZ2QozW1FaWnoKcU+du/Pzl9bjwL9eebbeCBXpgCorK8nMzKRLly5s2rSJZcuWHVvX0NDA888/D8BTTz3F+eef/6Xnjxo1ip07d7J161YAHn/8cS666CIA5s2bx69//Wuuu+46fvrTnzb5+rt372bp0qUAPP30002+RmtEcoTeVPMd/8/UKmCIu1eZ2RXAImDEl57k/jDwMEBOTk7z/9S1gaeW7+a9zaX889fHMKiXPvhZpCOaOXMmDz30EOPGjWPkyJFMmzbt2LquXbuyYcMGJk+eTI8ePXj22We/9Pz09HT+9Kc/cfXVVx97U/TWW29l4cKFpKSk8J3vfIf6+nqmT5/OO++8wyWXXPKF548ePZrHHnuM+fPnM2LECG677bao/vnsRL9CAJjZucA/u/vl4cd3A7j7/z3Bc3YCOe5e1tw2OTk5vmLFilPJfNK2llQx+/cfck52Lx773hSS9OEVIoHIy8tj9OjRQcdoUkZGBlVVVW22/507dzJ79mxyc3Mjfk5T3y8zW+nuTZ4OE8mQy6fACDMbamZpwDXAy8e9wAALj2GY2ZTwfssjTt2Gquvq+dGzq+mcmsx9V49XmYtIwmpxyMXd68zsh8AbhM54edTdN5jZreH1DwFXAbeZWR1wGLjGWzr0byf/8moeuYX7efiGyfTvnh50HBGJUW15dA6QnZ19UkfnpyKiC4vc/TXgteOWPdTo/oPAg9GN1novrS7g8WW7mHfhML561oCg44iItKmEncslt7CSn72Yy5Shvbjzcl1AJCKJLyELvXj/EW55bAWZXVJ58DsTNZOiiHQICTeXy6GaOn6wcAX7j9Ty/K3T6ddN4+Yi0jEk1KFrTV0D8x9fSW5hJQ9cM5Exp3cPOpKIJJjs7GzKypo9I/tL7rnnHpYsWdKGif4qYY7Q6xucf3huDR9uKePf/2Ycl47pH3QkEYlhR+c/SUpq2+PaX/3qV226/8YSotDrG5yf/PdaXl23l59dMYpv6cOeRWLf4rugaH109zngbJj1m2ZX79y5k1mzZnHxxRezdOlSFi1axHPPPcdzzz1HdXU1V1555bFZFpubZrc5zU2/e9NNNzF79myuuuqqqP5RmxL3Qy519Q38w3NreGl1If94+UjmXTg86EgiEsM2b97MjTfeyOrVq9m8eTNbtmxh+fLlrFmzhpUrV/LBBx8AzU+z25wTTb/bXuL6CP1wTT0/fGoVb28q4c6ZI/nbGWcEHUlEInWCI+m2NGTIkGNzuLz55pu8+eabTJw4EQhdXLRlyxYuvPBCHnjgAV566SUA8vPz2bJlC7179252v0lJSXz7298G4Prrr+eb3/xmG/9JvixuC33fwRpueexTVudX8OtvjOWGaUOCjiQicaDxtLbuzt133838+fO/sM3JTLPbnCBmdI3LIZdNRfuZ8+BH5O7Zz4LrJqnMReSUXH755Tz66KPHLvsvLCykpKTkhNPsNieS6XfbWtwdoX/wWSm3PrGSjE4p/Pf8cxk/qGfQkUQkTn31q18lLy+Pc889Fwi9sfnEE0+ccJrd5kQy/W5ba3H63LZyqtPn7ig7yL0vb+C3V43TZFsicSaWp89trbaYfvdkp8+NuyP0oX26svD7U4KOISISc+JyDF1EJNa09fS7kVChi0i7ipGPSoh5p/J9UqGLSLtJT0+nvLxcpd4Cd6e8vJz09JN7nzDuxtBFJH5lZWVRUFBAaWlp0FFiXnp6OllZWSf1HBW6iLSb1NRUhg4dGnSMhKUhFxGRBKFCFxFJECp0EZEEEdiVomZWCuw6xaf3ASL/yJBgKGN0KGN0KGPrxUq+Ie7et6kVgRV6a5jZiuYufY0Vyhgdyhgdyth6sZ4PNOQiIpIwVOgiIgkiXgv94aADREAZo0MZo0MZWy/W88XnGLqIiHxZvB6hi4jIcVToIiIJIu4K3cxmmtlmM9tqZncFnQfAzAaZ2btmlmdmG8zsjvDyXmb2lpltCX/NDDhnspmtNrNXYzRfTzN73sw2hb+X58Zgxv8T/jvONbOnzSw96Ixm9qiZlZhZbqNlzWYys7vDPz+bzezyADP+Nvx3vc7MXjKznrGWsdG6n5iZm1mfIDO2JK4K3cySgf8CZgFjgGvNbEywqQCoA37s7qOBacDt4Vx3AW+7+wjg7fDjIN0B5DV6HGv5/hN43d1HAeMJZY2ZjGY2EPh7IMfdxwLJwDUxkPHPwMzjljWZKfz/5TXAWeHn/CH8cxVExreAse4+DvgMuDsGM2Jmg4DLgN2NlgWV8YTiqtCBKcBWd9/u7jXAM8DcgDPh7nvdfVX4/gFCRTSQULbHwps9BnwjkICAmWUBXwP+2GhxLOXrDlwIPALg7jXuXkEMZQxLATqbWQrQBdhDwBnd/QNg33GLm8s0F3jG3avdfQewldDPVbtndPc33b0u/HAZcHSu2JjJGPYfwJ1A4zNIAsnYkngr9IFAfqPHBeFlMcPMsoGJwCdAf3ffC6HSB/oFGO13hP6nbGi0LJbyDQNKgT+Fh4X+aGZdYymjuxcC9xE6UtsLVLr7m7GUsZHmMsXqz9D3gcXh+zGT0czmAIXuvva4VTGTsbF4K3RrYlnMnHdpZhnAC8CP3H1/0HmOMrPZQIm7rww6ywmkAJOABe4+EThI8ENAXxAeh54LDAVOB7qa2fXBpjppMfczZGY/JzRs+eTRRU1s1u4ZzawL8HPgnqZWN7Es8C6Kt0IvAAY1epxF6FfewJlZKqEyf9LdXwwvLjaz08LrTwNKAop3HjDHzHYSGqa6xMyeiKF8EPq7LXD3T8KPnydU8LGU8VJgh7uXunst8CIwPcYyHtVcppj6GTKz7wKzgev8rxfFxErG4YT+8V4b/tnJAlaZ2QBiJ+MXxFuhfwqMMLOhZpZG6E2JlwPOhJkZobHfPHe/v9Gql4Hvhu9/F/hLe2cDcPe73T3L3bMJfc/ecffrYyUfgLsXAflmNjK86CvARmIoI6Ghlmlm1iX8d/4VQu+XxFLGo5rL9DJwjZl1MrOhwAhgeQD5MLOZwE+BOe5+qNGqmMjo7uvdvZ+7Z4d/dgqASeH/V2Mi45e4e1zdgCsIvSO+Dfh50HnCmc4n9OvWOmBN+HYF0JvQGQZbwl97xUDWGcCr4fsxlQ+YAKwIfx8XAZkxmPGXwCYgF3gc6BR0RuBpQmP6tYRK5+YTZSI0jLAN2AzMCjDjVkLj0Ed/Zh6KtYzHrd8J9AkyY0s3XfovIpIg4m3IRUREmqFCFxFJECp0EZEEoUIXEUkQKnQRkQShQhcRSRAqdBGRBPH/AeHrE2aN1aGlAAAAAElFTkSuQmCC\n", 52 | "text/plain": [ 53 | "
" 54 | ] 55 | }, 56 | "metadata": { 57 | "needs_background": "light" 58 | }, 59 | "output_type": "display_data" 60 | } 61 | ], 62 | "source": [ 63 | "import matplotlib.pyplot as plt\n", 64 | "\n", 65 | "plt.plot(sols, label = \"aprox pi\")\n", 66 | "plt.plot([np.pi]*epochs, label = \"real pi\")\n", 67 | "plt.legend()\n", 68 | "plt.show()" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "id": "ddde48fe", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [] 78 | } 79 | ], 80 | "metadata": { 81 | "kernelspec": { 82 | "display_name": "Python 3", 83 | "language": "python", 84 | "name": "python3" 85 | }, 86 | "language_info": { 87 | "codemirror_mode": { 88 | "name": "ipython", 89 | "version": 3 90 | }, 91 | "file_extension": ".py", 92 | "mimetype": "text/x-python", 93 | "name": "python", 94 | "nbconvert_exporter": "python", 95 | "pygments_lexer": "ipython3", 96 | "version": "3.8.8" 97 | } 98 | }, 99 | "nbformat": 4, 100 | "nbformat_minor": 5 101 | } 102 | -------------------------------------------------------------------------------- /ClasificadorKernel.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "7a67393d", 6 | "metadata": {}, 7 | "source": [ 8 | "# Dataset\n", 9 | "\n", 10 | "En primer lugar generamos el dataset en el que nos basaremos.\n", 11 | "Tendremos dos clases distintas que les daremos el valor 1 y -1 respectivamente y seguirán una distribución normal. Puedes cambiar este dataset por cualquier que te guste pero las clases siempre deberán estar representadas con los valores 1 y -1." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 1, 17 | "id": "97d4f16b", 18 | "metadata": {}, 19 | "outputs": [ 20 | { 21 | "data": { 22 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAYgUlEQVR4nO3df4hlZ33H8c931qQ4piDuLmiTzJ2FSiEVt7JjarF/tNXSVMSoIJhcbDRtB0FpBEG0A/WPMn8J0qCFMm2igb2JLWhU2hR/gJC2GOtEok2MSpr9YazUzYZWZQsxO9/+ceYms3fOufece57z43nO+wXD3Xvn7r3P3Zn9nud8z/f5PubuAgDEa6XrAQAA6iGQA0DkCOQAEDkCOQBEjkAOAJF7URdveuzYMV9fX+/irQEgWg8//PDT7n589vFOAvn6+rp2d3e7eGsAiJaZnct7nNQKAESOQA4AkSOQA0DkCOQAEDkCOQBEjkCOMM5MpM+vS/euZLdnJl2PCBiMTsoPkZgzE+nfN6XLl7L7l85l9yXpxLi7cQEDwYwc9X1764UgPnX5UvY4gMYRyFHfpfPVHgcQFIEc9a2uVXscQFAEctR3cls6snrlY0dWs8cBNI5AjvpOjKUbd6TVkSTLbm/c4UIn0BKqVhDGiTGBG+gIM3IAiByBHAAiRyAHgMgRyAEgcgRyxIv+LoAkAjliNe3vcumcJH+hv0vdYM7BAREikCNOTfR3qXtw4CCAjhDIEacm+rvUOTg0dYYAlEAgR5ya6O9S5+BAB0h0iECOODXR36XOwYEOkOgQgRxxaqK/S52DAx0g0SF6rSBeofu7TF/r21vZTHp1LQviZd7j5PaVuyRJdIBEawjkwEHLHhzqHASAmgjkQCiLDgJnJgR6NIIcOdCGQOWJk4m0vi6trGS3E6oboQCB3MyuN7Ovmdl3zewxM7sjxMCApAQoT5xMpM1N6dw5yT273dwkmCPMjPw5SR909xskvU7S+8zshgCvC6QjQHni1pZ0aeZYcOlS9jiGrXYgd/cfu/u39v/8M0mPS7q27usCSQlQnni+IOYXPY7hCJojN7N1Sa+R9I2c722a2a6Z7V64cCHk2wL9F2AB01pBzC96HMMRLJCb2TWSPivpA+7+09nvu/uOu2+4+8bx48dDvS0QhwALmLa3pdWZY8HqavY4hi1I+aGZXaUsiE/c/XMhXhNITs0FTOP9v7q1laVT1tayID6mgnHwagdyMzNJd0l63N0/Xn9IAIqMxwRuHBYitfJ6Se+S9Htm9sj+15sCvC4AoITaM3J3/1dJFmAsAIAlsLITACJHIEfz2AKtN1jinyaaZqFZ0x4j0+Xp0x4jEg2jWjZd4j9dHTpd4i9xATV2zMjRrKY2SWaGXxlL/NPFjBzNCr0FGjP8pbHEP13MyNGs0FuglZ3hV521D2CWzxL/dBHI0azQmySXmeFX7f0dqFd4UA0cWFjiny4COZoVepPkMjP8qnn5JvL4dTR0YBmPpZ0daTSSzLLbnR0udKbA3L31N93Y2PDd3d3W3xcJmM2RS9kM/+DB4d4VSXm/1ybdunf44arPb9rn1/eD+IzVkfTWs22PBj1iZg+7+8bs48zIEZcyM/yqefnQefy6Ql8gRvII5IjPiXE2M711L7udTdNUzcuHzuPX1bcDC3ovnkA+gKoCBFI1Lx86j19X3w4s6L04cuRl8qJASs5Msoutl85nM/GT21H+rk8m9E8PqShHHkcg5+IP0LzAB4/ZlgBSVu5Ipczy4r7YycUfoFkNlDzSEqA9cQRyLv4AzWqglp6WAO2JI5Bz8QdoVgNnvbQEaE8cgbxvVQVAaho466UlQHvi6X5YcwdyAHOc3M6vDKtx1ju9oEnVSvPiCeQAmjOdJAUueRyPCdxtIJBjOYnUOeMAznqjRSBHdWzuAPRKHBc70S99a/sKDByBHNVVLVWjTw7QKAI5qitTqvZ88Dbp6+/q1+476K3JRFpfl1ZWstsJvyalEMhR3aIFWlcs95YObdpAGgY5pr1Zzp2T3LPbzU2CeRkEclS3aIFWXg59Fn1yMIPeLMujagXLmVeqViZI0ycHM+jNsjxm5AhvUZCmTw5y0JtleQTyVHVZKZKXQ5dlN/TJQQF6syyP1EqKul6wE2K5NytHB4feLMuLY4cgVBP7jkpD2tqPAxYqaHSHIDO728x+YmaPhng91LRowU7fF+gMZeVoA7vyYJhC5cg/LemmQK+FuuYt2IkheAxla7+hHLDQuCCB3N0flPRMiNdCAPMW7MQQPNrc2q/Ls5OhHLDQOKpWUjRvwU4MwaOtrf26PjthL1oE0logN7NNM9s1s90LFy609bbDdWKcXdi8dS+7nV5AiyF4tLW1X9dnJ+xFi0BaC+TuvuPuG+6+cfz48bbeNk110gGxBI+iA1FIXZ+dsBctAqGOPDZ1a8Qb2tIrSqtrBWWagc5OypQWsisPAghVfnifpK9L+jUze8rM/jjE6yJHiHRAG7PdGFQ4O6ncXrXr/DsGJVTVyi3u/gp3v8rdr3P3u0K8LnJ0nQ4oo+916lMlUxtLtVftOv+OQWFlZ2z6vmozwVWZ6+tZ8J41Gklnzxb8pXtXdKgPuyTJsjMhYAmNruxEi/p+sTLBmehS7VVjqA5CMgjksel7pUMMqZ+Klmqv2rMDLluopY2qlRj1udKh6UqQDmxvZznxg7vXLGyv2qPqoGmOfzr+aY5forNgKsiRI6wEc+RSFgxjba+6VI4fvVSUIyeQIzxas/bKykpWbTPLTNrjumtUigI5qRWE1+fUzwCtreXPyNlCLR1c7AQSxxZq6SOQA4kbj6WdnSwnbpbd7uwU5/ipcIkPqRVgAMbjchdnqXCJEzNyoKxYWg/UsLV1ZZmllN3finc91yAwIwfKqNt1MhJLrWJF55iRo1mpzGITbD2QZ6lVrOgcgRzNSamVa0qtB+YcXKlwiROBHM1ZdhZbdRbfxqw/lSZYCw6uVStc0A8EcjRnmVls1Vl8W7P+njXBWlqJg+t4nC3d39vLbgni/UcgRxh5s+JlZrFVZ/FFz3/4jrCz9L53nSwrpRQRnkfVCvJV6ZdSVNFx4jbpzD2HG2jNm8XOCzR5Yyp6/rMXs6+D45HqBd4UWg8k2J0SzMiRZ1G6Ynb2vXtH/qz4vx6oPostCihXvSx/TFe/rNxnSrDCZCmppIhwBWbkOGxRemN29l3k0vnqs9iT2/ltcE35Y1p5cfb92e8VjWfoetQnHeEwI8dh89IbeUG+yDKn60W56GefyX/+L545/PyrjlYfTyr17mWcGGf7u966l90SxKPHjByHzcujlp3V1jldz5vFf3ureEyzzy/a3KJoPANZtYl0MSPHYfPyqEWz2quPNlvRUSW3W7XCZCCrNpEuZuQ4bFEeNW+2e+rO+VUtdXOyVXO7VXLzlOQhcgRy5CsKhFUDasi0RVPlf5TkIXIEcsxXNJsuG1DnpS36kn8uqpShJA+RIEeOYiGWv8eQtkhl1WZZQ6rQGQgCedNi/k8T4iJgLM2mOi7Ja217tZQ6UuJ5BPImxf6fJsRsmpWEC023Vzt3TnJ/YXu1RoJ5xYMz+3fGgUDepNjL2kLMpiNOW7QVxFrdXq3CwbnVAwxqMXdv/U03NjZ8d3e39fdt3b0rkvL+fS07he+7ooU1kQTiOmY3IZayDRaa6M29spIFyllmWSvZoD6/XlChM8pSSgccOyZdvHj4qaNR1t4W7TOzh919Y/ZxZuRNiiU/XCTi2fTS9q9pbH3gbGuz5Fa3VyuZ6ppM8oO41O/9O4eaCiKQNymF/PCQ+nIcuKZx/un8KNpEEFtme7WlA1bJg/O8A1Zf9+8cdCrI3Wt/SbpJ0vclPSHpw4uef+rUKR+MJ0+73z9yn1h2++TprkeEIveP3Cdyn8hHx854Fg6u/BqNmnnr06ez1zbLbk/P+TU5fdp9dfXKca2uzv87VZkd/uzTr5DvE9JolD/epn5mXZC06zkxtXaO3MyOSPqBpN+X9JSkb0q6xd2/W/R3BpMjX1aIJe2o7sA1jcm/3aLNv/tbXXr2Jc9/u6kceVXr69lsc1bI3HXRexw9Kj39dJj3CK3Vaw0daTJHfqOkJ9z9SXd/VtJnJN0c4HWHKfaSxZ6bm5I4cO1i/Pr7tPMnf6rRsbMy2+vVJsRF6Z2QaZ+idM+dd4Z7j9BavdbQMyEC+bWSfnjg/lP7j13BzDbNbNfMdi9cuBDgbRMVe8lijy3Moc5c0xi//j6d/eSva+8/7+vVJsRtBKzxODtwjUbZjLZPB7Iiy1xrSEVrFzvdfcfdN9x94/jx4229bXxiWNIeqYX12pFU6bQVsMbjLFWzt6deHciKxHjwCSVE06wfSbr+wP3r9h/DMujE15hSKYkINlieBqatrWzsa2tZEB9CwFpkPB7mv0OIGfk3Jb3SzE6Y2dWS3inpiwFed5hSKFnsqZRyqLHNltGs2oHc3Z+T9H5JX5L0uKR/cPfH6r7uYEVyeh+jIedQkbYg/cjd/QFJD4R4LSiK0/sYkZJAqljZiUEpSklMJllvEbPs69ixgawIROPaaBvADkEYvMlEuv126dlnX3js4kXpPe/J/syMHcuabb42LXmVwv5e0f0Qg1e0ilGi0x/qCb0Kl+6HQIF5KyL73Olvaigd/2L8nG2swpUI5MDc8sO+lyaG6vjX9yAZa2fDtkpeCeQYvO1t6eqrDz9+1VX9L00MsbtQDEGy1V2UAmqr5JVAjrgF2Nx6PJbuvjvr7Dd19Kj0qU/1/0Jn0Sn6uXPlZ9dFQfK22/ozQ28rRRFaW20DuNiJeA14K7qpeRdqpxa13y1q/1rlNZrWRuveGHCxE+kZeKfIyUT6+c8XP29RCqJMvrZsGqOpXDurcucjkCNeA+4UOc1rF+2rOWteCiIvSFZ9jYNjaiLXPuTOhmUQyBGvHm9u3XQVSF5eW5KOHMl//rxZ92yQXOY1isYU8oIkjcKKEcgRr552imyjCqRodnz58nIpiINB8p57lnuNWC9IpoBAnroAVR1dKDWj7WmnyDZK5Ypmx9OUQ50UxLJpjJTaBEcnb0fmpr9OnToVfHdp5HjytPtnVp/fGd4nyu4/2dNt0Pe1sUt8k4p2oDfz7N/+/pH7xLLbJX8Wffw36uOY+uT0affRKPs9GI2W+3eRtOs5MZUZecoirero8+KPMmcKhTPTV/w82Mbafbz418cx9UXT6TbqyFN274qkvJ+vSbfutT2a0orqms2yHG5XZjvZSfn11YXP2/wzjV/7icMvvDqS3nq2sXGje6Hq4KkjH6IeV3XM09dca9kzhcKZ6Ws/mf/CAyiXHLqmLwQTyFPW06qORfLqms2yGU2Xy8Wr/GfMLZWL9MCK+pqenBDIU9bTqo5FDs5opSyIT1MtXTZ0qv2fMdIDK+premUqOXL0Wp96bJTNkc91ZpJdbL50PpuJn9zu/YEVYUwm9feLLcqRE8jRa3278BniPyOwLC52Yr7AC4dCLVFfKp3R4CIolomjjwjkeKEdbID6ZilszWzl3GLgzwLEgECO4AuHFpbpVZgxV15kEukiqD6qclbV963iUveirgeAHgjcDnZumd7sZhDTGbNUeNFvPK6Qwhhwa9uQZi/sTs+qpMM/iyrPRTOYkSN4ffPcvHbTM2ZqtYOo0iahzy0VhoJAjuD1zXPz2k3PmKnVDqLK4ifa13aPQI7gC4fm5rWbnjFHugiqb6pUC/W1pcKQUEeOdrFhchSqLH4KslAKpVBHjn5gxhyFKtVCtK/tHjNyAIgEM3IASFStQG5m7zCzx8xsz8wOHSUAAM2rOyN/VNLbJT0YYCxAlFjViK7VWtnp7o9LkpmFGQ0QGVY1og/IkQNTS3RNZFUj+mDhjNzMvirp5Tnf2nL3L5R9IzPblLQpSWusFEDfLNEDRmJVI/phYSB39zeGeCN335G0I2XlhyFeEwhmXg+YOYF8bS1/ByPmKmgTqRVELdiFxiV7wDS9FyNQRt3yw7eZ2VOSfkvSP5nZl8IMC1gs5AYWy/aAYVUj+oCVnYhW0I2Z6QGDCLCyE8mpdaFxtkJFGlQPGGrf08IOQYjW0hcaiypUbtyR3no29DB7h9r39DAjR7SWutB4ZiI9dNug9/Wk9j09BHJEa+6FxrzFPdOZuF/Of8EDFSoppx6ofU8PqRVELXdj5qLUycqLD8/ED9qvUEk99UDte3qYkSM9RYt7fnGx+O8c2Ncz9dQDte/pIZAjPVU3crYjV1SopJ56oPY9PaRWkJ7VtSydMuvqo9Ll/1tYKz6E1ENuSgrRYkaO9JzczgL0QUdWpVN3lqoVJ/WA2BDIkZ55GzyfGGe14rfuZbc5C35IPbwg5eqdlLBEH4jMZJJdeD1/Pkv3bG83c5CZrd6RsjOToR7U+oAl+kACgjYKWyD16p2UEMiBHptNbdxxR3vBNfXqnZQQyIGS2s4X582+LxaUwjcRXIuqdPpevTPEvD6BHCihzZTGVF5qo0gTwTXG6p0ufk59QCAHSugiX1x2lt1UcA1ZvdPWLHmoeX2qVoASVlayGd4sM2lvr5n3LNo44+hR6Zprmq9aCaXN6pcufk5tomoFqKGLfHFRauPOO7MdkPb2sts+B3Gp3Cw51Iw91rx+XQRyoIQu8sWpLExaVP0SMq8dY14/CHdv/evUqVMOxOb0affRyN0suz19uusRxWE0cs9C9JVfo1G571eV8s9J0q7nxFRy5AAatShHnnpeOyRy5AA6sShFNNS8dkgEcgCNG4+LL9AONq8dEIEcQKdSuajbJTaWANA5Nrqohxk5AESOQA4MyBAbSg0BqRVgIGbLAKcLbyTSGrFjRg4k7OAM/LbbhtlQagiYkQOJmp2BX76c/zw2iogfM3IgUWX7mfdl4Q35++URyIFElZlpzy686SqYDnVDiFAI5ECiimbaR47kL7zpMpgOdUOIUGoFcjP7mJl9z8y+Y2b3m9lLA40LQE1FS9/vuSd/qXyXwZSNnuupOyP/iqRXufurJf1A0kfqDwkIb4j516pL37sMpjTOqqdWIHf3L7v7c/t3H5J0Xf0hAWENOf86r1nVrC6DKY2z6gmZI79d0j8XfdPMNs1s18x2L1y4EPBtgfnIv5bTZTClcVY9CwO5mX3VzB7N+br5wHO2JD0nqXCO4+477r7h7hvHjx8PM3qgBPKv5XQdTKucPYQWe+pt4YIgd3/jvO+b2bslvVnSG7yL7YaABdbW8nejJ/962BC7EKbQuqBu1cpNkj4k6S3uXmLpAdA+8q+YJ4XUW90c+Scl/bKkr5jZI2b2NwHGBATVdcoA/ZZC6q1WrxV3/9VQAwGaNMSUAcpJIfXGyk5gCbFfHMMLUki9EciBioZcl56iFFJv1kWhycbGhu/u7rb+vkAI6+v5p+KjUVY2BzTFzB52943Zx5mRAxWlcHEMaSGQAxXRFwR9QyAHKkrh4hjSQiAHKkrh4hjSwp6dwBKoS0efMCMHgMgRyAEgcgRyAIgcgRwAIkcgB4DIdbJE38wuSMpZ5NyaY5Ke7vD9Q0rps0hpfZ6UPouU1ueJ9bOM3P3QFmudBPKumdluXr+CGKX0WaS0Pk9Kn0VK6/Ok9FkkUisAED0COQBEbqiBfKfrAQSU0meR0vo8KX0WKa3Pk9JnGWaOHABSMtQZOQAkg0AOAJEbZCA3s780s++Y2SNm9mUz+5Wux1SHmX3MzL63/5nuN7OXdj2mZZnZO8zsMTPbM7Noy8PM7CYz+76ZPWFmH+56PHWY2d1m9hMze7TrsdRlZteb2dfM7Lv7v2d3dD2mEAYZyCV9zN1f7e6/IekfJf1Fx+Op6yuSXuXur5b0A0kf6Xg8dTwq6e2SHux6IMsysyOS/lrSH0q6QdItZnZDt6Oq5dOSbup6EIE8J+mD7n6DpNdJel/kPxtJAw3k7v7TA3dfIinqK77u/mV3f27/7kOSrutyPHW4++Pu/v2ux1HTjZKecPcn3f1ZSZ+RdHPHY1qauz8o6ZmuxxGCu//Y3b+1/+efSXpc0rXdjqq+wW4sYWbbkv5I0v9K+t2OhxPS7ZL+vutBDNy1kn544P5Tkn6zo7GggJmtS3qNpG90PJTakg3kZvZVSS/P+daWu3/B3bckbZnZRyS9X9JHWx1gRYs+z/5ztpSdOk7aHFtVZT4L0CQzu0bSZyV9YOYMPUrJBnJ3f2PJp04kPaCeB/JFn8fM3i3pzZLe4D1fHFDhZxOrH0m6/sD96/YfQw+Y2VXKgvjE3T/X9XhCGGSO3MxeeeDuzZK+19VYQjCzmyR9SNJb3P1S1+OBvinplWZ2wsyulvROSV/seEyQZGYm6S5Jj7v7x7seTyiDXNlpZp+V9GuS9pS1032vu0c7YzKzJyT9kqSL+w895O7v7XBISzOzt0n6hKTjkv5H0iPu/gedDmoJZvYmSX8l6Yiku919u9sRLc/M7pP0O8pav/63pI+6+12dDmpJZvbbkv5F0n8o+/8vSX/u7g90N6r6BhnIASAlg0ytAEBKCOQAEDkCOQBEjkAOAJEjkANA5AjkABA5AjkARO7/AalrOJsB/BUrAAAAAElFTkSuQmCC\n", 23 | "text/plain": [ 24 | "
" 25 | ] 26 | }, 27 | "metadata": { 28 | "needs_background": "light" 29 | }, 30 | "output_type": "display_data" 31 | } 32 | ], 33 | "source": [ 34 | "import pennylane as qml\n", 35 | "from pennylane import numpy as np \n", 36 | "import matplotlib.pyplot as plt\n", 37 | "\n", 38 | "np.random.seed(42)\n", 39 | "\n", 40 | "n_samples = 200\n", 41 | "\n", 42 | "# A es la clase 1\n", 43 | "# B es la clase -1\n", 44 | "\n", 45 | "A_train = np.array([[np.random.normal(loc=-0.7), np.random.normal(loc=0.7)] for i in range(n_samples//4)]) \n", 46 | "B_train = np.array([[np.random.normal(loc=0.7), np.random.normal(loc=-0.7)] for i in range(n_samples//4)]) \n", 47 | "\n", 48 | "train_data = np.concatenate([A_train, B_train])\n", 49 | "train_labels = [1] * (n_samples // 4) + [-1] * (n_samples // 4)\n", 50 | "\n", 51 | "A_test = np.array([[np.random.normal(loc=-0.7), np.random.normal(loc=0.7)] for i in range(n_samples//4)]) \n", 52 | "B_test = np.array([[np.random.normal(loc=0.7), np.random.normal(loc=-0.7)] for i in range(n_samples//4)]) \n", 53 | "\n", 54 | "test_data = np.concatenate([A_test, B_test])\n", 55 | "test_labels = [1] * (n_samples // 4) + [-1] * (n_samples // 4)\n", 56 | "\n", 57 | "plt.scatter(A_train[:,0], A_train[:,1], color = \"orange\")\n", 58 | "plt.scatter(B_train[:,0], B_train[:,1], color = \"blue\")\n", 59 | "\n", 60 | "plt.show()" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "id": "6b9a25f0", 66 | "metadata": {}, 67 | "source": [ 68 | "# Función Kernel\n", 69 | "En primer lugar definiremos el feature map, es decir, como vamos a codificar los datos. Se puede ver como la función que envían un vector del dominio clásico al dominio cuántico. Después de esto, hay que definir una función capaz de determinar si dos elementos son similares o no." 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 2, 75 | "id": "e151ae47", 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "def feature_map(x, wires):\n", 80 | " qml.RY(x[0], wires = wires[0])\n", 81 | " qml.RY(x[1], wires = wires[1])\n", 82 | " \n", 83 | "# ||^2\n", 84 | "\n", 85 | "dev = qml.device(\"default.qubit\", wires = 5)\n", 86 | "\n", 87 | "@qml.qnode(dev)\n", 88 | "def kernel(x1,x2):\n", 89 | " \n", 90 | " feature_map(x1, wires = [1,2])\n", 91 | " feature_map(x2, wires = [3,4])\n", 92 | " \n", 93 | " qml.Hadamard(wires = 0)\n", 94 | " qml.CSWAP(wires = [0,1,3])\n", 95 | " qml.CSWAP(wires = [0,2,4])\n", 96 | " qml.Hadamard(wires = 0)\n", 97 | " \n", 98 | " return qml.expval(qml.PauliZ(0))\n", 99 | "\n", 100 | "\n", 101 | " " 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "id": "2f9571a7", 107 | "metadata": {}, 108 | "source": [ 109 | "# Predicción\n", 110 | "\n", 111 | "Una vez que tenemos la función kernel definida ya podemos preguntar por las predicciones de nuestro conjunto de test. Es importante remarcar que este modelo es más lento a la hora de predecir que otros algoritmos variacionales pero a cambio no ha hecho falta realizar ningún entrenamiento!" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 3, 117 | "id": "d6fa72a3", 118 | "metadata": {}, 119 | "outputs": [ 120 | { 121 | "name": "stdout", 122 | "output_type": "stream", 123 | "text": [ 124 | "0.84\n" 125 | ] 126 | } 127 | ], 128 | "source": [ 129 | "def prediction(x):\n", 130 | " sol = 0\n", 131 | " for i in range(len(train_data)):\n", 132 | " sol += train_labels[i] * kernel(x, train_data[i])\n", 133 | " return np.sign(sol)\n", 134 | "\n", 135 | "prediction(test_data[0])\n", 136 | "\n", 137 | "n = 0\n", 138 | "for i in range(len(test_data)):\n", 139 | " if prediction(test_data[i]) == test_labels[i]:\n", 140 | " n += 1\n", 141 | " \n", 142 | "print(n / len(test_data))" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "id": "1f923fba", 148 | "metadata": {}, 149 | "source": [ 150 | "Enhorabuena! Has conseguido una predicción del 84\\%" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "id": "ad3ce154", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [] 160 | } 161 | ], 162 | "metadata": { 163 | "kernelspec": { 164 | "display_name": "Python 3 (ipykernel)", 165 | "language": "python", 166 | "name": "python3" 167 | }, 168 | "language_info": { 169 | "codemirror_mode": { 170 | "name": "ipython", 171 | "version": 3 172 | }, 173 | "file_extension": ".py", 174 | "mimetype": "text/x-python", 175 | "name": "python", 176 | "nbconvert_exporter": "python", 177 | "pygments_lexer": "ipython3", 178 | "version": "3.8.8" 179 | } 180 | }, 181 | "nbformat": 4, 182 | "nbformat_minor": 5 183 | } 184 | -------------------------------------------------------------------------------- /QuantumCounting/CountingSolutions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ce27678a", 6 | "metadata": {}, 7 | "source": [ 8 | "# Conteo de soluciones \n", 9 | "\n", 10 | "![img](IMG_2077.jpg)\n", 11 | "\n", 12 | "![img](IMG_2079.jpg)\n", 13 | "\n", 14 | "![img](IMG_2078.jpg)" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 12, 20 | "id": "4b44916a", 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "import pennylane as qml\n", 25 | "from pennylane import numpy as np\n", 26 | "\n", 27 | "target_wires = [0,1,2,3]\n", 28 | "estimation_wires = [4,5,6,7,8,9,10]\n", 29 | "\n", 30 | "def U(wires):\n", 31 | " \n", 32 | " #oracle\n", 33 | " qml.FlipSign(0, wires = wires)\n", 34 | " qml.FlipSign(12, wires = wires)\n", 35 | " qml.FlipSign(3, wires = wires)\n", 36 | " qml.FlipSign(2, wires = wires)\n", 37 | " qml.FlipSign(13, wires = wires)\n", 38 | " \n", 39 | " #grover\n", 40 | " \n", 41 | " qml.GroverOperator(wires = wires)\n", 42 | " \n", 43 | "dev = qml.device(\"default.qubit\", wires = target_wires + estimation_wires)\n", 44 | "\n", 45 | "@qml.qnode(dev)\n", 46 | "def circuit():\n", 47 | " \n", 48 | " for wire in target_wires:\n", 49 | " qml.Hadamard(wires = wire)\n", 50 | " \n", 51 | " matrix = qml.matrix(U)(wires = target_wires)\n", 52 | " qml.QuantumPhaseEstimation(matrix, estimation_wires = estimation_wires, target_wires = target_wires)\n", 53 | " return qml.probs(wires = estimation_wires)\n" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 13, 59 | "id": "14f0643e", 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": [ 65 | "" 66 | ] 67 | }, 68 | "execution_count": 13, 69 | "metadata": {}, 70 | "output_type": "execute_result" 71 | }, 72 | { 73 | "data": { 74 | "image/png": "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MbJnz57o6emJ8vLyXufLy8ujvb293+vt3bs3Ro4cGSUlJTFz5sy4/fbb473vfW+/65uammL06NH5Y+LEiYVsEwAYQE7Iu2lOPfXU2LJlS2zevDluvPHGaGhoiA0bNvS7fvHixbF37978sX379hOxTQAggeGFLB47dmwMGzYsOjo6ep3v6OiIioqKfq9XXFwc5513XkRETJ06NZ555ploamqKd7/73X2uLy0tjdLS0kK2BgAMUAU9M1JSUhLTpk2L5ubm/LlcLhfNzc1RXV19xLeTy+Wiq6urkB8NAAxSBT0zEhHR0NAQdXV1UVVVFdOnT4/ly5fH/v37o76+PiIi5s6dGxMmTIimpqaI+M/rP6qqquLcc8+Nrq6u+PnPfx533313rFy58vjeEwBgQCo4RmbNmhW7d++OJUuWRHt7e0ydOjXWrVuXf1Hrtm3borj41Sdc9u/fH1dffXX89a9/jZNPPjkmTZoUP/jBD2LWrFnH714AAANWUZZlWepN/C+dnZ0xevTo2Lt3b4waNSr1dvgfKhc9lP/6haUzE+4EGKw8zgwMR/rvt8+mAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUkcVIytWrIjKysooKyuLGTNmxKZNm/pde+edd8Y73/nOOO200+K0006Lmpqaw64HAIaWgmNk7dq10dDQEI2NjdHW1hZTpkyJ2tra2LVrV5/rN2zYELNnz45HHnkkWlpaYuLEiXHZZZfFjh07jnnzAMDAV3CMLFu2LObNmxf19fUxefLkWLVqVYwYMSJWr17d5/p77rknrr766pg6dWpMmjQpvvvd70Yul4vm5uZj3jwAMPAVFCPd3d3R2toaNTU1r95AcXHU1NRES0vLEd3GgQMH4uDBg3H66af3u6arqys6Ozt7HQDA4FRQjOzZsyd6enqivLy81/ny8vJob28/otu47rrrYvz48b2C5rWamppi9OjR+WPixImFbBMAGEBO6Ltpli5dGmvWrIkHHnggysrK+l23ePHi2Lt3b/7Yvn37CdwlAHAiDS9k8dixY2PYsGHR0dHR63xHR0dUVFQc9rq33HJLLF26NH71q1/FRRdddNi1paWlUVpaWsjWAIABqqBnRkpKSmLatGm9Xnz6yotRq6ur+73ezTffHDfccEOsW7cuqqqqjn63AMCgU9AzIxERDQ0NUVdXF1VVVTF9+vRYvnx57N+/P+rr6yMiYu7cuTFhwoRoamqKiIibbroplixZEvfee29UVlbmX1sycuTIGDly5HG8KwDAQFRwjMyaNSt2794dS5Ysifb29pg6dWqsW7cu/6LWbdu2RXHxq0+4rFy5Mrq7u+MjH/lIr9tpbGyMr371q8e2ewBgwCs4RiIiFixYEAsWLOjzsg0bNvT6/oUXXjiaHwEADBE+mwYASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgqaOKkRUrVkRlZWWUlZXFjBkzYtOmTf2ufeqpp+LDH/5wVFZWRlFRUSxfvvxo9woADEIFx8jatWujoaEhGhsbo62tLaZMmRK1tbWxa9euPtcfOHAgzjnnnFi6dGlUVFQc84YBgMGl4BhZtmxZzJs3L+rr62Py5MmxatWqGDFiRKxevbrP9W9729vim9/8Znz84x+P0tLSY94wADC4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\n", 75 | "text/plain": [ 76 | "
" 77 | ] 78 | }, 79 | "metadata": {}, 80 | "output_type": "display_data" 81 | } 82 | ], 83 | "source": [ 84 | "import matplotlib.pyplot as plt\n", 85 | "\n", 86 | "output = circuit()\n", 87 | "plt.bar(range(len(output)), output)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 14, 93 | "id": "d5c4159a", 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "2.552544031041707" 100 | ] 101 | }, 102 | "execution_count": 14, 103 | "metadata": {}, 104 | "output_type": "execute_result" 105 | } 106 | ], 107 | "source": [ 108 | "x = np.argmax(output)\n", 109 | "theta = np.pi * x / (2 ** len(estimation_wires))\n", 110 | "theta" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 15, 116 | "id": "22fa207a", 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "4.938532541079281\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "m = 2 ** len(target_wires) * np.sin(theta) ** 2\n", 129 | "print(m)" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": null, 135 | "id": "5070fdd7", 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "id": "74d5ca03", 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "id": "5324a98c", 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "id": "52308585", 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "id": "9f0084b9", 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "97b85910", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 3 (ipykernel)", 184 | "language": "python", 185 | "name": "python3" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.9.5" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 5 202 | } 203 | -------------------------------------------------------------------------------- /Quantum KNN.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "ce6c8dba", 6 | "metadata": {}, 7 | "source": [ 8 | "## Quantum KNN\n", 9 | "\n", 10 | "A lo largo de este notebook vamos a enseñar de forma sencilla como implementar la versión cuántica del KNN. En este ejemplo, utilizaremos el computador cuántico a modo de feature map para poder aplicar los datos en un nuevo espacio. \n", 11 | "\n", 12 | "Lo primero de todo será generar el dataset con el que vamos a trabajar. Dispondremos de puntos tipo A (naranjas) y tipo B (azules), que siguen una distribución normal." 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "id": "e33c5f65", 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "data": { 23 | "image/png": "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\n", 24 | "text/plain": [ 25 | "
" 26 | ] 27 | }, 28 | "metadata": { 29 | "needs_background": "light" 30 | }, 31 | "output_type": "display_data" 32 | } 33 | ], 34 | "source": [ 35 | "import pennylane as qml\n", 36 | "from pennylane import numpy as np \n", 37 | "import matplotlib.pyplot as plt\n", 38 | "\n", 39 | "np.random.seed(42)\n", 40 | "\n", 41 | "n_samples = 200\n", 42 | "\n", 43 | "A_train = np.array([[np.random.normal(loc=-0.7), np.random.normal(loc=0.7)] for i in range(n_samples//4)]) \n", 44 | "B_train = np.array([[np.random.normal(loc=0.7), np.random.normal(loc=-0.7)] for i in range(n_samples//4)]) \n", 45 | "\n", 46 | "train_labels = [\"A\"] * (n_samples // 4) + [\"B\"] * (n_samples // 4)\n", 47 | "\n", 48 | "A_test = np.array([[np.random.normal(loc=-0.7), np.random.normal(loc=0.7)] for i in range(n_samples//4)]) \n", 49 | "B_test = np.array([[np.random.normal(loc=0.7), np.random.normal(loc=-0.7)] for i in range(n_samples//4)]) \n", 50 | "\n", 51 | "test_labels = [\"A\"] * (n_samples // 4) + [\"B\"] * (n_samples // 4)\n", 52 | "\n", 53 | "plt.scatter(A_train[:,0], A_train[:,1], color = \"orange\")\n", 54 | "plt.scatter(B_train[:,0], B_train[:,1], color = \"blue\")\n", 55 | "\n", 56 | "plt.show()" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "id": "c058bf78", 62 | "metadata": {}, 63 | "source": [ 64 | "El siguiente de los pasos es por un lado mapear nuestro dataset a un nuevo espacio a través del computador y después calcular la distancia entre los estados. En particular, como ya vimos en [este video](https://youtu.be/tpPQCtBmRbc), la formula de la distancia es:\n", 65 | "\n", 66 | "$$d(x_1,x_2)=2-2\\vert\\langle\\phi(x_1)\\vert\\phi(x_2)\\rangle\\vert^2$$\n", 67 | "\n", 68 | "Por lo tanto, lo que haremos será calcular $\\vert\\langle\\phi(x_1)\\vert\\phi(x_2)\\rangle\\vert^2$ a través de [Swap-Test](https://youtu.be/V43R-26NtUU) y sustituir en la distancia." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 2, 74 | "id": "b3772fc1", 75 | "metadata": {}, 76 | "outputs": [ 77 | { 78 | "data": { 79 | "text/plain": [ 80 | "tensor(1.09554785, requires_grad=True)" 81 | ] 82 | }, 83 | "execution_count": 2, 84 | "metadata": {}, 85 | "output_type": "execute_result" 86 | } 87 | ], 88 | "source": [ 89 | "def feature_map(x, wires):\n", 90 | "\n", 91 | " qml.RY(x[0], wires = wires[0])\n", 92 | " qml.RY(x[1], wires = wires[1])\n", 93 | " \n", 94 | "# ||^2\n", 95 | "\n", 96 | "dev = qml.device(\"default.qubit\", wires = 5)\n", 97 | "\n", 98 | "@qml.qnode(dev)\n", 99 | "def swap_test(x1,x2):\n", 100 | " \n", 101 | " feature_map(x1, wires = [1,2])\n", 102 | " feature_map(x2, wires = [3,4])\n", 103 | " \n", 104 | " qml.Hadamard(wires = 0)\n", 105 | " qml.CSWAP(wires = [0,1,3])\n", 106 | " qml.CSWAP(wires = [0,2,4])\n", 107 | " qml.Hadamard(wires = 0)\n", 108 | " \n", 109 | " return qml.expval(qml.PauliZ(0))\n", 110 | " \n", 111 | "def distance(x1, x2):\n", 112 | " return 2 - 2 * swap_test(x1,x2)\n", 113 | "\n", 114 | "# Para ver que funciona, calcularemos la distancia entre dos puntos\n", 115 | "\n", 116 | "distance(A_train[0], A_train[1])" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "id": "609e00f8", 122 | "metadata": {}, 123 | "source": [ 124 | "Una vez que hemos definido la distancia, podemos utilizarla como nueva métrica del KNN, por lo que haremos uso de la librería `sklearn` para llevarlo a cabo de forma sencilla." 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 3, 130 | "id": "cda665ea", 131 | "metadata": {}, 132 | "outputs": [ 133 | { 134 | "data": { 135 | "text/plain": [ 136 | "0.77" 137 | ] 138 | }, 139 | "execution_count": 3, 140 | "metadata": {}, 141 | "output_type": "execute_result" 142 | } 143 | ], 144 | "source": [ 145 | "from sklearn.neighbors import KNeighborsClassifier\n", 146 | "\n", 147 | "neigh = KNeighborsClassifier(n_neighbors=3,metric=distance)\n", 148 | "\n", 149 | "neigh.fit(np.concatenate([A_train,B_train]),train_labels)\n", 150 | "neigh.score(np.concatenate([A_test,B_test]), test_labels)" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "id": "6699727e", 156 | "metadata": {}, 157 | "source": [ 158 | "Genial! Hemos conseguido un $77\\%$ de precisión con este feature map!\n", 159 | "\n", 160 | "Prueba a cambiar el feature map a ver si consigues mejorar estos valores :)" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "id": "95a1a0d6", 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [] 170 | } 171 | ], 172 | "metadata": { 173 | "kernelspec": { 174 | "display_name": "Python 3", 175 | "language": "python", 176 | "name": "python3" 177 | }, 178 | "language_info": { 179 | "codemirror_mode": { 180 | "name": "ipython", 181 | "version": 3 182 | }, 183 | "file_extension": ".py", 184 | "mimetype": "text/x-python", 185 | "name": "python", 186 | "nbconvert_exporter": "python", 187 | "pygments_lexer": "ipython3", 188 | "version": "3.8.8" 189 | } 190 | }, 191 | "nbformat": 4, 192 | "nbformat_minor": 5 193 | } 194 | -------------------------------------------------------------------------------- /QPE_Energy.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "code", 19 | "execution_count": 3, 20 | "metadata": { 21 | "colab": { 22 | "base_uri": "https://localhost:8080/" 23 | }, 24 | "id": "8ur-V5F58Z0K", 25 | "outputId": "f4cfc4aa-159c-4772-d59c-cb3cdae4c619" 26 | }, 27 | "outputs": [ 28 | { 29 | "output_type": "execute_result", 30 | "data": { 31 | "text/plain": [ 32 | "tensor(0.45005751, requires_grad=True)" 33 | ] 34 | }, 35 | "metadata": {}, 36 | "execution_count": 3 37 | } 38 | ], 39 | "source": [ 40 | "import pennylane as qml\n", 41 | "from scipy.linalg import expm\n", 42 | "import numpy as np\n", 43 | "\n", 44 | "H = 0.2 * qml.PauliX(0) @ qml.PauliZ(1) + 0.3* qml.PauliX(0) - 2.6 * qml.PauliY(1) - 0.3 * qml.PauliX(1)\n", 45 | "\n", 46 | "\n", 47 | "def phi():\n", 48 | " qml.Hadamard(wires = 0)\n", 49 | " qml.CRY(0.3, wires = [0,1])\n", 50 | "\n", 51 | "dev1 = qml.device(\"default.qubit\", wires = H.wires)\n", 52 | "\n", 53 | "@qml.qnode(dev1)\n", 54 | "def circuit1():\n", 55 | " phi()\n", 56 | " return qml.expval(H)\n", 57 | "\n", 58 | "# \n", 59 | "\n", 60 | "circuit1()" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "source": [ 66 | "estimation_wires = [2,3,4,5,6,7,8]\n", 67 | "\n", 68 | "sum_coeffs = sum([abs(c) for c in H.coeffs])\n", 69 | "H_norm = qml.Hamiltonian(np.concatenate([H.coeffs / (2 * sum_coeffs), np.array([0.5])]), H.ops + [qml.Identity(0)])\n", 70 | "exp_H = expm(2 * np.pi * 1j * qml.matrix(H_norm))\n", 71 | "\n", 72 | "dev2 = qml.device(\"default.qubit\", wires = H.wires + estimation_wires)\n", 73 | "\n", 74 | "@qml.qnode(dev2)\n", 75 | "def circuit2():\n", 76 | "\n", 77 | " phi()\n", 78 | " qml.QuantumPhaseEstimation(exp_H, estimation_wires = estimation_wires, target_wires = [0,1])\n", 79 | " return qml.probs(wires = estimation_wires)\n", 80 | "\n", 81 | "def energy(output):\n", 82 | " return 2 * sum_coeffs * (sum([output[i] * i / 2 ** len(estimation_wires) for i in range(2 ** len(estimation_wires))]) - 0.5)\n", 83 | "\n", 84 | "output = circuit2()\n", 85 | "energy(output)" 86 | ], 87 | "metadata": { 88 | "colab": { 89 | "base_uri": "https://localhost:8080/" 90 | }, 91 | "id": "I0XDOGJn8egd", 92 | "outputId": "2420e000-46c4-45ed-da53-84d10f451fd6" 93 | }, 94 | "execution_count": 10, 95 | "outputs": [ 96 | { 97 | "output_type": "execute_result", 98 | "data": { 99 | "text/plain": [ 100 | "0.44977244757812435" 101 | ] 102 | }, 103 | "metadata": {}, 104 | "execution_count": 10 105 | } 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "source": [ 111 | "import matplotlib.pyplot as plt\n", 112 | "\n", 113 | "output = circuit2()\n", 114 | "plt.bar(range(len(output)), output)" 115 | ], 116 | "metadata": { 117 | "colab": { 118 | "base_uri": "https://localhost:8080/", 119 | "height": 448 120 | }, 121 | "id": "RS2XzqwK_EqC", 122 | "outputId": "4843b6f1-01b0-455c-c477-b708f8b64356" 123 | }, 124 | "execution_count": 11, 125 | "outputs": [ 126 | { 127 | "output_type": "execute_result", 128 | "data": { 129 | "text/plain": [ 130 | "" 131 | ] 132 | }, 133 | "metadata": {}, 134 | "execution_count": 11 135 | }, 136 | { 137 | "output_type": "display_data", 138 | "data": { 139 | "text/plain": [ 140 | "
" 141 | ], 142 | "image/png": "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q50kDg4ODg4OjiFwtLS0HLUvTsq/wLp48eKYZ1MikYg+/vhjjR07VklJSf1+f+FwWLm5uWppaVFmZma/3/5gxb70jr3pGfvSO/amd+xNz4bCvjjndPDgQY0fP/6o6+KKkezsbKWkpKi1tTXmfGtrq3Jycnq8Tk5OTlzrJcnj8cjj8cScGzVqVDyjHpPMzMxB+x/8RGJfesfe9Ix96R170zv2pmeDfV+ysrK+dk1cL2BNS0tTUVGRgsFg9FwkElEwGFRZWVmP1ykrK4tZL0nr16/vdT0AAEgscf8zTSAQUGVlpYqLi1VSUqJly5apo6NDfr9fklRRUaEJEyaopqZGkrRgwQJNnz5d999/v2bMmKHVq1fr9ddf1yOPPNK/jwQAAAxKccfIrFmztG/fPlVVVSkUCqmwsFDr1q2T1+uVJDU3Nys5+csnXC644AKtWrVKv/71r3XrrbfqrLPO0tNPP61zzjmn/x7FcfJ4PKqurj7in4YSHfvSO/amZ+xL79ib3rE3PUukfUly7uvebwMAAHDi8Nk0AADAFDECAABMESMAAMAUMQIAAEwlfIzU1tYqLy9P6enpKi0tVUNDg/VIA6qmpkbnn3++Ro4cqXHjxmnmzJnauXNnzJrPP/9c8+bN09ixYzVixAhdc801R/whu0SwZMkSJSUl6aabboqeS+S92bNnj3784x9r7NixGj58uKZOnarXX389erlzTlVVVTr11FM1fPhw+Xw+vf/++4YTn3jd3d26/fbbNWnSJA0fPlyTJ0/WnXfeGfO5HImyL6+88oouv/xyjR8/XklJSUd8Hllf9uHjjz/WnDlzlJmZqVGjRun666/Xp59+OoCPov8dbV8OHz6shQsXaurUqTrllFM0fvx4VVRUaO/evTG3MRT3JaFjZM2aNQoEAqqurlZTU5MKCgpUXl6utrY269EGzKZNmzRv3jy99tprWr9+vQ4fPqxLL71UHR0d0TU333yznn32WT355JPatGmT9u7dq6uvvtpw6oG3detWPfzwwzr33HNjzifq3nzyySe68MILNWzYML344ovasWOH7r//fo0ePTq65p577tEDDzyguro6bdmyRaeccorKy8v1+eefG05+Yt19991avny5HnroIb3zzju6++67dc899+jBBx+MrkmUfeno6FBBQYFqa2t7vLwv+zBnzhy9/fbbWr9+vZ57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\n" 143 | }, 144 | "metadata": {} 145 | } 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "source": [], 151 | "metadata": { 152 | "id": "PwWlhgHO_fj1" 153 | }, 154 | "execution_count": null, 155 | "outputs": [] 156 | } 157 | ] 158 | } -------------------------------------------------------------------------------- /Challenge Ket.G/Problem 1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Analisis del problema\n", 8 | "Los datos de entrada tienen una forma como esta: \n", 9 | "\n", 10 | "inputs = [[2,2,1,0,0,3],\n", 11 | " [1,1,2,1,3,0], \n", 12 | " [1,3,2,3,3,1],\n", 13 | " [2,0,0,0,0,1]]\n", 14 | " \n", 15 | "donde los valores de cada estado van a tomar valores desde el 0 hasta el 3. Para codificar esto utilizaremos por tanto 2 qubits por valor ( ya que podemos ir desde el 0 = 00 hasta el 3 = 11), por lo que necesitaremos 2 x 6 = 12 qubits para cada estado. Al haber 4 estados de entrada necesitaremos otros dos qubits para almacenar dichos valores en la qRAM por lo que dicha parte ocupará en total 14 qubits." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 39, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "# construyamos la qRAM\n", 25 | "\n", 26 | "from qiskit import *\n", 27 | "from qiskit.visualization import plot_histogram\n", 28 | "\n", 29 | "def make_qRAM(inputs):\n", 30 | " \n", 31 | " qc = QuantumCircuit(14)\n", 32 | " \n", 33 | " for indx in range(4):\n", 34 | " \n", 35 | " binary_indx = bin(4 + indx)[-2:]\n", 36 | " \n", 37 | " if binary_indx[0] == '0':\n", 38 | " qc.x(0)\n", 39 | " if binary_indx[1] == '0':\n", 40 | " qc.x(1)\n", 41 | " \n", 42 | " for j, value in enumerate(inputs[indx]):\n", 43 | " \n", 44 | " binary_value = bin(4 + value)[-2:]\n", 45 | " \n", 46 | " if binary_value[0] == '1':\n", 47 | " qc.ccx(0,1, 2 + 2 * j)\n", 48 | " \n", 49 | " if binary_value[1] == '1':\n", 50 | " qc.ccx(0,1, 2 + 2 * j + 1)\n", 51 | " \n", 52 | " if binary_indx[0] == '0':\n", 53 | " qc.x(0)\n", 54 | " if binary_indx[1] == '0':\n", 55 | " qc.x(1)\n", 56 | " \n", 57 | " gate = qc.to_gate()\n", 58 | " gate.name = 'qRAM'\n", 59 | " return gate\n", 60 | "\n" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 86, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "# ya la teniamos definida en el canal\n", 70 | "\n", 71 | "from numpy import pi\n", 72 | "\n", 73 | "def QFT(n):\n", 74 | " qft_circ = QuantumCircuit(n)\n", 75 | " for i in range(n-1, -1, -1):\n", 76 | " qft_circ.h(i)\n", 77 | " \n", 78 | " for j in range(i - 1, -1, -1): \n", 79 | " qft_circ.cu1(pi/(2 ** (i - j)), j, i)\n", 80 | " \n", 81 | " \n", 82 | " for i in range(n // 2):\n", 83 | " qft_circ.swap(i, n - i - 1)\n", 84 | " gate = qft_circ.to_gate()\n", 85 | " gate.name = \"QFT\" + str(n)\n", 86 | " return gate\n", 87 | "\n", 88 | "\n", 89 | "def invQFT(n):\n", 90 | " qft_circ = QuantumCircuit(n)\n", 91 | " for i in range(n-1, -1, -1):\n", 92 | " qft_circ.h(i)\n", 93 | " \n", 94 | " for j in range(i - 1, -1, -1): \n", 95 | " qft_circ.cu1(pi/(2 ** (i - j)), j, i)\n", 96 | " \n", 97 | " \n", 98 | " for i in range(n // 2):\n", 99 | " qft_circ.swap(i, n - i - 1)\n", 100 | " qft_circ = qft_circ.inverse()\n", 101 | " gate = qft_circ.to_gate()\n", 102 | " gate.name = \"invQFT\" + str(n)\n", 103 | " return gate" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 117, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "def add_qubit(qc, q, sign = 1):\n", 113 | " \n", 114 | " if q > 7:\n", 115 | " sign = -sign\n", 116 | " \n", 117 | " for indx, qb in enumerate(range(14,18)):\n", 118 | " qc.cu1(sign * pi / (2**(3 - indx)), q, qb)\n", 119 | " " 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 118, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "def adder(qc, sign = 1):\n", 129 | " qc.append(QFT(4), range(14,18))\n", 130 | "\n", 131 | " for q in range(2,14):\n", 132 | " \n", 133 | " add_qubit(qc, q, sign)\n", 134 | " \n", 135 | " if q % 2 == 0:\n", 136 | " add_qubit(qc, q, sign)\n", 137 | " qc.barrier()\n", 138 | " \n", 139 | " qc.append(invQFT(4), range(14,18))" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 146, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "inputs = [[2,2,1,0,0,3], [1,3,2,3,3,1], [2,0,0,0,0,1], [1,1,2,1,3,0]]\n", 149 | "\n", 150 | "qc = QuantumCircuit(18,2)\n", 151 | "qc.h(range(2))\n", 152 | "qc.append(make_qRAM(inputs), range(14))\n", 153 | "\n", 154 | "\n", 155 | "adder(qc)\n", 156 | "\n", 157 | "# oracle\n", 158 | "\n", 159 | "qc.x(range(14,18))\n", 160 | "qc.h(17)\n", 161 | "qc.mct([14,15,16],17)\n", 162 | "qc.h(17)\n", 163 | "qc.x(range(14,18))\n", 164 | "\n", 165 | "\n", 166 | "\n", 167 | "adder(qc, -1)\n", 168 | "qc.append(make_qRAM(inputs), range(14))\n", 169 | "\n", 170 | "# grover\n", 171 | "\n", 172 | "qc.h(range(2))\n", 173 | "qc.x(range(2))\n", 174 | "qc.cz(0,1)\n", 175 | "qc.x(range(2))\n", 176 | "qc.h(range(2))\n", 177 | "\n", 178 | "qc.measure(range(2), range(2))\n", 179 | "qc = qc.reverse_bits()\n", 180 | "#qc.draw()\n", 181 | "\n" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 147, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "data": { 191 | "image/png": "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\n", 192 | "text/plain": [ 193 | "
" 194 | ] 195 | }, 196 | "execution_count": 147, 197 | "metadata": {}, 198 | "output_type": "execute_result" 199 | } 200 | ], 201 | "source": [ 202 | "backend = Aer.get_backend('qasm_simulator')\n", 203 | "job = execute(qc, backend, shots = 1000)\n", 204 | "plot_histogram(job.result().get_counts())" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": null, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [] 220 | } 221 | ], 222 | "metadata": { 223 | "kernelspec": { 224 | "display_name": "Python 3", 225 | "language": "python", 226 | "name": "python3" 227 | }, 228 | "language_info": { 229 | "codemirror_mode": { 230 | "name": "ipython", 231 | "version": 3 232 | }, 233 | "file_extension": ".py", 234 | "mimetype": "text/x-python", 235 | "name": "python", 236 | "nbconvert_exporter": "python", 237 | "pygments_lexer": "ipython3", 238 | "version": "3.8.3" 239 | } 240 | }, 241 | "nbformat": 4, 242 | "nbformat_minor": 4 243 | } 244 | -------------------------------------------------------------------------------- /LCU.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "5e19c984", 6 | "metadata": {}, 7 | "source": [ 8 | "![lcu.jpeg](lcu.jpeg)\n" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "b8cbea2d", 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "data": { 19 | "text/plain": [ 20 | "array([[0.+0.j, 1.+0.j],\n", 21 | " [0.+0.j, 0.+0.j]])" 22 | ] 23 | }, 24 | "execution_count": 1, 25 | "metadata": {}, 26 | "output_type": "execute_result" 27 | } 28 | ], 29 | "source": [ 30 | "import pennylane as qml\n", 31 | "import numpy as np\n", 32 | "\n", 33 | "H = 0.5 * qml.PauliX(0) + 0.5j * qml.PauliY(0)\n", 34 | "\n", 35 | "qml.matrix(H)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 9, 41 | "id": "b93b036a", 42 | "metadata": {}, 43 | "outputs": [ 44 | { 45 | "data": { 46 | "text/plain": [ 47 | "(
, )" 48 | ] 49 | }, 50 | "execution_count": 9, 51 | "metadata": {}, 52 | "output_type": "execute_result" 53 | }, 54 | { 55 | "data": { 56 | "image/png": "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zTeW8UmTJmnFihU1ZyZrrM2bN9d5aPJnn31W720cDodWrFihSZMmWca/+eYbJScn8+FACwv4ZmbdunX6yU9+ok8++UR33323pkyZou+++04///nPtWDBArvLA9AIpaWluuOOO1RcXKxrrrlGOTk5Gj169AVvN3r0aOXk5GjIkCEqLi7WHXfcwSFnLeTUqVO6/vrrNXfuXJ06dUr33XefZs2apVtvvVWnT59Wenq61q1bZ3eZAWfnzp1KS0trtvWlpaUxhwZ+benSpVq1apVlbMSIEVqyZEmj5sb8UH2T/p9//nm1bt26wduGhoZqyZIlGj58uGX83XffveBpotE0AX1q5srKSiUnJ6tVq1basGFDzany0tLSNGTIED322GO666671LNnT3sLBeCRuXPn1nwj8z//8z/q1KmTx7ft1KmT1qxZo4SEBBUUFGju3Ll67rnnWq7YIPXcc89p586d+vWvf60lS5YoJCTEcvn+/fsb/M0GeGf69OleHVpWn4qKCk2fPl0bNmxotnUCzcXpdGrOnDmWsU6dOumNN97wupGR6p/0/9BDD3l0+9DQUL3xxhtKSEiwzOGcM2eO/vM//1ORkZFe14b6BfQ3M//85z9VUFCge++913LO74suukiPPfaYysvL9de//tW+AgF47OjRo3rppZcknftErjGNzHmdOnXS0qVLJUkvvfQSZzlrAZs3b5YkPfjgg26NjCT16tWrzuPO4b2cnJxGTfb31MaNGzltM/zS8uXLLc2CJL322mvq0aOH1+v0ZNK/J6KiovTqq69axo4fP87fmy0ooJuZjz/+WJI0atQot8vOH5qyfv16X5YEwEuvvfZazWR/Tw4tq88tt9yiwYMHq7y83O0NB03XuXNnSdLXX39tcyXBoyVfx2QE/qaqqkrPPPOMZWzMmDEaO3Zsk9bbmEn/F3L77bdrzJgxlrFnnnlGVVVVXteH+gV0M5OXlydJiouLc7vskksuUbt27Wqug8Dx9NNP68033/Touo8//ri++uor7d27t8Ff+c3Pz9fy5cstYx9//LGmTZum5557TgcPHqzzdsuXL1d+fv4FazivsrJSv//97/X++++rurrao8cQLLKzsyVJEydObPK6fvGLX0iS/vd//7fJ64JVUlKSJOnXv/61Zs2apY8++kjHjx+3uarAdv7bMNPW7W+C5b3Dk3X7s9WrV7udRGTWrFlNWqc3k/4vZObMmZbl/Px8vf/++16vD/UL6DkzJ0+elHTusLK6dOjQoeY6pnC5XHI6nXaX4XOeHgteWlqqLl26qKioSBMnTtTgwYO1a9cuXXnllTp79qwGDx6s9957Tx07dqw568i3336rkpIS7dy5Ux9++KE+++wz/elPf9Ljjz+uqVOn6tlnn1VERIT69OmjxYsXy+l0qrKyUoMHD66534iICI0fP15Dhw7Vvn379KMf/Uhdu3aVJL3++us6ceKE/vznPys9PV1dunRRVFSUnE6nSkpKtGnTJjmdTj322GM187e2b9+un/70p/rpT3+qm266SZdffrmOHz+ukpISZWRkNGoCdUVFhfGT3V0ul7Zv3y5Juvbaa5u8vmuuuUaStG3bNp0+fbrOw6FM0pxzJZpq7NixWrBggX73u99pwYIFNSdaiY2N1S233KLf/OY3dX7AZBfT81FRUdGiE/V37typkydPKizM3D8XPMlHsLx3LFmyROvWrdPBgwf1m9/8Rh06dLjgc9fc+Wjq/qr22Wj79++vG264wev1NWXSf0NuvPFGXX311crJyakZe/vttzVu3Div14m6mbt3ClJOp1Pt2rWzuwy/9d577+nw4cM6ePCgTp8+renTp+vRRx/VjBkzlJqaKuncD2nFxsbqk08+qbldZGSk+vXrp9tuu63mk5iqqip98sknuueee1RdXa09e/Zow4YNGjlypPbt2ydJuvPOO3XzzTdLOvcN4MMPP6xHH31UjzzyiFJTU3X55ZfrZz/7mQ4ePKjt27eroKBAcXFxKioq0v79+/Xf//3f2rt3r3JzczV06FAlJibqxRdfrKmrf//+mjVrltLS0nTmzBnNnz+/0cfvLl26tGaeSCDo3bt3k9dx/nCC4uJitW/fvsnrg9V//dd/KTk5WWvXrtWnn36qrVu3asuWLVq0aJFeeeUVvf32200+JKS5BFo+mltZWZk6duxodxktLljeO+Li4nTDDTdo6NChF2xkJP/MR+1vSyZPntykD6SaOum/PiEhIZo8ebKmTZtWM7Zly5YmrRN1C+hm5vw3MvV9+1JSUqKLL77YlyWhhX355Zf605/+pLNnz9Y0fec/WTm/s/vnP/+pTz/9VA899JClMXA4HHr33XfVq1cvvfLKK9q7d68efPBBvfLKKwoLC1OPHj1044036vjx47r88sslSRkZGdq1a5d+9rOf1XxyWfv+PvjgAxUXF+upp55S3759derUKfXr10/t2rXTW2+9pS+//FLx8fFavXq124TG0NBQhYSEyOVyKT4+XgsXLmQuAozQvn17JSUl1Rx2dvLkST322GN68cUX9atf/UqHDx9u0qeeQHPivcMM3333nQoLCy1jQ4cO9Xp9zTXpvz61aztw4ICOHDmi7t27N8v6cU6IK4B/yeexxx7TU089pb/97W+65557LJd99913uvTSS3XjjTcaddx8sB5m9vDDD1s+HZo2bZpXPw738ccfq7KysuYTMZN89dVXys7OVlFRkX7/+9/Xe70HH3zQ8gldcnKynn32WR9U2HJcLpd69uyp4uJibdu2TQMGDGjS+rZt26ZBgwapU6dOKiwsNP4ws+bKR0tzuVzq1auXCgsLtXXrVg0cONDnNQRaPioqKtS9e3eVl5e3yPodDoeOHDli9GFmzZGPQHrv+Oqrr3TppZfW+c2ML/LRlO2xevVq3XHHHTXL7du314kTJ7w+HXO3bt3c5sr079+/5rDmpqqqqlLHjh11+vTpmrHVq1d7/M107e3hr/t2u5m7d/LA8OHD9dRTT+mjjz5ya2YyMzNrrmOSkJAQtW3b1u4yfC48PLxZ1jNixIhmWY8dfvzjH+vHP/5xo28XHh4eEK+ZAQMGKDs7W5999lmTm5nzX/UPHDgwIA7bbK58tDR/3H8FQj769eunrVu3tti665t3aormyEcgvXc05n2kJfLRlO1R+1ThgwcP9rqRaYlJ/7WFhoZq8ODBlnmuOTk5fnOYbaAI6LOZ3XTTTerdu7feeustywSskydP6s9//rNat26t+++/374CAXjs/CeizXGu/vNnF7rpppuavC5YLV68WF988UWdl/3973/X3r171bFjR8XHx/u4ssB13XXXGbluoLFOnTplWY6OjvZqPS016b8utWv84bc0aB4B/c1MWFiYli1bptGjRysxMVH33HOP2rdvr1WrVqmwsFDz589XTEyM3WUC8MAvf/lLpaWl6fPPP1dmZqbXvzWzdu1affHFF2rdunXNWYnQfNasWaMpU6aoT58++slPfqL/+I//UGlpqf71r39p48aNatWqlV588UU5HA67Sw0YkyZN0sKFC1ts3YC/SEhI0D333KMzZ87ozJkzuuqqq7xaT0tN+q9Lv379NGrUKLVp00Zt2rRRQkJCs99HsAvoZkaSbrjhBn3yySf63e9+p7ffflsVFRW66qqrNG/ePP385z+3uzwAHurWrZumTp2q559/XsnJycrJyVGnTp0atY7i4mIlJydLkqZOnVpzClQ0n3nz5uknP/mJsrKytGHDBn377beSpB49emjixImaMWOGLXNlAtnVV1+tYcOGaePGjc263mHDhvGHF/zKfffdp/vuu69J62jpSf+1zZw50+03Z9C8Ar6ZkaQhQ4ZozZo1dpcBoImefPJJffjhhyooKNCYMWO0Zs0ajxua4uJijRkzRocOHVJsbKyefPLJFq42OP34xz/WI488okceecTuUoLKCy+8oEGDBjXbbw6Fh4cz0RgB6fyp+X+of//+uuyyy2yoBs0hoOfMAAgsbdu21d///nd16tRJn3/+uRISErR27doL3m7t2rVKSEjQ559/rk6dOunvf/+78ZO+gR/q16+fnnjiiWZb3xNPPOH1ITyAv/LFpH/4Hs0MAKPEx8dr/fr1io2N1aFDhzRmzBgNGTJEL774orZt26bvv/9e33//vbZt26YXX3xRQ4YMsXwjs379eiafIyClpqbqwQcfbPJ6pk+fXvNDkUCg8OWkf/hWUBxmBiCwxMfHa8eOHZo7d65eeuklffHFF/WeQUs692N006ZN05NPPqnIyEgfVgr4TkhIiBYuXKioqCilpaU1+pCz8PBwPfHEE0pNTTX+t5eA2nw56R++xTczAIzUtm1bPffcczp06JDS09M1cuRIy/yZTp06aeTIkUpPT9ehQ4f07LPP0sgg4IWEhGj27NnaunWrhg0b5vHthg0bpm3btmn27Nk0Mgg4vp70D9/imxkARuvatatSU1OVmpqq06dPq3379pKkwsLCgPhBTMAb/fr104YNG7Rjxw69+uqr2rx5s3bs2KHy8nJJksPhUL9+/XTddddp0qRJnLUMAY1J/4GNZgZAwPjhJ8p8ugyc+12O559/XtK5H4zu2LGjJOnIkSO66KKLbKwM8A0m/Qc+DjMDACAIhIWF1fl/IFAx6T840MwAAAAg4DDpPzjQzAAAACCgMOk/eNDMAAAAIKAw6T940MzASNXV1XaX4Ld4bsBroH48N+A1UD87npuWuM8vv/wyICb981r1DM0MjOBwOCzL508vCndlZWWW5YiICJsqga+QD8+Rj+BDPjzn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Ojpajz76qPLz87VlyxY9/fTTGjhwoMc/Cgj4g6qqKj3zzDOWsTFjxmjs2LFNWm9jJv1fyO23364xY8ZYxp555hlVVVV5XR/qRzMDIGC88sor6tixo375y1/q/fff12233eY2IRMIRhdddJFee+01OZ1O3X///Zo4caLCw8O1YsUKhYWF2V0e4LHVq1eroKDAMjZr1qwmrdObSf8XMnPmTMtyfn6+3n//fa/Xh/qxBzOMy+XiuEvYrvZpMP1Fjx49NH36dP3pT39SeHi4lixZYndJbioqKtx+2A2BxV/zcdNNN2n69OlauHChpHOfFF9++eU2V2VFPgJfU/PxzjvvWJb79++vG264wev1NWXSf0NuvPFGXX311crJyakZe/vttzVu3Div14m60cwYxul0ql27dnaXAfilo0ePavHixZLOvWF++OGHSk5Otrkqq6VLl2rp0qV2l4EgNW/ePC1cuFCXXHKJX56KmXzgQmp/WzJ58uQmzYls6qT/+oSEhGjy5MmaNm1azdiWLVuatE7UjcPMAASMKVOmqKioSOnp6erSpYtmzpzp9hsEQDBr06aNJNX87hpgku+++06FhYWWsaFDh3q9vuaa9F+f2rUdOHBAR44caZZ149/4ZsYwkZGROn36tN1lIMg9/PDDfvfp6YoVK/Tee+/ptttuU2pqqmJiYnTPPffoV7/6lbKysuwur0ZycrKeffZZu8tAC/LHfJiCfAS+puSj9jcb7du3b9Khks056b8uV1xxhdq1a2f5u23Lli1NPlkBrGhmDBMSEqK2bdvaXQaCXHh4uN0lWBw+fFgPPfSQOnXqVDNP5uc//7neffddvfvuu1q8eLEeeOABm6s8Jzw8nAwHOH/Lh0nIR+BrSj527NhhWR48eLDXvyvTEpP+awsNDdXgwYO1bt26mrGcnByamWbGYWYAjPerX/1K33//vV544QVdeumlNeMvvviiunbtqkceecTt0AQAgFlOnTplWY6OjvZqPS016b8utWvk6JrmF/DfzCxbtkyffPKJJCk3N7dm7OOPP5Z07njGX//613aVB6CJFi9erMzMTN11112aMGGC5bKuXbvqpZde0l133aVJkyYpOzubeQIAYKiEhATdc889OnPmjM6cOaOrrrrKq/W01KT/uvTr10+jRo1SmzZt1KZNGyUkJDT7fQS7gG9mPvnkE7dfXd20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\n", 57 | "text/plain": [ 58 | "
" 59 | ] 60 | }, 61 | "metadata": {}, 62 | "output_type": "display_data" 63 | } 64 | ], 65 | "source": [ 66 | "coeffs = np.array([0.5, 0.5])\n", 67 | "coeffs_sqrt = np.sqrt(coeffs)\n", 68 | "\n", 69 | "dev = qml.device(\"default.qubit\", wires = 2)\n", 70 | "\n", 71 | "@qml.qnode(dev)\n", 72 | "def circuit():\n", 73 | " \n", 74 | " qml.AmplitudeEmbedding(coeffs_sqrt, normalize = True, pad_with = 0, wires = 0)\n", 75 | " qml.ctrl(qml.PauliX, control = 0, control_values = [0])(wires = 1)\n", 76 | " qml.S(wires = 0)\n", 77 | " qml.ctrl(qml.PauliY, control = 0, control_values = [1])(wires = 1)\n", 78 | " qml.adjoint(qml.AmplitudeEmbedding)(coeffs_sqrt, normalize = True, pad_with = 0, wires = 0)\n", 79 | " \n", 80 | " return qml.state()\n", 81 | "\n", 82 | "qml.draw_mpl(circuit)()\n", 83 | " " 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 12, 89 | "id": "388da4b4", 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "[[ 0.+0.j 1.+0.j 0.+0.j -0.+0.j]\n", 97 | " [-0.+0.j 0.+0.j -1.+0.j 0.+0.j]\n", 98 | " [ 0.+0.j -0.+0.j 0.+0.j 1.+0.j]\n", 99 | " [-1.+0.j 0.+0.j 0.+0.j 0.+0.j]]\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | "print(np.round(qml.matrix(circuit)(),2))" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 8, 110 | "id": "699ab209", 111 | "metadata": {}, 112 | "outputs": [ 113 | { 114 | "data": { 115 | "text/plain": [ 116 | "array([[1.+0.j, 0.+0.j],\n", 117 | " [0.+0.j, 0.+1.j]])" 118 | ] 119 | }, 120 | "execution_count": 8, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "qml.matrix(qml.S)(wires = 0)" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "id": "b4bcfb1b", 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [] 136 | } 137 | ], 138 | "metadata": { 139 | "kernelspec": { 140 | "display_name": "Python 3 (ipykernel)", 141 | "language": "python", 142 | "name": "python3" 143 | }, 144 | "language_info": { 145 | "codemirror_mode": { 146 | "name": "ipython", 147 | "version": 3 148 | }, 149 | "file_extension": ".py", 150 | "mimetype": "text/x-python", 151 | "name": "python", 152 | "nbconvert_exporter": "python", 153 | "pygments_lexer": "ipython3", 154 | "version": "3.11.1" 155 | } 156 | }, 157 | "nbformat": 4, 158 | "nbformat_minor": 5 159 | } 160 | -------------------------------------------------------------------------------- /HHL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "fc419575", 6 | "metadata": {}, 7 | "source": [ 8 | "![img](hhl_model.jpeg)" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "27c3d840", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pennylane as qml\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Esta celda es el conjunto de operaciones necesarias para implementar la división \n", 22 | "\n", 23 | "def add_k_fourier(k, wires):\n", 24 | " for j in range(len(wires)):\n", 25 | " qml.RZ(k * np.pi / (2**j), wires=wires[j])\n", 26 | " \n", 27 | "def substract_m_n(wires_m, wires_n):\n", 28 | " # |m>|n> -> |m - n> |n>\n", 29 | " \n", 30 | " qml.QFT(wires = wires_m)\n", 31 | " \n", 32 | " \n", 33 | " for i in range(len(wires_n)):\n", 34 | " qml.ctrl(add_k_fourier, control=wires_n[i])(-2 **(len(wires_n) - i - 1), wires_m)\n", 35 | " \n", 36 | " qml.adjoint(qml.QFT)(wires = wires_m)\n", 37 | "\n", 38 | "def is_greater(wires_m, wires_n, wires_aux, wires_target):\n", 39 | " \n", 40 | " wires_m_aux = [wires_aux] + list(wires_m)\n", 41 | " substract_m_n(wires_m_aux, wires_n)\n", 42 | " \n", 43 | " qml.PauliX(wires = wires_aux)\n", 44 | " qml.CNOT(wires = [wires_aux, wires_target])\n", 45 | " qml.PauliX(wires = wires_aux)\n", 46 | " \n", 47 | " qml.adjoint(substract_m_n)(wires_m_aux, wires_n)\n", 48 | " \n", 49 | "\n", 50 | "def division(wires_dividendo, wires_divisor, wires_aux_dividendo, wires_solucion, wires_aux):\n", 51 | " \n", 52 | " wires_dividendo_totales = wires_aux_dividendo + wires_dividendo\n", 53 | " \n", 54 | " for i in range(len(wires_solucion)):\n", 55 | " window = wires_dividendo_totales[i - 1: len(wires_divisor)+ i]\n", 56 | " if i == 0:\n", 57 | " window = wires_dividendo_totales[0: len(wires_divisor)]\n", 58 | " \n", 59 | " is_greater(window, wires_divisor, wires_aux, wires_solucion[i])\n", 60 | " qml.ctrl(substract_m_n, control = wires_solucion[i])(window, wires_divisor)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 2, 66 | "id": "b4b0da81", 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "# Subrutina del HHL\n", 71 | "\n", 72 | "import scipy\n", 73 | "\n", 74 | "A = 1/64 * np.array([[15, 9, 5, -3],\n", 75 | " [9, 15, 3, -5],\n", 76 | " [5, 3, 15, -9],\n", 77 | " [-3, -5, -9, 15]])\n", 78 | "\n", 79 | "U = scipy.linalg.expm(2 * np.pi * 1j * A)\n", 80 | "\n", 81 | "\n", 82 | "dev = qml.device(\"default.qubit\", wires = 21)\n", 83 | "\n", 84 | "wires_b = [0,1]\n", 85 | "wires_divisor = [2,3,4,5]\n", 86 | "wires_solucion = [11,12,13,14,15]\n", 87 | "wires_dividendo = [6,7,8,9,10]\n", 88 | "wires_aux_window = [16,17,18]\n", 89 | "aux_div = 19\n", 90 | "wire_rotacion = 20\n", 91 | "\n", 92 | "def qpe_division():\n", 93 | " qml.QuantumPhaseEstimation(U, wires_b, wires_divisor)\n", 94 | " qml.PauliX(wires = wires_dividendo[0])\n", 95 | " division(wires_dividendo, wires_divisor, wires_aux_window, wires_solucion, aux_div)\n", 96 | "\n", 97 | "@qml.qnode(dev)\n", 98 | "def circuit():\n", 99 | "\n", 100 | " #inicializamos b\n", 101 | " qml.Hadamard(wires = 0)\n", 102 | " qml.Hadamard(wires = 1)\n", 103 | "\n", 104 | " qpe_division()\n", 105 | "\n", 106 | " for i in range(len(wires_solucion)):\n", 107 | "\n", 108 | " C = 1/2 ** (len(wires_solucion)- 1)\n", 109 | " qml.CRY(2 *np.arccos(2 ** (len(wires_solucion)-i-1) * C), wires = [wires_solucion[i], wire_rotacion])\n", 110 | " \n", 111 | " qml.PauliX(wires = wire_rotacion)\n", 112 | " \n", 113 | " qml.adjoint(qpe_division)()\n", 114 | "\n", 115 | " return qml.density_matrix(wires = wires_b + [wire_rotacion])" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 3, 121 | "id": "dffffecc", 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "import functools as ft\n", 126 | "\n", 127 | "def qubit_postselect_dm(meas_outputs, wires, in_state):\n", 128 | " \n", 129 | " num_wires = int(np.log2(len(in_state)))\n", 130 | " arr = [np.identity(2) for _ in range(num_wires)]\n", 131 | " for i in range(len(wires)):\n", 132 | " if meas_outputs[i]=='0':\n", 133 | " arr[int(wires[i])]=np.array([1,0])\n", 134 | " elif meas_outputs[i]=='1':\n", 135 | " arr[int(wires[i])]=np.array([0,1])\n", 136 | " \n", 137 | " projector = ft.reduce(np.kron,arr)\n", 138 | " out_state = np.linalg.multi_dot([projector, in_state, projector.T])\n", 139 | " out_state = out_state/np.trace(out_state)\n", 140 | " \n", 141 | " return [out_state[i][i] for i in range(len(out_state))]" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 4, 147 | "id": "46e7a4d3", 148 | "metadata": {}, 149 | "outputs": [ 150 | { 151 | "name": "stderr", 152 | "output_type": "stream", 153 | "text": [ 154 | "/Users/guille/Documents/GitHub/pennylane/pennylane/qnode.py:823: UserWarning: The device was switched during the call of the QNode, to avoid this behaviour definean interface argument instead of auto.\n", 155 | " warnings.warn(\n" 156 | ] 157 | }, 158 | { 159 | "name": "stdout", 160 | "output_type": "stream", 161 | "text": [ 162 | "[(0.002941176470605185+2.3366182719901103e-34j), (0.14411764705886757+3.614998646227333e-33j), (0.35588235294116893-1.5558228322110126e-33j), (0.49705882352935826-2.2928376412153303e-33j)]\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "dm = circuit()\n", 168 | "output = qubit_postselect_dm(\"1\", [2], dm)\n", 169 | "print(output)" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 5, 175 | "id": "a3923a3c", 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "name": "stderr", 180 | "output_type": "stream", 181 | "text": [ 182 | "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/matplotlib/transforms.py:762: ComplexWarning: Casting complex values to real discards the imaginary part\n", 183 | " points = np.asarray(points, float)\n" 184 | ] 185 | }, 186 | { 187 | "data": { 188 | "text/plain": [ 189 | "" 190 | ] 191 | }, 192 | "execution_count": 5, 193 | "metadata": {}, 194 | "output_type": "execute_result" 195 | }, 196 | { 197 | "data": { 198 | "image/png": "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/etfV1xcXJ/Xtbe3Kz09XQcPHlRSUtLpmKqp0bRe1jpyjab1staRazSt18tanXM6cuSIpkyZ0u84TzGSkpKihIQEtbS09Djf0tKitLS0Xq9JS0vzNF6SfD6ffD5fj3MTJkwY8DyTkpJG/P8Zvmw0rZe1jlyjab2sdeQaTesd6Fr7uyNyjKdP0yQmJionJ0d1dXXRc5FIRHV1dSooKOj1moKCgh7jJWnjxo19jgcAAKOL51/TBINBFRcXKzc3V3l5eaqsrFRHR0f00zVLlizR1KlTFQqFJEnLly/X/Pnz9cc//lELFy7U2rVr9dZbb+nPf/7z0K4EAADEJM8xUlRUpEOHDmnFihUKh8PKzs5WbW1t9E2qBw4cUHz88Rsu8+bN01NPPaXf/e53+s1vfqPzzz9fzz77rC666KKhW8X/5/P5VFFRccKveEaq0bRe1jpyjab1staRazStdzjWGudO9nkbAACAYcTfpgEAAKaIEQAAYIoYAQAApogRAABgKuZj5OOPP9YNN9ygpKQkTZgwQUuXLtVnn33W7zULFixQXFxcj+PnP//5aZqxN1VVVcrIyJDf71d+fr62bt3a7/inn35as2fPlt/v18UXX6znn3/+NM301HlZ65o1a07YQ7/ffxpnO3ivvvqqrr32Wk2ZMkVxcXH9/p2mY+rr63XJJZfI5/Np5syZWrNmzbDPcyh4XWt9ff0J+xoXF9fvn484U4RCIV166aUaP368zj33XC1atEi7du066XWx+JodzFpj+TX70EMPac6cOdF/5KugoEAvvPBCv9fE4r5K3tc6VPsa8zFyww03aMeOHdq4caP+/ve/69VXX9XNN9980utKS0v10UcfRY977733NMzWm3Xr1ikYDKqiokJNTU3KyspSYWGhWltbex3/+uuva/HixVq6dKm2bdumRYsWadGiRXrnnXdO88y987pW6Yt//e/Le7h///7TOOPB6+joUFZWlqqqqgY0fu/evVq4cKGuuOIKNTc367bbbtNNN92kF198cZhneuq8rvWYXbt29djbc889d5hmOHQ2bdqkW2+9VW+88YY2btyozz//XFdffbU6Ojr6vCZWX7ODWasUu6/Z8847TytXrlRjY6Peeustfec739F1112nHTt29Do+VvdV8r5WaYj21cWwd99910lyb775ZvTcCy+84OLi4twHH3zQ53Xz5893y5cvPw0zPDV5eXnu1ltvjX7d3d3tpkyZ4kKhUK/jf/SjH7mFCxf2OJefn+9+9rOfDes8h4LXtT722GMuOTn5NM1u+Ehy69ev73fMr3/9a3fhhRf2OFdUVOQKCwuHcWZDbyBrfeWVV5wk98knn5yWOQ2n1tZWJ8lt2rSpzzGx/Jr9soGsdaS8Zo+ZOHGie/TRR3v93kjZ12P6W+tQ7WtM3xlpaGjQhAkTlJubGz0XCAQUHx+vLVu29Hvtk08+qZSUFF100UUqLy/X0aNn1p+u7urqUmNjowKBQPRcfHy8AoGAGhoaer2moaGhx3hJKiws7HP8mWIwa5Wkzz77TNOmTVN6evpJyz2Wxeq+nors7GxNnjxZV111lV577TXr6QxKW1ubJGnSpEl9jhkpezuQtUoj4zXb3d2ttWvXqqOjo88/azJS9nUga5WGZl/PyL/aO1DhcPiE27djxozRpEmT+v0d849//GNNmzZNU6ZM0dtvv6077rhDu3bt0jPPPDPcUx6ww4cPq7u7O/ov2x6Tmpqq9957r9drwuFwr+PP9N+3D2ats2bNUk1NjebMmaO2tjatWrVK8+bN044dO3TeeeedjmmfNn3ta3t7u/7zn//o7LPPNprZ0Js8ebKqq6uVm5urzs5OPfroo1qwYIG2bNmiSy65xHp6AxaJRHTbbbfp29/+dr//2nSsvma/bKBrjfXX7Pbt21VQUKD//ve/GjdunNavX6/MzMxex8b6vnpZ61Dt6xkZI2VlZbrnnnv6HbNz585BP/6X31Ny8cUXa/Lkybryyiu1Z88ezZgxY9CPi9OnoKCgR6nPmzdPF1xwgR5++GHdfffdhjPDqZg1a5ZmzZoV/XrevHnas2eP7r//fj3++OOGM/Pm1ltv1TvvvKPNmzdbT2XYDXStsf6anTVrlpqbm9XW1qa//e1vKi4u1qZNm/r8IR3LvKx1qPb1jIyRX/7yl/rJT37S75jp06crLS3thDc4/u9//9PHH3+stLS0AT9ffn6+JGn37t1nTIykpKQoISFBLS0tPc63tLT0uba0tDRP488Ug1nrV5111lmaO3eudu/ePRxTNNXXviYlJY2ouyJ9ycvLi6kf6suWLYu+mf5k/2UYq6/ZY7ys9ati7TWbmJiomTNnSpJycnL05ptv6oEHHtDDDz98wthY31cva/2qwe7rGfmekXPOOUezZ8/u90hMTFRBQYE+/fRTNTY2Rq99+eWXFYlEooExEM3NzZK+uEV8pkhMTFROTo7q6uqi5yKRiOrq6vr83V1BQUGP8ZK0cePGfn/XdyYYzFq/qru7W9u3bz+j9nCoxOq+DpXm5uaY2FfnnJYtW6b169fr5Zdf1je+8Y2TXhOrezuYtX5VrL9mI5GIOjs7e/1erO5rX/pb61cNel9P+S2wxq655ho3d+5ct2XLFrd582Z3/vnnu8WLF0e///7777tZs2a5LVu2OOec2717t7vrrrvcW2+95fbu3euee+45N336dHf55ZdbLaFPa9eudT6fz61Zs8a9++677uabb3YTJkxw4XDYOefcjTfe6MrKyqLjX3vtNTdmzBi3atUqt3PnTldRUeHOOusst337dqslDJjXtd55553uxRdfdHv27HGNjY3u+uuvd36/3+3YscNqCQN25MgRt23bNrdt2zYnya1evdpt27bN7d+/3znnXFlZmbvxxhuj4//1r3+5sWPHuttvv93t3LnTVVVVuYSEBFdbW2u1hAHzutb777/fPfvss+6f//yn2759u1u+fLmLj493//jHP6yWMGC/+MUvXHJysquvr3cfffRR9Dh69Gh0zEh5zQ5mrbH8mi0rK3ObNm1ye/fudW+//bYrKytzcXFx7qWXXnLOjZx9dc77WodqX2M+Rv7973+7xYsXu3HjxrmkpCRXUlLijhw5Ev3+3r17nST3yiuvOOecO3DggLv88svdpEmTnM/nczNnznS33367a2trM1pB/x588EH3f//3fy4xMdHl5eW5N954I/q9+fPnu+Li4h7j//rXv7pvfvObLjEx0V144YVuw4YNp3nGg+dlrbfddlt0bGpqqvvud7/rmpqaDGbt3bGPr371OLa+4uJiN3/+/BOuyc7OdomJiW769OnuscceO+3zHgyva73nnnvcjBkznN/vd5MmTXILFixwL7/8ss3kPeptnZJ67NVIec0OZq2x/Jr96U9/6qZNm+YSExPdOeec46688sroD2fnRs6+Oud9rUO1r3HOOeftXgoAAMDQOSPfMwIAAEYPYgQAAJgiRgAAgCliBAAAmCJGAACAKWIEAACYIkYAAIApYgQAAJgiRgAAgCliBAAAmCJGAACAKWIEAACY+n9i44oPymK2gAAAAABJRU5ErkJggg==\n", 199 | "text/plain": [ 200 | "
" 201 | ] 202 | }, 203 | "metadata": {}, 204 | "output_type": "display_data" 205 | } 206 | ], 207 | "source": [ 208 | "import matplotlib.pyplot as plt\n", 209 | "\n", 210 | "plt.bar(range(len(output)), output)" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 6, 216 | "id": "3edabb45", 217 | "metadata": {}, 218 | "outputs": [ 219 | { 220 | "data": { 221 | "text/plain": [ 222 | "" 223 | ] 224 | }, 225 | "execution_count": 6, 226 | "metadata": {}, 227 | "output_type": "execute_result" 228 | }, 229 | { 230 | "data": { 231 | "image/png": "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\n", 232 | "text/plain": [ 233 | "
" 234 | ] 235 | }, 236 | "metadata": {}, 237 | "output_type": "display_data" 238 | } 239 | ], 240 | "source": [ 241 | "solucion = (1/4 * np.array([-1, 7 ,11, 13])) ** 2\n", 242 | "\n", 243 | "plt.bar(range(len(solucion)), solucion)" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": null, 249 | "id": "927235c1", 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [] 253 | } 254 | ], 255 | "metadata": { 256 | "kernelspec": { 257 | "display_name": "Python 3 (ipykernel)", 258 | "language": "python", 259 | "name": "python3" 260 | }, 261 | "language_info": { 262 | "codemirror_mode": { 263 | "name": "ipython", 264 | "version": 3 265 | }, 266 | "file_extension": ".py", 267 | "mimetype": "text/x-python", 268 | "name": "python", 269 | "nbconvert_exporter": "python", 270 | "pygments_lexer": "ipython3", 271 | "version": "3.11.1" 272 | } 273 | }, 274 | "nbformat": 4, 275 | "nbformat_minor": 5 276 | } 277 | --------------------------------------------------------------------------------