Skip to content

Instantly share code, notes, and snippets.

@johntyree
Created April 6, 2013 14:41
Show Gist options
  • Save johntyree/5326312 to your computer and use it in GitHub Desktop.
Save johntyree/5326312 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "Discrete Derivatives"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"import numpy as np\n",
"import scipy.sparse as sps\n",
"def filterprint(domain, prec=1, fmt=\"f\", predicate=lambda x: x == 0, blank='- '):\n",
" \"\"\"\n",
" Pretty print a NumPy array, hiding values which match a predicate\n",
" (default: x == 0). predicate must be callable.\n",
"\n",
" Aliased to fp.\n",
"\n",
" Print an array with three decimal places in scientific notation when the\n",
" value is larger than 2, and '-' otherwise.\n",
"\n",
" fp(domain, 3, 'e', lambda x: x > 2)\n",
"\n",
" \"\"\"\n",
" if hasattr(domain, \"todense\"):\n",
" domain = domain.todense()\n",
" # if domain.ndim == 1: # Print 1-D vectors as columns\n",
" # domain = domain[:,np.newaxis]\n",
" tmp = \"% .{0}{1}\".format(prec, fmt)\n",
" domain = np.atleast_2d(domain)\n",
" xdim, ydim = np.shape(domain)\n",
" pad = max(len(tmp % x) for x in domain.flat)\n",
" fmt = \"% {pad}.{prec}{fmt}\".format(pad=pad, prec=prec, fmt=fmt)\n",
" bstr = \"{:>{pad}}\".format(blank, pad=pad)\n",
" for i in range(xdim):\n",
" for j in range(ydim):\n",
" if not predicate(domain[i,j]):\n",
" print fmt % domain[i,j],\n",
" else:\n",
" print bstr,\n",
" print\n",
" return\n",
"fp = filterprint"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These functions generate tri-diagonal matrices. When applied, they will compute (discrete) derivatives like https://en.wikipedia.org/wiki/Finite_difference_method"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def D(dim):\n",
" '''Discrete first derivative operator with no boundary.'''\n",
" operator = np.zeros((3, dim))\n",
" operator[0,2:] = 0.5\n",
" operator[2,:-2] = -0.5\n",
" return sps.dia_matrix((operator, (1,0,-1)), shape=(dim,dim))\n",
"\n",
"def D2(dim):\n",
" '''Discrete second derivative operator with no boundary.'''\n",
" operator = np.zeros((3, dim))\n",
" operator[0,2:] = 1\n",
" operator[1,1:-1] = -2\n",
" operator[2,:-2] = 1\n",
" return sps.dia_matrix((operator, (1,0,-1)), shape=(dim,dim))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"fst_deriv = D(10)\n",
"snd_deriv = D2(10)\n",
"print \"First derivative\"\n",
"fp(fst_deriv)\n",
"print \"Second derivative\"\n",
"fp(snd_deriv)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"First derivative\n",
" - - - - - - - - - - \n",
"-0.5 - 0.5 - - - - - - - \n",
" - -0.5 - 0.5 - - - - - - \n",
" - - -0.5 - 0.5 - - - - - \n",
" - - - -0.5 - 0.5 - - - - \n",
" - - - - -0.5 - 0.5 - - - \n",
" - - - - - -0.5 - 0.5 - - \n",
" - - - - - - -0.5 - 0.5 - \n",
" - - - - - - - -0.5 - 0.5\n",
" - - - - - - - - - - \n",
"Second derivative\n",
" - - - - - - - - - - \n",
" 1.0 -2.0 1.0 - - - - - - - \n",
" - 1.0 -2.0 1.0 - - - - - - \n",
" - - 1.0 -2.0 1.0 - - - - - \n",
" - - - 1.0 -2.0 1.0 - - - - \n",
" - - - - 1.0 -2.0 1.0 - - - \n",
" - - - - - 1.0 -2.0 1.0 - - \n",
" - - - - - - 1.0 -2.0 1.0 - \n",
" - - - - - - - 1.0 -2.0 1.0\n",
" - - - - - - - - - - \n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For linear functions $y = x$, the derivative $dy/dx$ is 1 everywhere."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = np.arange(10)\n",
"y = x\n",
"dx = 1\n",
"print \"Our domain\"\n",
"fp(a)\n",
"print \"1st Deriv\"\n",
"fp(fst_deriv.dot(y) * (1/dx)) \n",
"print \"2nd Deriv\"\n",
"fp(snd_deriv.dot(y) * (1/dx**2))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Our domain\n",
" - 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0\n",
"1st Deriv\n",
" - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - \n",
"2nd Deriv\n",
" - - - - - - - - - - \n"
]
}
],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Quadratic functions have derivative 2 as expected. Note first deriv is now linear"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = np.arange(10)\n",
"y = x**2.0\n",
"dx = np.hstack((0,np.diff(x)))\n",
"print \"Our domain\"\n",
"fp(y)\n",
"print \"1st Deriv\"\n",
"fp(fst_deriv.dot(y) * (1/dx))\n",
"print \"2nd Deriv\"\n",
"fp(snd_deriv.dot(y) * (1/dx**2))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Our domain\n",
" - 1.0 4.0 9.0 16.0 25.0 36.0 49.0 64.0 81.0\n",
"1st Deriv\n",
" - 2.0 4.0 6.0 8.0 10.0 12.0 14.0 16.0 - \n",
"2nd Deriv\n",
" - 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 - \n"
]
}
],
"prompt_number": 33
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These have been forward examples. We don't invert anything."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment