From 3d541d14242c5ccd3d872769796c29fb4eb5d09e Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 5 Dec 2024 17:14:48 -0600 Subject: [PATCH] Update cleared --- .../interpolation/Interpolation Error.ipynb | 11 +- .../interpolation/Lebesgue Constant.ipynb | 252 ++++++++++++++++++ 2 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 cleared-demos/interpolation/Lebesgue Constant.ipynb diff --git a/cleared-demos/interpolation/Interpolation Error.ipynb b/cleared-demos/interpolation/Interpolation Error.ipynb index 5771f1f..c1f8afe 100644 --- a/cleared-demos/interpolation/Interpolation Error.ipynb +++ b/cleared-demos/interpolation/Interpolation Error.ipynb @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "collapsed": false, "jupyter": { @@ -70,9 +70,12 @@ "elif 0:\n", " def f(x):\n", " return np.sin(20*x)\n", + "elif 0:\n", + " def f(x):\n", + " return (x>=0.5).astype(np.int32).astype(np.float64) * (x-0.5)**2\n", "else:\n", " def f(x):\n", - " return (x>=0.5).astype(np.int).astype(np.float)\n", + " return (x>=0.5).astype(np.int32).astype(np.float64)\n", " " ] }, @@ -277,7 +280,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -291,7 +294,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.3" + "version": "3.13.0" } }, "nbformat": 4, diff --git a/cleared-demos/interpolation/Lebesgue Constant.ipynb b/cleared-demos/interpolation/Lebesgue Constant.ipynb new file mode 100644 index 0000000..2c29e3a --- /dev/null +++ b/cleared-demos/interpolation/Lebesgue Constant.ipynb @@ -0,0 +1,252 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "55af40c4-ecf0-4a02-b7b4-9afb96786313", + "metadata": {}, + "source": [ + "# Lebesgue Constant\n", + "\n", + "Copyright (C) 2024 Andreas Kloeckner\n", + "\n", + "
\n", + "MIT License\n", + "Permission is hereby granted, free of charge, to any person obtaining a copy\n", + "of this software and associated documentation files (the \"Software\"), to deal\n", + "in the Software without restriction, including without limitation the rights\n", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", + "copies of the Software, and to permit persons to whom the Software is\n", + "furnished to do so, subject to the following conditions:\n", + "\n", + "The above copyright notice and this permission notice shall be included in\n", + "all copies or substantial portions of the Software.\n", + "\n", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n", + "THE SOFTWARE.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a956ac5a-ccc1-4aec-8ebf-24b2e1541f5a", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import numpy.linalg as la\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d734ec26-3d68-4a6f-ae16-5afbfaa005e8", + "metadata": {}, + "outputs": [], + "source": [ + "n = 10\n", + "nodes = np.linspace(-1, 1, n)" + ] + }, + { + "cell_type": "markdown", + "id": "bfbe471d-cf99-4b09-9828-ee1cb0704835", + "metadata": {}, + "source": [ + "Create a Vandermonde matrix (as `vdm`) for monomial interpolation with `nodes`." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "7ba02567-c5df-452e-8be0-205b403b22b0", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "523271cd-e6b3-46ec-8f42-24d58029de87", + "metadata": {}, + "source": [ + "Create a \"fine\" set of nodes (as `nodes_fine`) and a corresponding Vandermonde matrix with the monomials (as `vdm_fine`):" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "db776c8d-28e3-42d9-b756-58326cb0cfa0", + "metadata": {}, + "outputs": [], + "source": [ + "nodes_fine = np.linspace(-1, 1, 10_000)\n", + "\n", + "vdm_fine = np.array([\n", + " nodes_fine**i for i in range(n)\n", + "]).T" + ] + }, + { + "cell_type": "markdown", + "id": "d1002ba4-9297-486d-b947-08d66c26cfb0", + "metadata": {}, + "source": [ + "Generate 300 random functions with nodal data $\\|\\boldsymbol y\\|_\\infty \\le 1$ and plot their interpolants on the fine grid:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7dcf5af9-90b3-4d30-b351-cd67ebdbbcd1", + "metadata": {}, + "outputs": [], + "source": [ + "for _ in range(300):\n", + " y = 2*np.random.rand(n) - 1\n", + " coeffs = la.solve(vdm, y)\n", + " yfine = vdm_fine @ coeffs\n", + " plt.plot(nodes_fine, yfine)" + ] + }, + { + "cell_type": "markdown", + "id": "4727b2e4-219d-4941-b71e-7534411bda56", + "metadata": {}, + "source": [ + "Systematically estimate the Lebesgue constant:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "3dbbe752-7892-48f0-8e7d-0e86540aa758", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "70caa6e1-063a-4cbc-8903-4b761a88ca98", + "metadata": {}, + "source": [ + "Plug in all-ones data, disregarding signs:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a83fbe81-bf4d-40e1-bbed-cfc45f8576c6", + "metadata": {}, + "outputs": [], + "source": [ + "interp = vdm_fine @ la.inv(vdm)\n", + "worst = np.sum(np.abs(interp), axis=1)\n", + "plt.plot(nodes_fine, worst)" + ] + }, + { + "cell_type": "markdown", + "id": "68a17a7d-026a-426a-a869-54c61da720f9", + "metadata": {}, + "source": [ + "Now experiment:\n", + "\n", + "- Increase `n`.\n", + "- Can you come up with better `nodes`?" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "2636686b-f5ff-4d80-9111-b1b5165aa5f0", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "5d53ac63-0ded-489b-8788-b9a39c1efaee", + "metadata": {}, + "source": [ + "### Chebyshev nodes\n", + "\n", + "Extremal/second kind:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "474e4729-5076-445e-b728-edf855d46d20", + "metadata": {}, + "outputs": [], + "source": [ + "k = n - 1\n", + "i = np.arange(0, k+1)\n", + "\n", + "def f(x):\n", + " return np.cos(k*np.arccos(x))\n", + "\n", + "nodes = np.cos(i/k*np.pi)" + ] + }, + { + "cell_type": "markdown", + "id": "3875152e-1583-471e-a618-2ebe032c92e7", + "metadata": {}, + "source": [ + "Roots/first kind:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "9b52b06b-37cf-4ee5-a8c9-abccf455cbdc", + "metadata": {}, + "outputs": [], + "source": [ + "i = np.arange(1, n+1)\n", + "x = np.linspace(-1, 1, 3000)\n", + "\n", + "def f(x):\n", + " return np.cos(n*np.arccos(x))\n", + "\n", + "nodes = np.cos((2*i-1)/(2*n)*np.pi)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1bc26ebc-5c42-4e98-890c-83728a410390", + "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.13.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file