diff --git a/.ipynb_checkpoints/moodys_challenge-checkpoint.ipynb b/.ipynb_checkpoints/moodys_challenge-checkpoint.ipynb
new file mode 100644
index 0000000..845c1cb
--- /dev/null
+++ b/.ipynb_checkpoints/moodys_challenge-checkpoint.ipynb
@@ -0,0 +1,1017 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "de7fe4be-dd2d-4d8c-9358-5ab6a636496e",
+ "metadata": {},
+ "source": [
+ "# Quantum Machine Learning for detecting financial crashes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6c89cba0-4047-4b23-b949-baa20f67fae5",
+ "metadata": {},
+ "source": [
+ "### Learning objectives of the challenge"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7fb51a43-6f42-4077-a894-38c874c61721",
+ "metadata": {},
+ "source": [
+ "**1.** How to use classical topological data analysis, TDA, for financial bubble early warning? \n",
+ "**2.** How to implement its quantum counterpart? \n",
+ "**3.** Conduct a resource analysis on the quantum algorithm. Which step is most costly? \n",
+ "**4.** Get used to Quantum Phase Estimation, QPE. \n",
+ "**5.** How is the influence of the classical noise (the random fluctuations in financial markets)? \n",
+ "**6.** How is the influence of quantum noise? "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "85d339f8-0a2d-4c84-88d2-ae2f5d7e7597",
+ "metadata": {},
+ "source": [
+ "## The challenge"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ddf18fd5",
+ "metadata": {},
+ "source": [
+ "### Main idea\n",
+ "\n",
+ "Topological Data Analysis (TDA) is a robust and innovative technique that has demonstrated impressive results in detecting financial crashes—critical transitions between financial regimes—and providing early warning signals. By analyzing changes in Betti numbers, TDA can reveal shifts in underlying structures that precede these transitions. In this notebook, we employ a quantum TDA algorithm to calculate Betti numbers, enabling effective early detection of financial crashes.\n",
+ "\n",
+ "### What is topological data analysis\n",
+ "\n",
+ "Topology studies the properties of geometric objects that are preserved under continuous deformations, such as stretching, twisting, crumpling, and bending. Homology serves as a tool to study and quantify the topological properties of spaces. The homology of an object is often summarized using $k$-th Betti numbers, which count the number of $k$-dimensional holes within the object. For example, the zeroth Betti number, $\\beta_0$, counts the number of connected components; the first Betti number, $\\beta_1$, counts the number of loops; and the second Betti number, $\\beta_2$, counts the number of enclosed volumes, and so on.\n",
+ "\n",
+ "In finance, input data is typically represented as time series, which are subsequently transformed into a series of discrete points. To model the underlying structure with them, we construct a simplicial complex (specifically, a Vietoris–Rips complex), a collection of simple shapes that connect the points together. Those simple shapes are called simplex, and they are generalization of the notion of a triangle or tetrahedron to arbitrary dimensions. A $k$-simplex is a collection of $k + 1$ vertices with $k(k + 1)/2$ edges in $k$ dimensions. A resolution threshold, $\\epsilon$, is chosen so that any two points within $\\epsilon$ distance of each other are connected by a line segment in the simplicial complex. As $\\epsilon$ increases, more connections are added, and lower-order components may merge into higher-order components. This results in a decrease in the lower-order Betti numbers and an increase in the higher-order Betti numbers. The study of how topological properties change across a sequence of resolution thresholds is called persistent homology.\n",
+ "\n",
+ "\n",
+ "\n",
+ "For example, consider the figure above, which consists of five points. When $\\epsilon$ is small, no lines connect the points. Consequently, $\\beta_0 = 5$, as there are five discrete points, each representing an independent connected component, and no higher-dimensional features are present. As $\\epsilon$ increases, the Betti numbers for the configuration on the right become:\n",
+ "\n",
+ "* $\\beta_0=2$: There are two connected components (a line segment and a triangle).\n",
+ "* $\\beta_1=1$: There is one 1-dimensional hole (the triangle encloses a region).\n",
+ "* $\\beta_k=0$ for $k\\ge2$: No higher-dimensional features exist.\n",
+ "\n",
+ "This example also illustrates how Betti numbers change with the resolution threshold. The sequence of Betti numbers as the resolution threshold varies forms a curve known as the Betti curve. This curve can be utilized as input for kernel construction in machine learning applications.\n",
+ "\n",
+ "### What is quantum TDA?\n",
+ "\n",
+ "TDA can be used for extracting complex and valuable shape-related summaries of high-dimensional data. However, as the size of the dataset grows, the number of simplices considered increases significantly, leading to an exponential rise in the computational complexity of TDA algorithms ([ref](https://quantum-journal.org/papers/q-2022-11-10-855/)). \n",
+ "\n",
+ "Quantum computers have the potential to significantly accelerate TDA algorithms. Lloyd et al. introduced a fully quantum TDA algorithm leveraging quantum random access memory (qRAM), Grover's search algorithm, and quantum phase estimation (QPE) ([ref](https://www.nature.com/articles/ncomms10138)). In this approach, classical data is first loaded and encoded into the quantum amplitudes of a quantum state via qRAM. Grover's algorithm is then employed to construct the simplex state, with a membership function used to determine whether a given simplex belongs to the complex. Finally, the combinatorial Laplacian (also referred to as the \"Dirac operator\") is constructed, and the Betti numbers—key topological invariants—are extracted using QPE. \n",
+ "\n",
+ "However, this quantum TDA algorithm is really costly for NISQ computers. Even more, the qRAM requires long-lasting quantum coherence and low computational error to store and process the loaded data. Several exciting alternatives approaches have been proposed since then. It must be noted that quantum TDA is one of the first quantum machine learning algorithms with short depth and potential significant speedup under certain assumptions.\n",
+ "\n",
+ "Here is a list of different versions of quantum TDA. Note that they may be beyond the scope of this challenge, and mainly for your interest:\n",
+ "\n",
+ "* [QTDA via the estimation of the density of states (December 2023, University of Exeter)](https://arxiv.org/abs/2312.07115)\n",
+ "* [NISQ-TDA (Sep 2022, IBM Research + University of the Witwatersrand)](https://arxiv.org/pdf/2209.09371)\n",
+ "* [Quantum persistent homology (Nov 2022, University of Tennessee)](https://arxiv.org/abs/2211.04465)\n",
+ "* [Hybrid qTDA (Oct 2022, Deloitte)](https://arxiv.org/abs/2209.10596)\n",
+ "* [Quantum-Enhanced TDA (Feb 2023, Tata Consultancy Services)](https://arxiv.org/pdf/2302.09553)\n",
+ "\n",
+ "### Does TDA have applications in finance?\n",
+ "\n",
+ "Betti numbers offer valuable insights into the structure and shape of complex data. While their use in finance is still in its early stages, they show promise in various applications, such as credit risk prediction ([ref](https://ora.ox.ac.uk/objects/uuid:9f4bed48-1763-486f-acbe-393670fab6bb/files/skw52j939s)), fraud detection, financial bubble detection ([ref](https://arxiv.org/abs/2304.06877)), capturing financial instability ([ref](https://arxiv.org/pdf/2110.00098)), etc. It can also be used as an unsupervised learning algorithm for anomaly detection.\n",
+ "\n",
+ "Several studies suggest that Betti numbers serve as effective indicators of market crashes. The zeroth betti number $\\beta_0$ is small at the beginning of a market crash and increases as the market crash progresses. It can be interpreted as that there is a giant connected component in the market just before the crash, and as the market crashed, this broke up into many smaller components ([ref](https://www.mdpi.com/1099-4300/23/9/1211), [ref](https://www.frontiersin.org/journals/physics/articles/10.3389/fphy.2021.572216/full)). \n",
+ "\n",
+ "This concept serves as the foundation for the idea behind this challenge."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7d128bf0",
+ "metadata": {},
+ "source": [
+ "## Problem Statement - Detecting financial bubbles by using quantum topological data analysis (qTDA)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cfe38b05-e39a-4d01-a1d6-b6fafcec3db3",
+ "metadata": {},
+ "source": [
+ "The goal of this challenge is to build a quantum TDA pipeline for detecting financial market crashes. The process is outlined in the following key steps, with detailed instructions provided below. Follow the **Instructions** and **Action** parts carefully and implement the necessary code after **Answer** to complete the pipeline.\n",
+ "\n",
+ "These references deal with the problem at hand and can be helpful to consult:\n",
+ "* [Quantum-Enhanced Topological Data Analysis: A Peep from an Implementation Perspective](https://arxiv.org/pdf/2302.09553)\n",
+ "* [Towards Quantum Advantage via Topological Data Analysis](https://quantum-journal.org/papers/q-2022-11-10-855/)\n",
+ "\n",
+ "
\n",
+ " \n",
+ "**STEPS**\n",
+ " \n",
+ "* Input: a time series of stock price; Output: a time-evolution of topological properties.\n",
+ "\n",
+ "* Preparing point cloud\n",
+ " * Apply Taken's embedding.\n",
+ " * Apply a sliding window for obatining a time-varying point-cloud.\n",
+ "* Building Laplacian\n",
+ " * Construct the Vietoris-Rips (VR) complex from the point cloud using [`GUDHI`](https://gudhi.inria.fr/).\n",
+ " * Build the boudnary operator of this complex.\n",
+ " * Build the Laplacian matrix based on the boundary operators, then pad it and rescale it.\n",
+ "* Applying quantum phase estimation\n",
+ " * Use Quantum Phase Estimation (QPE) to find the number non-zero eigenvalues of the Laplacian matrix. Round up the results and get the Betti numbers.\n",
+ " * Vary the resolution threshold and obtain a series of Betti numbers, which are the Betti curves.\n",
+ "* Detecting financial market crashes\n",
+ " * Find the relation between Betti numbers and financial market crashes.\n",
+ " \n",
+ "
NOTE:\n",
+ "\n",
+ "In the coding process, it is recommended to start with the following initial values for the variables: \n",
+ "\n",
+ "* `N = 4` # dimension of vectors\n",
+ "* `d = 5` # time delay\n",
+ "* `w = 5` # window size\n",
+ "* `epsilon = 0.1` # resolution threshold\n",
+ "* `q = 3` # number of precision qubits\n",
+ "\n",
+ "However, you will be tasked with determining the optimal values later in this challenge.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1656ba25",
+ "metadata": {},
+ "source": [
+ "### Step 0: Loading data\n",
+ "\n",
+ "\n",
+ "To assess the practical applicability of TDA with quantum techniques, we will analyze a small dataset of the S&P 500 index from the period surrounding the 2008 financial crisis. You may find the associated file: *SP500.csv*"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "4ec880cd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "time_series = np.log(pd.read_csv(\"sp500.csv\", header=None).to_numpy().squeeze())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b4597392",
+ "metadata": {},
+ "source": [
+ "### Step 1: Preparing point cloud\n",
+ "\n",
+ "**Instruction:**\n",
+ "\n",
+ "Consider a time series $X = \\{x_0, x_1, \\ldots, x_{L-1}\\}$ of numerical values of length $L$ as input. We choose and fix an embedded dimension $N$ and a time-delay $d \\ge 1$. Taken's embedding theorem convert this time series into a series of $N$-dimensional time-delay coordinate vectors $Z=\\{z_0, z_1, \\dots, z_{L-1-(N-1)d}\\}$:\n",
+ "\n",
+ "$$\n",
+ "\\begin{align*}\n",
+ "z_0 =& (x_0, x_d, \\ldots, x_{(N-1)d}),\\\\\n",
+ "z_1 =& (x_1, x_{1+d}, \\ldots, x_{1+(N-1)d}),\\\\\n",
+ "\\vdots\\\\\n",
+ "z_t =& (x_t, x_{t+d}, \\ldots, x_{t+(N-1)d}),\\\\\n",
+ "\\vdots&\\\\\n",
+ "z_{L-1-(N-1)d} =& (x_{L-1-(N-1)d}, x_{L-1-(N-2)d}, \\ldots, x_{L-1}).\n",
+ "\\end{align*}\n",
+ "$$\n",
+ "\n",
+ "To detect qualitative changes along a time series, we apply a sliding window of size $w$ and assess how topological properties change along the sliding window. For a proper size, $w$ needs to fullfill $N \\ll w \\ll L$. The sliding window gives a time-varying point cloud embedded in $\\mathcal{R}^N$:\n",
+ "\n",
+ "$$\n",
+ "Z^t = \\{z_t, z_{t+1}, \\ldots, z_{t+w-1}\\}, \\quad \\text{for } t \\in \\{0, \\ldots, K-1\\}\n",
+ "$$\n",
+ "\n",
+ "**Action:**\n",
+ "\n",
+ "Following Takens' embedding theorem, transform the `time_series` into a series of $ N $-dimensional vectors. Afterward, apply a sliding window to these vectors and obtain a time-varying point cloud.\n",
+ "\n",
+ "**Answer:**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "7b701be6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "N = 4 # dimension of vectors\n",
+ "d = 5 # time delay\n",
+ "w = 5 # window size\n",
+ "epsilon = 0.1 # resolution threshold\n",
+ "q = 3 # number of precision qubits"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "f2c20448-d9f6-4c2b-8b1d-9303e7531b0c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def takens_embedding(X, N, d, w):\n",
+ " # check validity of inputs\n",
+ " L = len(X)\n",
+ " \n",
+ " if L < w:\n",
+ " raise Exception(\"input error\")\n",
+ " if w < N:\n",
+ " raise Exception(\"input error\")\n",
+ " \n",
+ " T = int(L - (N-1) * d)\n",
+ " z = np.zeros([T, N])\n",
+ "\n",
+ " # \n",
+ " for i in range(T):\n",
+ " t = i\n",
+ " for j in range(N):\n",
+ " z[i, j] = X[t]\n",
+ " t += d\n",
+ " \n",
+ " K = L - (N - 1)*d - w + 1\n",
+ " \n",
+ " Z = np.zeros([K, w, N])\n",
+ " \n",
+ " for t in range(K):\n",
+ " for j in range(w):\n",
+ " Z[t, j, :] = z[t + j, :]\n",
+ " \n",
+ " return z, Z"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "d2723255-2166-40f8-9906-f971a03c1950",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[[[7.13389833 7.17081353 7.16110014 7.15205153]\n",
+ " [7.14663437 7.1664011 7.14610857 7.14628387]\n",
+ " [7.15787955 7.15850232 7.14739207 7.15252724]\n",
+ " [7.15000317 7.15946102 7.14883305 7.16494271]\n",
+ " [7.15460754 7.16732333 7.15964177 7.16181205]]\n",
+ "\n",
+ " [[7.14663437 7.1664011 7.14610857 7.14628387]\n",
+ " [7.15787955 7.15850232 7.14739207 7.15252724]\n",
+ " [7.15000317 7.15946102 7.14883305 7.16494271]\n",
+ " [7.15460754 7.16732333 7.15964177 7.16181205]\n",
+ " [7.17081353 7.16110014 7.15205153 7.16068091]]\n",
+ "\n",
+ " [[7.15787955 7.15850232 7.14739207 7.15252724]\n",
+ " [7.15000317 7.15946102 7.14883305 7.16494271]\n",
+ " [7.15460754 7.16732333 7.15964177 7.16181205]\n",
+ " [7.17081353 7.16110014 7.15205153 7.16068091]\n",
+ " [7.1664011 7.14610857 7.14628387 7.14995608]]\n",
+ "\n",
+ " ...\n",
+ "\n",
+ " [[6.84576817 6.8813343 6.76743518 6.7259366 ]\n",
+ " [6.8574904 6.82972617 6.77423817 6.65814903]\n",
+ " [6.86967691 6.82546547 6.78875494 6.65470005]\n",
+ " [6.8744389 6.83743206 6.75812644 6.72647918]\n",
+ " [6.90109565 6.80419869 6.74558041 6.75396287]]\n",
+ "\n",
+ " [[6.8574904 6.82972617 6.77423817 6.65814903]\n",
+ " [6.86967691 6.82546547 6.78875494 6.65470005]\n",
+ " [6.8744389 6.83743206 6.75812644 6.72647918]\n",
+ " [6.90109565 6.80419869 6.74558041 6.75396287]\n",
+ " [6.8813343 6.76743518 6.7259366 6.76198067]]\n",
+ "\n",
+ " [[6.86967691 6.82546547 6.78875494 6.65470005]\n",
+ " [6.8744389 6.83743206 6.75812644 6.72647918]\n",
+ " [6.90109565 6.80419869 6.74558041 6.75396287]\n",
+ " [6.8813343 6.76743518 6.7259366 6.76198067]\n",
+ " [6.82972617 6.77423817 6.65814903 6.79041496]]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "c, tk = takens_embedding(time_series, N, d, w)\n",
+ "print(tk)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9376bd0b",
+ "metadata": {},
+ "source": [
+ "
\n",
+ " \n",
+ "BONUS EXERCISE: \n",
+ "\n",
+ "`gtda.time_series.TakensEmbedding` can conduct this transformation. Try avoid using this function and build your own embedding function.\n",
+ "\n",
+ "
NOTE:\n",
+ "\n",
+ "From step 2, we present an example originally provided in the appendix of [Khandelwal's and Chandra's paper](https://arxiv.org/abs/2302.09553). This example can be used to verify your code.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c945e850",
+ "metadata": {},
+ "source": [
+ "### Step 2: Building Laplacian\n",
+ "\n",
+ "**Instruction:**\n",
+ "\n",
+ "In this step, we are going to use `GUDHI`, a Python package specialized in TDA and and higher dimensional geometry understanding. For detailed instructions on the functions we will use, please refer to [this website](https://gudhi.inria.fr/python/latest/rips_complex_user.html#).\n",
+ "\n",
+ "A simplicial complex is constructed on the point cloud using `gudhi.RipsComplex` class, followed by its `create_simplex_tree` method. The resolution threshold `epsilon` is set via the `max_edge_length` parameter. This process identifies the connectivity of the complex within the resolution threshold and produces a simplex tree. The simplex tree serves as a general representation of simplicial complexes. Using its `get_filtration` method, simplicies are retrieved as a collection of lists, where elements are grouped based on their connections. Each dimension up to a specified maximum is represented by its respective collection of lists.\n",
+ "\n",
+ "**Example:**\n",
+ "\n",
+ "Here is an example of a simplex tree $\\mathcal{K}$ with a maximum dimension of 2. In its zeroth dimension, each point is a connected component; In the first dimension, 6 line segments connect 6 pairs of points $[1, 2], [1, 3], [2, 3], [3, 4], [3, 5], [4, 5]$; In the second dimension, a filled trangle is formed among points $[1 ,2 ,3]$.\n",
+ "\n",
+ "$$\n",
+ "\\mathcal{K} = [[[1], [2], [3], [4], [5]],[[1, 2], [1, 3], [2, 3], [3, 4], [3, 5], [4, 5]], [[1, 2, 3]]]\n",
+ "$$\n",
+ "\n",
+ "**Action:**\n",
+ "\n",
+ "Build a simplicial complex by applying functions from `GUDHI` on the point cloud obtained in step 1, and extract its simplex tree. It is recommended to store the simplex tree in a format similar to the example provided, i.e., in the format $[S_0, S_1, S_2, \\dots]$, where $S_i$ represents the set of $i$-simplices.\n",
+ "\n",
+ "**Answer:**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "026d6b61",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import gudhi\n",
+ "from collections import defaultdict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "c587cb06-56e7-4cc2-9df6-e1a72e4e5937",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def create_simplex_tree_list(tk, epsilon):\n",
+ " K = len(tk)\n",
+ " simplex_tree_list = [None] * K\n",
+ " rips_complexes = []\n",
+ " \n",
+ " for k in range(K):\n",
+ " rips_complex = gudhi.RipsComplex(points=tk[k], max_edge_length=epsilon).create_simplex_tree(max_dimension=5)\n",
+ " rips_complexes.append(rips_complex)\n",
+ " # Initialize a dictionary to store simplices by their sizes\n",
+ " simplex_dict = defaultdict(list)\n",
+ " # Extract simplices and group them by size\n",
+ " for simplex, _ in rips_complex.get_simplices():\n",
+ " simplex_dict[len(simplex)].append(list(simplex))\n",
+ " # Convert dictionary to a sorted list of lists\n",
+ " simplex_tree_list[k] = [simplex_dict[k] for k in sorted(simplex_dict.keys())]\n",
+ " return rips_complexes, simplex_tree_list"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "db61c76e-cb4a-4d37-a486-f994e8a21149",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trees, simplex_tree_list = create_simplex_tree_list(tk, epsilon)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "f084bc0b-fd69-4ca7-85d7-9fc4db75fe63",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[[[0], [1], [2], [3], [4]],\n",
+ " [[0, 1],\n",
+ " [0, 2],\n",
+ " [0, 3],\n",
+ " [0, 4],\n",
+ " [1, 2],\n",
+ " [1, 3],\n",
+ " [1, 4],\n",
+ " [2, 3],\n",
+ " [2, 4],\n",
+ " [3, 4]],\n",
+ " [[0, 1, 2],\n",
+ " [0, 1, 3],\n",
+ " [0, 1, 4],\n",
+ " [0, 2, 3],\n",
+ " [0, 2, 4],\n",
+ " [0, 3, 4],\n",
+ " [1, 2, 3],\n",
+ " [1, 2, 4],\n",
+ " [1, 3, 4],\n",
+ " [2, 3, 4]],\n",
+ " [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]],\n",
+ " [[0, 1, 2, 3, 4]]]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "simplex_tree_list[0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "573efefa",
+ "metadata": {},
+ "source": [
+ "**Instruction:**\n",
+ "\n",
+ "Let $S_k$ be the set of $k$-simplicies in the complex $\\mathcal{K}$ with individual simplicies denoted by $s_k ∈ S_k$ written as $[j_0, j_1, \\dots, j_k]$ where $j_i$ is the $i$-th vertex of $s_k$. Note that the vertices are ordered in ascending fashion in the initial point cloud, and this order is kept throughout. The restricted boundary operator $\\partial_k$ is defined on the $k$-simplicies as:\n",
+ "\n",
+ "$$\n",
+ "\\begin{align*}\n",
+ "\\partial_k s_k &= \\sum_{t=0}^{k} (-1)^t [v_0, \\dots, v_{t-1}, v_{t+1}, \\dots, v_k]\\\\\n",
+ "&= \\sum_{t=0}^{k} (-1)^t s_{k-1} (t)\n",
+ "\\end{align*}\n",
+ "$$\n",
+ "\n",
+ "where $s_{k−1}(t)$ is defined as the lower simplex defined from $s_k$ by leaving out the vertex $v_t$. \n",
+ "\n",
+ "**Example:**\n",
+ "\n",
+ "In the simplex tree $\\mathcal{K}$ we have 1 2-simplex and 6 1-simplicies. By leaving out vertice $v_0=1$, $v_1=2$, $v_2=3$, we obtain the lower simplex $s_1=[2, 3]$, $s_2=[1, 3]$, $s_3=[1, 2]$, respectively. Therefore, the boundary operator on the 2-simplicies $\\partial_2$ should be a 6-by-1 matrix:\n",
+ "\n",
+ "$$\n",
+ "\\partial_2 =\n",
+ "\\begin{bmatrix}\n",
+ "1 \\\\\n",
+ "-1 \\\\\n",
+ "1 \\\\\n",
+ "0 \\\\\n",
+ "0 \\\\\n",
+ "0\n",
+ "\\end{bmatrix}\n",
+ "$$\n",
+ "\n",
+ "In the same way, the boundary operator on the 1-simplicies $\\partial_1$ is:\n",
+ "\n",
+ "$$\n",
+ "\\partial_1 =\n",
+ "\\begin{bmatrix}\n",
+ "1 & 1 & 0 & 0 & 0 & 0 \\\\\n",
+ "-1 & 0 & 1 & 0 & 0 & 0 \\\\\n",
+ "0 & -1 & -1 & 1 & 1 & 0 \\\\\n",
+ "0 & 0 & 0 & -1 & 0 & 1 \\\\\n",
+ "0 & 0 & 0 & 0 & -1 & -1\n",
+ "\\end{bmatrix}\n",
+ "$$\n",
+ "\n",
+ "**Action:**\n",
+ "\n",
+ "Define a function that generates the boundary operator for a specified dimension, using a given simplex tree as input.\n",
+ "\n",
+ "**Answer:**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "246e41ce",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "t = gudhi.RipsComplex(points=tk[-1], max_edge_length=epsilon).create_simplex_tree(max_dimension=5)\n",
+ "tree = simplex_tree_list[-1]\n",
+ "\n",
+ "def boundary_operator(tree, tree_obj, k):\n",
+ " if k <= 1: return None\n",
+ " \n",
+ " simplex_head = tree[k - 1] \n",
+ " simplex_tail = tree[k - 2]\n",
+ "\n",
+ " boundary = np.zeros([len(simplex_tail), len(simplex_head)])\n",
+ " flip_counter = 0\n",
+ "\n",
+ " for head_i in range(len(simplex_head)):\n",
+ " g = tree_obj.get_boundaries(simplex_head[head_i])\n",
+ " x = None\n",
+ " \n",
+ " try:\n",
+ " x = next(g)[0]\n",
+ " except StopIteration:\n",
+ " print(\"No simps\")\n",
+ " \n",
+ " for tail_i in range(len(simplex_tail)):\n",
+ " if simplex_tail[tail_i] == x:\n",
+ " boundary[tail_i][head_i] = (-1) ** flip_counter\n",
+ " flip_counter += 1\n",
+ "\n",
+ " if x:\n",
+ " try:\n",
+ " x = next(g)[0]\n",
+ " except StopIteration:\n",
+ " x = None\n",
+ "\n",
+ " return boundary"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "f64f25e4-a0b8-422b-8141-94c567ce302c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[ 1., 1., 0., 0., 0.],\n",
+ " [-1., 0., 1., 0., 0.],\n",
+ " [ 0., -1., -1., 0., 0.],\n",
+ " [ 1., 0., 0., 1., 0.],\n",
+ " [ 0., 1., 0., -1., 0.],\n",
+ " [ 0., 0., 1., 1., 0.],\n",
+ " [-1., 0., 0., 0., 1.],\n",
+ " [ 0., -1., 0., 0., -1.],\n",
+ " [ 0., 0., -1., 0., 1.],\n",
+ " [ 0., 0., 0., -1., -1.]])"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "x = 0\n",
+ "y = 1\n",
+ "boundary_operator(simplex_tree_list[x], trees[x], len(simplex_tree_list[x]) - y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "81764f0d",
+ "metadata": {},
+ "source": [
+ "**Instruction:**\n",
+ "\n",
+ "The combinatorial laplacian $\\Delta_k$ is defined as:\n",
+ "\n",
+ "$$\n",
+ "\\Delta_k = \\left( \\partial_k \\right)^\\dagger \\partial_k \n",
+ "+ \\partial_{k+1} \\left( \\partial_{k+1} \\right)^\\dagger\n",
+ "$$\n",
+ "\n",
+ "The QPE algorithm will be used to estimate the number of zero eigenvalues of the Laplacian matrix. Since its exponential matrix serves as the unitary matrix in this algorithm, it must have dimensions $2^q \\times 2^q$, where $q$ represents the number of target qubits. It is recommanded to pad the combinatorial laplacian $\\Delta_k$ with an identity matrix with $\\tilde{\\lambda}_{max}/2$ in place of ones, where $\\tilde{\\lambda}_{max}$ is the estimate of the maximum eigenvalue of $\\Delta_k$ using the Gershgorin circle theorem ([details](https://mathworld.wolfram.com/GershgorinCircleTheorem.html)), such that:\n",
+ "\n",
+ "$$\n",
+ "\\tilde{\\Delta}_k =\n",
+ "\\begin{bmatrix}\n",
+ "\\Delta_k & 0 \\\\\n",
+ "0 & \\frac{\\widetilde{\\lambda}_{\\text{max}}}{2} \\cdot I_{2q - |S_k|}\n",
+ "\\end{bmatrix}_{2q \\times 2q}\n",
+ "$$\n",
+ "\n",
+ "where $\\Delta_k$ is the padded combinatorial laplacian and $q = \\lceil \\log_2 |S_k| \\rceil$ is the number of qubits this operator will act on. In QPE, as $2\\pi\\theta$ increases beyond $2\\pi$, the eigenvalues will start repeating due to their periodic form. Thus, $\\theta$ is restricted to $[0, 1)$. As $\\lambda \\to 2\\pi\\theta$ this means that $λ \\in [0, 2\\pi)$. Thus, we need to restrict the eigenvalues of the combinatorial laplacian to this range. This can be achieved by rescaling $\\tilde{\\Delta}_k$ by $\\delta/\\tilde{\\lambda}_{max}$ where $\\delta$ is slightly less than $2\\pi$. Thus, the rescaled matrix $H$ and the unitary marix $U$ for QPE are:\n",
+ "\n",
+ "$$\n",
+ "\\begin{align*}\n",
+ "H &= \\frac{\\delta}{\\tilde{\\lambda}_k} \\tilde{\\Delta}_k\\\\\n",
+ "U &= e^{iH}\n",
+ "\\end{align*}\n",
+ "$$\n",
+ "\n",
+ "**Example:**\n",
+ "\n",
+ "In our example, the combinational laplacian is in the form of a $6\\times6$ matrix:\n",
+ "\n",
+ "$$\n",
+ "\\begin{align*}\n",
+ "\\Delta_1 &= (\\partial_1)^\\dagger \\partial_1 + \\partial_2 (\\partial_2)^\\dagger\\\\\n",
+ "&=\n",
+ "\\begin{bmatrix}\n",
+ "3 & 0 & 0 & 0 & 0 & 0 \\\\\n",
+ "0 & 3 & 0 & -1 & -1 & 0 \\\\\n",
+ "0 & 0 & 3 & -1 & -1 & 0 \\\\\n",
+ "0 & -1 & -1 & 2 & 1 & -1 \\\\\n",
+ "0 & -1 & -1 & 1 & 2 & 1 \\\\\n",
+ "0 & 0 & 0 & -1 & 1 & 2\n",
+ "\\end{bmatrix}\n",
+ "\\end{align*}\n",
+ "$$\n",
+ "\n",
+ "It is padded with $\\tilde{\\lambda}_{max}=6$ and $\\delta=6$ to its nearest power of 2, which is 8 ($q=3$):\n",
+ "\n",
+ "$$\n",
+ "\\begin{align}\n",
+ "H_1 = \\begin{bmatrix}\n",
+ "3 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n",
+ "0 & 3 & 0 & -1 & -1 & 0 & 0 & 0 \\\\\n",
+ "0 & 0 & 3 & -1 & -1 & 0 & 0 & 0 \\\\\n",
+ "0 & -1 & -1 & 2 & 1 & -1 & 0 & 0 \\\\\n",
+ "0 & -1 & -1 & 1 & 2 & 1 & 0 & 0 \\\\\n",
+ "0 & 0 & 0 & -1 & 1 & 2 & 0 & 0 \\\\\n",
+ "0 & 0 & 0 & 0 & 0 & 0 & 3 & 0 \\\\\n",
+ "0 & 0 & 0 & 0 & 0 & 0 & 0 & 3\n",
+ "\\end{bmatrix}\n",
+ "\\end{align}\n",
+ "$$\n",
+ "\n",
+ "**Action:**\n",
+ "\n",
+ "Define a function to build the Laplacian, where Define a function that automatically determines whether the input Laplacian matrix requires padding. If padding is needed, the function will pad and rescale the matrix accordingly. Then, build the unitary based on the padded matrix, in the form of a circuit.\n",
+ "\n",
+ "**Answer:**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "8f818f78",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# write your code here"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0acfea73",
+ "metadata": {},
+ "source": [
+ "### Step 3: Applying QPE\n",
+ "\n",
+ "**Instruction:**\n",
+ "\n",
+ "The Betti number is the number of zero eigenvalues in the Laplacian ([ref](https://link.springer.com/article/10.1007/PL00009218)). \n",
+ "\n",
+ "$$\n",
+ "\\beta_k = \\dim (\\ker(\\Delta_k))\n",
+ "$$\n",
+ "\n",
+ "The betti curve is then a series of Betti numbers on different resolution threshold `epsilon`.\n",
+ "\n",
+ "To estimate the number of zero eigenvalues (nullity) in the padded Laplacian matrix (padding didn't add more zero eigenvalues), QPE algorithm is employed. The fundamental concept is that, if the target qubits start out in the maximally mixed state (shown below), which can be thought of as a random choice of an eigenstate, the proportion of all-zero states among all measured states is equal to the proportion of zero eigenvalues among all eigenvalues. Assume the all-zero state show up for $\\{i|\\tilde{\\theta}_i=0\\}$ times in $\\alpha$ shots, the probability of getting all-zero state $p(0)$ is given by:\n",
+ "\n",
+ "$$\n",
+ "\\begin{align*}\n",
+ "p(0) &= \\frac{\\left| \\{i \\mid \\tilde{\\theta}_i = 0\\} \\right|}{\\alpha} = \\frac{\\tilde{\\beta}_k}{2^q} \\\\\n",
+ "\\implies \\tilde{\\beta}_k &= 2^q \\cdot p(0)\n",
+ "\\end{align*}\n",
+ "$$\n",
+ "\n",
+ "Where $\\tilde{\\beta}_k$ is the estimation of $k$-th Betti number. This estimation is then rounded to the nearest integer to obtain the final result."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fc95fe90",
+ "metadata": {},
+ "source": [
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "72511671",
+ "metadata": {},
+ "source": [
+ "For your reference, the tutorial of QPE in several major quantum computing libraries are listed below:\n",
+ "\n",
+ "* [Qiskit](https://github.com/qiskit-community/qiskit-textbook/blob/main/content/ch-algorithms/quantum-phase-estimation.ipynb)\n",
+ "* [Pennylane](https://pennylane.ai/qml/demos/tutorial_qpe)\n",
+ "* [CUDA-Q](https://nvidia.github.io/cuda-quantum/latest/specification/cudaq/examples.html#quantum-phase-estimation:~:text=Quantum%20Phase%20Estimation-,%C2%B6,-C%2B%2B)\n",
+ "* [Cirq](https://quantumai.google/cirq/experiments/textbook_algorithms#phase_estimation)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "481e000c",
+ "metadata": {},
+ "source": [
+ "**Example:**\n",
+ "\n",
+ "In our example, the probability of measuring all-zero states is approximately $p(0)=0.137 = \\tilde{\\beta}_k / 2^3 \\implies \\tilde{\\beta}_k = 1.096$, which is then rounded to $1$.\n",
+ "\n",
+ "**Action:**\n",
+ "\n",
+ "Utilize your preferred quantum computing library to apply QPE for estimating the number of zero eigenvalues in the Laplacian matrix. Note that the exponential of the Laplacian matrix is used as the unitary operator in QPE.\n",
+ "\n",
+ "**Answer:**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "id": "848ef40c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit import QuantumCircuit, ClassicalRegister\n",
+ "from qiskit.circuit.library import UnitaryGate, QFT\n",
+ "from scipy.linalg import expm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "816fd6cf-df5e-4bda-a9d5-12b64faf2123",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "H1 = np.array([\n",
+ " [3, 0, 0, 0, 0, 0, 0, 0],\n",
+ " [0, 3, 0, -1, -1, 0, 0, 0],\n",
+ " [0, 0, 3, -1, -1, 0, 0, 0],\n",
+ " [0, -1, -1, 2, 1, -1, 0, 0],\n",
+ " [0, -1, -1, 1, 2, 1, 0, 0],\n",
+ " [0, 0, 0, -1, 1, 2, 0, 0],\n",
+ " [0, 0, 0, 0, 0, 0, 3, 0],\n",
+ " [0, 0, 0, 0, 0, 0, 0, 3]\n",
+ "])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "023e191c-0553-47a5-8730-d21b0ea2b84c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def quantum_phase_estimator(L):\n",
+ " # take e^iL\n",
+ " U = expm(1j * L)\n",
+ " return U"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "e6a3622e-5b6b-4a2f-ae9b-2ffc828f68d1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "U = quantum_phase_estimator(H1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "id": "6db1e94c-c74b-4cc4-81d2-a458bb4e193f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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nFZaWqpVq1ZJOtE/yaWXXurVNs4U6H++/qVLl6qqqkorVqzQNddc43Z97du35049AKBOQWZz9c8OHTrUGg507H/t/W1qn4G3uTEgQ/3w4cOVnZ2t2bNna8SIEdW9Jq9fv16TJk2SzXais7O0tLQayzmdThUXF+vNN9/UddddJ0m6/PLLtW3bNv35z3/2OtR704QC7tntTsVc+IbKyh1up7trMv9z+5bfpIRzImW1lanjiHc83v7Qi3pp+Uv5Hi/XVCQMX6j9B0sVHxev/B+Mux9ng8+gfux2uxYvXux22vbt26vD88UXX6ywsDCP11+fQH/S8OHDtXTpUknSf/7znzpDfU5OjiyWgPxvDQDQAJ54foGKiktOXAPk59caDnTsf+39DZTPICB7v09PT1ebNm20b98+9erVS3369FG3bt00aNAgJSUladiwYZJq93zfunVrSaoR3k0mk4YPH64ffvih8XYAdbJYgpTWvY3ftt8/NdZv2waaij179lT/vWfPnh4v70mgl6QOHTooOjq6etsul8uLqgEAAAJTQIb6hIQErVy5Utdcc43CwsKUl5en1q1ba/78+VqyZIlycnIk1Q71vXr1qnOd5eXlPq0Z9Tegl/+CNaEekHbv3l3996SkJI+W9TTQSyd+uXpyO0VFRTp8mLdQAAAAnBSQoV46cffo008/1fHjx3X8+HGtW7dOd955p0pKSpSXl6egoCD17t27xjLXXnutJNV4H7LT6dTy5cs1cODARq0fdRs3vItfthsVEawrL/T/szaAvx09elTSibDdrl27ei/nTaA/KT4+vtb2AQAAEKDP1J9OVlaWXC6XUlJSFBFR89Vno0eP1iWXXKI777xThw8fVqdOnfTyyy8rKyurRk/P8K9L+sepV9eWyso91qjbnTSqq2Ki6u48DGguhg8frsOHD8vhcCgoqP6/G/7oo4+8CvTSiY5Nw8LCFBISolatWnlVNwAAQCBqdqF+69atkmo3vZdO3HX6+OOPNWPGDD300EMqKipSv3799Nlnn1U/hw//M5lMuu+mVN371zWNut17xnv+7DAQiLz9Prz22muVk5OjnJwcjwK9JJ133nk677zzvNouAABAICPUn6Jly5aaP3++5s+f35hlwUO//kV3/XPxDn2/vXGerb33xp7qk9K6UbYFBKqQkBBNnz5d+/fvV2Jior/LAQAA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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 48,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "qc = QuantumCircuit(9)\n",
+ "qc.h(3)\n",
+ "qc.h(4)\n",
+ "qc.h(5)\n",
+ "qc.cx(3, 6)\n",
+ "qc.cx(4, 7)\n",
+ "qc.cx(5, 8)\n",
+ "qc.h(0)\n",
+ "qc.h(1)\n",
+ "qc.h(2)\n",
+ "U_power = np.linalg.matrix_power(U, 0)\n",
+ "unitary_gate = UnitaryGate(U_power)\n",
+ "qc.append(unitary_gate.control(1), [0, 3, 4, 5])\n",
+ "U_power = np.linalg.matrix_power(U, 1)\n",
+ "unitary_gate = UnitaryGate(U_power)\n",
+ "qc.append(unitary_gate.control(1), [1, 3, 4, 5])\n",
+ "U_power = np.linalg.matrix_power(U, 2)\n",
+ "unitary_gate = UnitaryGate(U_power)\n",
+ "qc.append(unitary_gate.control(1), [2, 3, 4, 5])\n",
+ "qc.append(QFT(3, do_swaps=False).inverse(), [0, 1, 2])\n",
+ "qc.add_register(ClassicalRegister(6))\n",
+ "qc.measure([0, 1, 2, 6, 7, 8], [0, 1, 2, 3, 4, 5])\n",
+ "qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "id": "798b076a-d5af-4fc2-b9d9-3517c8ea0bd3",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "NameError",
+ "evalue": "name 'Aer' is not defined",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn[49], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m aer_sim \u001b[38;5;241m=\u001b[39m \u001b[43mAer\u001b[49m\u001b[38;5;241m.\u001b[39mget_backend(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124maer_simulator\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 2\u001b[0m shots \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2048\u001b[39m\n\u001b[1;32m 3\u001b[0m t_qc \u001b[38;5;241m=\u001b[39m transpile(qc, aer_sim)\n",
+ "\u001b[0;31mNameError\u001b[0m: name 'Aer' is not defined"
+ ]
+ }
+ ],
+ "source": [
+ "aer_sim = Aer.get_backend('aer_simulator')\n",
+ "shots = 2048\n",
+ "t_qc = transpile(qc, aer_sim)\n",
+ "qobj = assemble(t_qc, shots=shots)\n",
+ "results = aer_sim.run(qobj).result()\n",
+ "answer = results.get_counts()\n",
+ "\n",
+ "plot_histogram(answer)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f8724ca3",
+ "metadata": {},
+ "source": [
+ "
NOTE:\n",
+ "\n",
+ "The unitary operator can be constructed by converting the exponential matrix of the Laplacian into a quantum circuit. For instance, in Qiskit, this can be implemented using `circuit.unitary(exp_matrix)`. Alternative methods for constructing the unitary operator will be optionally explored in the **BONUS** section at the end of this notebook.\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "BONUS EXERCISE: \n",
+ "\n",
+ "1. Why we should measure all-zero states?\n",
+ "2. What is the difference between a maximally mixed state and the $(H\\ket{0})^{\\otimes n}$ state? Two possible aspects are:\n",
+ "\n",
+ "* Plotting of their density matrix.\n",
+ "* Results from QPE.\n",
+ "\n",
+ "3. What parameters affect the accuracy of the estimation before rounding? For Laplacian matrices of varying sizes, how does the accuracy depend on these parameters? Within what range of values do these parameters guarantee (or are highly likely to produce) a correct final result?\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1cbe5cf2",
+ "metadata": {},
+ "source": [
+ "### Step 4: Detecting market crashes"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7f27e81b",
+ "metadata": {},
+ "source": [
+ "**Instruction:**\n",
+ "\n",
+ "At this point, we have betti curves for each window across our dataset, and we wish to use this to detect market crashes. One such way is to take the difference between these curves—or the pairwise distance—for successive windows and look for spikes. This can be done with the $L^p$ norm of the betti curve for each window, defined as follows:\n",
+ "\n",
+ "$$||x||_p = (\\sum_{n}^{i=1} |x_i|^p)^{1/p}$$\n",
+ "\n",
+ "Combining these pairwise distances into a vector, we get a single output curve we can analyze. Experiment with different values of $p$, but a good starting point is the $L^2$ Norm. Using this, it is possible to detect regions where a market crash is occuring. Comparing detected crashes with the price data indicates how accurate the crash detection methodology is ([ref](https://github.com/giotto-ai/stock-market-crashes/blob/master/Stock%20Market%20Crash%20Detection.ipynb)). \n",
+ "\n",
+ "**Action:**\n",
+ "\n",
+ "Use the $L^p$ norm to create pairwise distance curves for successive windows, and then use the results to define when a crash is occuring. Compare this with your data to see how well it performs. You may find the following classical solver is useful.\n",
+ "\n",
+ "**Answer:**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "5ef68f98",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ripser import ripser\n",
+ "\n",
+ "def classical_betti_solver(point_cloud, epsilon, dim):\n",
+ " '''Return the Betti number on a given point cloud.\n",
+ " Args:\n",
+ " point_cloud: the point cloud after applying the sliding window.\n",
+ " epsilon: resolution threshold.\n",
+ " dim: the dimension on which the Betti number is calculated\n",
+ " '''\n",
+ " result = ripser(point_cloud, maxdim=dim)\n",
+ " diagrams = result[\"dgms\"]\n",
+ " return len(\n",
+ " [interval for interval in diagrams[dim] if interval[0] < epsilon < interval[1]]\n",
+ " )\n",
+ "\n",
+ "# write your code here"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d1c2e4b5",
+ "metadata": {},
+ "source": [
+ "## *BONUS:* Explore future directions of quantum TDA\n",
+ "\n",
+ "The following is a non-exhaustive list of possible next steps for the quantum TDA pipeline. It is recommended to at least explore 1 option or sub-option.\n",
+ "\n",
+ "- **Find more of applications of TDA in finance**:\n",
+ "\n",
+ " There are several directions where to extend the analysis. Most work on time series analysis has used persistent homology, and more specifically, the $L^{P}$ norm of persistence landscapes, which can be used to detect early warning signals of imminent market crashes. This is precisely studied in the seminal work by Gidea and Katz, see [ref](https://arxiv.org/abs/1703.04385)\n",
+ " - Analyze financial correlation network and their degree of association with Betti curves or other topological features. From the time-series of multiple stock prices, we can build time-dependent correlation networks, which exhibit topological structures and might show some association to the evolution of betti curves or other topological data measures. Generally speaking, the cross correlations in a stock market will be in the form of a high-dimension topological space, with more complicated features. One can also think about other time varying financial graphs (e.g. cryptocurrencies). The following articles can help uncover more applications: \n",
+ " \n",
+ " - [Integral Betti signature confirms the hyperbolic geometry of brain, climate,and financial networks](https://www.arxiv.org/pdf/2406.15505)\n",
+ " - [Using Topological Data Analysis (TDA) and Persistent Homology to Analyze the Stock Markets in Singapore and Taiwan](https://www.frontiersin.org/journals/physics/articles/10.3389/fphy.2021.572216/full)\n",
+ " - Build a ML classifier or regressor on top of vectorized features such as Betti Curves (given their potential to identify trends, patterns or potential turning points in the market) to help with investment or risk management strategies. Show that Betti curves have some predictive skill, as key topological descriptors. See [ref1](https://arxiv.org/abs/2411.13881) and [ref2](https://www.sciencedirect.com/science/article/pii/S2405918823000235) for further information on the topic.\n",
+ "- **A hybrid and more NISQ-friendly quantum TDA pipeline**:\n",
+ " \n",
+ " QPE remains primarily theoretical. Its circuits are simply too deep to run on real hardware. Come up an with iterative or hybrid quantum phase estimation protocol or use tools that increase the algorithmic performance when running quantum circuits on real hardware. Benchmark them against textbook-QPE circuits. Here are some proposals to subtitute the QPE part:\n",
+ " - Variational Quantum Deflation (VQD) Algorithm: VQD is a quantum algorithm that uses a variational technique to find the k eigenvalues of the Hamiltonian H of a given system. [ref](https://quantum-journal.org/papers/q-2019-07-01-156/)\n",
+ " - Variational Quantum Eigensolver (VQE): Using VQE to determine the spectra of adjancency or laplacian matrix. Inspired by: [ref](https://arxiv.org/pdf/1912.12366)\n",
+ " \n",
+ " Finally, run some circuits on simulator + real hardware and compare the performance (runtime, noise effects, # resources) of the new proposal to the QPE solution of the above sections.\n",
+ "\n",
+ "- **A proper procedure of encoding the Laplacian matrix to the unitary**:\n",
+ "\n",
+ " In Step 3, encoding the exponential matrix is recommanded. An alternative approach is to conduct the Paulis decomposition on the Laplacian, then followed by Trotterization. Can you implement this approach in your pipeline? What parameters influence the accuracy? Can you optimize your code to minimize the circuit depth?\n",
+ "\n",
+ "- **Extend the quantum TDA to extract persistent Betti numbers**: \n",
+ " \n",
+ " Implement a quantum TDA algorithm for persistent Betti numbers. Esstimating the persistent Betti numbers is a more general task than estimating the Betti number and it is more practical for TDA. It is an open problem to construct a quantum algorithm for the persistent Betti numbers in a way that is preferable for NISQ devices, and the only current implementation of a quantum algorithm for persistent betti number is shown [here](https://quantum-journal.org/papers/q-2022-12-07-873/pdf/)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "0de4a8f2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# write your code here"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c098599c-7ab0-48b1-9e33-51d22502310d",
+ "metadata": {},
+ "source": [
+ "# This is the end of the challenge. Good luck!"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 [moodys]",
+ "language": "python",
+ "name": "python3_moodys_yhl12u"
+ },
+ "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.11.9"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/.ipynb_checkpoints/sp500-checkpoint.csv b/.ipynb_checkpoints/sp500-checkpoint.csv
new file mode 100644
index 0000000..a958c1c
--- /dev/null
+++ b/.ipynb_checkpoints/sp500-checkpoint.csv
@@ -0,0 +1,83 @@
+1253.755
+1269.825
+1284.185
+1274.11
+1279.99
+1300.9025
+1295.175
+1284.985
+1286.2175
+1296.37
+1288.3275
+1269.1575
+1270.7875
+1272.62
+1286.45
+1276.7225
+1269.38
+1277.33
+1293.2875
+1289.245
+1287.7875
+1274.05
+1251.88
+1233.35
+1265.9375
+1245.7725
+1233.3775
+1231.3775
+1244.8425
+1212.37
+1191.7475
+1178.125
+1182.3375
+1249.6075
+1228.485
+1201.7175
+1187.6325
+1201.2375
+1200.965
+1152.5775
+1145.7925
+1155.89
+1134.3
+1119.885
+1057.0025
+1033.425
+985.7825
+955.645
+885.4275
+966.9125
+1016.02
+945.4125
+918.0025
+941.66
+967.3075
+966
+913.97
+898.3725
+869.6925
+862.42
+899.8525
+939.895
+950.9775
+962.6375
+967.2325
+993.3625
+973.925
+924.9375
+921.005
+932.0925
+901.625
+869.08
+875.0125
+887.8075
+861.0275
+850.2925
+833.7525
+779.1075
+776.425
+834.205
+857.45
+864.3525
+889.2825
\ No newline at end of file
diff --git a/assets/.ipynb_checkpoints/Screenshot 2025-01-30 at 22.17.47-checkpoint.png b/assets/.ipynb_checkpoints/Screenshot 2025-01-30 at 22.17.47-checkpoint.png
new file mode 100644
index 0000000..ff5060f
Binary files /dev/null and b/assets/.ipynb_checkpoints/Screenshot 2025-01-30 at 22.17.47-checkpoint.png differ
diff --git a/moodys_challenge.ipynb b/moodys_challenge.ipynb
index 7ee0e87..6b04a65 100644
--- a/moodys_challenge.ipynb
+++ b/moodys_challenge.ipynb
@@ -161,15 +161,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "4ec880cd",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
"\n",
- "time_series = np.log(pd.read_csv(\"SP500.csv\", header=None).to_numpy().squeeze())"
+ "time_series = np.log(pd.read_csv(\"sp500.csv\", header=None).to_numpy().squeeze())"
]
},
{
@@ -209,12 +210,108 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "7b701be6",
"metadata": {},
"outputs": [],
"source": [
- "# write your code here"
+ "N = 4 # dimension of vectors\n",
+ "d = 5 # time delay\n",
+ "w = 5 # window size\n",
+ "epsilon = 0.1 # resolution threshold\n",
+ "q = 3 # number of precision qubits"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "f2c20448-d9f6-4c2b-8b1d-9303e7531b0c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def takens_embedding(X, N, d, w):\n",
+ " # check validity of inputs\n",
+ " L = len(X)\n",
+ " \n",
+ " if L < w:\n",
+ " raise Exception(\"input error\")\n",
+ " if w < N:\n",
+ " raise Exception(\"input error\")\n",
+ " \n",
+ " T = int(L - (N-1) * d)\n",
+ " z = np.zeros([T, N])\n",
+ "\n",
+ " # \n",
+ " for i in range(T):\n",
+ " t = i\n",
+ " for j in range(N):\n",
+ " z[i, j] = X[t]\n",
+ " t += d\n",
+ " \n",
+ " K = L - (N - 1)*d - w + 1\n",
+ " \n",
+ " Z = np.zeros([K, w, N])\n",
+ " \n",
+ " for t in range(K):\n",
+ " for j in range(w):\n",
+ " Z[t, j, :] = z[t + j, :]\n",
+ " \n",
+ " return z, Z"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "d2723255-2166-40f8-9906-f971a03c1950",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[[[7.13389833 7.17081353 7.16110014 7.15205153]\n",
+ " [7.14663437 7.1664011 7.14610857 7.14628387]\n",
+ " [7.15787955 7.15850232 7.14739207 7.15252724]\n",
+ " [7.15000317 7.15946102 7.14883305 7.16494271]\n",
+ " [7.15460754 7.16732333 7.15964177 7.16181205]]\n",
+ "\n",
+ " [[7.14663437 7.1664011 7.14610857 7.14628387]\n",
+ " [7.15787955 7.15850232 7.14739207 7.15252724]\n",
+ " [7.15000317 7.15946102 7.14883305 7.16494271]\n",
+ " [7.15460754 7.16732333 7.15964177 7.16181205]\n",
+ " [7.17081353 7.16110014 7.15205153 7.16068091]]\n",
+ "\n",
+ " [[7.15787955 7.15850232 7.14739207 7.15252724]\n",
+ " [7.15000317 7.15946102 7.14883305 7.16494271]\n",
+ " [7.15460754 7.16732333 7.15964177 7.16181205]\n",
+ " [7.17081353 7.16110014 7.15205153 7.16068091]\n",
+ " [7.1664011 7.14610857 7.14628387 7.14995608]]\n",
+ "\n",
+ " ...\n",
+ "\n",
+ " [[6.84576817 6.8813343 6.76743518 6.7259366 ]\n",
+ " [6.8574904 6.82972617 6.77423817 6.65814903]\n",
+ " [6.86967691 6.82546547 6.78875494 6.65470005]\n",
+ " [6.8744389 6.83743206 6.75812644 6.72647918]\n",
+ " [6.90109565 6.80419869 6.74558041 6.75396287]]\n",
+ "\n",
+ " [[6.8574904 6.82972617 6.77423817 6.65814903]\n",
+ " [6.86967691 6.82546547 6.78875494 6.65470005]\n",
+ " [6.8744389 6.83743206 6.75812644 6.72647918]\n",
+ " [6.90109565 6.80419869 6.74558041 6.75396287]\n",
+ " [6.8813343 6.76743518 6.7259366 6.76198067]]\n",
+ "\n",
+ " [[6.86967691 6.82546547 6.78875494 6.65470005]\n",
+ " [6.8744389 6.83743206 6.75812644 6.72647918]\n",
+ " [6.90109565 6.80419869 6.74558041 6.75396287]\n",
+ " [6.8813343 6.76743518 6.7259366 6.76198067]\n",
+ " [6.82972617 6.77423817 6.65814903 6.79041496]]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "c, tk = takens_embedding(time_series, N, d, w)\n",
+ "print(tk)"
]
},
{
@@ -273,12 +370,91 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"id": "026d6b61",
"metadata": {},
"outputs": [],
"source": [
- "# write your code here"
+ "import gudhi\n",
+ "from collections import defaultdict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "c587cb06-56e7-4cc2-9df6-e1a72e4e5937",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def create_simplex_tree_list(tk, epsilon):\n",
+ " K = len(tk)\n",
+ " simplex_tree_list = [None] * K\n",
+ " rips_complexes = []\n",
+ " \n",
+ " for k in range(K):\n",
+ " rips_complex = gudhi.RipsComplex(points=tk[k], max_edge_length=epsilon).create_simplex_tree(max_dimension=5)\n",
+ " rips_complexes.append(rips_complex)\n",
+ " # Initialize a dictionary to store simplices by their sizes\n",
+ " simplex_dict = defaultdict(list)\n",
+ " # Extract simplices and group them by size\n",
+ " for simplex, _ in rips_complex.get_simplices():\n",
+ " simplex_dict[len(simplex)].append(list(simplex))\n",
+ " # Convert dictionary to a sorted list of lists\n",
+ " simplex_tree_list[k] = [simplex_dict[k] for k in sorted(simplex_dict.keys())]\n",
+ " return rips_complexes, simplex_tree_list"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "db61c76e-cb4a-4d37-a486-f994e8a21149",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "trees, simplex_tree_list = create_simplex_tree_list(tk, epsilon)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "f084bc0b-fd69-4ca7-85d7-9fc4db75fe63",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[[[0], [1], [2], [3], [4]],\n",
+ " [[0, 1],\n",
+ " [0, 2],\n",
+ " [0, 3],\n",
+ " [0, 4],\n",
+ " [1, 2],\n",
+ " [1, 3],\n",
+ " [1, 4],\n",
+ " [2, 3],\n",
+ " [2, 4],\n",
+ " [3, 4]],\n",
+ " [[0, 1, 2],\n",
+ " [0, 1, 3],\n",
+ " [0, 1, 4],\n",
+ " [0, 2, 3],\n",
+ " [0, 2, 4],\n",
+ " [0, 3, 4],\n",
+ " [1, 2, 3],\n",
+ " [1, 2, 4],\n",
+ " [1, 3, 4],\n",
+ " [2, 3, 4]],\n",
+ " [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4], [1, 2, 3, 4]],\n",
+ " [[0, 1, 2, 3, 4]]]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "simplex_tree_list[0]"
]
},
{
@@ -337,12 +513,73 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 9,
"id": "246e41ce",
"metadata": {},
"outputs": [],
"source": [
- "# write your code here"
+ "def boundary_operator(tree, tree_obj, k):\n",
+ " if k <= 1: return None\n",
+ " \n",
+ " simplex_head = tree[k - 1] \n",
+ " simplex_tail = tree[k - 2]\n",
+ "\n",
+ " boundary = np.zeros([len(simplex_tail), len(simplex_head)])\n",
+ " flip_counter = 0\n",
+ "\n",
+ " for head_i in range(len(simplex_head)):\n",
+ " g = tree_obj.get_boundaries(simplex_head[head_i])\n",
+ " x = None\n",
+ " \n",
+ " try:\n",
+ " x = next(g)[0]\n",
+ " except StopIteration:\n",
+ " print(\"No simps\")\n",
+ " \n",
+ " for tail_i in range(len(simplex_tail)):\n",
+ " if simplex_tail[tail_i] == x:\n",
+ " boundary[tail_i][head_i] = (-1) ** flip_counter\n",
+ " flip_counter += 1\n",
+ "\n",
+ " if x:\n",
+ " try:\n",
+ " x = next(g)[0]\n",
+ " except StopIteration:\n",
+ " x = None\n",
+ "\n",
+ " return boundary"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "f64f25e4-a0b8-422b-8141-94c567ce302c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[ 1., 1., 0., 0., 0.],\n",
+ " [-1., 0., 1., 0., 0.],\n",
+ " [ 0., -1., -1., 0., 0.],\n",
+ " [ 1., 0., 0., 1., 0.],\n",
+ " [ 0., 1., 0., -1., 0.],\n",
+ " [ 0., 0., 1., 1., 0.],\n",
+ " [-1., 0., 0., 0., 1.],\n",
+ " [ 0., -1., 0., 0., -1.],\n",
+ " [ 0., 0., -1., 0., 1.],\n",
+ " [ 0., 0., 0., -1., -1.]])"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "x = 0\n",
+ "y = 1\n",
+ "boundary_operator(simplex_tree_list[x], trees[x], len(simplex_tree_list[x]) - y)"
]
},
{
@@ -423,12 +660,95 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 11,
"id": "8f818f78",
"metadata": {},
"outputs": [],
"source": [
- "# write your code here"
+ "import scipy.linalg as la\n",
+ "\n",
+ "def gershgorin_max_eigenvalue(A):\n",
+ " n = A.shape[0]\n",
+ " max_estimate = float('-inf')\n",
+ " \n",
+ " for i in range(n):\n",
+ " center = A[i, i]\n",
+ " radius = sum(abs(A[i, j]) for j in range(n) if j != i)\n",
+ " max_estimate = max(max_estimate, center + radius)\n",
+ " \n",
+ " return max_estimate\n",
+ "\n",
+ "\n",
+ "def unitary(x, y):\n",
+ " k = len(simplex_tree_list[x]) - y\n",
+ " delta = 6\n",
+ "\n",
+ " Laplacian = boundary_operator(simplex_tree_list[x], trees[x], k).T @ boundary_operator(simplex_tree_list[x], trees[x], k) + \\\n",
+ " boundary_operator(simplex_tree_list[x], trees[x], k + 1) @ boundary_operator(simplex_tree_list[x], trees[x], k + 1).T\n",
+ "\n",
+ " lambda_max = gershgorin_max_eigenvalue(Laplacian)\n",
+ " \n",
+ " if Laplacian.shape[0] == 2 ** q:\n",
+ " Padded_Laplacian = Laplacian\n",
+ " else:\n",
+ " zeros = np.zeros((2 ** q, 2 ** q))\n",
+ " Padded_Laplacian= la.block_diag(Laplacian, lambda_max /2 * np.identity(2 ** q - Laplacian.shape[0]))\n",
+ "\n",
+ " H = Padded_Laplacian * delta / lambda_max\n",
+ "\n",
+ " return la.expm(1j * H)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "69fcde0a-1cd8-4c9a-a4e9-82ab0168f3d2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[ 0.2109614 +0.30608853j, 0.09392841+0.65893153j,\n",
+ " 0.06493486+0.45553447j, -0.02899355-0.20339706j,\n",
+ " 0.37438239-0.15713191j, 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ],\n",
+ " [ 0.09392841+0.65893153j, -0.35535612-0.3981572j ,\n",
+ " 0.47238911+0.0453142j , -0.06901318+0.00095095j,\n",
+ " -0.02899355-0.20339706j, 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ],\n",
+ " [ 0.06493486+0.45553447j, 0.47238911+0.0453142j ,\n",
+ " 0.04801981-0.35189205j, 0.47238911+0.0453142j ,\n",
+ " 0.06493486+0.45553447j, 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ],\n",
+ " [-0.02899355-0.20339706j, -0.06901318+0.00095095j,\n",
+ " 0.47238911+0.0453142j , -0.35535612-0.3981572j ,\n",
+ " 0.09392841+0.65893153j, 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ],\n",
+ " [ 0.37438239-0.15713191j, -0.02899355-0.20339706j,\n",
+ " 0.06493486+0.45553447j, 0.09392841+0.65893153j,\n",
+ " 0.2109614 +0.30608853j, 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ],\n",
+ " [ 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , -0.9899925 +0.14112001j,\n",
+ " 0. +0.j , 0. +0.j ],\n",
+ " [ 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ,\n",
+ " -0.9899925 +0.14112001j, 0. +0.j ],\n",
+ " [ 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , 0. +0.j ,\n",
+ " 0. +0.j , -0.9899925 +0.14112001j]])"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "unitary(-1,1)"
]
},
{
@@ -499,12 +819,162 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 13,
"id": "848ef40c",
"metadata": {},
"outputs": [],
"source": [
- "# write your code here"
+ "from qiskit import QuantumCircuit, ClassicalRegister\n",
+ "from qiskit.circuit.library import UnitaryGate, QFT\n",
+ "from scipy.linalg import expm"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "816fd6cf-df5e-4bda-a9d5-12b64faf2123",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "H1 = np.array([\n",
+ " [3, 0, 0, 0, 0, 0, 0, 0],\n",
+ " [0, 3, 0, -1, -1, 0, 0, 0],\n",
+ " [0, 0, 3, -1, -1, 0, 0, 0],\n",
+ " [0, -1, -1, 2, 1, -1, 0, 0],\n",
+ " [0, -1, -1, 1, 2, 1, 0, 0],\n",
+ " [0, 0, 0, -1, 1, 2, 0, 0],\n",
+ " [0, 0, 0, 0, 0, 0, 3, 0],\n",
+ " [0, 0, 0, 0, 0, 0, 0, 3]\n",
+ "])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "023e191c-0553-47a5-8730-d21b0ea2b84c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def quantum_phase_estimator(L):\n",
+ " # take e^iL\n",
+ " U = expm(1j * L)\n",
+ " return U"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "e6a3622e-5b6b-4a2f-ae9b-2ffc828f68d1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "U = quantum_phase_estimator(H1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "id": "6db1e94c-c74b-4cc4-81d2-a458bb4e193f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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nFZaWqpVq1ZJOtE/yaWXXurVNs4U6H++/qVLl6qqqkorVqzQNddc43Z97du35049AKBOQWZz9c8OHTrUGg507H/t/W1qn4G3uTEgQ/3w4cOVnZ2t2bNna8SIEdW9Jq9fv16TJk2SzXais7O0tLQayzmdThUXF+vNN9/UddddJ0m6/PLLtW3bNv35z3/2OtR704QC7tntTsVc+IbKyh1up7trMv9z+5bfpIRzImW1lanjiHc83v7Qi3pp+Uv5Hi/XVCQMX6j9B0sVHxev/B+Mux9ng8+gfux2uxYvXux22vbt26vD88UXX6ywsDCP11+fQH/S8OHDtXTpUknSf/7znzpDfU5OjiyWgPxvDQDQAJ54foGKiktOXAPk59caDnTsf+39DZTPICB7v09PT1ebNm20b98+9erVS3369FG3bt00aNAgJSUladiwYZJq93zfunVrSaoR3k0mk4YPH64ffvih8XYAdbJYgpTWvY3ftt8/NdZv2waaij179lT/vWfPnh4v70mgl6QOHTooOjq6etsul8uLqgEAAAJTQIb6hIQErVy5Utdcc43CwsKUl5en1q1ba/78+VqyZIlycnIk1Q71vXr1qnOd5eXlPq0Z9Tegl/+CNaEekHbv3l3996SkJI+W9TTQSyd+uXpyO0VFRTp8mLdQAAAAnBSQoV46cffo008/1fHjx3X8+HGtW7dOd955p0pKSpSXl6egoCD17t27xjLXXnutJNV4H7LT6dTy5cs1cODARq0fdRs3vItfthsVEawrL/T/szaAvx09elTSibDdrl27ei/nTaA/KT4+vtb2AQAAEKDP1J9OVlaWXC6XUlJSFBFR89Vno0eP1iWXXKI777xThw8fVqdOnfTyyy8rKyurRk/P8K9L+sepV9eWyso91qjbnTSqq2Ki6u48DGguhg8frsOHD8vhcCgoqP6/G/7oo4+8CvTSiY5Nw8LCFBISolatWnlVNwAAQCBqdqF+69atkmo3vZdO3HX6+OOPNWPGDD300EMqKipSv3799Nlnn1U/hw//M5lMuu+mVN371zWNut17xnv+7DAQiLz9Prz22muVk5OjnJwcjwK9JJ133nk677zzvNouAABAICPUn6Jly5aaP3++5s+f35hlwUO//kV3/XPxDn2/vXGerb33xp7qk9K6UbYFBKqQkBBNnz5d+/fvV2Jior/LAQAA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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 48,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "qc = QuantumCircuit(9)\n",
+ "qc.h(3)\n",
+ "qc.h(4)\n",
+ "qc.h(5)\n",
+ "qc.cx(3, 6)\n",
+ "qc.cx(4, 7)\n",
+ "qc.cx(5, 8)\n",
+ "qc.h(0)\n",
+ "qc.h(1)\n",
+ "qc.h(2)\n",
+ "U_power = np.linalg.matrix_power(U, 0)\n",
+ "unitary_gate = UnitaryGate(U_power)\n",
+ "qc.append(unitary_gate.control(1), [0, 3, 4, 5])\n",
+ "U_power = np.linalg.matrix_power(U, 1)\n",
+ "unitary_gate = UnitaryGate(U_power)\n",
+ "qc.append(unitary_gate.control(1), [1, 3, 4, 5])\n",
+ "U_power = np.linalg.matrix_power(U, 2)\n",
+ "unitary_gate = UnitaryGate(U_power)\n",
+ "qc.append(unitary_gate.control(1), [2, 3, 4, 5])\n",
+ "qc.append(QFT(3, do_swaps=False).inverse(), [0, 1, 2])\n",
+ "qc.add_register(ClassicalRegister(6))\n",
+ "qc.measure([0, 1, 2, 6, 7, 8], [0, 1, 2, 3, 4, 5])\n",
+ "qc.draw(\"mpl\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "id": "9cd197f6-6382-49ca-b054-b6a6021f5719",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from qiskit import transpile\n",
+ "import qiskit_aer"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 58,
+ "id": "798b076a-d5af-4fc2-b9d9-3517c8ea0bd3",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'001010': 25,\n",
+ " '100110': 24,\n",
+ " '011000': 64,\n",
+ " '011010': 17,\n",
+ " '101010': 40,\n",
+ " '001100': 29,\n",
+ " '111010': 43,\n",
+ " '011110': 23,\n",
+ " '000010': 50,\n",
+ " '010000': 8,\n",
+ " '101110': 57,\n",
+ " '001000': 7,\n",
+ " '000110': 68,\n",
+ " '100000': 39,\n",
+ " '101000': 47,\n",
+ " '010100': 32,\n",
+ " '110110': 67,\n",
+ " '100100': 52,\n",
+ " '001110': 44,\n",
+ " '100010': 5,\n",
+ " '110010': 50,\n",
+ " '111110': 84,\n",
+ " '010010': 28,\n",
+ " '011100': 41,\n",
+ " '010110': 56}"
+ ]
+ },
+ "execution_count": 58,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "backend = qiskit_aer.Aer.get_backend('qasm_simulator')\n",
+ "\n",
+ "new_circuit = transpile(qc, backend)\n",
+ "job = backend.run(new_circuit, shots = 1000)\n",
+ "results = job.result()\n",
+ "counts = results.get_counts()\n",
+ "counts"
]
},
{
@@ -560,7 +1030,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 16,
"id": "5ef68f98",
"metadata": {},
"outputs": [],
@@ -619,7 +1089,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 17,
"id": "0de4a8f2",
"metadata": {},
"outputs": [],
@@ -638,9 +1108,9 @@
],
"metadata": {
"kernelspec": {
- "display_name": "tda",
+ "display_name": "Python 3 [moodys]",
"language": "python",
- "name": "python3"
+ "name": "python3_moodys_yhl12u"
},
"language_info": {
"codemirror_mode": {
@@ -652,7 +1122,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.11"
+ "version": "3.11.9"
}
},
"nbformat": 4,