{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Numerical Differentiation Script\n",
"### Ewan Miles - 06/05/2020\n",
"\n",
"**This code is entirely open-source and thus editable by any user.**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This one-function script is short but sweet. It is comprised of a function, **diff()**, which takes two arrays, `x` and `y`, and calculates the numerical derivative points of `y`, that is, $y'$. This is useful for finding the minimum/maximum/stationary point of graphed experimental data. \n",
"\n",
"For example, you have a curve with no fitted function, and require the stationary point for a specific value. Well, the first derivative of the y points (the $y'$ points), will cross the x-axis at the x-coordinate of the stationary point, as stationary points have a gradient of 0. From there, the stationary point of the data can be found.\n",
"\n",
"Thus this function can be used to plot the \"first numerical derivative\" of your data without need of a function, often used to find a stationary point among other things. It uses the simple recursive relationship below to calculate each first derivative point by point, called the \"central difference method\":\n",
"\n",
"$$(1)\\space \\space \\normalsize{y'_i=\\frac{(y_{i+1}-y_{i-1})}{2(x_{i+1}-x_i)}}$$\n",
"\n",
"where $x_{i+1}$ is the point after $x_i$, and $x_{i-1}$ the point previous, as an example. This leads to an issue at the ends, as the recursive relationship breaks down (There is no $y_{i-1}$ when $y_0$ is the starting point). Thus, the first point is found with:\n",
"\n",
"$$(2)\\space \\space \\normalsize{y'_0=\\frac{(y_1-y_0)}{(x_1-x_0)}}$$\n",
"\n",
"and likewise the last with:\n",
"\n",
"$$(3)\\space \\space \\normalsize{y'_f=\\frac{(y_f-y_{f-1})}{(x_f-x_{f-1})}}$$\n",
"\n",
"where $x_f$ is the final point, $x_{f-1}$ the point before it, etc.\n",
"\n",
"This is generally held to be a good approximation. All that is contained in this script is the function, for you to modify/use at will in conjunction with your own data."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def diff(x,y):\n",
" \"\"\"\n",
" Function which calculates and outputs an array of the numerical derivatives of y, with inputs:\n",
" - x: Array of xpoints\n",
" - y: Array of ypoints\n",
" Outputs new_y1 array, which, when plotted with x, will give the \"first derivative graph\"\n",
" \"\"\"\n",
" \n",
" #Index to iterate over the arrays\n",
" index = 0\n",
" new_y1 = []\n",
" while index < len(y):\n",
" while index < len(x):\n",
" \n",
" #Define the character in the array currently being observed as array[current index]\n",
" ychar = y[index]\n",
" xchar = x[index]\n",
" \n",
" #Calculate derivative for first point according to (2)\n",
" if index == 0:\n",
" first = ychar\n",
" y3 = y[index+1]\n",
" x3 = x[index+1]\n",
" diffy = (y3-first)/(x3-xchar)\n",
" new_y1.append(diffy)\n",
" \n",
" #Calculate derivative for final point according to (3)\n",
" elif index == len(x)-1:\n",
" last = ychar\n",
" y0 = y[index-1]\n",
" x0 = x[index-1]\n",
" diffy = (last-y0)/(xchar-x0)\n",
" new_y1.append(diffy)\n",
" \n",
" #Calculate all other derivative points according to (1)\n",
" else:\n",
" y0 = y[index-1]\n",
" y3 = y[index+1]\n",
" x3 = x[index+1]\n",
" diffy = (y3-y0)/(2*(x3-xchar))\n",
" new_y1.append(diffy)\n",
" index+= 1\n",
" \n",
" #Return array of first derivative points\n",
" return new_y1"
]
}
],
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}