2023-03-28 01:04:30 +02:00
{
"cells": [
{
"cell_type": "markdown",
"id": "9785abf6",
"metadata": {},
"source": [
"We have:\n",
"$$\n",
"\\nabla f = (I + \\beta A) \\vec s - \\vec y\n",
" = \\vec s - \\vec y + \\beta A \\vec s\n",
"$$ \n",
"We can substitute in the partial derivatives:\n",
"$$ \n",
"\\left(\\begin{matrix}\n",
"s_0 - y_0 + \\beta (s_0 - s_1) \\\\\n",
"s_1 - y_1 + \\beta (2s_1 - s_0 - s_2) \\\\\n",
"\\vdots \\\\\n",
"s_N - y_N + \\beta (s_N - s_{N - 1})\n",
"\\end{matrix}\\right) \n",
"= \\vec s - \\vec y + \\beta A \\vec s\n",
"$$\n",
"\n",
"Adding $\\vec y - \\vec s$ to both sides and then dividing by $\\beta$ yields:\n",
"$$ \n",
"\\left(\\begin{matrix}\n",
"s_0 - s_1 \\\\\n",
"2s_1 - s_0 - s_2 \\\\\n",
"\\vdots \\\\\n",
"s_N - s_{N - 1}\n",
"\\end{matrix}\\right) \n",
"= A \\vec s\n",
"$$\n",
"\n",
"Solving for $A$ is trivial and yields:\n",
"$$ \n",
"A = \\left(\\begin{matrix}\n",
"1 & -1 & & & & & \\\\\n",
"-1 & 2 & -1 & & & & \\\\\n",
" & -1 & 2 & -1 & & & \\\\\n",
" & & \\ddots & \\ddots & \\ddots & & \\\\\n",
" & & & -1 & 2 & -1 & \\\\\n",
" & & & & -1 & 2 & -1\\\\\n",
" & & & & & -1 & 1\n",
"\\end{matrix}\\right) \n",
"$$"
]
},
{
"cell_type": "code",
2023-03-28 02:00:58 +02:00
"execution_count": 3,
2023-03-28 01:04:30 +02:00
"id": "e7d69a97",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import modules.tridiagonal as tridiagonal\n",
"\n",
"def sample_with_noise(points, vectorized_g):\n",
" \"\"\"\n",
" Sample a function at a given set of points,\n",
" introducing noise in the process.\n",
"\n",
" Returns a tuple of the real values of the function\n",
" and the values with introduced noise.\n",
"\n",
" For performance reasons, this function takes in\n",
" a vectorized version of `g`. If you want to pass\n",
" a non vectorized function use `np.vectorize`. Eg:\n",
" ```py\n",
" sample_with_noise(points, np.vectorize(g))\n",
" ```\n",
" \"\"\"\n",
" gs = vectorized_g(points)\n",
" ys = gs + 0.05 * np.random.randn(len(gs))\n",
"\n",
" return (gs, ys)\n",
"\n",
2023-03-28 02:00:58 +02:00
"def p5(x):\n",
2023-03-28 01:04:30 +02:00
" \"\"\"\n",
" Vectorized version of the function\n",
" described in the pdf.\n",
" \"\"\"\n",
2023-03-28 02:00:58 +02:00
" n = 5\n",
2023-03-28 01:04:30 +02:00
" result = 0\n",
"\n",
" for k in range(n + 1):\n",
" result += x**k\n",
"\n",
" return result/(n + 1)\n",
"\n",
"def smooth(data, beta):\n",
" \"\"\"\n",
" Smooth noisy data (y) by means of solving \n",
" a minimization problem.\n",
"\n",
" Args:\n",
" data (numpy.array): noisy data to be smoothed (y)\n",
" beta (float): parameter >= 0 that balances fit and smoothing\n",
"\n",
" Returns:\n",
" numpy array of smoothed data (s)\n",
" \"\"\"\n",
" x = data[0]\n",
" y = data[1]\n",
"\n",
" # We need to solve for s in:\n",
" # (I + βA)s - y = 0\n",
" # <=> (I + βA)s = y\n",
" #\n",
" # Because A and I are tridiagonal, I + βA\n",
" # is tridiagonal as well (linear combinations\n",
" # of tridiagonal matrices are themselves\n",
" # tridiagonal)\n",
" #\n",
" # This means we can use our existing implementation\n",
" # of tridiagonal linear equation system solving.\n",
" # \n",
" # We start by constructing \n",
" # iba := I + βA\n",
" n = len(x) - 1\n",
"\n",
" # The a component of the a-c-e tridiagonal representation of iba\n",
" iba_a = np.ones(n + 1) * (2 * beta + 1)\n",
" iba_a[0] = 1 + beta\n",
" iba_a[-1] = 1 + beta\n",
"\n",
" # I + βA\n",
" iba = (\n",
" iba_a,\n",
" -np.ones(n),\n",
" -np.ones(n)\n",
" )\n",
"\n",
" data_smoothed = tridiagonal.solve(*iba, y)\n",
"\n",
" return data_smoothed"
]
},
{
"cell_type": "code",
2023-03-28 02:00:58 +02:00
"execution_count": 6,
2023-03-28 01:04:30 +02:00
"id": "2b9f2b79",
"metadata": {},
"outputs": [
{
"data": {
2023-03-28 02:00:58 +02:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHgCAYAAABZ+0ykAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAACNG0lEQVR4nOzdd3xT5fvw8U+6d0p3Syd7lF0QKFAQmYIgKKB+GYI+ouIAleEC/ClDHDjAgTJURFSGg43sJXuWTWkZhdJSumdynj9iA6ErnWnT682rryZ37nPOfU5Cz5V7qhRFURBCCCGEMBMWpi6AEEIIIUR5kuBGCCGEEGZFghshhBBCmBUJboQQQghhViS4EUIIIYRZkeBGCCGEEGZFghshhBBCmBUJboQQQghhViS4EUIIIYRZkeBGiDJavHgxKpVK/2NnZ4ePjw/dunVj5syZxMXFlXrfkZGRTJs2jcuXL5dfgYuwbds2VCoV27Ztq5TjFadr16507dq1RNtUtXMwpYKuxdq1a5k2bZrJyiREZZDgRohysmjRIvbu3cumTZuYN28eLVu2ZPbs2TRu3JjNmzeXap+RkZFMnz690oKbqmb+/PnMnz+/RNu0bt2avXv30rp16woqVfW2du1apk+fbupiCFGhrExdACHMRWhoKGFhYfrngwcPZvz48XTq1IlBgwZx/vx5vL29TVjC6qdJkyYl3sbFxYX27dtXQGlKJyMjAzs7O1QqlamLIkSNITU3QlSgwMBAPv74Y1JSUvjmm2/06QcPHmTYsGEEBwdjb29PcHAwTzzxBNHR0fo8ixcv5vHHHwegW7du+mavxYsXA7Bp0yYGDBiAv78/dnZ21KtXj+eee474+HijynbmzBl69+6Ng4MDHh4ejB07lpSUlALzbt68me7du+Pi4oKDgwPh4eH8888/BnmmTZuGSqXi1KlTPPHEE6jVary9vRk9ejRJSUkGeTMzM5kyZQohISHY2NhQu3ZtXnzxRe7cuWOQr6Bmqa+++ooWLVrg5OSEs7MzjRo14s0339S/XlBTzKhRo3BycuLChQv07dsXJycnAgICeO2118jKyjLY/9WrV3nsscdwdnbG1dWVp556igMHDhhc+8LkNVFu3LiR0aNH4+npiYODg/4Yy5cvp0OHDjg6OuLk5ESvXr04cuSIwT4uXbrEsGHD8PPzw9bWFm9vb7p3787Ro0f1eVQqVYFNS8HBwYwaNarQ8o0aNYp58+bp95H3k1cz+Ntvv/HAAw+gVqtxcHCgTp06jB49ushzFqIqkpobISpY3759sbS0ZMeOHfq0y5cv07BhQ4YNG4abmxuxsbF89dVXtG3blsjISDw8PHj44YeZMWMGb775JvPmzdM3s9StWxeAixcv0qFDB5555hnUajWXL1/mk08+oVOnTpw4cQJra+tCy3Tz5k0iIiKwtrZm/vz5eHt7s3TpUsaNG5cv708//cSIESMYMGAAS5Yswdramm+++YZevXqxYcMGunfvbpB/8ODBDB06lDFjxnDixAmmTJkCwMKFCwFQFIWBAwfyzz//MGXKFDp37szx48eZOnUqe/fuZe/evdja2hZY7l9++YUXXniBl156iY8++ggLCwsuXLhAZGRkse9DTk4OjzzyCGPGjOG1115jx44d/N///R9qtZp3330XgLS0NLp168bt27eZPXs29erVY/369QwdOrTY/d9r9OjRPPzww/z444+kpaVhbW3NjBkzePvtt3n66ad5++23yc7OZs6cOXTu3Jn9+/fra6n69u2LRqPhww8/JDAwkPj4ePbs2ZMv8CuNd955h7S0NH7//Xf27t2rT/f19WXv3r0MHTqUoUOHMm3aNOzs7IiOjmbLli1lPq4QlU4RQpTJokWLFEA5cOBAoXm8vb2Vxo0bF/p6bm6ukpqaqjg6OiqfffaZPv23335TAGXr1q1FlkGr1So5OTlKdHS0Aih//PFHkfknTZqkqFQq5ejRowbpPXr0MDheWlqa4ubmpvTv398gn0ajUVq0aKG0a9dOnzZ16lQFUD788EODvC+88IJiZ2enaLVaRVEUZf369QXmW758uQIo3377rT4tIiJCiYiI0D8fN26c4urqWuS5bd26Nd81GzlypAIov/76q0Hevn37Kg0bNtQ/nzdvngIo69atM8j33HPPKYCyaNGiIo+d91kYMWKEQXpMTIxiZWWlvPTSSwbpKSkpio+PjzJkyBBFURQlPj5eAZS5c+cWeRxAmTp1ar70oKAgZeTIkfrnBV2LF198USnoT/9HH32kAMqdO3eKPLYQ1YE0SwlRCRRFMXiemprKpEmTqFevHlZWVlhZWeHk5ERaWhqnT582ap9xcXGMHTuWgIAArKyssLa2JigoCKDYfWzdupWmTZvSokULg/Qnn3zS4PmePXu4ffs2I0eOJDc3V/+j1Wrp3bs3Bw4cIC0tzWCbRx55xOB58+bNyczM1I8ay6sJuL/55PHHH8fR0TFfc9e92rVrx507d3jiiSf4448/jG6CA10zTP/+/fOV7d6mwO3bt+Ps7Ezv3r0N8j3xxBNGHwd0tVf32rBhA7m5uYwYMcLgOtrZ2REREaFvQnNzc6Nu3brMmTOHTz75hCNHjqDVakt07NJq27YtAEOGDOHXX3/l2rVrlXJcISqCBDdCVLC0tDQSEhLw8/PTpz355JN8+eWXPPPMM2zYsIH9+/dz4MABPD09ycjIKHafWq2Wnj17snLlSiZOnMg///zD/v372bdvH0Cx+0hISMDHxydf+v1pN2/eBOCxxx7D2tra4Gf27NkoisLt27cNtnF3dzd4ntfElFemhIQErKys8PT0NMinUqnw8fEhISGh0HIPHz6chQsXEh0dzeDBg/Hy8uKBBx5g06ZNRZ4vgIODA3Z2dvnKlpmZqX+ekJBQYKfvknYE9/X1NXiedx3btm2b7zouX75cH6SpVCr++ecfevXqxYcffkjr1q3x9PTk5ZdfLrQ/VHnp0qULq1ev1gdh/v7+hIaGsmzZsgo9rhAVQfrcCFHB1qxZg0aj0XeMTUpK4u+//2bq1KlMnjxZny8rKytfoFCYkydPcuzYMRYvXszIkSP16RcuXDBqe3d3d27cuJEv/f40Dw8PAL744otCRyCV9Mbv7u5Obm4ut27dMghwFEXhxo0b+hqEwjz99NM8/fTTpKWlsWPHDqZOnUq/fv04d+6cvuaqtNzd3dm/f3++9IKuVVHuHxmVdx1///33YssYFBTE999/D8C5c+f49ddfmTZtGtnZ2Xz99deALii7vyM0UGRgaIwBAwYwYMAAsrKy2LdvHzNnzuTJJ58kODiYDh06lGnfQlQmqbkRogLFxMTw+uuvo1aree655wDdjU9RlHydZr/77js0Go1B2v21Hnnybp737+PeEVlF6datG6dOneLYsWMG6T///LPB8/DwcFxdXYmMjCQsLKzAHxsbG6OOmSevA/JPP/1kkL5ixQrS0tLydVAujKOjI3369OGtt94iOzubU6dOlagcBYmIiCAlJYV169YZpP/yyy9l2m+vXr2wsrLi4sWLhV7HgjRo0IC3336bZs2acfjwYX16cHAwx48fN8i7ZcsWUlNTiy1LYZ+p+/NEREQwe/ZsgHwjuoSo6qTmRohycvLkSX1firi4OHbu3MmiRYuwtLRk1apV+loKFxcXunTpwpw5c/Dw8CA4OJjt27fz/fff4+rqarDP0NBQAL799lucnZ2xs7MjJCSERo0aUbduXSZPnoyiKLi5ufHXX38Z1TwD8Oqrr7Jw4UIefvhh3n//ff1oqTNnzhjkc3Jy4osvvmDkyJHcvn2bxx57DC8vL27dusWxY8e4desWX331VYmuU48ePejVqxeTJk0iOTmZ8PBw/WipVq1aMXz48EK3ffbZZ7G3tyc8PBxfX19u3LjBzJkzUavVxdb4GGPkyJF8+umn/O9//+P999+nXr16rFu3jg0bNgBgYVG674PBwcG89957vPXWW1y6dInevXtTq1Ytbt68yf79+3F0dGT69OkcP36ccePG8fjjj1O/fn1sbGzYsmULx48fN6jlGz58OO+88w7vvvs
2023-03-28 01:04:30 +02:00
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plot\n",
"\n",
"# Reusable function to plot the data\n",
"def plot_denoise_results(β, N, ax):\n",
" # Create the data\n",
" x = np.linspace(-1, 1, num=N+1)\n",
2023-03-28 02:00:58 +02:00
" g, y = sample_with_noise(x, p5)\n",
2023-03-28 01:04:30 +02:00
" s = smooth((x, y), β)\n",
"\n",
" ax.set_title(f\"{β=} and {N=}\")\n",
" ax.set_xlabel(\"x\")\n",
" ax.set_ylabel(\"y\")\n",
" ax.plot(x, y, \".\", label=\"raw data points\")\n",
" ax.plot(x, g, \"-\", label=\"original function\")\n",
" ax.plot(x, s, \"--\", label=\"denoised values\")\n",
" ax.legend()\n",
"\n",
"\n",
"N = 100\n",
"β = 10\n",
"\n",
"fig, ax = plot.subplots()\n",
"fig.suptitle(f\"Data denoising results\")\n",
"\n",
"# Plot the data\n",
"plot_denoise_results(β, N, ax)"
]
},
{
"cell_type": "markdown",
"id": "f2e5c860",
"metadata": {},
"source": [
"We notice that finding a point where $\\nabla f(s) = 0$ is the same as finding a point where $\\frac 1 \\beta \\nabla f(s) = \\nabla \\frac 1 \\beta f(s) = 0$. We can use this to our advantage, by defining $h(s) = \\frac 1 \\beta f(s)$ and finding the points where $\\nabla h(s) = 0$ instead. When $\\beta \\to \\infty$, we have:\n",
"$$\n",
"\\lim_{\\beta \\to \\inf} h _\\beta (s) =\n",
"\\lim_{\\beta \\to \\inf} \n",
" \\frac 1 {2\\beta} \\sum_{k=0}^n (y_k - s_k)^2\n",
" +\\frac 1 2 \\sum_{k=1}^n (s_k - s_{k - 1})^2\n",
" = \\frac 1 2 \\sum_{k=1}^n (s_k - s_{k - 1})^2\n",
"$$\n",
"\n",
"It now becomes trivial to verify that $\\nabla f(s) = As$, which means the solution to this will simply be the zero vector."
]
},
{
"cell_type": "code",
"execution_count": 70,
"id": "d7f7dbdf",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABQsAAAPLCAYAAAD4+99NAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3gU1dvG8e9ueiNAQgk9dJDeexEFFBFBNIoviKI/FRUVpalIsYCgiAUsqKCCigVQAUGkF+lFmigYCEIghJJAElJ25/1jycKSHpJssrk/15WL3dkzM89Oln0yZ545x2QYhoGIiIiIiIiIiIgUe2ZnByAiIiIiIiIiIiKFgzoLRUREREREREREBFBnoYiIiIiIiIiIiFyhzkIREREREREREREB1FkoIiIiIiIiIiIiV6izUERERERERERERAB1FoqIiIiIiIiIiMgV6iwUERERERERERERQJ2FIiIiIiIiIiIicoU6C0VERERERERERARQZ6GIiIiIiIiIiIhcoc5CERERSWPOnDmYTCb7j7e3N+XLl6dr165MmjSJqKioXG9706ZNjB8/ngsXLuRdwJkYP348JpOpQPaVldTjevTo0Xxdx5WldzwK+jOVV+Lj45kwYQJ169bF29uboKAg7r//fs6fP+/s0ERERKQYU2ehiIiIZGj27Nn88ccfrFixghkzZtCkSRPefPNN6tWrx++//56rbW7atIkJEyYUuY6dvNCrVy/++OMPQkJC8nWd4qYofqYMw+D+++9n+vTpPPbYY/z666+88sorzJ8/n7ffftvZ4YmIiEgx5u7sAERERKTwatCgAS1atLA/v/vuu3nuuefo0KED/fr1459//qFcuXJOjLBoKVOmDGXKlMn3dfJbfHw8vr6+zg6jSFu7di0///wz33//Pf379wewV+7GxcU5OToREREpzlRZKCIiIjlSpUoV3n77bS5evMjHH38MwOHDh3nooYeoVasWvr6+VKxYkd69e7N3716HdcePH8+IESMACA0Ntd/mvGbNmmxvIzNLliyhSZMmeHl5ERoayltvvZVuu3/++YcBAwZQtmxZvLy8qFevHjNmzEgTq8lkYv/+/dx///0EBgZSrlw5Hn74YWJiYtJsc8OGDXTr1o2AgAB8fX1p164dS5YscWiT3i20Z86c4X//+x+VK1fGy8uLMmXK0L59e3vlZnrr5DS2n376iUaNGuHl5UX16tV59913s317dmq7nTt30r9/f0qVKkWNGjWyfRyz8x4HDx5MtWrVMtx3VvFl9JnKar8Zye5nMbfbB/j+++8pVaoUffv2tS9bt24dp0+f5uabb85y/VTvvPMOixYtyrRNSkpKmmUWiyXb+xAREZHiRZWFIiIikmO33347bm5urFu3DoCTJ08SFBTE5MmTKVOmDOfOneOLL76gdevW7Nq1izp16gDwyCOPcO7cOd5//30WLFhgv7W2fv367N69O1vbyMjKlSvp06cPbdu25dtvv8VisTBlyhROnz7t0O7AgQO0a9fO3ulZvnx5li9fzrBhw4iOjmbcuHEO7e+++27CwsIYMmQIe/fuZcyYMQB8/vnn9jZr167l1ltvpVGjRnz22Wd4eXkxc+ZMevfuzTfffENYWFiGcQ8cOJCdO3fy+uuvU7t2bS5cuMDOnTs5e/Zslr+H7MS2bNky+vXrR6dOnZg/fz4pKSm89dZbaY5LVvr168d9993H448/TlxcXI6O4428x6xk9pm69957c7Xf7H6eb+R9bdq0idatW9v3t3z5ckaOHEm3bt244447sv3+t2/fzqhRo/juu++46667HF7buXMnAwYM4J9//uGWW25h3rx5XLx4kf79+7N7926aNWvG119/Ta1atbK9PxERESkGDBEREZHrzJ492wCMbdu2ZdimXLlyRr169dJ9LSUlxUhKSjJq1aplPPfccw6vTZ061QCM8PDwTGPIbBvpad26tVGhQgUjISHBviw2NtYoXbq0ce2fPD169DAqVapkxMTEOKz/1FNPGd7e3sa5c+cMwzCMcePGGYAxZcoUh3ZDhw41vL29DavVal/Wpk0bo2zZssbFixcd4m/QoIFRqVIle9vU43rte/f39zeeffbZDN9XeuvkJLaWLVsalStXNhITE+3LLl68aAQFBRnZ+VMwdV+vvPKKw/LsHsfsvMcHH3zQqFq1aob7vlZ6xyOjz1RW+82ujD6Lud1+QkKC4e7ubowbN86YOHGiARiAUaVKFeP48eM5jm3AgAGGh4eHsXDhQofXGjVqZCxbtsw4e/asERYWZvTo0cNo2bKlMWrUKOPs2bPG/Pnzjfbt2+c4fhEREXFtug1ZREREcsUwDPvjlJQU3njjDerXr4+npyfu7u54enryzz//cPDgwWxt70a2ERcXx7Zt2+jXrx/e3t725QEBAfTu3dv+/PLly6xcuZK+ffvi6+tLSkqK/ef222/n8uXLbN682WHbd955p8PzRo0acfnyZfuM0HFxcWzZsoX+/fvj7+9vb+fm5sbAgQP577//OHToUIaxt2rVijlz5vDaa6+xefNmkpOTsz5YOYht+/bt3HXXXXh6etrb+fv7OxyX7Lj77rvtj3N6HG/kPd6I3O43u5/F3G5/586dpKSk0KpVKx544AGWL1/OhAkTuHjxIp06deLSpUsAREdHO8xKnt6Pu7s7X3/9NcnJydx77732itH//vuPSpUq0aNHD0qXLs0XX3zB4cOH7RWTpUuX5t577wWw709EREQEdBuyiIiI5EJcXBxnz56lYcOGAAwfPpwZM2YwatQoOnfuTKlSpTCbzTzyyCMkJCRka5s3so3z589jtVopX758mteuXXb27FlSUlJ4//33ef/999PdVnR0tMPzoKAgh+deXl4A9pjOnz+PYRjpzlZcoUIF+34zMn/+fF577TU+/fRTxo4di7+/P3379mXKlCnpvp/cxJbeJDQ5nZjm2veX0+N4I+/xRuR2v9n9LOZ2+1u3bgVsnY3BwcFUr16d7t27U7t2be6//342b97MLbfcQkBAALNmzcryfS5btowff/yRPn362D8ThmFgNl+tC/Dy8iIkJISzZ89itVodXru2419EREREnYUiIiKSY0uWLMFisdClSxcA5s6dy6BBg3jjjTcc2kVHR1OyZMlsbfNGtlGqVClMJhOnTp1K89q1y0qVKmWv+HvyySfT3VZoaGi24r12m2azmcjIyDSvnTx5EoDg4OAM1w8ODmb69OlMnz6diIgIfv75Z0aPHk1UVBTLli3LUSzpxWYymdIdnzC9Y5WZaycayelxzOo9ent7k5iYmGYb13fc5lRuj212P4u53f7WrVupXr16hp+L1E5mLy8vHnnkkUzf45IlS1i8eDH9+/fnm2++wd3d9ud9pUqVOHbsGL/99htt27bljTfewMPDg4SEBJ5++mmmTJnC77//jsViISAgINN9iIiISPGizkIRERHJkYiICF544QUCAwN57LHHAFtHUmpVW6olS5Zw4sQJatas6bD8+uq3VDnZxvX8/Pxo1aoVCxYsYOrUqfZbkS9evMgvv/xib+fr60vXrl3ZtWsXjRo1crg1N7f8/Pxo3bo1CxYs4K233sLHxwcAq9XK3LlzqVSpErVr187WtqpUqcJTTz3FypUr2bhxY57E1qJFCxYtWsRbb71lf7+XLl1i8eLFud7ujRzH9N5jtWrViIqK4vTp0/aKx6SkJJYvX56tbWb0mcpqvxnJzWcxJ9vfunVrmkpUwzD49NNPadCgAfXr1890/WtNnTrVPpFOakdh6nuYM2cODzzwAH/99Rdt2rRhwYIFJCUlcffdd+Pv70+dOnX44Ycfsr0vERERKR7UWSgiIiIZ2rdvn30suqioKNavX8/s2bNxc3Nj4cKFlClTBoA77riDOXPmULduXRo1asSOHTuYOnUqlSpVSrPN1FuX3333XR588EE8PDyoU6dOjraRnldffZWePXty66238vzzz2OxWHjzzTfx8/Pj3Llz9nbvvvsuHTp0oGPHjjzxxBNUq1aNixcvcvjwYX755RdWrVqV4+M0adIkbr31Vrp27coLL7y
"text/plain": [
"<Figure size 1280x960 with 9 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, axs = plot.subplots(\n",
" 3,\n",
" 3,\n",
" layout=\"constrained\",\n",
" figsize=(12.8, 9.6)\n",
")\n",
"\n",
"fig.suptitle(r\"Data denoising results as $\\beta \\to \\infty$\")\n",
"\n",
"N = 100\n",
"\n",
"for i in range(len(axs.flat)):\n",
" ax = axs.flat[i]\n",
" plot_denoise_results(2**i, N, ax)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dfc485d5",
"metadata": {},
"outputs": [],
"source": []
}
],
"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.10.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}