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
+}