diff --git a/examples/evolutions.ipynb b/examples/evolutions.ipynb index 9d31ad8..cc3ae85 100644 --- a/examples/evolutions.ipynb +++ b/examples/evolutions.ipynb @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "21685242", "metadata": {}, "outputs": [], @@ -53,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "d8527d79", "metadata": {}, "outputs": [ @@ -97,7 +97,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "5714c87f", "metadata": {}, "outputs": [ @@ -115,7 +115,7 @@ "include \"stdgates.inc\";\n", "qubit[4] qb;\n", "bit[4] cb;\n", - "gate TFIM_3q_J100_h70(time) aa,ab,ac{\n", + "gate TFIM_3q_j100_h70(time) aa,ab,ac{\n", "\tcnot aa, ab;\n", "\trz(2.0 * time) ab;\n", "\tcnot aa, ab;\n", @@ -132,7 +132,7 @@ "\n", "gate GQSP_1_TFIM(θa,θb,θc) aa,ab,ac,ad{\n", "\try(θa) aa;\n", - "\tctrl(1) @ TFIM_3q_J100_h70(0.1) aa, ab, ac, ad;\n", + "\tctrl(1) @ TFIM_3q_j100_h70(0.1) aa, ab, ac, ad;\n", "\tp(θb) aa;\n", "\try(θc) aa;\n", "}\n", @@ -149,7 +149,7 @@ "include \"stdgates.inc\";\n", "qubit[4] qb;\n", "bit[4] cb;\n", - "gate TFIM_3q_J100_h70(time) aa,ab,ac{\n", + "gate TFIM_3q_j100_h70(time) aa,ab,ac{\n", "\tcnot aa, ab;\n", "\trz(2.0 * time) ab;\n", "\tcnot aa, ab;\n", @@ -166,13 +166,13 @@ "\n", "gate GQSP_3_TFIM(θa,θb,θc,θd,θe,θf,θg) aa,ab,ac,ad{\n", "\try(θa) aa;\n", - "\tctrl(1) @ TFIM_3q_J100_h70(0.1) aa, ab, ac, ad;\n", + "\tctrl(1) @ TFIM_3q_j100_h70(0.1) aa, ab, ac, ad;\n", "\tp(θb) aa;\n", "\try(θe) aa;\n", - "\tctrl(1) @ TFIM_3q_J100_h70(0.1) aa, ab, ac, ad;\n", + "\tctrl(1) @ TFIM_3q_j100_h70(0.1) aa, ab, ac, ad;\n", "\tp(θc) aa;\n", "\try(θf) aa;\n", - "\tctrl(1) @ TFIM_3q_J100_h70(0.1) aa, ab, ac, ad;\n", + "\tctrl(1) @ TFIM_3q_j100_h70(0.1) aa, ab, ac, ad;\n", "\tp(θd) aa;\n", "\try(θg) aa;\n", "}\n", @@ -288,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "7c651bcd", "metadata": {}, "outputs": [ @@ -300,13 +300,13 @@ "Trotter Decomposition - Two vs Multi-Hamiltonian\n", "----------------------------------------------------\n", "Configuration 1: Two-Hamiltonian Trotter (Suzuki)\n", - "Two-Hamiltonian: 1858 characters\n", + "Two-Hamiltonian: 1864 characters\n", "\tMethod: Suzuki-Trotter, Depth: 2\n", "OPENQASM 3;\n", "include \"stdgates.inc\";\n", "qubit[3] qb;\n", "bit[3] cb;\n", - "gate TFIM_3q_J100_h70(time) aa,ab,ac{\n", + "gate TFIM_3q_j100_h70(time) aa,ab,ac{\n", "\tcnot aa, ab;\n", "\trz(2.0 * time) ab;\n", "\tcnot aa, ab;\n", @@ -321,7 +321,7 @@ "\trx(1.4 * time) ac;\n", "}\n", "\n", - "gate HeisenbergXYZ_3q_Jx100_Jy120_Jz80(time) aa,ab,ac{\n", + "gate HeisenbergXYZ_3q_j_x100_j_y120_j_z80(time) aa,ab,ac{\n", "\try(pi/2) aa;\n", "\try(pi/2) ab;\n", "\tcnot aa, ab;\n", @@ -360,9 +360,9 @@ "\n", "def trot_suz_3_TFIM_HeisenbergXYZ_2(qubit[3] qubits,float time,int recursion_depth) {\n", "\tif (recursion_depth < 2){\n", - "\t\tTFIM_3q_J100_h70(time/2) qb[qubits[0]],qb[qubits[1]],qb[qubits[2]];\n", - "\t\tHeisenbergXYZ_3q_Jx100_Jy120_Jz80(time) qb[qubits[0]],qb[qubits[1]],qb[qubits[2]];\n", - "\t\tTFIM_3q_J100_h70(time/2) qb[qubits[0]],qb[qubits[1]],qb[qubits[2]];\n", + "\t\tTFIM_3q_j100_h70(time/2) qb[qubits[0]],qb[qubits[1]],qb[qubits[2]];\n", + "\t\tHeisenbergXYZ_3q_j_x100_j_y120_j_z80(time) qb[qubits[0]],qb[qubits[1]],qb[qubits[2]];\n", + "\t\tTFIM_3q_j100_h70(time/2) qb[qubits[0]],qb[qubits[1]],qb[qubits[2]];\n", "\t\treturn;\n", "\t}\n", "\tfloat suzuki_coeff = 1.0/(4.0 - pow(4.0, 1.0/(2.0*recursion_depth - 1.0)));\n", @@ -377,16 +377,16 @@ "\n", "\n", "Configuration 2: Multi-Hamiltonian Trotter\n", - "Multi-Hamiltonian: 3342 characters\n", + "Multi-Hamiltonian: 3351 characters\n", "\tHamiltonians: 3, Depth: 2\n", "\n", "Configuration 3: Linear Trotter Decomposition\n", - "Linear Trotter: 1769 characters\n", + "Linear Trotter: 1784 characters\n", "Method: First-order, Steps: 4\n", "Trotter Configuration Comparison:\n", - "\tTwo-Hamiltonian (Suzuki): 1858 chars\n", - "\tMulti-Hamiltonian: 3342 chars\n", - "\tLinear decomposition: 1769 chars\n" + "\tTwo-Hamiltonian (Suzuki): 1864 chars\n", + "\tMulti-Hamiltonian: 3351 chars\n", + "\tLinear decomposition: 1784 chars\n" ] } ], @@ -492,7 +492,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "4b4b3bff", "metadata": {}, "outputs": [ @@ -508,19 +508,13 @@ "[('Z', np.complex128(1+0j))]\n", "Pauli-Z: 508 characters\n", "Testing Random 4x4 matrix (4, 4)...\n", - "[('II', np.complex128(0.4604637367120007+0.838946781387169j)), ('XI', np.complex128(0.5655598377382944+0.588833075307832j)), ('XX', np.complex128(0.4238844968885312+0.3326317061016123j)), ('IX', np.complex128(0.33106499350145013+0.33007330113196753j)), ('XY', np.complex128(-0.06002262495215413+0.2992097507618375j)), ('IY', np.complex128(-0.1797796889495182+0.20356340119461624j)), ('YI', np.complex128(-0.13521719508002197+0.19794667244217146j)), ('ZX', np.complex128(0.02442078075316162-0.23360780554666702j)), ('XZ', np.complex128(-0.18057751029366081-0.148700172760367j)), ('ZY', np.complex128(0.2184605953247674+0.03821255057383305j)), ('IZ', np.complex128(-0.095147349933698+0.07351264181838879j)), ('ZI', np.complex128(-0.11616413227155017+0.02567510247519522j)), ('YY', np.complex128(-0.05126587163767765+0.10703189572053626j)), ('YZ', np.complex128(-0.09614107149005136-0.02889548280897075j)), ('YX', np.complex128(-0.0870637778551501+0.04327330864487838j)), ('ZZ', np.complex128(0.0896637111235748-0.035398963079813106j))]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Random 4x4: 2019 characters\n", + "[('IX', np.complex128(0.6312692451983448+0.7062795340748755j)), ('II', np.complex128(0.3312704466731056+0.6543110856138611j)), ('XX', np.complex128(0.48885549810002155+0.46708079988828466j)), ('XI', np.complex128(0.5064276643525388+0.42560849024074227j)), ('YI', np.complex128(-0.2209432140524214-0.32680593560317794j)), ('XY', np.complex128(0.3051770998894734-0.08729195918180288j)), ('YY', np.complex128(0.22903059831001216-0.17048096768847246j)), ('ZZ', np.complex128(-0.12674613849154037+0.09991843038070033j)), ('ZI', np.complex128(-0.14733787825849548+0.023772954678058178j)), ('IY', np.complex128(-0.13339759254293293-0.04272733136592735j)), ('IZ', np.complex128(-0.018907216413733607-0.13091360941091704j)), ('ZX', np.complex128(0.007991339043142087-0.10180140392762566j)), ('ZY', np.complex128(-0.05995761592784832-0.0542893312281765j)), ('XZ', np.complex128(-0.016121493337997672+0.07795486151092063j)), ('YZ', np.complex128(0.06407397205381465+0.006693388785256826j)), ('YX', np.complex128(0.03553879879197233-0.04432680229575253j))]\n", + "Random 4x4: 2023 characters\n", "\n", "Configuration 2: Operator Chain Input\n", "Testing Single Pauli chain (3 operators)...\n", "[('X', 0.5), ('Z', 0.3), ('Y', 0.2)]\n", - "\tSingle Pauli: 719 characters\n", + "\tSingle Pauli: 717 characters\n", "\tOperators: ['X', 'Z', 'Y']\n", "OPENQASM 3;\n", "include \"stdgates.inc\";\n", @@ -545,7 +539,7 @@ "\ty aa;\n", "}\n", "\n", - "gate SEL_8998145479025848162 aa,ab,ac,ad{\n", + "gate SEL_247308947824619046 aa,ab,ac,ad{\n", "\tctrl(2) @ X aa,ab,ac,ad;\n", "\tx aa;\n", "\tctrl(2) @ Z aa,ab,ac,ad;\n", @@ -555,13 +549,13 @@ "\tx ab;\n", "}\n", "\n", - "gate PS_2_8654309695166846104 aa,ab,ac,ad{\n", + "gate PS_2_8139876655021836051 aa,ab,ac,ad{\n", "\tPREP_3905172865891942725 aa,ab;\n", - "\tSEL_8998145479025848162 aa,ab,ac,ad;\n", + "\tSEL_247308947824619046 aa,ab,ac,ad;\n", "\tinv @ PREP_3905172865891942725 aa,ab;\n", "}\n", "\n", - "PS_2_8654309695166846104 qb[3],qb[4],qb[0],qb[1];\n", + "PS_2_8139876655021836051 qb[3],qb[4],qb[0],qb[1];\n", "cb[{3, 4}] = measure qb[{3, 4}];\n", "cb[{0, 1, 2, 3}] = measure qb[{0, 1, 2, 3}];\n", "\n", @@ -573,9 +567,9 @@ "Prep-Select Configuration Comparison:\n", "Matrix inputs:\n", "\tPauli-Z: 508 chars\n", - "\tRandom 4x4: 2019 chars\n", + "\tRandom 4x4: 2023 chars\n", "Operator chains:\n", - "\tSingle Pauli: 719 chars\n", + "\tSingle Pauli: 717 chars\n", "\tTwo-qubit Pauli: 756 chars\n" ] } @@ -681,7 +675,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "a44b4a64", "metadata": {}, "outputs": [ @@ -698,10 +692,10 @@ " Step 2: Applying GQSP...\n", " Step 3: Applying prep-select...\n", "[('Z', np.complex128(1+0j))]\n", - "Integrated pipeline: 2465 characters\n", - " Contains Trotter: True\n", - " Contains GQSP: True\n", - " Contains PrepSelect: True\n" + "Integrated pipeline: 2471 characters\n", + "\tContains Trotter: True\n", + "\tContains GQSP: True\n", + "\tContains PrepSelect: True\n" ] } ], @@ -789,40 +783,19 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "id": "22dfb86d", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "OPENQASM 3;\n", - "include \"stdgates.inc\";\n", - "qubit[3] qb;\n", - "gate Z_on_two3 aa,ab,ac{\n", - "\tx ac;\n", - "\tctrl(2) @ z aa, ab, ac;\n", - "\tx ac;\n", - "}\n", - "\n", - "def Grover3Z_on_two3(qubit[3] reg) {\n", - "\th reg;\n", - "\tfor int i in [0:2] {\n", - "\t\t//Za\n", - "\t\tZ_on_two3 reg[0], reg[1], reg[2];\n", - "\t\th reg;\n", - "\t\t//Z0\n", - "\t\tx reg;\n", - "\t\tctrl(2) @ z reg[0], reg[1], reg[0];\n", - "\t\tx reg;\n", - "\t\th reg;\n", - "\t}\n", - "}\n", - "\n", - "input angle[32] theta ;\n", - "Grover3Z_on_two3(qb[{0 ,1 ,2}]);\n", - "\n" + "ename": "TypeError", + "evalue": "GateLibrary.add_var() got an unexpected keyword argument 'type'. Did you mean 'qtype'?", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 51\u001b[39m\n\u001b[32m 47\u001b[39m \u001b[38;5;28mself\u001b[39m.controlled_op(\u001b[38;5;28mself\u001b[39m.name, (qubits[-\u001b[32m1\u001b[39m], [control] + qubits[:-\u001b[32m1\u001b[39m]))\n\u001b[32m 50\u001b[39m \u001b[38;5;66;03m# Define input parameter\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m51\u001b[39m theta = \u001b[43mprogram\u001b[49m\u001b[43m.\u001b[49m\u001b[43madd_var\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mtheta\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43minput angle[32]\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 53\u001b[39m \u001b[38;5;66;03m# Apply Grover with custom gate\u001b[39;00m\n\u001b[32m 54\u001b[39m ampl.grover(Za, reg, \u001b[32m3\u001b[39m)\n", + "\u001b[31mTypeError\u001b[39m: GateLibrary.add_var() got an unexpected keyword argument 'type'. Did you mean 'qtype'?" ] } ], @@ -901,7 +874,7 @@ ], "metadata": { "kernelspec": { - "display_name": "venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -915,7 +888,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.8" + "version": "3.13.9" } }, "nbformat": 4, diff --git a/examples/qaoa.ipynb b/examples/qaoa.ipynb new file mode 100644 index 0000000..73a7c06 --- /dev/null +++ b/examples/qaoa.ipynb @@ -0,0 +1,522 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "47f77f7f", + "metadata": {}, + "source": [ + "## Import Required Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "1c81f61d", + "metadata": {}, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\n", + "import networkx as nx\n", + "from qbraid_algorithms.qaoa import QAOA\n", + "import pyqasm\n", + "\n", + "from qiskit_qasm3_import import parse\n", + "from qiskit_ibm_runtime import Session, Sampler as Sampler, Estimator\n", + "from qiskit_aer import AerSimulator\n", + "from scipy.optimize import minimize\n", + "from qiskit.visualization import plot_histogram\n", + "from qiskit.quantum_info import SparsePauliOp\n", + "import numpy as np\n", + "from typing import Sequence" + ] + }, + { + "cell_type": "markdown", + "id": "0f421985", + "metadata": {}, + "source": [ + "## Graph definition for max-cut problem\n", + "\n", + "The Max-Cut problem is an optimization problem that is hard to solve (more specifically, it is an _NP-hard_ problem) with a number of different applications in clustering, network science, and statistical physics. This example considers a graph of nodes connected by edges, and aims to partition the nodes into two sets such that the number of edges traversed by this cut is maximized.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "18ff0ac8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "edges = [(0, 1), (0, 2), (0, 4), (1, 2), (2, 3), (3, 4)]\n", + "graph = nx.Graph(edges)\n", + "positions = nx.spring_layout(graph, seed=1)\n", + "\n", + "nx.draw(graph, with_labels=True, pos=positions)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8805a7ad", + "metadata": {}, + "source": [ + "## Compute cost function\n", + "In this case the *Qiskit* object are used to calculate the cost but it can be done with custom methods" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "9d2812e8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cost Function Hamiltonian: SparsePauliOp(['IIIZZ', 'IIZIZ', 'ZIIIZ', 'IIZZI', 'IZZII', 'ZZIII'],\n", + " coeffs=[1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j])\n" + ] + } + ], + "source": [ + "def build_max_cut_paulis(graph: nx.Graph) -> list[tuple[str, float]]:\n", + " \"\"\"Convert the graph to Pauli list.\n", + " \n", + " This function does the inverse of `build_max_cut_graph`\n", + " \"\"\"\n", + " pauli_list = []\n", + " for i,j in graph.edges:\n", + " pauli_list.append((\"ZZ\", [i, j], 1))\n", + " return pauli_list\n", + "\n", + "n = 5\n", + "max_cut_paulis = build_max_cut_paulis(graph)\n", + "cost_hamiltonian = SparsePauliOp.from_sparse_list(max_cut_paulis, n)\n", + "print(\"Cost Function Hamiltonian:\", cost_hamiltonian)" + ] + }, + { + "cell_type": "markdown", + "id": "383019ac", + "metadata": {}, + "source": [ + "## Create cost function\n", + "Here we create two different cost functions, one for getting the counts that uses the *Sampler* primitive for retreiving the counts and the *Estimator* to calculate the cost" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "5e8714c7", + "metadata": {}, + "outputs": [], + "source": [ + "def cost_function_res(params):\n", + " qaoa = QAOA(5, use_input=False)\n", + " qaoa.setup_maxcut(graph=graph)\n", + " program = qaoa.generate_algorithm(3, param=params)\n", + " module = pyqasm.loads(program)\n", + " module.unroll()\n", + " loaded_circuit = parse(pyqasm.dumps(module))\n", + " aer_sim = AerSimulator()\n", + " with Session(backend=aer_sim):\n", + " sampler = Sampler()\n", + " sampler.options.dynamical_decoupling.enable = True\n", + " sampler.options.dynamical_decoupling.sequence_type = \"XY4\"\n", + " sampler.options.twirling.enable_gates = True\n", + " sampler.options.twirling.num_randomizations = \"auto\"\n", + " result = sampler.run([loaded_circuit], shots=10000).result()\n", + " return result[0].data.cb.get_counts(), result[0].data.cb.get_int_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "76eec508", + "metadata": {}, + "outputs": [], + "source": [ + "objective_func_vals = []\n", + "def cost_function(params):\n", + " qaoa = QAOA(5, use_input=False)\n", + " qaoa.setup_maxcut(graph=graph)\n", + " program = qaoa.generate_algorithm(3, param=params)\n", + " module = pyqasm.loads(program)\n", + " module.unroll()\n", + " loaded_circuit = parse(pyqasm.dumps(module))\n", + " aer_sim = AerSimulator()\n", + " with Session(backend=aer_sim) as session:\n", + " sampler = Estimator(mode=session)\n", + " sampler.options.default_shots = 20000\n", + " pub = (loaded_circuit, cost_hamiltonian, [])\n", + " result = sampler.run([pub]).result()\n", + " cost = result[0].data.evs\n", + " objective_func_vals.append(cost)\n", + " return cost" + ] + }, + { + "cell_type": "markdown", + "id": "0f8a48f1", + "metadata": {}, + "source": [ + "## Define initial parameters and minimize the cost function" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "df258b64", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " message: Return from COBYLA because the trust region radius reaches its lower bound.\n", + " success: True\n", + " status: 0\n", + " fun: -2.2875\n", + " x: [-2.921e-01 2.782e+00 2.051e+00 4.779e+00 2.335e+00\n", + " 3.005e+00]\n", + " nfev: 57\n", + " maxcv: 0.0\n" + ] + } + ], + "source": [ + "initial_gamma = np.pi\n", + "initial_beta = np.pi / 2\n", + "init_params = [initial_beta, initial_beta, initial_beta, initial_gamma, initial_gamma, initial_gamma]\n", + "result = minimize(\n", + " cost_function,\n", + " init_params,\n", + " method=\"COBYLA\",\n", + " tol=1e-2,\n", + " )\n", + "print(result)" + ] + }, + { + "cell_type": "markdown", + "id": "c52d23ac", + "metadata": {}, + "source": [ + "## Visualization of the cost vs iterations during minimization" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e8596cb2", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(12, 6))\n", + "plt.plot(objective_func_vals)\n", + "plt.xlabel(\"Iteration\")\n", + "plt.ylabel(\"Cost\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "14bb8eec", + "metadata": {}, + "source": [ + "## Output distribution with initial parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "103981ed", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cical\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python313\\site-packages\\qiskit_ibm_runtime\\fake_provider\\local_service.py:273: UserWarning: Options {'dynamical_decoupling': {'enable': True, 'sequence_type': 'XY4'}, 'twirling': {'enable_gates': True, 'num_randomizations': 'auto'}} have no effect in local testing mode.\n", + " warnings.warn(f\"Options {options_copy} have no effect in local testing mode.\")\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHWCAYAAAD6oMSKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAb55JREFUeJztnQe0FEX6t4sogoCAREUERTGtoKACioKuCibMomsA15zQNYCKLOawCuYc1jVhRESWRRFkBRVBgVVRAXFhUUBEwECmv/Mrv7r/vkP3TM+dmTszPc9zzhy4Pf1OVXVXV//qraq3qnie5xkAAAAAKHqq5jsDAAAAAJAdEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMaF6vjNQqGzcuNF89913pm7duqZKlSr5zg4AAACUKJ7nmZ9//tm0aNHCVK2a3CeHsAtBoq5ly5b5zgYAAACAZcGCBWabbbYxyUDYhSBPnbuI9erVy3d2AAAAoERZuXKldTY5bZIMhF0IbvhVog5hBwAAAPkmytQwFk8AAAAAxASEHQAAAEBMQNgBAMSIhx56yPzhD38om0bSuXNn889//rPs+wMPPNAO5/g/5513Xtn3M2bMMH369LHzeTbffHOz8847m3vuuSdPpQGAdGGOHQBAjNCKudtuu820bdvWhkj4+9//bo4++mjz6aefml133dWec/bZZ5sbbrihzKZ27dpl/582bZpp0qSJefbZZ624mzx5sjnnnHNMtWrVzEUXXZSXMgFAdKp4evIhcAVK/fr1zYoVK1g8AQBFTcOGDc2dd95pzjrrLOuxa9++vRk2bFhk+wsvvNDMmjXLvPvuuznNJwBkrkkYigUAiCkbNmwwL774ovn111/tkKzjueeeM1tttZXZbbfdzMCBA81vv/2W9Hf0MpE4BIDCh6FYAICY8Z///McKudWrV5stttjCvP7662aXXXax351yyimmVatWNoL9zJkzzdVXX22++uor89prrwX+loZihw8fbt56661KLgUAVASGYkNgKBYAipW1a9ea+fPn2/brlVdeMY8//rh57733ysSdHw2vHnTQQWbOnDlm++23L/fdZ599Zrp3724uvfRSc91111ViCQDAD0OxAAAlTM2aNc0OO+xg9tprL3PrrbeaPfbYI3Rl6z777GP/lbDz88UXX1jBp4UTiDqA4gFhBwAQczZu3GjWrFkT+N306dPtv82bNy879vnnn1tP3RlnnGFuvvnmSssnAGQOc+wAAGKEFkP07NnTbLvttubnn382zz//vJkwYYL517/+ZebOnWv/7tWrl2nUqJGdY3fZZZeZbt262dh3bvi1R48e5tBDDzWXX365WbRokT2ucCeNGzfOc+kAIBUIOwCAGLFkyRJz+umnm++//97OyZFgk6j74x//aBYsWGDeeecdG+pEK2UVp+64444rN9SqOXk//PCDjWOnj0MLLr799ts8lQoAosLiiRBYPAEAAACFAIsnACDW22I51C/VsKO2xRoxYkTZcbbFAoBShaFYACjKbbGEhhQl6hJhWywAKFUYig2BoViAwt0Wy63mPOKII8zUqVPtik4F4e3du3eoPdtiAUCxwlAsAMR6WyxtgaUdFB544AHTrFmzSL/DtlgA+Zs+ce6559oA2JoaodXV8sB/+eWX5X5j3LhxpkuXLqZu3br2udauKOvXr89DaYobhB0AFOy2WNoOa7PNNjPnnXdeuW2xFKJDLwC9HKLgtsXScCwA5G76hKZByIuukDl6PhUTUShY9lNPPWW95lqlrcHCQw45xHbc3LxYheE57LDD7JQLPa8jR440AwYMyHPJig+GYkNgKBagMLfF0g4Jf/nLX2zjL+EnNM8ubCiWbbEACmP6hB/FUNSOKG4ru2uuuca8/fbb5uOPPy4758033zQnnniiDeEjL14pszINTcLiCQAo6G2xXG9fDb5WtmooR4F2t9xyy3LnKx7b/vvvb4PxOtgWC6DykRfu5ZdfLjd9wo+Oy3vXunVru7hJaGeUWrVqlTtPz/rq1autF/DAAw+stPwXOwzFAkBRbYuloRn19rV4wn3E0KFD7cvCwbZYAIUzfUI8+OCD9nt9NP9OHjp14IR2OtGUiRdeeMEKw4ULF5obbrjBfqdg2xAdhB0AFOS2WBMnTrQ7Hehlob/liTv11FPtpOrddtut3EdoCy15APzDr5rD47bF0kc7KgBAbthpp51sR+ujjz4y559/vu1UyWvu0POrKRSaUrHjjjvaYVZ55ISeVQ3bShBKGOp7zbkTVasiVdKBOXYhMMcOIH9oTo5WyPm3xdIKOW2LFUTiHLu//vWvZsiQIZucx7ZYAJXHwQcfbOfPPfLII4FzaBs0aGDnziqYuEOSRM+9vtOzKo/flClTTKdOnUwps5JwJ/FZAk4EfShFnnjiCduoa+hVE6e1v2mYqHMvA//CCQk7HUv8IOoAKn/6RBDumUz8Xp20Fi1a2PedhmX17ttzzz0rKcfxAGFX4EvA/RH0ZXPttdfaYan7778/zyUDgDiSjXhkl1xyiW3bNKTWvn37PJQCCmn6xDfffGNuvfVW+z7TSnfNpTvhhBNsHXLDrUJDsbLVu+7GG2+07857773X7hgDaaChWNiUFStWaIja/pttGjRo4D3++OOB382YMcOmO2fOnFD7Cy64wOvevXvW8wUA+efBBx/0dt99d69u3br2s++++3qjR48u+/6cc87x2rRp49WqVcvbaqutvKOOOsqbNWtWud/473//6/Xq1cvbfPPNvcaNG3tXXHGFt27dukjpjxw50nvrrbe8r7/+2vvqq6+8a665xqtRo4b32Wef2e8feeQR77333vPmzZvnTZs2zTvyyCO9li1beuvXry/7jYsvvti7//77vdNOO83bY489snZtoHDrTr9+/bxWrVp5NWvWtHYHHXSQN3bsWPvdwoULvZ49e3pNmjSxdWmbbbbxTjnlFO/LL78s9xt6r9WvX9/mb5999imX91InHU2CsKtEYaeG74UXXrAV//PPP9/k+19++cXr37+/17p1a2/NmjWhv3Pqqad6xx13XNbyBQCFQ6bCSv/utttu3sEHH+x9+umn9uWol/jAgQMrvTM6ePDgtIRdMmHy448/ehdddJG344472he/yiwBuXz58nK/8c4773idO3f2tthiC69p06beVVddFVnUFjuFWHcgOyDsCkzYzZw506tTp45XrVo12xvRg+fngQcesN8rvZ122impt27SpEle9erVvX/9618Z5wsAioN0hJVexlWrVvUWLVpUds5DDz3k1atXL2mHMRed0XSFXTJh8p///Mc79thj7Tkq67hx47y2bduW6+ROnz7d5nXIkCHe7NmzvQkTJnjt2rXz/vKXv3ilSr7qDmQXhF2BCTs9EGpkpk6d6g0YMMD2gPyNpHqcasjUk1IPas899/RWrVq1ye+oYZPtjTfemHGeAKDwqYiwGjRo0CZi6ptvvrHt2SeffFKpndF0hV26wuSll16y18Z55ORZ6tixY7lzJATl4Vu5cqVXSuSr7kD+NQmLJyoxgr4mE2sCqbZR8a9s1RLmtm3bmm7dutmtkzQRWaEb/BBBH6B0yCTQq+L1NW3atNzvub/1Xa7jkWULLSB78cUXQ3cvEC70Q/Xq1SPtXlAK5LvuQP5B2BXBEnAi6AOUFvkWVtnojOZKmDiWLl1qV06qs+tg94L81x3IPwi7Al8CTgR9gNIjE2GlnTkWL15c7vfc3/qusuKR5UqYuGCthx9+uBV8ilnoYPeCwqs7UPmURk3PIwquevrpp9vGSkOp2shc8eoUbFVDBv/+979tw6MH8aSTTjJ169a1Ak+x64QePIk4xbFr3rx52acYonAni4e1bNkyc/HFF9vrIiGr7aAU+0pDK0H8+OOPNiagglcuX768kksCkF/SEVZ6ztSJVNvj0HCbnsEgz1cu4pHNmTPHijN1QletWlW2p692G8hUmPz888/msMMOs22lBEmNGjXK2asDrDZC+ZNXT3H2RJs2bUwpUpl1BwqEHM3zK3pyGceuVMh0hZufo48+2sZB0j356aefKr0sAJWFFli5kBRaxKC/q1SpYmOCzZ0717vlllvsQizFG9MqeS24atiwobd48eJyISsOOeQQu0p0zJgxNq6YC1nR6upRST/ZiEd2wAEH2Gc18aMypYtim51xxhn2/2qPFQJFv//rr79GsteCgMQ4e4VKpuFeLr30Uq9Tp072vil6gn5D1/3111/PSt2B/MGq2CyAsMsN6axw8zd2asgl/hB2EHeyIay+/fZbe56CzGolvcJ9uOcqlbArVFGrtlhBayV81Bn8/vvvyz5+0XbHHXdYW3Ugb7jhBnudJGxKoTOsGKcSarJp1KiR16FDB1tH+vTpk5W6E2dRPH36dO/kk0+210XnKEzOsGHDvEIBYZcFEHaVu/RePPbYY7Yh8aNzmzVrZnuY48ePR9gBZEghC7tkotY9/6k8gXHbvaAinWE/99xzjxUrcSdTUfzEE094l1xyiY19KO/mP/7xDytu77vvPq/YNMnva8QBcoTma2jehlZdaaVbOivcNO+jT58+djK05uBpfg8AxJcnnngi9LsDDzzQzgdLxbvvvmvigFb1vvzyy2mFe0nku+++M6+99po54IADTNw58sgjy/19880323neH374oTnrrLPMq6++Wvad9jrW93/605/M+vXr7fXr169fOXvNyfzggw/s9bvoootMMcHiCcgpmaxw06TtnXfe2T58AAClQCbhXhzqENeuXdtsvfXWVvg9/vjjppTYUIEYiGHnNGzY0BQbCLsiXVUqHn30UduL1Xdhq0W//vpruypsq622suftt99+Zvz48ZVWhkxWuKnnrR6rHjx9tKpYqCyDBw+utDIAABRDZ9gxdOhQ88knn5g33njDzJ07164ULgWyIYodWvE9fPjwpOcUKgzFFjAK73HbbbfZmEMagvj73/9uRZqCS+66667mt99+s6JIH3m3gjjiiCOsvUSSQhIMGzbMHtPDno+4RP6l92qcFFBUD+HIkSM3iRgv17lCJTgUKkbucoWIkSsdACBuuM6wUIdY7Z46w4888kikcC9Cbbs+7dq1sx6n/fff3wwaNMiGyioFUbxixQobKkyiWIGY/eIulSh28WP1rpUDQbERiw2EXZHOGZCw69+/vz2uGFNBqFcye/ZsO29Fnj8hoagtZVRxcy3sJDZ79uxp58epMXr++edtXhXHTw+XHhiJU8Xo09/6iMaNG5tq1aptIt5UHqHh2S233DKneQcAKATS6QyH2YtsBZCOuyj+IgbbdzIUG6M5A4k0atTI9mCeeeYZa6dJoqrgCn6sSp/P4MwaJtBQg1znehD9wZcXLFhgip1sDKNvt9129jv/R8Iccgv3DvJFsuDQrjOstlyddf3tdiLS+0GMHj3aPPXUU7bjrt9466237JBk165dbZ0sdVF8yCGHWPEXJorjsn0nHruYrCoNQi+Td955x/Tu3dv2ULSljkTdmDFjTIMGDYpihVumNsU8jC60z+XZZ59d9rfuI+QW7h3kC9cZ1r622vpLHQzXGZbAU2dYOK+UY968eVa4abrNY489Zi677DIraFq2bGmOPfZYM2DAABN3Mh0h+uyzz0yPHj2sR9Rt3yn0nc4pJhB2MZgzEIZeShdeeKEVc5qXpodeq6M0xCvvWdznWxTzMLpfDLBH46ZsN+CtpN9/e9vhFf5t7h3ki0w7w/I2adJ/KZKpKH7Ft32nPo5WrVpZ72cxwVBsgZNqVWkytGBi1KhRdghXrvg999zTzq+TwJMXAgp3GN0hz5GG1Dt06GDj+Wk4HSoP7h1A8YhiCbA1a9ZYkafRKok6vygO+rghai2kCPq+2ESdwGMXow2dE5HbWWgI1o/+dhNqoTCH0cUll1xixbhWtakXrqEG9UbvvvvunOYbuHcAULwg7Ip0zoBwE2fnzJlT9jLS8I/O1wtFLybNpdPw7fXXX182/0KuZy33hsIdRhf+2FMaVpD39txzz7WeW62Kg9zBvas4GrbWx3k6NHyt9kdtmVt8orZMC6jUrv3000+brHLX8Lcm/use6NoFLVCBeE2hyGT6BJSHodgCJtmqUvHwww/bYR43Qbtbt272b634cYF8tVDil19+sZNCO3bsaN5//30btFJDulC4w+hB7LPPPnY4L8rQQDZWdi5btsyuxtM5evFqWx7VpVIgn/cuLotPpk2bZqZOnWrbHi0+0YpD4RafXHPNNaG/sXbtWnPCCSfYAL0AkB4IuyKdM5BsTsCZZ55Zdo7EnMTgjz/+aFcBae8713OOO6nEjYbZtLhE86A03HbccceZxYsXl/uNcePGmS5dupRNhL/66qsrPFcqnWH0IOS9cCubK+PlKlGn899++207V1NhGKJGYS+0a58plXnvih0tPunVq5ddVbzjjjta75vusRafCC0+0SrNfffdN/Q3hgwZYld27r777pWYc4B4wFAslGzYCr04NNyjbcu0ikobPSs0wKRJk6z9jBkz7Avq2muvtbEAFy5caGNCaUL93/72t5wOo0uAaxWXVrnpuP5WfrVvbpRQNZmu7Jw1a5b19spLrM6BuO++++z1UNlbtGhRsNc+U/J97+JElI3sASDLeBDIihUrtK7c/gvxoUGDBt7jjz/uLV++3KtRo4b38ssvl303a9Yse88/+OAD+/fAgQO9jh07lrMfOXKkV6tWLW/lypVJ0+nXr5/XqlUrr2bNml7jxo29gw46yBs7dmzZ94MHD7ZpJX6eeuop+/20adO8ffbZx6tfv75Nb+edd/ZuueUWb/Xq1WmXef369d4LL7xg8/L555+X+278+PE23Z9++qnc8SeeeMLbcsstyx1bt26dV61aNe+1117z8n3tW109KunnwQcf9HbffXevbt269rPvvvt6o0ePLvutVatWeRdccIHXsGFDr06dOt6xxx7rLVq0qOzeNWrUKPD+6HPFFVdU2r3LBamuXTaYOXOmva6qL7oOb7311ibnhNU9P7qmsofKIZPnxt2vsOdm8eLFOa93cWZFGpoEjx2UpOdAQ5Tr1q0zBx98cNk52ldRXhd5WDRMpKG3xOjkWoCiYUTZa45aReJRuWH0sH0KhVZUuqGrfKzslEcqcdiwevXq1iPlAnfm89qnIhOP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ww+mTZs29jwAAAAAKGBh16hRIzsUe9VVV9lVr1od66hVq5aNb3f77bebhg0bZiuvAAAAAJCrAMVbbbWVefLJJ63H7ssvvyzbeaJdu3amRo0amfw0AAAAAORa2N18883m119/NUOGDCkTb/p39913LztH8e2uvfZaU7duXTNgwIB0kwAAAACAXC+eeOedd8z1119vh2GTeeRq1qxpz5G4I44dAAAAQAEKu2eeecY0aNDAXHTRRSnPvfDCC+38Ou0XCwAAAAAFJuwmT55sDj74YLPZZpulPFfn6NxJkyZlkj8AAAAAyIWw++6772wIk6ho54nvv/8+nSQAAAAAoDKEXdWqVc26desin69zZQMAAAAAuSct1aXtwT777LPI5+vcrbfeuiL5AgAAAIBcCrv999/fvPvuu+bbb79Nea7O0bndunVLN08AAAAAkGthp5WuGl49/vjjzdKlS0PP+/HHH80JJ5xg1q9fb84///yK5AsAAAAAchmgeM899zT9+/c3w4YNM7vssos577zzTPfu3c0222xjv1+4cKEZN26cefTRR+1esZdffrm1AQAAAIAC3HnirrvusnvB3nnnnXYXCn38eJ5nqlWrZgYOHGhuuummbOYVAAAAALIp7KpUqWJuueUWc9ZZZ9ngw4ptt2jRIvtds2bNTNeuXc2ZZ55ptt9++3R/GgAAAAAyoMKxSCTc5JHTAokvvvjCfvT/G2+8MSNRN3HiRHPkkUfaFbgSkSNGjNjknFmzZpmjjjrK1K9f39SpU8d06tTJzJ8/v+z71atX2/mA2tZsiy22MMcdd5xZvHhxhfMEAAAAUAwUXJC5X3/91eyxxx7mgQceCPx+7ty5Zr/99jPt2rUzEyZMMDNnzjSDBg2yw8OOyy67zLz55pvm5ZdfNu+9954NrHzsscdWYikAAAAAimAoNtf07NnTfsK49tprTa9evcwdd9xRdszvIVyxYoV54oknzPPPP2969Ohhj2nIeOeddzYffvih2XfffXNcAgAAAID8UHDCLhkbN240b731lrnqqqvMoYceaj799FO7bZkWavTu3dueM23aNBuSRfvUOuTd23bbbc0HH3wQKuzWrFljP46VK1faf/VbbrcN7aKhhSEbNmyweXG44wrvosUjDh3Td2HHo+zioXOqV//9Nul3/NSoUSOSvdCwtn4nMe+pSFamTPLujqeTd+Vb+Y9K1PsUhmyD7lOUvPvzr/uUmHeVqSJ5j3r/XN7D7l/UvIfdv6j2grpXvu5FSTusjUgn72F1r6J5L4W6p/OSteX5yDt17/e6l07e1wfcv3TyXpH7F9TGB9W9THRELIXdkiVLzC+//GJuu+02O7/v9ttvN2PGjLHDrOPHjzcHHHCAXchRs2ZNs+WWW5azbdq0adkijyBuvfVWM2TIkE2Ojx071tSuXdv+X+KwQ4cOdvjXP6dvp512suJxypQpNsyLo3379qZVq1Z23uDPP/9cdrxz586mSZMm9rdTMXr0aOuhXLVqlS2jQxXm8MMPj2QvGjdubLp06WJmz55tvvrqK/crKe2TlSlK2gqHs/nmm5flw6EyRc173bp1rfd1wYIFZvr06b4zkuc/9X1Kbq9Yje4++R8qV6Yo+Xf3Sb+ljoVDZUpG+fsUVPeS513XKlndi5J3EVb3otoL6l75uhclbX8bkVj3ouY9rO6lynu8617qsidry6OmHVb3UqXvPz+47qUuf1zrXpS0k71zU+G/9kF1L0q997cRwe1exXXEpEmTTFSqeFFcF3lCivf1118v88Zprpy2KOvTp48danVoIYUWUbzwwgv2eN++fct538Tee+9tK6bEYFSPXcuWLW3FrFevXs48dm0HJRd3s288JKnHbrsBb6W0D+s9pEr729sOT1qmHa77V4XzruOtB45OK++JPaJU+Z9782FJ71Mq+29u6Zm05xo1/2Eeu2TXLyzv7v5FzXvY/Ytab8LuX5R66yi1uqe8J2sjouQ9mdckat7D6l5Fn5s41L0oZU/Wlucj7/77F+W5Kda6lyzvOr79tWMi5319wP1rc80/I+c96P5Fqfe59NgtW7bMLgjVdDOnSWLhsdtqq63shVJwZD+aP/f++++XhVxZu3atWb58eTmvnVbF6rswNttsM/tJRJUzcchTFzrItRvWmww7HmUo1X9OlPNTpRGW9zDSLVMu867KHWU4pKL3KRGXVkXynmiXrbxHvX8urahlTSSxzOleg6DzqXvFnfdSqHvunELKO3Uv2lCqP+3qFbh/QeVN5xqElTXd5ymTdq8sL6aI0BCrQpv43Zri66+/LnOT77XXXvZmaAcMh86XyzOKOxYAAACgWCk4j53m0M2ZM6fs73nz5tlx64YNG9qx6SuvvNKcdNJJplu3bnZoVXPsFNpEoU+EYtspeLK2M5ONXJYXX3yxFXWsiAUAAIA4U3DCburUqeUmaUqgiTPOOMM8/fTT5phjjjEPP/ywXexwySWX2AmHr776qo1t5xg6dKh1iSowsebNaQXtgw8+mJfyAAAAAJSssDvwwANThqLo16+f/YShYMUKcBwW5BgAAAAgjhTVHDsAAAAACAdhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATEHYAAAAAMQFhBwAAABATik7YbdiwwQwaNMi0bt3abL755mb77bc3N954o/E8r+wc/f/66683zZs3t+ccfPDBZvbs2XnNNwAAAECuKTphd/vtt5uHHnrI3H///WbWrFn27zvuuMPcd999Zefo73vvvdc8/PDD5qOPPjJ16tQxhx56qFm9enVe8w4AAACQS6qbImPy5Mnm6KOPNocffrj9e7vttjMvvPCCmTJlSpm3btiwYea6666z54lnnnnGNG3a1IwYMcKcfPLJec0/AAAAQK4oOmHXpUsX8+ijj5qvv/7a7LjjjmbGjBnm/fffN3fffbf9ft68eWbRokV2+NVRv359s88++5gP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9+7m4osvNgcffHBKewmShg0bpmygw/KUz/Lnu+z5Tv+ll14yd9xxh33e9Nzp9/QMnnXWWZG2INTONs2aNUuZfrIX9urVq2359az7RX06YjWTTs2SJUvMF198YeuQv74VS/oVTVt2s2fPts+f7qG2n/Tv/VkZoj6f1z4b5a9o2fN97detW2emTp1qJkyYYN+7O++8s9lmm21Mo0aN7G8lS99/vdUh13n56oQFImEH+efZZ5/12rRp4/30009lx/T/9957z7v66qu9bbbZxrvkkku8devWhf7G7bff7k2YMMH74YcfvPXr1wee89tvv4Xab7fddt4pp5zi3Xfffd5DDz3kXXfddV7Xrl29li1ben/605+8b775JtRWeXvyySe9GTNmeD///HPgOStXrsxJ2tlIv3nz5t6ll17qvfjii96YMWO8hx9+2PvjH//obb755l6XLl28jz76KGn6xx57rDdo0CBru2TJksBz3L3duHFjQZU/32XPd/pbbbWVd8MNN3jjxo3zvvzyS++f//ynd/rpp3tbbLGF16pVK++NN95Imv4+++xj79FTTz3lzZ8/f5PvlebSpUtD05ed7vMuu+zi7brrrt5uu+1mn/nZs2d7UVixYkVgmlGOuXajUaNGNm1diwYNGnhnnnmmrUtRCLrmlZV+pmlfccUVNj1dc93vWrVqeYcffritS1FIvN9KZ8OGDZucF3SsEK59JuXPtOz5vvZnnnmmveZ77rmn17BhQ69atWpep06dbPsbZuPn66+/3iT9sPduZYOwKxBuueUW74gjjgj9/qWXXvKaNm3qTZ8+PfB7vRSrVKni1a5d2+vcubN31113eZ9++qlt9N1D/euvv9oXll5eiTz//PNe69at7TmOVatWeV999ZV90ary9+nTp9z3/rwpbb0E9913X/vAvvbaa96cOXO8NWvWlP1Wjx49vE8++SSraWcjfdnLdu3atWXHdM2WL1/u/etf//J69eplhcaPP/4YmP4rr7xi01ejoJe8BNrdd9/tTZ482fvll1/sOcpH27Ztvffff7+gyp/vsuc7fV0npR/UIOs56devn9exY0dv4cKFgenLXun37NnTpt+9e3fv4osvtmLQiUl1xiRS33777U3sX3jhBZv+4MGD7bV44oknvMsvv9zr0KGDzbOO+69NIur4nXXWWd7LL79s87t69epNzlH53bUI6lCq7j344IP2t959913vb3/7m7f33nvbtuSMM84IFcti7Nix3sEHH+zdeeed3sSJEzcRmbqXqntB4jPT9DNN+5lnnvG23377sms3d+5c+3+Ji+rVq3sHHHCAN2vWrNCyv/nmm94OO+zgXXjhhdZOHerE9NWR9nfWs1X2fJc/07Ln+9r//e9/t+mrM6e2Rc/YlClTvL59+3p16tTxdtxxR+/f//53aPqvvvqqzafye//992/SPkgY6pmbOXOmlw8QdgXCBx98YB9mvZSCXuB68UiwqYcX1vs455xzrMdO4k2VU58jjzzS+8c//mEfnOeee86rWbNmoP0DDzxgX/xqCMIaEQlLNT6JnH322faBmDRpkjdgwADb+5QHQi/km2++2do8+uij3mabbZb1tLORvq6LGtMw8fDhhx/a35N4DkKNy2mnneZ9/PHH3r333msFul7M3bp1884991zrSRs6dKjtkRZa+fNd9nynP2rUKG/33Xf35s2bF9jz18tl55139u65555A+8suu8w7+eSTrYdFIlOiTtddZZLYkzC76aabrLALQi8weef8yOOqTpm8kBJ9ahPCUL2RsJRAkKhUevJ4/Pe//y3r0Kn+KJ0gJAz+8pe/lDumsi9atMh6EnVtEvPn59BDD/W23HJLW9799tvPikx1RpR/N7rw1ltvWY90ttPPNG11Gvr37x/4nYSWPOYS9mGorum663ck6g855BD7/L3zzjtlHaoRI0Z4VatWzXrZ813+TMue72t/3HHHeRdccEHZ334PnZ4d/b7enWEcc8wxtp3Ru1b/qo1QOzB8+PCyUTG1LfIC5gOEXQGhF4CGYy+66CJv2rRpVuC5SqoeQf369e3LOxE9xKrUiY3A66+/bhsPVe6tt97aur1PPfXUwLS/+OILKyw1JPa///0v8JyDDjrIu/766zcRnMq3vAx+9IBJbOrha9eunRWZegiymXa20leacslrSO+zzz4LdMPrIb/yyis3Oa5z9dLXUKgf9f70YtaLV96kGjVq2PwUWvnzXfZ8py/PoHr+8nSqhx7kuTvhhBM2SUNIOMnDdv7555c7LjEoIa0XkxNeeukGPbfHH3+8HXYP49prr7VlWLx48SbfySPwhz/8wYpjeWwkZFUW3fOjjz7aClp5KSU0VYag66dOgT5hDBs2zA6VBQ0LK/299trLimd5gm+8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", + "text/plain": [ + "
" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "res_bin, res_int = cost_function_res(init_params)\n", + "plot_histogram(res_bin)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "0d1cf38b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{5: 0.0609, 19: 0.0442, 18: 0.0559, 22: 0.1022, 11: 0.1019, 14: 0.0457, 26: 0.0612, 12: 0.0444, 9: 0.102, 17: 0.0456, 3: 0.0034, 21: 0.0578, 10: 0.053, 20: 0.1043, 13: 0.0594, 29: 0.0029, 1: 0.0067, 4: 0.005, 27: 0.0059, 7: 0.0035, 25: 0.003, 0: 0.0019, 28: 0.0038, 15: 0.0021, 23: 0.0027, 16: 0.0021, 2: 0.0029, 6: 0.003, 30: 0.0055, 24: 0.0029, 31: 0.0022, 8: 0.002}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cical\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python313\\site-packages\\qiskit_ibm_runtime\\fake_provider\\local_service.py:273: UserWarning: Options {'dynamical_decoupling': {'enable': True, 'sequence_type': 'XY4'}, 'twirling': {'enable_gates': True, 'num_randomizations': 'auto'}} have no effect in local testing mode.\n", + " warnings.warn(f\"Options {options_copy} have no effect in local testing mode.\")\n" + ] + } + ], + "source": [ + "res_bin, res_int = cost_function_res(result.x)\n", + "shots = 10000\n", + "final_distribution_bin = {key: val / shots for key, val in res_bin.items()}\n", + "final_distribution_int = {key: val / shots for key, val in res_int.items()}\n", + "print(final_distribution_int)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "ec6a816c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Result bitstring: [0, 0, 1, 0, 1]\n" + ] + } + ], + "source": [ + "def to_bitstring(integer, num_bits):\n", + " result = np.binary_repr(integer, width=num_bits)\n", + " return [int(digit) for digit in result]\n", + " \n", + " \n", + "keys = list(final_distribution_int.keys())\n", + "values = list(final_distribution_int.values())\n", + "most_likely = keys[np.argmax(np.abs(values))]\n", + "most_likely_bitstring = to_bitstring(most_likely, len(graph))\n", + "most_likely_bitstring.reverse()\n", + " \n", + "print(\"Result bitstring:\", most_likely_bitstring)" + ] + }, + { + "cell_type": "markdown", + "id": "586cb315", + "metadata": {}, + "source": [ + "## Output distribution after optimization" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "a6c223b0", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6QAAAI+CAYAAACrNcdMAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYrFJREFUeJzt3Qm8leP+//+rQaWoKEpJKSkppVJyKEOUOUMSR0lyfEkRIVIRJ1MJRTrnCIdI5qETiQynSEok81Tf0iSK5uH+Pd7X/3+v771Xa++91trrvq+11n49H49Fe+173/N1Xffnmu4ynud5BgAAAACAiJWNeoMAAAAAAAgBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAABJKlOmjBkxYkSk2zz22GPtx8Xx6d/6bs2aNZFsv0GDBubiiy+OZFsAgOxAQAoAyAqPPfaYDX78T/ny5U3dunVtgLJs2TKTjWbPnm2Dtt9//z2p5XUswWPcY489TMOGDc25555rnn/+ebNz504n+xWlbN43AED0yjvYJgAAhbrtttvMgQceaDZv3mw+/PBDG6h+8MEHZtGiRaZSpUom24KrW2+91Qaa1atXT+pvKlasaP75z3/af2/atMn8/PPP5tVXX7VBqVpCX375ZVO1atXY8m+++WYk++XvjyoCwlTUvn399dembFnqygGgNCEgBQBklZNPPtm0bdvW/vvSSy81NWvWNHfddZd55ZVXzHnnnWdynQK+v/71rwW+u/32282dd95phgwZYvr162emTJkS+12FChVC3R+1ym7dutUG+64DfgXrAIDShWpIAEBWO+aYY+z/v//++wLff/XVV7ZVce+997aBlIJYBa1B27Zts61xjRs3tsvUqFHDHH300WbGjBnFjtFUC57GNBZG3U4HDx5s/60WXb8b7k8//ZTWcd54443mpJNOMlOnTjXffPNNkfv34IMPmkMPPdRUrlzZ7LXXXvbYJ0+enNR+6d/9+/c3Tz31lF2HgsDp06cXOUZWY0hVGaCWW53DgQMH2hZsn9atv1VrdrzgOovbt0RjSH/44QfTvXt3e511vEceeaR5/fXXCywza9Ysu55nn33W3HHHHWb//fe31/uEE04w3333XYpXAgAQJVpIAQBZzQ9WFHj5vvjiC/OXv/zFjjFVIFelShUbjHTr1s2OxTzrrLNiAdCoUaNsS2u7du3M+vXrzbx588z8+fPNiSeeWKL9Ovvss23g+PTTT5v77rvPtuTKPvvsk/Y6L7roIttFVwHzwQcfnHCZf/zjH2bAgAE2GPcDw88++8x89NFH5oILLkhqv95++217vhSY6vdFBd6iYFTL6FyqG/UDDzxgfvvtN/PEE0+Ees5WrlxpjjrqKLNx40Z7zAqGH3/8cXPGGWeY5557LnadfWplVpff6667zqxbt87cfffd5sILL7TnBgCQnQhIAQBZRYGEWuQUaCmQUAunWvFOO+202DIKxA444ADz8ccfx7p5XnHFFbb184YbbogFKmpJO+WUU8zEiRMzvp+HHXaYad26tQ2uFAgXF9Qlo3nz5glbg4N0TGrZVEtquvulsZqff/65adasWVL7pdZMjW2VK6+80raUPvTQQzbw0/bCOmcKMBWUvv/++/bairo0az2DBg0yZ555ZoExp7pnPv3001g3Z1Vi6F7R+GP/3AIAsgtddgEAWaVz5862xaxevXq2FVCtn+qKq26YsnbtWtvCp1a7P/74wwav+vz666+mS5cu5ttvv43NyqtJc9Saqu9ygWbdFR1XYXRM//u//2uD8XR16tQp6WDUD0KDrrrqKvv/adOmmTBp/WrZ9oNR/xxddtlltuV88eLFBZbv06dPgTG3fndvdfsFAGQnAlIAQFYZP3687bKqLplq3VSwGZzsRmMCPc8zt9xyiw1cg5/hw4fbZVatWhWbsVevF1H31xYtWtjxi+remq3+/PNP+/8999yz0GXUAqygTIGaxsYqWPzvf/+b0nbU4pkKbSeoUaNGtmUy3fGyydIMxE2aNNnl+0MOOST2+yC1mgf53bzVvRgAkJ3osgsAyCoKtPxZdtWtU61jGhupbqYKxPx3daq7qFpEEznooIPs/zt27Gi7v6q7qcZm6nUrGrs4YcIEO65UNBmOAtx4O3bsMFFT19Lg/ieiYEzn4rXXXrOTEWnMrLrPDhs2zHZvTsbuu+9eov3UOSvqZ1fnsFy5cgm/T3R9AQDZgRZSAEDWUoChiXSWL19uxo0bZ79r2LCh/f9uu+1mu/cm+gRbGDU7q7pyatzi0qVL7fjD4EyyakVTK2q8+Na3RAoLxNL173//266zuAmX1I25R48eZtKkSWbJkiXm1FNPtbPL+jPfZnq/4rs8q5VaFQP+GFC/JTL+PCY6h6nsW/369W3wHU8zLPu/BwDkNgJSAEBW0ytP1Go6duxYG3Dtu+++9rtHHnnE/PLLL7ssv3r16ti/Na40SC2san3csmVLge6nCnCCf7dw4cKkusEqMJREAW2qNIGPWnEVaMZ3kQ2KPyaNmdR4ULUC6jU3md4vvxt1/Gtn/HfGiiY50oy57733XoHl1HIbL5V9U5ftuXPnmjlz5sS+27Bhg52kSsFwKuNgAQDZiS67AICsp7Gfehel3nN5+eWX2wBJXXk1LlSzrqrVVLOxKnDRhD8KKEUBi4LXNm3a2JZSvfJFY1P1uhPfJZdcYsaMGWO7//bt29eOP1WXXs1kq9fEFEXrlZtvvtmcf/75ttX29NNPjwVdiWzfvt08+eST9t8KsNWKqEmbNLb1uOOOK3ZGYL2rtHbt2va1N7Vq1TJffvmlbT1WK6nfMpzOfhXlxx9/tK9a6dq1qz3H2n91o27ZsmVsGXWBVlCt/6vLtYLT4PtU0zlneqWPWrYV+Oq1L7qGeu2L9kddlYMz7AIAcpQHAEAWmDRpkgb6eR9//PEuv9uxY4fXqFEj+9m+fbv97vvvv/d69erl1a5d29ttt928unXreqeddpr33HPPxf7u9ttv99q1a+dVr17d23333b2mTZt6d9xxh7d169YC63/yySe9hg0behUqVPBatWrlvfHGG17v3r29+vXrF1hO+zd8+PAC340cOdJuu2zZsvb3P/74Y6HHqHVqGf9TuXJlr0GDBt4555xj91vHGa9Tp07243vkkUe8jh07ejVq1PAqVqxoz8ngwYO9devWJbVf+veVV16ZcP/ij0//1neLFy/2zj33XG/PPff09tprL69///7epk2bCvztxo0bvb59+3rVqlWzy5133nneqlWrUjpnOt86R0G6ztq2rmGlSpXs9XzttdcKLPPOO+/Y9UydOrXA91qvvte9BQDITmX0H9dBMQAAAACg9KGvCwAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACc4D2kCezcudMsX77cvs+tTJkyrncHAAAAAHKKXubyxx9/mDp16hT53mgC0gQUjNarV8/1bgAAAABATlu6dKnZf//9C/09AWkCahn1T17VqlVd7w4AAAAA5JT169fbRj4/tioMAWkCfjddBaMEpAAAAACQnuKGQDKpEQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJwgIAUAAAAAOEFACgAAAABwgoAUAAAAAOAEASkAAAAAwAkCUgAAAACAE+XdbBYAgOT8sXaz2fzntoysq9Ieu5k9966UkXUBAICSIyAFAGR1MPrUsA/Nju07M7K+cuXLmgtvO5KgFACALEGXXQBA1lLLaKaCUdG6MtXaCgAASo6AFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJzgPaTI23cXZurVDpX22I13FgIAAAAhICBFXgajTw37MGPvLixXvqy58LYjCUqzEBUPAAAAuY2AFHlHAUqmglHRurTOYLCSyUBICIZSR8UDAABA7iMgBRwHQkIwlJ0VDwAAAAgXkxoBjgOhYDAEAAAAlCYEpAAAAAAAJwhIAQAAAAClMyAdP368adCggalUqZJp3769mTt3bqHLfvHFF+acc86xy5cpU8aMHTu2xOsEAAAAAJTCgHTKlClm0KBBZvjw4Wb+/PmmZcuWpkuXLmbVqlUJl9+4caNp2LChufPOO03t2rUzsk4AAAAAQCkMSMeMGWP69etn+vTpY5o1a2YmTJhgKleubB599NGEyx9xxBHmnnvuMeeff76pWLFiRtYJAAAAAChlAenWrVvNJ598Yjp37vx/O1O2rP15zpw5ka5zy5YtZv369QU+AAAAAIA8DUjXrFljduzYYWrVqlXge/28YsWKSNc5atQoU61atdinXr16aW0fAAAAAJBDkxplgyFDhph169bFPkuXLnW9SwAAAACQ98q72nDNmjVNuXLlzMqVKwt8r58Lm7AorHVqPGphY1IBAAAAAHnWQlqhQgXTpk0bM3PmzNh3O3futD936NAha9YJAAAAAMizFlLR61l69+5t2rZta9q1a2ffK7phwwY7Q6706tXL1K1b147x9CctWrx4cezfy5YtM59++qnZY489zEEHHZTUOgEAAAAA2cFpQNqjRw+zevVqM2zYMDvpUKtWrcz06dNjkxItWbLEzpLrW758uTn88MNjP997773206lT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vP766+b666+336sV9cADD7TbUEtqYUaNGmVuvfXWpPYbAAAAAOCghbRatWr2oxbSPffcM/azPrVr1zaXXXaZefLJJ5Na15o1a2wQW6tWrQLf62eNJ01E3xe1vLr66l2od955p21JffPNN81ZZ51lA2mNJy2MAlZ1N/Y/S5cuTeoYAAAAAAARtZBOmjTJ/r9BgwbmuuuuS6l7bhTUQipnnnmmueaaa+y/W7VqZceeqjtwYZMsqaW3sNmCAQAAAABZNstuSem1MOXKlTMrV64s8L1+VmtrIvq+qOW1Ts3uq/GoQRpv+sEHH5R4nwEA+YeZywEAyIEuu5o86LfffrP/1mRB+rmwTzIqVKhg2rRpY2bOnFmghVM/d+jQIeHf6Pvg8jJjxozY8lrnEUccYb7++usCy3zzzTemfv36yR4qAAAAACCbWkjVDdbv1lrUBEGp0ARFvXv3Nm3btrXvHh07dqzZsGGDnXVXevXqZerWrWsnHZKBAwfabrejR482p556qnnmmWfMvHnzzMSJE2Pr1Ay8PXr0sO9C1Stopk+fbl599VX7ChgAAAAAQPYon0433Ux02RUFjqtXrzbDhg2zExNpvKcCSH/ioiVLltiZd32awXfy5Mlm6NCh5qabbjKNGze2M+w2b948towmMdJ4UQWxAwYMME2aNDHPP/+8fTcpAAAAACDHx5BmUv/+/e0nkUStmt27d7efolxyySX2AwAAAADIg4B0r732su8fTcbatWtLsk8AAAAAgFIg6YBU4zsBAAAAAIg8INXkQwCA3MIrTQAAQF4EpOvXrzdVq1aN/bso/nIAAAAAAGRkDOkvv/xi9t13X1O9evWE40k9z7Pf79ixI9nVAgAAAABKqaQD0rffftvsvffe9t/vvPNOmPsEAAAAACgFkg5IO3XqlPDfAAAAAABE+h7S3377zfzrX/8yX375pf25WbNmpk+fPrFWVAAAAAAAilLWpOG9994zDRo0MA888IANTPXRvw888ED7OwAAAAAAQmkhvfLKK02PHj3Mww8/bMqVK2e/00RGV1xxhf3d559/ns5qAQAAAAClSFoB6XfffWeee+65WDAq+vegQYPME088kcn9Q57i3YgAAAAA0uqy27p169jY0SB917Jly0zsFwAAAAAgzyXdQvrZZ5/F/j1gwAAzcOBA21J65JFH2u8+/PBDM378eHPnnXeGs6cAAAAAgNIZkLZq1cqUKVPGeJ4X++7666/fZbkLLrjAji8FAAAAACAjAemPP/6Y7KIAAAAAAGQuIK1fv36yiwIAAAAAEM4su77FixebJUuWmK1btxb4/owzzijJagEAAAAApUBaAekPP/xgzjrrLPu+0eC4Uv3bfycpAAAAAAAZf+2LZtg98MADzapVq0zlypXNF198Yd577z3Ttm1bM2vWrHRWCQAAAAAoZdJqIZ0zZ455++23Tc2aNU3ZsmXt5+ijjzajRo2yr4RZsGBB5vcUAAAAAJBX0mohVZfcPffc0/5bQeny5ctjEx99/fXXmd1DAAAAAEBeSquFtHnz5mbhwoW222779u3N3XffbSpUqGAmTpxoGjZsmPm9BAAAAADknbQC0qFDh5oNGzbYf992223mtNNOM8ccc4ypUaOGmTJlSqb3EQCQpUaMGJHV6wMAAHkYkHbp0iX274MOOsh89dVXZu3atWavvfaKzbQLAAAAAEBo7yGVpUuX2v/Xq1evpKsCAAAAAJQiaU1qtH37dnPLLbeYatWqmQYNGtiP/q2uvNu2bcv8XgIAAAAA8k5aLaRXXXWVeeGFF+xkRh06dIi9CkZjf3799Vfz8MMPZ3o/AQAAAAB5Jq2AdPLkyeaZZ54xJ598cuy7ww47zHbb7dmzJwEpAAAAACCcLrsVK1a03XTj6TUwev0LAAAAAAChBKT9+/c3I0eONFu2bIl9p3/fcccd9ncAAAAAAGSsy+7ZZ59d4Oe33nrL7L///qZly5b254ULF5qtW7eaE044IdlVAgAAAABKsaQDUs2iG3TOOecU+JnXvgAAAAAAQglIJ02alNKKAQAAAADI+Cy7vtWrV5uvv/7a/rtJkyZmn332KcnqAAAAAAClSFqTGm3YsMFccsklZr/99jMdO3a0nzp16pi+ffuajRs3Zn4vAQAAAAB5J62AdNCgQebdd981r776qvn999/t5+WXX7bfXXvttZnfSwAAAABA3kmry+7zzz9vnnvuOXPsscfGvjvllFPM7rvvbs477zzz8MMPZ3IfAQAAAAB5KK0WUnXLrVWr1i7f77vvvnTZBQAAAACEF5B26NDBDB8+3GzevDn23aZNm8ytt95qfwcAAAAAQChddseOHWu6du1q9t9/f9OyZUv73cKFC02lSpXMG2+8kc4qAQAAAAClTFoBaYsWLcy3335rnnrqKfPVV1/Z73r27GkuvPBCO44UAAAAAICMB6Tbtm0zTZs2Na+99prp169fqn8OAAAAAEB6Y0h32223AmNHAQAAAACIbFKjK6+80tx1111m+/btaW0UAAAAAIC0xpB+/PHHZubMmebNN9+040mrVKlS4PcvvPBCpvYPAAAAAJCn0gpIq1evbs4555zM7w0AAAAAoNRIKSDduXOnueeee8w333xjtm7dao4//ngzYsQIZtYFAAAAAIQ7hvSOO+4wN910k9ljjz1M3bp1zQMPPGDHkwIAAAAAEGpA+sQTT5iHHnrIvPHGG+all14yr776qn0XqVpOAQAAAAAILSBdsmSJOeWUU2I/d+7c2ZQpU8YsX748pY0CAAAAAJBSQKrXvFSqVGmX95Ju27Yt0/sFAAAAAMhzKU1q5Hmeufjii03FihVj323evNlcfvnlBV79wmtfAAAAAAAZDUh79+69y3d//etfU1kFAAAAAACpB6STJk1KZXEAJaBXKmXjukqTTJ83rgMAAEAJxpACAAAAAJApBKQAAAAAACcISAEAAAAAThCQAgAAAACyf1IjAEgWEwIBAACgOASk2AWBBAAAAIAo0GUXAAAAAOAEASkAAAAAwAkCUgAAAACAEwSkAAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAAA4QUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAApTcgHT9+vGnQoIGpVKmSad++vZk7d26Ry0+dOtU0bdrULt+iRQszbdq0Qpe9/PLLTZkyZczYsWND2HMAAAAAQM4GpFOmTDGDBg0yw4cPN/PnzzctW7Y0Xbp0MatWrUq4/OzZs03Pnj1N3759zYIFC0y3bt3sZ9GiRbss++KLL5oPP/zQ1KlTJ4IjAQAAAADkVEA6ZswY069fP9OnTx/TrFkzM2HCBFO5cmXz6KOPJlz+/vvvN127djWDBw82hxxyiBk5cqRp3bq1GTduXIHlli1bZq666irz1FNPmd122y2iowEAAAAA5ERAunXrVvPJJ5+Yzp07/98OlS1rf54zZ07Cv9H3weVFLarB5Xfu3GkuuugiG7Qeeuihxe7Hli1bzPr16wt8AAAAAAB5HJCuWbPG7Nixw9SqVavA9/p5xYoVCf9G3xe3/F133WXKly9vBgwYkNR+jBo1ylSrVi32qVevXlrHAwAAAADIoS67maYWV3Xrfeyxx+xkRskYMmSIWbduXeyzdOnS0PcTAAAAAEo7pwFpzZo1Tbly5czKlSsLfK+fa9eunfBv9H1Ry7///vt2QqQDDjjAtpLq8/PPP5trr73WzuSbSMWKFU3VqlULfAAAAAAAeRyQVqhQwbRp08bMnDmzwPhP/dyhQ4eEf6Pvg8vLjBkzYstr7Ohnn31mPv3009hHs+xqPOkbb7wR8hEBAAAAAJJV3jimV7707t3btG3b1rRr186+L3TDhg121l3p1auXqVu3rh3nKQMHDjSdOnUyo0ePNqeeeqp55plnzLx588zEiRPt72vUqGE/QZplVy2oTZo0cXCEAAAAAICsDEh79OhhVq9ebYYNG2YnJmrVqpWZPn16bOKiJUuW2Jl3fUcddZSZPHmyGTp0qLnppptM48aNzUsvvWSaN2/u8CgAAAAAADkXkEr//v3tJ5FZs2bt8l337t3tJ1k//fRTifYPAAAAAJB5eTfLLgAAAAAgNxCQAgAAAACcICAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJwgIAUAAAAAOEFACgAAAABwgoAUAAAAAOAEASkAAAAAwAkCUgAAAACAEwSkAAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAAA4QUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJwgIAUAAAAAOEFACgAAAABwgoAUAAAAAOAEASkAAAAAwAkCUgAAAACAEwSkAAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAAA4QUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJwgIAUAAAAAOEFACgAAAABwgoAUAAAAAOAEASkAAAAAwAkCUgAAAACAEwSkAAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAAA4QUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAApTcgHT9+vGnQoIGpVKmSad++vZk7d26Ry0+dOtU0bdrULt+iRQszbdq02O+2bdtmbrjhBvt9lSpVTJ06dUyvXr3M8uXLIzgSAAAAAEDOBKRTpkwxgwYNMsOHDzfz5883LVu2NF26dDGrVq1KuPzs2bNNz549Td++fc2CBQtMt27d7GfRokX29xs3brTrueWWW+z/X3jhBfP111+bM844I+IjAwAAAABkdUA6ZswY069fP9OnTx/TrFkzM2HCBFO5cmXz6KOPJlz+/vvvN127djWDBw82hxxyiBk5cqRp3bq1GTdunP19tWrVzIwZM8x5551nmjRpYo488kj7u08++cQsWbIk4qMDAAAAAGRlQLp161YbKHbu3Pn/dqhsWfvznDlzEv6Nvg8uL2pRLWx5WbdunSlTpoypXr16wt9v2bLFrF+/vsAHAAAAAJDHAemaNWvMjh07TK1atQp8r59XrFiR8G/0fSrLb9682Y4pVTffqlWrJlxm1KhRtmXV/9SrVy/tYwIAAAAA5EiX3TBpgiN13fU8zzz88MOFLjdkyBDbiup/li5dGul+AgAAAEBpVN7lxmvWrGnKlStnVq5cWeB7/Vy7du2Ef6Pvk1neD0Z//vln8/bbbxfaOioVK1a0HwAAAABAKWkhrVChgmnTpo2ZOXNm7LudO3fanzt06JDwb/R9cHnRJEbB5f1g9NtvvzVvvfWWqVGjRohHAQAAAADIuRZS0Stfevfubdq2bWvatWtnxo4dazZs2GBn3RW9Q7Ru3bp2nKcMHDjQdOrUyYwePdqceuqp5plnnjHz5s0zEydOjAWj5557rn3ly2uvvWbHqPrjS/fee28bBAMAAAAA3HMekPbo0cOsXr3aDBs2zAaOrVq1MtOnT49NXKRXtWjmXd9RRx1lJk+ebIYOHWpuuukm07hxY/PSSy+Z5s2b298vW7bMvPLKK/bfWlfQO++8Y4499thIjw8AAAAAkKUBqfTv399+Epk1a9Yu33Xv3t1+EmnQoIGdxAgAAAAAkN3yepZdAAAAAED2IiAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJwgIAUAAAAAOEFACgAAAABwgoAUAAAAAOAEASkAAAAAwAkCUgAAAACAEwSkAAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAAA4QUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADhBQAoAAAAAcIKAFAAAAADgBAEpAAAAAMAJAlIAAAAAgBMEpAAAAAAAJwhIAQAAAABOEJACAAAAAJwgIAUAAAAAOEFACgAAAABwgoAUAAAAAOAEASkAAAAAwAkCUgAAAACAEwSkAAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAAA4QUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcKO9mswAAIFNGjBiRlesCAKA4tJACAAAAAJwgIAUAAAAAOEFACgAAAABwgjGkAADAqUyPW2UcLADkDgJSAAAAABlBBRNSRZddAAAAAIATtJACAIAi0eIBAAgLLaQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADjBpEYAAADI6GRTTFwFIFm0kAIAAAAAnKCFFAAc4VUaQHRo/QOA7EQLKQAAAADACVpIAQAIES3hpQPXGblyH+VDb4F8OAb8HwJSAAAA5AUCFSD30GUXAAAAAOAELaQAAAAA8P+jpT1aBKQAAAA5INcfkvNhnG0+HAPc4z4qiC67AAAAAAAnCEgBAAAAAE4QkAIAAAAAnCAgBQAAAACU3oB0/PjxpkGDBqZSpUqmffv2Zu7cuUUuP3XqVNO0aVO7fIsWLcy0adMK/N7zPDNs2DCz3377md1339107tzZfPvttyEfBQAAAAAgpwLSKVOmmEGDBpnhw4eb+fPnm5YtW5ouXbqYVatWJVx+9uzZpmfPnqZv375mwYIFplu3bvazaNGi2DJ33323eeCBB8yECRPMRx99ZKpUqWLXuXnz5giPDAAAAACQ1a99GTNmjOnXr5/p06eP/VlB5Ouvv24effRRc+ONN+6y/P3332+6du1qBg8ebH8eOXKkmTFjhhk3bpz9W7WOjh071gwdOtSceeaZdpknnnjC1KpVy7z00kvm/PPP32WdW7ZssR/funXr7P/Xr19vslFwX0sq0TFmcv1RbCN+/X/88YfZtHVDxtb//61zvam43gtt/fHbyIfrHPb6w77O+XCO8uE+yrXrnI95aqbXn2gbnKPot5Hr649iG6QF9+uPYhu5vv5sjln8/VJ8ViTPoS1btnjlypXzXnzxxQLf9+rVyzvjjDMS/k29evW8++67r8B3w4YN8w477DD77++//15H7C1YsKDAMh07dvQGDBiQcJ3Dhw+3f8OHDx8+fPjw4cOHDx8+fEzGPkuXLi0yJnTaQrpmzRqzY8cO23oZpJ+/+uqrhH+zYsWKhMvre//3/neFLRNvyJAhttuwb+fOnWbt2rWmRo0apkyZMiYXqUaiXr16ZunSpaZq1aqs38E2cn39UWwj19cfxTY4Bvfrj2Ibub7+KLbBMbhffxTbyPX1R7ENjsH9+vPlGMKmllH1dKpTp052d9nNBhUrVrSfoOrVq5t8oBs4zJs419cfxTZyff1RbCPX1x/FNjgG9+uPYhu5vv4otsExuF9/FNvI9fVHsQ2Owf368+UYwlStWrXsntSoZs2aply5cmblypUFvtfPtWvXTvg3+r6o5f3/p7JOAAAAAED0nAakFSpUMG3atDEzZ84s0F1WP3fo0CHh3+j74PKiSY385Q888EAbeAaXUZO3ZtstbJ0AAAAAgOg577KrsZu9e/c2bdu2Ne3atbMz5G7YsCE2626vXr1M3bp1zahRo+zPAwcONJ06dTKjR482p556qnnmmWfMvHnzzMSJE+3vNebz6quvNrfffrtp3LixDVBvueUW23dZr4cpLdQFWa/Sie+KzPqj20aurz+KbeT6+qPYBsfgfv1RbCPX1x/FNjgG9+uPYhu5vv4otsExuF9/vhxDtiijmY1c74Re2XLPPffYSYdatWpl3yHavn17+7tjjz3WNGjQwDz22GOx5adOnWpf6/LTTz/ZoFPvHT3llFNiv9ch6QIqSP3999/N0UcfbR566CFz8MEHOzk+AAAAAECWBqQAAAAAgNLH6RhSAAAAAEDpRUAKAAAAAHCCgBQAAAAA4AQBKQAAAADACQJSAAAAAIATBKRAKZIPk2rnwzGgeFxnAMgt5NtIFwEpQs9A8imDyvSx+OsL6xzpPbw//PCD+eWXX8yOHTtMmTJlIrkemdzGn3/+aVauXGk2bdpkdu7caY9B/w9DrqeFXF5/lNc5LGGnZ1+unZegzZs3mz/++CP04wnzHEV1ncNc//bt2822bdtMVDJ9LP71DTstkNayL9/OxWfKMM/J5ojy1LARkJZSP/30k5kyZYrZsGFDaEHKxo0b7f/DWr+CrLffftu8++675scff4x9n6ltLV261Dz77LPm+eefN3Pnzo0dS6Z8//33ZvTo0ebXX38N5Rx99tln5vjjjzcnnHCC/f+ZZ55pVqxYkdFjCPs8ff7556Zr167mmGOOMccdd5wZMGCAva/Kli2bsQw3irSwZcsW+/8w1p8PaTmK6xx2fhF2epb169fb/2fyvMSn5dmzZ9tgJQyLFi2y+dDRRx9tr/e9995rH2QzeTxhn6MornPY6W3x4sXm/PPPN507dzYXXHCBee6558zWrVsztv6wy85vvvnGXHPNNWb58uWhXeew7yNZvXq1LaeVLvztSSaueRRpLary+aGHHjIPP/ywee211zJ+L4VdLqxduzbU+2hRBNc5Mh5Kna+//trbc889vbp163r//ve/vQ0bNtjvd+7cmbFtfPnll96ZZ57pTZ06NfZdJtf/2WefeXXq1PFatmzp7b777l7btm29O++8M2Pb0vr33Xdf74gjjvD22Wcfr169et6gQYO8TPnmm2+8vffe227jtttu83799deMnqOlS5d6tWvX9gYPHuy999573j/+8Q/vqKOOst/NmTPHy5Qwz9OPP/7o1axZ0xswYID34osvejfddJN3+OGHe02aNPFWrFhhl9mxY0dOpIXLL7/cmz17duy7TK0/H9JyFNc57Pwi7PQsixcv9tq1a+fdd999se9Kel7ir3OlSpW8Bg0aeO+//35G1y3fffedt9dee3n9+vXzJk6c6PXs2dNr3bq117lzZ++PP/6wy5R0m2Gfoyiuc9jpTcdQrVo1769//at3xx132HJB1+HSSy/1Nm7cWOL1h1126j7ab7/97L10ySWXeMuXL8/4dQ77PvLP04EHHugdeuihXrly5bxTTz3Ve/TRRzNyzaNIa1Hk259//rlNb3/5y1+8xo0b27LuwgsvtM83mRB2uaD76IADDvCuu+662Hfbt2/3MuW7CK5zlAhIS5nffvvNZnwXXHCB161bN69Zs2be448/ntEH2R9++MFr1KiRV7lyZe+0007zXnrppdjvMrF+PQQo07v66qvtvz/88ENv+PDhNkMZ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7GpRVquqjl1uuukm0759+1220bJlS3PbbbfFfv7nP/9pDjnkELt/TZs2tfvrK+xc/fzzz3YfdS107Iceeqht1fUtWrTIBpQKqnXM6oK8Zs2a2O+1jzoW/V7nbfTo0bvspyokTjnlFPPMM88Uer4AANmJgBQAkFP+/PNP8+STT5qDDjrIBpXxFGz54wm//vpr26p6//332//37NnTXHLJJebLL7+0AefZZ59tPM8z1113nTnvvPMKtMQeddRRsXUqAB44cKD9uy5duiTcr++//9689NJL5rXXXrOfd99919x5552x3w8aNMj897//Na+88oqZMWOGef/99838+fNjv583b54NEhUAar+nT59uOnbsWOh5UJfldevWmbZt2+7yu3vvvdcGkwsWLDC33HKL3Tcd2znnnGP/TkGjAtT+/fvb5RUoz5071y7n++KLL+yyF1xwgf1ZweWwYcPMHXfcYc+Dxq1q3Qrkg+LP1ZVXXmm2bNli3nvvPfP555+bu+66K9aiqy7Vxx9/vDn88MPt8euYV65caa+Fb/DgwfZcqrLgzTfftNcteN587dq1s+cUAJBjPAAAsljv3r29cuXKeVWqVLEfFV377bef98knn8SW+fHHH+33CxYssD+/88479ufffvsttoyW13c//fRTods588wzC3znr3fs2LEFvp80aZJXrVq12M/Dhw/3Kleu7K1fvz723eDBg7327dvbf+v73XbbzZs6dWrs97///rv9m4EDB9qfn3/+ea9q1aoF1lGUF1980Z6XnTt3Fvi+fv36Xrdu3Qp817dvX++yyy4r8N3777/vlS1b1tu0aZP9uWXLlt5tt90W+/2QIUNi+y+NGjXyJk+eXGAdI0eO9Dp06FDkuWrRooU3YsSIhMegvz/ppJMKfLd06VK7nq+//tr7448/vAoVKnjPPvts7Pe//vqrt/vuu8fOm+/ll1+2x7Njx46E2wIAZCdaSAEAWU9dcNUdVx+15KnlTd081R00WWoxPOGEE2yXXY27/Mc//mF+++23pP42UStkPHWV3XPPPWM/q3vpqlWr7L9/+OEHO55SrXg+dett0qRJ7OcTTzzR1K9f3zRs2NB2W1WL5MaNGwvd3qZNm2xXZnWTLW5/NfmRuhmrZdL/6BxqEqAff/wx1ko6efJk+2+1Gj/99NP2O7/brFpP+/btW2Adt99+e4FW1UTbVquvlvvLX/5ihg8fXmAyKu3XO++8U2Cd6gosWq8+GgMb7E689957FzhvPnVF1vGoNRYAkDsISAEAWU9jD9VFV58jjjjCjmVUkKSgMlkaZ6iuspr4plmzZnZCIAU2fkBW3PaLs9tuuxX4WYFiKrO+KphVV1QFggpm1T1WQXRhMwXXrFnTBqyJJi2K3191c/7b3/4WC+r1UTD47bffmkaNGtll1J1ZXYW1D7Nnz7ZjdDWbsP/3ovMdXIfGf3744YdFbvvSSy+1AbmCbHXZVcCqc++vV+NLg+vUR/tVVHflRNauXWu3rcAUAJA7CEgBADlHwV7ZsmVtK2EiFSpUiE38E/93aqm79dZb7fhKLffiiy/G/iZ++UxRq6cC1o8//jj2ncZ/xr86RrMEa6Klu+++27YkaqKgt99+O+E6NYmSLF68uNjtt27d2i7nB/XBj3+u9t9/fzsZkVpm9VGLrT+TsCYbqlOnjg0s4//+wAMPLHb7Gtd7+eWXmxdeeMFce+21sYoE7ZfGqqp1OX69Ci4VLOu8ffTRR7F1qVU70St3FBxrLCoAILeEPz8+AAAlpG6YK1asiAUk48aNi7WuJaKurwo+NbmQZl9Vq5kCH70y5qSTTrKBloIczdKrWWNFQdEbb7xhWwk1WZK61GaKWj979+5tJ+hRl1NtX91XFVT7XW61rwr41DKoGWk1E61aWBN1T5V99tnHBnSanMgPTgtzww03mCOPPNJOYqQWSwV7ClDVYqxz6VMXXe2XWl01C3CQgnh1v9V50QRJuiaaiEjXQxM2FUazCKt79cEHH2yXVRdd/5xrwiMFp2qdvf766+25+e677+xsuWoFVxdedRPWedM10Xm7+eab7XmLpwmNdG0BALmFFlIAQNbT7KvqxqqPxhOqpXHq1Kn2tSmJ1K1b1wZQmvFVrXsKxPQKFM30qgBVwdHQoUPtK0QULEm/fv1s8KcupQr2NCNuJo0ZM8Z06NDBvj9VraBqqfVfoSJ6jYxaEDXrrL6fMGGC7b6r16QURsGlWjOLc9hhh9mZatWyqFe/qCVRXYLV6hmk18z8+uuvtitwt27ddtmWgsRJkybZcbhqTdW41OJaSNXqrMBTx6RAVufef12Mtq/zrGUUTGq9CmB1Lvyg85577rH7rMoHnbejjz7atGnTpsA2li1bZrsZ9+nTp9hzAQDILmU0s5HrnQAAoLTRGFgFzgqK1QqYDnVZVhCt17go2C2t1AKs1teJEye63hUAQIrosgsAQAQ0ZvWrr76yM+1q/KjeNypnnnlm2utUV+QnnnjCrFmzxpRm6spbVLdhAED2ooUUAICIAlJ1e9UYVU0kpG6n6sarbqoAAJRWBKQAAAAAACeY1AgAAAAA4AQBKQAAAADACQJSAAAAAIATBKQAAAAAACcISAEAAAAAThCQAgAAAACcICAFAAAAADhBQAoAAAAAMC78P6J1YJWtd3EjAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.rcParams.update({\"font.size\": 10})\n", + "final_bits = final_distribution_bin\n", + "values = np.abs(list(final_bits.values()))\n", + "top_4_values = sorted(values, reverse=True)[:4]\n", + "positions = []\n", + "for value in top_4_values:\n", + " positions.append(np.where(values == value)[0])\n", + "fig = plt.figure(figsize=(11, 6))\n", + "ax = fig.add_subplot(1, 1, 1)\n", + "plt.xticks(rotation=45)\n", + "plt.title(\"Result Distribution\")\n", + "plt.xlabel(\"Bitstrings (reversed)\")\n", + "plt.ylabel(\"Probability\")\n", + "ax.bar(list(final_bits.keys()), list(final_bits.values()), color=\"tab:grey\")\n", + "for p in positions:\n", + " ax.get_children()[int(p[0])].set_color(\"tab:purple\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "76444240", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10100\n", + "10110\n", + "01001\n", + "01011\n" + ] + } + ], + "source": [ + "for p in positions:\n", + " print(list(final_bits.keys())[p[0]])" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "ca9172e6", + "metadata": {}, + "outputs": [], + "source": [ + "def evaluate_sample(x: Sequence[int], graph: nx.Graph) -> float:\n", + " assert len(x) == len(\n", + " list(graph.nodes())\n", + " ), \"The length of x must coincide with the number of nodes in the graph.\"\n", + " return sum(\n", + " x[u] * (1 - x[v]) + x[v] * (1 - x[u])\n", + " for u, v in list(graph.edges)\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "3a6a65a6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The value of the cut is: 5\n" + ] + } + ], + "source": [ + "cut_value = evaluate_sample(most_likely_bitstring, graph)\n", + "print(\"The value of the cut is:\", cut_value)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "01920bcd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The value of the cut is: 5\n", + "The value of the cut is: 5\n", + "The value of the cut is: 5\n", + "The value of the cut is: 5\n" + ] + } + ], + "source": [ + "for p in positions:\n", + " result = list(final_bits.keys())[p[0]]\n", + " bin = [int(digit) for digit in result]\n", + " bin.reverse()\n", + " cut_value = evaluate_sample(bin, graph)\n", + " print(\"The value of the cut is:\", cut_value)\n", + " #print(list(final_bits.keys())[p[0]])" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "968c5412", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The value of the cut is: 5\n", + "The value of the cut is: 4\n", + "The value of the cut is: 5\n", + "The value of the cut is: 2\n" + ] + } + ], + "source": [ + "# results from https://quantum.cloud.ibm.com/docs/en/tutorials/quantum-approximate-optimization-algorithm\n", + "result = [\"01011\", \"10101\", \"10110\", \"11000\"]\n", + "for r in result:\n", + " bin = [int(digit) for digit in r]\n", + " bin.reverse()\n", + " cut_value = evaluate_sample(bin, graph)\n", + " print(\"The value of the cut is:\", cut_value)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/qbraid_algorithms/qaoa/__init__.py b/qbraid_algorithms/qaoa/__init__.py new file mode 100644 index 0000000..97d580a --- /dev/null +++ b/qbraid_algorithms/qaoa/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2025 qBraid +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" + Quantum Approximate Optimization Algorithm (QAOA) used to define cost and mixer Hamiltonians + and generate QASM programs accordingly. +""" +from .qaoa import QAOA + +__all__ = ["QAOA"] diff --git a/qbraid_algorithms/qaoa/qaoa.py b/qbraid_algorithms/qaoa/qaoa.py new file mode 100644 index 0000000..32f4f4b --- /dev/null +++ b/qbraid_algorithms/qaoa/qaoa.py @@ -0,0 +1,362 @@ +# Copyright 2025 qBraid +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Quantum Approximate Optimization Algorithm (QAOA) Implementation + +This module provides an implementation of the Quantum Approximate Optimization Algorithm ansatz +for different standard mixer and cost Hamiltonians, namely maximum-cut, maximum clique and minimum vertex cover. +""" + +import networkx as nx + +from qbraid_algorithms.qtran import QasmBuilder, std_gates + + +class QAOA: + """ + Quantum Approximate Optimization Algorithm (QAOA) class used to define cost and mixer Hamiltonians + and generate QASM programs accordingly. + """ + def __init__(self, num_qubits : int, qasm_version : int = 3, use_input : bool = True): + self.builder = QasmBuilder(num_qubits, version=qasm_version) + self.use_input = use_input + self.mixer_hamiltonian = "" + self.cost_hamiltonian = "" + self.layer_circuit = "" + self._x_mixer_count = 0 + self._max_clique_cost_count = 0 + self._xy_mixer_count = 0 + self._min_vertex_cover_cost_count = 0 + self._maxcut_cost_count = 0 + + def xy_mixer(self, graph : nx.Graph) -> str: + r""" + Generate XY mixer Hamiltonian subroutine. + + xy_mixer_hamiltonian = $$\frac{1}{2}\sum_{(i,j)\in E(G)} X_iX_j + Y_iY_j$$ + + This mixer was introduced in + From the Quantum Approximate Optimization Algorithm to a Quantum Alternating Operator Ansatz + by Stuart Hadfield, Zhihui Wang, Bryan O’Gorman, + Eleanor G. Rieffel, Davide Venturelli, and Rupak Biswas Algorithms 12.2 (2019). + Args: + graph : nx.Graph + Graph that describes the problem + Returns: + mixer Hamiltonian subroutine name + """ + if len(graph.nodes) > self.builder.qubits: + raise ValueError( + f"The graph provided has more nodes" + f"({len(graph.nodes)}) than the qubits initialized ({self.builder.qubits})" + ) + + std = self.builder.import_library(lib_class=std_gates) + + mixer_name = f"qaoa_xy_mixer_{self._xy_mixer_count}_{self.builder.qubits}" + self._xy_mixer_count += 1 + + qubit_array_param = f"qubit[{self.builder.qubits}] qubits" + + alpha = "float alpha" + + std.begin_subroutine( + mixer_name, [qubit_array_param, alpha] + ) + old_call_space = std.call_space + std.call_space = "qubits[{}]" + + for i,j in graph.edges: + std.cnot(i,j) + std.rx("-alpha", j) + std.ry("-alpha", j) + std.cnot(i,j) + std.call_space = old_call_space + std.end_subroutine() + + return mixer_name + + def x_mixer(self, graph : nx.Graph) -> str: + r""" + Generate X mixer Hamiltonian subroutine. + + x_mixer_hamiltonian = $$\sum_{i} X_i$$ + + This mixer is used in A Quantum Approximate Optimization Algorithm + by Edward Farhi, Jeffrey Goldstone, Sam Gutmann [arXiv:1411.4028]. + Args: + graph : nx.Graph + Graph that describes the problem + Returns: + mixer Hamiltonian subroutine name + """ + if len(graph.nodes) > self.builder.qubits: + raise ValueError( + f"The graph provided has more nodes" + f"({len(graph.nodes)}) than the qubits initialized ({self.builder.qubits})" + ) + std = self.builder.import_library(lib_class=std_gates) + + mixer_name = f"qaoa_x_mixer_{self._x_mixer_count}_{self.builder.qubits}" + self._x_mixer_count += 1 + + qubit_array_param = f"qubit[{self.builder.qubits}] qubits" + + alpha = "float alpha" + + std.begin_subroutine( + mixer_name, [qubit_array_param, alpha] + ) + old_call_space = std.call_space + std.call_space = "qubits[{}]" + for i in graph.nodes: + std.rx("2 * alpha", i) + std.call_space = old_call_space + std.end_subroutine() + + return mixer_name + + def min_vertex_cover_cost(self, graph : nx.Graph) -> str: + r""" + Generate min vertex cover cost Hamiltonian subroutine. + + cost_hamiltonian $$3\sum_{(i,j)\in E(G)} (Z_i \otimes Z_j + Z_i + Z_j)-\sum_{i \in V(G)} Z_i$$ + https://openqaoa.entropicalabs.com/problems/minimum-vertex-cover/ + As described in Ising formulations of many NP problems by Andrew Lucas [arXiv:1302.5843] + Args: + graph : nx.Graph + Graph that describes the problem + Returns: + Cost Hamiltonian subroutine name + """ + if len(graph.nodes) > self.builder.qubits: + raise ValueError( + f"The graph provided has more nodes" + f"({len(graph.nodes)}) than the qubits initialized ({self.builder.qubits})" + ) + std = self.builder.import_library(lib_class=std_gates) + + cost_name = f"qaoa_min_vertex_cover_cost_{self._min_vertex_cover_cost_count}_{self.builder.qubits}" + self._min_vertex_cover_cost_count += 1 + + qubit_array_param = f"qubit[{self.builder.qubits}] qubits" + + gamma = "float gamma" + + # cost hamiltonian $$3\sum_{(i,j)\in E(G)} (Z_i \otimes Z_j + Z_i + Z_j)-\sum_{i \in V(G)} Z_i$$ + std.begin_subroutine( + cost_name, [qubit_array_param , gamma] + ) + old_call_space = std.call_space + std.call_space = "qubits[{}]" + for i,j in graph.edges: + std.cnot(i,j) + std.rz("3 * 2 * gamma", j) + std.cnot(i,j) + std.rz("3 * 2 * gamma", i) + std.rz("3 * 2 * gamma", j) + + for i in graph.nodes: + std.rz("-2 * gamma", i) + std.call_space = old_call_space + std.end_subroutine() + + return cost_name + + def max_clique_cost(self, graph : nx.Graph) -> str: + r""" + Generate max clique cost Hamiltonian subroutine. + + cost_hamiltonian $$3\sum_{(i,j)\in E(\bar{G})} (Z_i \otimes Z_j - Z_i - Z_j)+\sum_{i \in V(G)} Z_i$$ + As described in Ising formulations of many NP problems by Andrew Lucas [arXiv:1302.5843] + Args: + graph : nx.Graph + Graph that describes the problem + Returns: + Cost Hamiltonian subroutine name + """ + if len(graph.nodes) > self.builder.qubits: + raise ValueError( + f"The graph provided has more nodes" + f"({len(graph.nodes)}) than the qubits initialized ({self.builder.qubits})" + ) + std = self.builder.import_library(lib_class=std_gates) + + cost_name = f"qaoa_max_clique_cost_{self._max_clique_cost_count}_{self.builder.qubits}" + self._max_clique_cost_count += 1 + + qubit_array_param = f"qubit[{self.builder.qubits}] qubits" + + gamma = "float gamma" + + # cost hamiltonian $$3\sum_{(i,j)\in E(\bar{G})} (Z_i \otimes Z_j - Z_i - Z_j)+\sum_{i \in V(G)} Z_i$$ + std.begin_subroutine( + cost_name, [qubit_array_param , gamma] + ) + old_call_space = std.call_space + std.call_space = "qubits[{}]" + graph_complement = nx.complement(graph) + + for i,j in graph_complement.edges: + std.cnot(i,j) + std.rz("3 * 2 * gamma", j) + std.cnot(i,j) + std.rz("-3 * 2 * gamma", i) + std.rz("-3 * 2 * gamma", j) + + for i in graph.nodes: + std.rz("2 * gamma", i) + std.call_space = old_call_space + std.end_subroutine() + + return cost_name + + def qaoa_maxcut(self, graph : nx.Graph) -> tuple[str, str] : + r""" + Generate cost hamiltonian and mixer hamiltonian subroutines. + + cost_hamiltonian = $$\sum_{E(graph)} Z_i \otimes Z_j$$ + This Hamiltonian is decribed in + Quantum Approximate Optimization Algorithm for MaxCut: + A Fermionic View by Zhihui Wang, Stuart Hadfield, + Zhang Jiang, Eleanor G. Rieffel [arXiv:1706.02998]. + + mixer_hamiltonian = $$\sum_{i} X_i$$ + Args: + graph : nx.Graph + Graph that describes the problem + Returns: + (mixer, cost) : tuple[str, str] mixer and cost hamiltonian subroutine names respectively + """ + if len(graph.nodes) > self.builder.qubits: + raise ValueError( + f"The graph provided has more nodes" + f"({len(graph.nodes)}) than the qubits initialized ({self.builder.qubits})" + ) + std = self.builder.import_library(lib_class=std_gates) + + cost_name = f"qaoa_maxcut_cost_{self._maxcut_cost_count}_{self.builder.qubits}" + self._maxcut_cost_count += 1 + + qubit_array_param = f"qubit[{self.builder.qubits}] qubits" + + gamma = "float gamma" + + # cost hamiltonian $$\sum_{E(graph)} Z_i \otimes Z_j$$ + std.begin_subroutine( + cost_name, [qubit_array_param , gamma] + ) + old_call_space = std.call_space + std.call_space = "qubits[{}]" + for i,j in graph.edges: + std.cnot(i,j) + std.rz("-2 * gamma", j) + std.cnot(i,j) + std.call_space = old_call_space + std.end_subroutine() + + # mixer hamiltonian $$\sum_{i} X_i$$ + mixer_name = self.x_mixer(graph) + + return mixer_name, cost_name + + def setup_maxcut(self, graph : nx.Graph): + r""" + Perform the setup for a Max Cut problem with the given graph. + + Args: + graph : nx.Graph + Graph that describes the problem + """ + self.mixer_hamiltonian, self.cost_hamiltonian = self.qaoa_maxcut(graph=graph) + self.layer_circuit = self.layer(self.cost_hamiltonian, self.mixer_hamiltonian) + + def layer(self, cost_ham : str, mixer_ham : str) -> str : + r""" + Create layer circuit. + Args: + cost_ham : str + Name of cost Hamiltonian subroutine + mixer_ham : str + Name of mixer Hamiltonian subroutine + Returns: + Name of layer subroutine + """ + std = self.builder.import_library(lib_class=std_gates) + + name = f"qaoa_layer_function_{self.builder.qubits}" + + qubit_array_param = f"qubit[{self.builder.qubits}] qubits" + gamma = "float gamma" + alpha = "float alpha" + + std.begin_subroutine( + name, [qubit_array_param , gamma, alpha] + ) + + std.call_subroutine(cost_ham, ["qubits", "gamma"]) + std.call_subroutine(mixer_ham, ["qubits", "alpha"]) + + std.end_subroutine() + + return name + + def generate_algorithm(self, depth : int, layer : str = "", param = None) -> str: + r""" + Load the Quantum Approximate Optimization Algorithm (QAOA) ansatz as a pyqasm module. + + Args: + depth : int + Depth of the circuit (i.e. number of layer repetitions) + layer : str + Name of the layer circuit subroutine + param : list[float] + Parameters for circuit definitions, the number of parameters to provide is 2*depth. + The expected format is [gamma_0 alpha_0 gamma_1 alpha_1 ... gamma_(depth-1) alpha_(depth-1)], + where gamma and alpha are the coefficients for the cost and mixer Hamiltonians respetively + + Returns: + (str) qasm code containing the QAOA ansatz circuit + """ + if param is None and self.use_input is False: + raise ValueError( + "param cannot be None if use_input is False" + ) + std = self.builder.import_library(lib_class=std_gates) + + layer = self.layer_circuit if layer == "" else layer + + num_qubits = self.builder.qubits + + for i in range(depth): + if self.use_input: + std.add_input_var(f"gamma_{i}", qtype="float") + std.add_input_var(f"alpha_{i}", qtype="float") + else: + std.classical_op(f"float gamma_{i} = {param[i*2]}") + std.classical_op(f"float alpha_{i} = {param[i*2+1]}") + + for q in range(self.builder.qubits): + std.reset(q) + + for q in range(self.builder.qubits): + std.h(q) + + for i in range(depth): + std.call_subroutine(layer, parameters=[f"qb[0:{num_qubits}]", f"gamma_{i}", f"alpha_{i}"]) + + std.measure(list(range(num_qubits)), list(range(num_qubits))) + + return self.builder.build() diff --git a/qbraid_algorithms/qtran/gate_library.py b/qbraid_algorithms/qtran/gate_library.py index ba114b4..f4e019c 100644 --- a/qbraid_algorithms/qtran/gate_library.py +++ b/qbraid_algorithms/qtran/gate_library.py @@ -52,7 +52,7 @@ class GateLibrary: """ def __init__( - self, gate_import, gate_ref, gate_defs, program_append, builder, annotated=False + self, gate_import, gate_ref, gate_defs, program_append, builder, subroutine_ref, annotated=False ): """ Initialize the gate library with necessary components. @@ -67,6 +67,7 @@ def __init__( """ self.gate_import = gate_import # Libraries to import self.gate_ref = gate_ref # Available gate names + self.subroutine_ref = subroutine_ref # Available subroutine names self.gate_defs = gate_defs # Gate definitions dictionary self.program = program_append # Function to append code self.builder = builder # Circuit builder reference @@ -142,7 +143,7 @@ def call_subroutine(self, subroutine, parameters, capture=None): subroutine: Name of the gate to apply parameters: list of all parameters to apply """ - if subroutine not in self.gate_ref: + if subroutine not in self.subroutine_ref: print( f"stdgates: subroutine {subroutine} is not part of visible scope, " f"make sure that this isn't a floating reference / malformed statement, " @@ -304,7 +305,7 @@ def begin_subroutine(self, name, parameters: list[str], return_type=None): parameters: List of parameter names return_type: Optional return type specification """ - if name in self.gate_ref: + if name in self.subroutine_ref: print(f"warning: subroutine {name} replacing existing namespace") call = ( f"def {name}({','.join(parameters)}) {' -> ' + return_type if return_type is not None else ''}" @@ -312,27 +313,28 @@ def begin_subroutine(self, name, parameters: list[str], return_type=None): ) self.program(call) self.builder.scope += 1 + self.subroutine_ref.append(name) - def close_scope(self): + def __close_scope(self): """Close the current scope block and decrease indentation level.""" self.builder.scope -= 1 self.program("}") def end_if(self): """End conditional block.""" - self.close_scope() + self.__close_scope() def end_loop(self): """End loop block.""" - self.close_scope() + self.__close_scope() def end_gate(self): """End gate definition block.""" - self.close_scope() + self.__close_scope() def end_subroutine(self): """End subroutine definition block.""" - self.close_scope() + self.__close_scope() def controlled_op(self, gate_call, params, n=0): """ @@ -402,12 +404,46 @@ def add_var(self, name, assignment=None, qtype=None): name: variable name Assignment: whatever definition you want as long as it resolves to a string """ - if name in self.gate_ref: - print(f"warning: gate {name} replacing existing namespace") call = f"{qtype if qtype is not None else 'let'} {name} {f'= {assignment}' if assignment is not None else ''};" self.program(call) return name + def add_input_var(self, name, assignment=None, qtype=None): + """ + simple stub for programatically adding a variable + + Args: + name: variable name + Assignment: whatever definition you want as long as it resolves to a string + """ + call = (f"input {qtype if qtype is not None else 'let'} " + f"{name} {f'= {assignment}' if assignment is not None else ''};") + self.program(call) + return name + + def add_output_var(self, name, assignment=None, qtype=None): + """ + simple stub for programatically adding a variable + + Args: + name: variable name + Assignment: whatever definition you want as long as it resolves to a string + """ + call = (f"output {qtype if qtype is not None else 'let'} " + f"{name} {f'= {assignment}' if assignment is not None else ''};") + self.program(call) + return name + + def classical_op(self, operation): + """ + simple stub for programatically perform a classical operation + + Args: + operation: operation string + """ + call = f"{operation};" + self.program(call) + def merge(self, program, imports, definitions, name): """ Merges data from a built library/GateBuilder into the current library bases scope @@ -466,6 +502,7 @@ class std_gates(GateLibrary): "swap", "ccx", "cswap", + "reset" ] name = "stdgates.inc" # Standard library file name @@ -530,6 +567,10 @@ def rz(self, theta, targ): """Apply rz gate""" self.call_gate("rz", targ, phases=theta) + def reset(self, targ): + """Apply reset command""" + self.call_gate("reset", targ) + # ═══════════════════════════════════════════════════════════════════════════ # Two-QUBIT GATES # ═══════════════════════════════════════════════════════════════════════════ @@ -540,3 +581,10 @@ def cnot(self, control, targ): def cry(self, theta, control, targ): """Apply controlled ry gate""" self.call_gate("cry", targ, controls=control, phases=theta) + + # ═══════════════════════════════════════════════════════════════════════════ + # Three-QUBIT GATES + # ═══════════════════════════════════════════════════════════════════════════ + def cswap(self, control, targ1, targ2): + """Apply controlled swap gate""" + self.call_gate("cswap", f"{targ1}, {targ2}", controls=control) diff --git a/qbraid_algorithms/qtran/qasm_builder.py b/qbraid_algorithms/qtran/qasm_builder.py index 8934cd8..e3edb46 100644 --- a/qbraid_algorithms/qtran/qasm_builder.py +++ b/qbraid_algorithms/qtran/qasm_builder.py @@ -68,6 +68,7 @@ def __init__(self): self.imports = [] # List of library names to import (e.g., "std_gates.inc") self.gate_defs = {} # Dictionary mapping gate names to definition strings self.gate_refs = [] # List of available gate names for validation + self.subroutine_refs = [] # List of available subroutine names for validation self.program = "" # Accumulated OpenQASM program code self.scope = 0 # Current indentation/nesting level @@ -98,6 +99,7 @@ def import_library(self, lib_class, annotated=False): program_append=self.program_append, # Provide code appending function builder=self, # Pass reference to this builder annotated=annotated, # Set annotation mode + subroutine_ref=self.subroutine_refs # Share subroutine definitions dictionary ) def program_append(self, line): diff --git a/requirements-test.txt b/requirements-test.txt index acbe046..14f26ac 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,4 +1,5 @@ pytest pytest-cov qiskit[qasm3-import]>=2.1.0,<2.3.0 -qiskit-aer>=0.17.0,<0.18.0 \ No newline at end of file +qiskit-aer>=0.17.0,<0.18.0 +networkx \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e10e60c..f10d67c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ pyqasm>=0.5.0,<1.1.0 sympy>=1.14.0 scipy>=1.16.0 numpy>=2.3.1 +networkx>=3.1.0 \ No newline at end of file diff --git a/tests/test_qaoa.py b/tests/test_qaoa.py new file mode 100644 index 0000000..e46a790 --- /dev/null +++ b/tests/test_qaoa.py @@ -0,0 +1,180 @@ +# Copyright 2025 qBraid +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Tests for QAOA implementation. +""" +import networkx as nx +import pyqasm + +from qbraid_algorithms import qaoa + +from .local_device import LocalDevice + + +def test_generate_program(): + """Test that generate_program correctly returns a str object.""" + qaoa_module = qaoa.QAOA(5) + edges = [(0, 1), (0, 2), (0, 4), (1, 2), (2, 3), (3, 4)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + program = qaoa_module.generate_algorithm(2) + assert isinstance(program, str) + assert qaoa_module.builder.qubits == 5 # 5 data qubits + + +def test_unroll(): + """Test that pyqasm unrolls correclty.""" + qaoa_module = qaoa.QAOA(5, use_input=False) + edges = [(0, 1), (0, 2), (0, 4), (1, 2), (2, 3), (3, 4)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + program = qaoa_module.generate_algorithm(2, param=[1, 2, 3, 4]) + module = pyqasm.loads(program) + module.unroll() + +def test_correct_hamiltonian_from_graph(): + """Test that the cost Hamiltonian for maxcut is generated correctly.""" + qaoa_module = qaoa.QAOA(5) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + program = qaoa_module.generate_algorithm(2) + assert ("\tcnot qubits[0],qubits[1];\n"+ + "\trz(-2 * gamma) qubits[1];\n"+ + "\tcnot qubits[0],qubits[1];\n"+ + "\tcnot qubits[0],qubits[2];\n"+ + "\trz(-2 * gamma) qubits[2];\n"+ + "\tcnot qubits[0],qubits[2];") in program + +def test_use_input(): + """Test the use_input parameter.""" + qaoa_module = qaoa.QAOA(5, use_input=False) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + program = qaoa_module.generate_algorithm(2, param=[1, 2, 3, 4]) + assert "gamma_0 = 1" in program + assert "alpha_0 = 2" in program + assert "gamma_1 = 3" in program + assert "alpha_1 = 4" in program + + +def test_execution(): + """Test correct execution in local device.""" + device = LocalDevice() + qaoa_module = qaoa.QAOA(5, use_input=False) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + program = qaoa_module.generate_algorithm(2, param=[1, 2, 3, 4]) + module = pyqasm.loads(program) + module.unroll() + program_str = pyqasm.dumps(module) + _ = device.run(program_str, shots=1000) + +def test_x_mixer(): + """Test that the x mixer Hamiltonian is generated correctly.""" + qaoa_module = qaoa.QAOA(8) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + program = qaoa_module.generate_algorithm(2) + assert ("\trx(2 * alpha) qubits[0];\n"+ + "\trx(2 * alpha) qubits[1];\n"+ + "\trx(2 * alpha) qubits[2];") in program + +def test_xy_mixer(): + """Test that the x mixer Hamiltonian is generated correctly.""" + qaoa_module = qaoa.QAOA(8) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.setup_maxcut(graph=graph) + qaoa_module.mixer_hamiltonian = qaoa_module.xy_mixer(graph=graph) + program = qaoa_module.generate_algorithm(2) + assert ("\tcnot qubits[0],qubits[1];\n" + "\trx(-alpha) qubits[1];\n"+ + "\try(-alpha) qubits[1];\n"+ + "\tcnot qubits[0],qubits[1];\n"+ + "\tcnot qubits[0],qubits[2];\n"+ + "\trx(-alpha) qubits[2];\n"+ + "\try(-alpha) qubits[2];\n"+ + "\tcnot qubits[0],qubits[2];") in program + +def test_min_vertex_cover(): + """Test that the cost Hamiltonian for min vertex cover is generated correctly.""" + qaoa_module = qaoa.QAOA(5) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.cost_hamiltonian = qaoa_module.min_vertex_cover_cost(graph=graph) + program = qaoa_module.generate_algorithm(2) + assert ("cnot qubits[0],qubits[1];\n"+ + "\trz(3 * 2 * gamma) qubits[1];\n"+ + "\tcnot qubits[0],qubits[1];\n"+ + "\trz(3 * 2 * gamma) qubits[0];\n"+ + "\trz(3 * 2 * gamma) qubits[1];\n"+ + "\tcnot qubits[0],qubits[2];\n"+ + "\trz(3 * 2 * gamma) qubits[2];\n"+ + "\tcnot qubits[0],qubits[2];\n"+ + "\trz(3 * 2 * gamma) qubits[0];\n"+ + "\trz(3 * 2 * gamma) qubits[2];\n"+ + "\trz(-2 * gamma) qubits[0];\n"+ + "\trz(-2 * gamma) qubits[1];\n"+ + "\trz(-2 * gamma) qubits[2];") in program + +def test_max_clique(): + """Test that the cost Hamiltonian for max clique is generated correctly.""" + qaoa_module = qaoa.QAOA(5) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + qaoa_module.cost_hamiltonian = qaoa_module.max_clique_cost(graph=graph) + program = qaoa_module.generate_algorithm(2) + assert ("\tcnot qubits[1],qubits[2];\n"+ + "\trz(3 * 2 * gamma) qubits[2];\n"+ + "\tcnot qubits[1],qubits[2];\n"+ + "\trz(-3 * 2 * gamma) qubits[1];\n"+ + "\trz(-3 * 2 * gamma) qubits[2];\n"+ + "\trz(2 * gamma) qubits[0];\n"+ + "\trz(2 * gamma) qubits[1];\n"+ + "\trz(2 * gamma) qubits[2];") in program + +def test_validation(): + """Test the validation inside Hamiltonian generation""" + qaoa_module = qaoa.QAOA(1) + edges = [(0, 1), (0, 2)] + graph = nx.Graph(edges) + try: + qaoa_module.x_mixer(graph=graph) + assert False + except ValueError: + assert True + try: + qaoa_module.xy_mixer(graph=graph) + assert False + except ValueError: + assert True + try: + qaoa_module.qaoa_maxcut(graph=graph) + assert False + except ValueError: + assert True + try: + qaoa_module.min_vertex_cover_cost(graph=graph) + assert False + except ValueError: + assert True + try: + qaoa_module.max_clique_cost(graph=graph) + assert False + except ValueError: + assert True diff --git a/tox.ini b/tox.ini index bccbd44..dc74e18 100644 --- a/tox.ini +++ b/tox.ini @@ -49,7 +49,7 @@ envdir = .tox/linters skip_install = true deps = mypy commands = - mypy qbraid_algorithms + mypy --install-types --non-interactive qbraid_algorithms [testenv:headers] envdir = .tox/linters