From 24b9aca51a767f22ebad06a3b5e41a0de9698288 Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Thu, 26 Sep 2024 09:08:23 +0100 Subject: [PATCH] phase squashing notebook --- scratchpads/phase-squashing.ipynb | 616 ++++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 scratchpads/phase-squashing.ipynb diff --git a/scratchpads/phase-squashing.ipynb b/scratchpads/phase-squashing.ipynb new file mode 100644 index 00000000..67bfc57c --- /dev/null +++ b/scratchpads/phase-squashing.ipynb @@ -0,0 +1,616 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "id": "aa06120b", + "metadata": {}, + "outputs": [], + "source": [ + "import sys, os; sys.path.insert(0, '..')\n", + "import random, logging, math\n", + "import pyzx as zx\n", + "from fractions import Fraction\n", + "from pyzx.gadget_extract import *\n", + "Z = zx.VertexType.Z\n", + "X = zx.VertexType.X\n", + "SE = zx.EdgeType.SIMPLE\n", + "HE = zx.EdgeType.HADAMARD\n", + "# zx.settings.drawing_backend = 'matplotlib'" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "abb9cd7f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.00+0.00i = sqrt(2)^2\n", + "2\n" + ] + } + ], + "source": [ + "c = zx.qasm(\"\"\"\n", + "qreg q[4];\n", + "cx q[0], q[1];\n", + "cx q[1], q[2];\n", + "s q[2];\n", + "\"\"\")\n", + "g = c.to_graph()\n", + "print(g.scalar)\n", + "print(g.num_edges() - g.num_vertices() + g.num_outputs())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b29c0dc8", + "metadata": {}, + "outputs": [], + "source": [ + "def num_spiders(g):\n", + " return len([v for v in g.vertices() if g.type(v) == Z or g.type(v) == X])\n", + "\n", + "def inv(g):\n", + " return (g.scalar.power2 == g.num_edges() - num_spiders(g) - g.num_outputs())" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "a8f60750", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "559\n", + "True\n" + ] + } + ], + "source": [ + "c = zx.Circuit.load('../circuits/QFT_and_Adders/QFTAdd16_before')\n", + "g = c.to_graph()\n", + "zx.full_reduce(g)\n", + "print(g.num_edges() - g.num_vertices() + g.num_outputs())\n", + "print(g.scalar.power2 == g.num_edges() - num_spiders(g) - g.num_outputs())" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "aeb06e7f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "zx.draw(c)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "d9a8bce2", + "metadata": {}, + "outputs": [], + "source": [ + "def squash_reduce(g, err_budget, quiet=True):\n", + " total_err = 0\n", + " for i in range(50, -1, -1):\n", + " zx.full_reduce(g)\n", + " th = Fraction(1, 2**i)\n", + " if not quiet: print(f'threshold Δθ <= 2^-{i} π')\n", + " for v in list(g.vertices()):\n", + " p = g.phase(v)\n", + " if p.denominator > 2:\n", + " new_p = Fraction(round(2*p), 2)\n", + " err = abs(float(p)-round(new_p))\n", + " if err <= th:\n", + " if total_err + err > err_budget:\n", + " zx.full_reduce(g)\n", + " if not quiet: print('exceeded error budget, done.')\n", + " return\n", + " else:\n", + " norm_err = 2*(math.sin(err/2)**2)\n", + " if not quiet: print(f' * {p} ~ {new_p} (ε = {norm_err})')\n", + " g.set_phase(v, new_p)\n", + " total_err += norm_err\n", + " zx.full_reduce(g)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "79b1ddf4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Circuit QFTAdd16_before on 32 qubits with 1822 gates.\n", + " 1026 is the T-count\n", + " 796 Cliffords among which\n", + " 716 2-qubit gates (716 CNOT, 0 other) and\n", + " 32 Hadamard gates.\n" + ] + } + ], + "source": [ + "print(c.to_basic_gates().stats())" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "c5e37ac3", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extracting circuit...\n", + "Circuit on 32 qubits with 1278 gates.\n", + " 236 is the T-count\n", + " 1042 Cliffords among which\n", + " 574 2-qubit gates (328 CNOT, 246 other) and\n", + " 466 Hadamard gates.\n" + ] + } + ], + "source": [ + "g1 = c.to_graph()\n", + "squash_reduce(g1, err_budget=0.01)\n", + "print(\"extracting circuit...\")\n", + "c1 = zx.extract_circuit(g1, up_to_perm=True)\n", + "zx.basic_optimization(c1)\n", + "#zx.draw(c1)\n", + "print(c1.stats())" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "44aad5a9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extracting circuit...\n", + "Circuit on 32 qubits with 2142 gates.\n", + " 402 is the T-count\n", + " 1740 Cliffords among which\n", + " 964 2-qubit gates (613 CNOT, 351 other) and\n", + " 776 Hadamard gates.\n" + ] + } + ], + "source": [ + "g1 = c.to_graph()\n", + "squash_reduce(g1, err_budget=0.0)\n", + "print(\"extracting circuit...\")\n", + "c1 = zx.extract_circuit(g1, up_to_perm=True)\n", + "zx.basic_optimization(c1)\n", + "#zx.draw(c1)\n", + "print(c1.stats())" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "1c955dc6", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extracting circuit...\n", + "Circuit on 32 qubits with 499 gates.\n", + " 113 is the T-count\n", + " 386 Cliffords among which\n", + " 190 2-qubit gates (12 CNOT, 178 other) and\n", + " 196 Hadamard gates.\n" + ] + } + ], + "source": [ + "g1 = c.to_graph()\n", + "squash_reduce(g1, err_budget=0.1)\n", + "print(\"extracting circuit...\")\n", + "c1 = zx.extract_circuit(g1, up_to_perm=True)\n", + "#zx.draw(c1)\n", + "print(c1.stats())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15f333c6", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}