{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<script async src=\"https://www.googletagmanager.com/gtag/js?id=UA-59152712-8\"></script>\n",
    "<script>\n",
    "  window.dataLayer = window.dataLayer || [];\n",
    "  function gtag(){dataLayer.push(arguments);}\n",
    "  gtag('js', new Date());\n",
    "\n",
    "  gtag('config', 'UA-59152712-8');\n",
    "</script>\n",
    "\n",
    "# Creating the Finite-Difference Table for Centered First and Second  Derivatives, from 2nd through 10th-Order Accuracy\n",
    "\n",
    "<!-- abstract? -->\n",
    "\n",
    "## *Courtesy Brandon Clark*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2021-03-07T17:10:38.726193Z",
     "iopub.status.busy": "2021-03-07T17:10:38.709466Z",
     "iopub.status.idle": "2021-03-07T17:10:55.793088Z",
     "shell.execute_reply": "2021-03-07T17:10:55.793689Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Installing astropy, needed for creating the output table. Please wait a few seconds...\n",
      "\u001b[33mWARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2436baa30>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/pip/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2436bac40>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/pip/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2436b58b0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/pip/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2436b5dc0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/pip/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2436b5cd0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/pip/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2429bdd90>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/astropy/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2429bdf40>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/astropy/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2429c9130>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/astropy/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2429c92e0>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/astropy/\u001b[0m\n",
      "\u001b[33mWARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7ff2429c9490>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/astropy/\u001b[0m\n",
      "astropy installed.\n",
      "Derivative Accuracy    -5      -4     -3     -2   -1      0       1    2     3      4      5   \n",
      "---------- -------- ------- ------- ------ ----- ---- ---------- --- ----- ----- ------- ------\n",
      "       1st        2                              -1/2            1/2                           \n",
      "       1st        4                         1/12 -2/3            2/3 -1/12                     \n",
      "       1st        6                  -1/60  3/20 -3/4            3/4 -3/20  1/60               \n",
      "       1st        8           1/280 -4/105   1/5 -4/5            4/5  -1/5 4/105  -1/280       \n",
      "       1st       10 -1/1260   5/504  -5/84  5/21 -5/6            5/6 -5/21  5/84  -5/504 1/1260\n",
      "       2nd        2                                 1         -2   1                           \n",
      "       2nd        4                        -1/12  4/3       -5/2 4/3 -1/12                     \n",
      "       2nd        6                   1/90 -3/20  3/2     -49/18 3/2 -3/20  1/90               \n",
      "       2nd        8          -1/560  8/315  -1/5  8/5    -205/72 8/5  -1/5 8/315  -1/560       \n",
      "       2nd       10  1/3150 -5/1008  5/126 -5/21  5/3 -5269/1800 5/3 -5/21 5/126 -5/1008 1/3150\n"
     ]
    }
   ],
   "source": [
    "print(\"Installing astropy, needed for creating the output table. Please wait a few seconds...\")\n",
    "!pip install -U pip astropy > /dev/null\n",
    "print(\"astropy installed.\")\n",
    "# Step 0: Import needed modules\n",
    "import numpy as np\n",
    "import finite_difference as fin\n",
    "from astropy.table import Table\n",
    "\n",
    "# Step 1: Set the maximum finite-difference accuracy order computed in the table\n",
    "max_fdorder = 10\n",
    "\n",
    "# Step 2: Set up table parameters\n",
    "#    One column for deriv order, one for deriv accuracy, and max_fdorder+1\n",
    "numcols = 2 + max_fdorder + 1\n",
    "#    8 rows: max_fdorder accuracy orders per derivative order, times 2 derivative orders (first & second derivative)\n",
    "numrows = int(max_fdorder/2 * 2)\n",
    "#    Center column index of table will be at 2 + max_fdorder/2  (zero-offset indexing)\n",
    "column_corresponding_to_zero_fd_point = 2 + int(max_fdorder/2)\n",
    "#    The table is initialized as a matrix of zeroes in numpy...\n",
    "numpy_matrix = np.zeros((numrows, numcols), dtype=object)\n",
    "#    Then we replace all elements with the empty string to match the Wikipedia article.\n",
    "for row in range(numrows):\n",
    "    for col in range(numcols):\n",
    "        numpy_matrix[row,col] = \"\"\n",
    "\n",
    "# Step 3: Construct the first-order derivative finite difference coefficients\n",
    "rowcount = 0\n",
    "for fdorder in range(2, max_fdorder+1, 2): # loop runs from 2 to max_fdorder inclusive, skipping odd orders.\n",
    "    numpy_matrix[rowcount, 0] = \"1st\"\n",
    "    numpy_matrix[rowcount, 1] = fdorder\n",
    "    fdcoeffs, fdstencl = fin.compute_fdcoeffs_fdstencl(\"D0\", fdorder)\n",
    "    for i in range(fdorder):\n",
    "        numpy_matrix[rowcount, column_corresponding_to_zero_fd_point + fdstencl[i][0]] = fdcoeffs[i]\n",
    "    rowcount += 1\n",
    "\n",
    "# Step 4: Construct the second-order derivative finite difference coefficients\n",
    "for fdorder in range(2, max_fdorder+1, 2): # loop runs from 2 to max_fdorder inclusive, skipping odd orders.\n",
    "    numpy_matrix[rowcount, 0] = \"2nd\"\n",
    "    numpy_matrix[rowcount, 1] = fdorder\n",
    "    fdcoeffs, fdstencl = fin.compute_fdcoeffs_fdstencl(\"DD00\", fdorder)\n",
    "    for i in range(fdorder+1):\n",
    "        numpy_matrix[rowcount, column_corresponding_to_zero_fd_point + fdstencl[i][0]] = fdcoeffs[i]\n",
    "    rowcount += 1\n",
    "\n",
    "# Step 5: Construct an astropy table from the numpy matrix with the following header info, and then print it:\n",
    "colnames = ['Derivative','Accuracy']\n",
    "for i in range(-int(max_fdorder/2),int(max_fdorder/2)+1):\n",
    "    colnames.append(str(i))\n",
    "table = Table(numpy_matrix, names=colnames)\n",
    "table.pprint(max_width=-1)"
   ]
  }
 ],
 "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.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}