{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e49ad235",
   "metadata": {},
   "source": [
    "# Interpolation of data\n",
    "- Börge Göbel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9a5970cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42e0d49c",
   "metadata": {},
   "source": [
    "## 1. Taylor expansion"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50b6c172",
   "metadata": {},
   "source": [
    "You can expand any continuous function as a polynomials\n",
    "\n",
    "\\\\( f(x)=\\sum_{n=0}^\\infty \\frac{1}{n!}f^{(n)}(x_0)\\,(x-x_0)^n\\\\)\n",
    "\n",
    "Here, \\\\( f^{(n)} \\\\) is the nth derivative and \\\\( x_0 \\\\) is the argument around which we expand the function"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43d6a72a",
   "metadata": {},
   "source": [
    "### 1.1 Example: Exponential function"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "522c0227",
   "metadata": {},
   "source": [
    "\\\\( f(x)=f'(x)=f''(x)=\\dots=f^{(n)}(x)=\\exp(x) \\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6bf6da3e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "79d68bef",
   "metadata": {},
   "source": [
    "### 1.2 Example: sin function at \\\\(x_0 = 0\\\\)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ac2e6a0",
   "metadata": {},
   "source": [
    "\\\\( f(0) = f''(0) = f^{(4)}(0) = \\dots = 0 \\\\)\n",
    "\n",
    "\\\\( f'(0) = f^{(5)}(0) = f^{(9)}(0) = \\dots = 1 \\\\)\n",
    "\n",
    "\\\\( f'''(0) = f^{(7)}(0) = f^{(11)}(0) = \\dots = -1 \\\\)\n",
    "\n",
    "\\\\( \\sin(x) = x - \\frac{1}{3!}x^3 + \\frac{1}{5!}x^5  - \\frac{1}{7!}x^7 \\pm \\dots = \\sum_{n=0}^\\infty \\frac{(-1)^n}{(2n+1)!}x^{2n+1}\\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3f8ca47",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "9b9303de",
   "metadata": {},
   "source": [
    "- Accuracy of \\\\( \\sin(10.5) \\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fcca724d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "3fa84c9d",
   "metadata": {},
   "source": [
    "### 1.3 Implementation of a general function"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0b2914c",
   "metadata": {},
   "source": [
    "Derivative (more details in separate section): \\\\( f'(x) = \\lim_{h\\rightarrow 0} \\frac{f(x+h)-f(x)}{h} \\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8fa7e6b2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "c3797164",
   "metadata": {},
   "source": [
    "Higher derivatives: \\\\( f^{(n)}(x) = \\lim_{h\\rightarrow 0} \\frac{1}{h^n}\\sum_{k=0}^n(-1)^{k+n} \\,\\frac{n!}{k!(n-k)!} \\,f(x+kh)\\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "79be1154",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "777c00ec",
   "metadata": {},
   "source": [
    "## 2. Interpolation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c44bbf6",
   "metadata": {},
   "source": [
    "### 2.1 Generate data points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2459d9c8",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "6ed78b40",
   "metadata": {},
   "source": [
    "Modify x and y values by adding random numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a51fd2a7",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "11eb81d5",
   "metadata": {},
   "source": [
    "## 2.2 Spline interpolation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61bc4320",
   "metadata": {},
   "source": [
    "A spline interpolation always fits the data perfectly and even has a continuous derivative, if a cubic spline is used.\n",
    "\n",
    "The spline is defined piecewise."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfd29e75",
   "metadata": {},
   "source": [
    "### 2.2.1 Unperturbed data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2caa50df",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6f72d71d",
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy import interpolate"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a60f24f5",
   "metadata": {},
   "source": [
    "- linear splines"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19bb52c2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "83643535",
   "metadata": {},
   "source": [
    "- zoom"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "702413ca",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "23b0b018",
   "metadata": {},
   "source": [
    "- cubic spline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7a1c69cf",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "0b2b89c3",
   "metadata": {},
   "source": [
    "### 2.2.2 Perturbed data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd695e4e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "7353a64a",
   "metadata": {},
   "source": [
    "- How to handle data which is not smooth?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "519df67c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "3bab25d9",
   "metadata": {},
   "source": [
    "## 2.3 Fitting a model function"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a6ef777",
   "metadata": {},
   "source": [
    "Choose ideal parameters of a (physically motivated) model function such that error is minimized."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3354650",
   "metadata": {},
   "source": [
    "### 2.3.1 Define model function"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ee68e24",
   "metadata": {},
   "source": [
    "For practice, we consider a polynomial: \\\\( f(x) = a_0 + a_1 x + a_2 x^2 + \\dots + a_n x^n = \\sum_{k=0}^n a_k x^k\\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5dfbbf96",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "deb94dd0",
   "metadata": {},
   "source": [
    "### 2.3.2 Define error "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba18c206",
   "metadata": {},
   "source": [
    "There are many reasonable definitions of an error function but a very common choice is: \\\\( \\Delta = \\sum_{i=1}^n \\left(y_i-f(x_i)\\right)^2\\\\)\n",
    "\n",
    "\\\\( f \\\\) is the fit function that is determined by the coefficients \\\\( a_i \\\\) in our case.\n",
    "\n",
    "\\\\( (x_i, y_i) \\\\) are the data points that we try to fit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2c809aa",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "74701646",
   "metadata": {},
   "source": [
    "### 2.3.3 Update coefficients to reduce the error (gradient descent)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1274500",
   "metadata": {},
   "source": [
    "We can use several different methods to minimize the error, e. g. a Monte-Carlo algorithm. Here, we will use the gradient descent method. The coefficients \\\\( a_i \\\\) will be updated along the gradient direction of the error function \\\\( \\nabla_{\\vec{a}} \\Delta\\\\). The gradient consists of elements \\\\( \\frac{\\partial}{\\partial a_k} \\Delta = -2 \\sum_{i=1}^n \\left(y_i-f(x_i)\\right) \\frac{\\partial}{\\partial a_k}f(x_i) = -2 \\sum_{i=1}^n \\left(y_i-f(x_i)\\right) x_i^{k}\\\\)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2e7a9c7",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "23fb3610",
   "metadata": {},
   "source": [
    "### 2.3.4 Loop for the actual fitting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe7686c6",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "72361f21",
   "metadata": {},
   "source": [
    "- Comparison of a and a0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f680177f",
   "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.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
