Skip to content

Instantly share code, notes, and snippets.

@leouieda
Last active December 20, 2015 15:58
Show Gist options
  • Save leouieda/6158113 to your computer and use it in GitHub Desktop.
Save leouieda/6158113 to your computer and use it in GitHub Desktop.
A trial implementation for the refactor of the fatiando.inversion package
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "trial_inversion_refactor"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Sample implementation for the fatiando.inversion package refactor"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%pylab inline\n",
"import numpy\n",
"import matplotlib.pyplot as plt\n",
"import scipy.sparse"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
"For more information, type 'help(pylab)'.\n"
]
}
],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def safe_solve(matrix, vector):\n",
" if scipy.sparse.issparse(matrix) or scipy.sparse.issparse(vector):\n",
" estimate, status = scipy.sparse.linalg.cgs(matrix, vector)\n",
" if status >= 0:\n",
" return estimate\n",
" else:\n",
" raise ValueError('CGS exited with input error')\n",
" else:\n",
" return numpy.linalg.solve(matrix, vector)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Non-linear optimizer\n",
"\n",
"Optimizers receive a list of goal functions, initial estimate and auxiliary variables.\n",
"Goal functions know how to compute their value, gradient and Hessian at a given point in parameter space `p`.\n",
"Goal functions need to be \"moved\" to the computation point before getting these values using the `.at(p)` method call.\n",
"The `.precompute(p)` method call is when the goal functions can compute intensive tasks (like Jacobian matrix building) in order to not repeat the computation when calculating gradient and Hessian."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def levmarq(goals, initial, maxit=30, maxsteps=10, lamb=10, dlamb=2, tol=10**-5, precondition=True):\n",
" nparams = len(initial)\n",
" diag = range(len(initial))\n",
" p = initial\n",
" misfit = sum(g.mu*g.at(p).value() for g in goals)\n",
" for iteration in xrange(maxit):\n",
" [g.precompute() for g in goals]\n",
" if precondition:\n",
" hessian = numpy.zeros((nparams, nparams))\n",
" minus_gradient = numpy.zeros(nparams)\n",
" for g in goals:\n",
" h = g.hessian()\n",
" precond = numpy.abs(h[diag,diag])\n",
" precond[precond < 10**-10] = 10**-10\n",
" hessian += g.mu*(h.T/precond).T\n",
" minus_gradient -= g.mu*g.gradient()/precond\n",
" else:\n",
" hessian = sum(g.mu*g.hessian() for g in goals)\n",
" minus_gradient = -sum(g.mu*g.gradient() for g in goals)\n",
" stagnation = True\n",
" for step in xrange(maxsteps):\n",
" damping = lamb*hessian[diag,diag]\n",
" hessian[diag,diag] += damping\n",
" newp = p + safe_solve(hessian, minus_gradient)\n",
" newmisfit = sum(g.mu*g.at(newp).value() for g in goals)\n",
" if newmisfit >= misfit:\n",
" hessian[diag,diag] -= damping\n",
" if lamb < 10**15:\n",
" lamb *= dlamb\n",
" else:\n",
" if lamb > 10**-15:\n",
" lamb /= float(dlamb)\n",
" stagnation = False\n",
" break\n",
" if stagnation: \n",
" [g.at(p) for g in goals]\n",
" stop = True\n",
" else:\n",
" p = newp\n",
" stop = newmisfit < misfit and abs((newmisfit - misfit)/float(misfit)) < tol\n",
" misfit = newmisfit \n",
" yield p, misfit, {'steps':step + 1, 'stagnation':stagnation, 'lambda':lamb}\n",
" if stop:\n",
" break"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear solver\n",
"\n",
"The linear overdetermined solver asks for the hessian and the gradient calculated at the null vector:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def overdetermined(goals):\n",
" [g.precompute() for g in goals]\n",
" hessian = None\n",
" gradient = None\n",
" for g in goals:\n",
" h = g.hessian()\n",
" if hessian is None and gradient is None:\n",
" nparams = len(h)\n",
" hessian = numpy.zeros((nparams, nparams))\n",
" gradient = numpy.zeros(nparams)\n",
" diag = range(nparams)\n",
" precond = numpy.abs(h[diag,diag])\n",
" precond[precond < 10**-10] = 10**-10\n",
" hessian += g.mu*(h.T/precond).T\n",
" gradient += g.mu*g.gradient_at_null()/precond\n",
" p = safe_solve(hessian, -gradient)\n",
" [g.at(p) for g in goals]\n",
" return p "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Goal functions\n",
"\n",
"An $\\ell_2$-norm goal function. This is a generic goal function and needs to be subclassed in order to be used."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class L2Norm(object):\n",
" def __init__(self, data, weights=None):\n",
" super(L2Norm, self).__init__()\n",
" self.data = data\n",
" self.size = len(data)\n",
" self.mu = 1.\n",
" self._p = None\n",
" self._predicted = None\n",
" self._jacobian = None\n",
" self.weights = weights\n",
" \n",
" def at(self, p):\n",
" self._predicted = self.predicted(p)\n",
" self._p = p\n",
" self._jacobian = None\n",
" return self\n",
" \n",
" def precompute(self):\n",
" self._jacobian = self.jacobian(self._p)\n",
" \n",
" def residuals(self):\n",
" return self.data - self._predicted\n",
"\n",
" def value(self):\n",
" if self.weights is None: \n",
" return numpy.linalg.norm(self.residuals())**2/self.size\n",
" else:\n",
" return numpy.sum(self.weights*(self.residuals()**2))/self.size \n",
" \n",
" def hessian(self):\n",
" if self.weights is None:\n",
" return 2*numpy.dot(self._jacobian.T, self._jacobian)/self.size\n",
" else:\n",
" return 2*numpy.dot(self._jacobian.T, (self.weights*self._jacobian.T).T)/self.size\n",
" \n",
" def gradient(self):\n",
" if self.weights is None:\n",
" return -2*numpy.dot(self._jacobian.T, self.residuals())/self.size\n",
" else:\n",
" return -2*numpy.dot(self._jacobian.T, self.weights*self.residuals())/self.size\n",
" \n",
" def gradient_at_null(self):\n",
" if self.weights is None:\n",
" return -2*numpy.dot(self._jacobian.T, self.data)/self.size\n",
" else:\n",
" return -2*numpy.dot(self._jacobian.T, self.weights*self.data)/self.size\n",
" \n",
" def jacobian(self, p):\n",
" raise NotImplementedError(\"Jacobian matrix not implemented\")\n",
" \n",
" def predicted(self, p):\n",
" raise NotImplementedError(\"Predicted data not implemented\") \n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Regularizing functions are also goal functions:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Damping(object):\n",
" def __init__(self, mu, size):\n",
" super(Damping, self).__init__()\n",
" self.size = size\n",
" self._stored_hessian = 2*numpy.identity(size)\n",
" self.mu = mu\n",
" self._p = None\n",
" \n",
" def at(self, p):\n",
" self._p = p\n",
" return self\n",
" \n",
" def precompute(self):\n",
" pass\n",
" \n",
" def value(self):\n",
" return numpy.linalg.norm(self._p)**2\n",
" \n",
" def hessian(self):\n",
" return self._stored_hessian\n",
" \n",
" def gradient(self):\n",
" return 2*self._p\n",
" \n",
" def gradient_at_null(self):\n",
" return 0\n",
" \n",
"class Smoothness(object): \n",
" def __init__(self, mu, hessian):\n",
" super(Smoothness, self).__init__()\n",
" self.mu = mu\n",
" self._p = None\n",
" self._stored_hessian = hessian\n",
" \n",
" def at(self, p):\n",
" self._p = p\n",
" return self\n",
" \n",
" def precompute(self):\n",
" pass\n",
" \n",
" def value(self):\n",
" # Need to divide by 2 because the hessian is 2*R.T*R\n",
" return numpy.sum(self._p*numpy.dot(self._stored_hessian, self._p))/2.\n",
" \n",
" def hessian(self):\n",
" return self._stored_hessian\n",
" \n",
" def gradient(self):\n",
" return 2*self._p\n",
" \n",
" def gradient_at_null(self):\n",
" return 0\n",
" \n",
"class Smoothness1D(Smoothness):\n",
" def __init__(self, mu, size):\n",
" super(Smoothness1D, self).__init__(mu, self._calculate_hessian(size))\n",
" self.size = size\n",
" \n",
" def _calculate_hessian(self, size):\n",
" fd = numpy.zeros((size - 1, size), dtype='f')\n",
" fd[xrange(size - 1),xrange(size - 1)] = 1\n",
" fd[xrange(size - 1),xrange(1, size)] = -1 \n",
" return 2*numpy.dot(fd.T, fd)\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example use: polynomial regression\n",
"\n",
"This is a problem specific goal function that wraps the data and auxiliary values. It also knows how to compute the Jacobian matrix and predicted data for the case of a second order regression. Since this is a linear problem, the Jacobian can be computed only once."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class PolyData(L2Norm):\n",
" def __init__(self, x, y, weights=None):\n",
" super(PolyData, self).__init__(y, weights)\n",
" self.x = x\n",
" self._stored_jacobian = None\n",
" \n",
" def _calculate_jacobian(self):\n",
" self._stored_jacobian = numpy.transpose([self.x**2, self.x, numpy.ones_like(x)])\n",
" \n",
" def jacobian(self, p):\n",
" if self._stored_jacobian is None:\n",
" self._calculate_jacobian()\n",
" return self._stored_jacobian\n",
"\n",
" def predicted(self, p):\n",
" return numpy.dot(self._stored_jacobian, p)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Testing this on some synthetic data:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def fit(data, initial, log=True, **kwargs):\n",
" for i, step in enumerate(levmarq([data], initial, **kwargs)):\n",
" p, misfit, report = step\n",
" if log:\n",
" print 'estimate:', p.tolist(), misfit, report, 'iterations:', i\n",
" return p"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = numpy.linspace(0, 10, 100)\n",
"numpy.random.seed(1)\n",
"a, b, c = 10, -100, 30000\n",
"y = a*x**2 + b*x + c + numpy.random.normal(scale=20, size=len(x))\n",
"data = PolyData(x, y)\n",
"plt.figure()\n",
"# Use the linear solver\n",
"print \"LINEAR:\"\n",
"print 'estimated:', overdetermined([data]).tolist(), data.value()\n",
"print 'true:', [a, b, c]\n",
"plt.plot(x, y, '.k', x, data._predicted, '-r')\n",
"# Run through the non-linear optimizer\n",
"print \"NON-LINEAR:\"\n",
"fit(data, numpy.array([0, 0, 0])).tolist()\n",
"print 'true:', [a, b, c]\n",
"plt.plot(x, data._predicted, '--b')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"LINEAR:\n",
"estimated: [9.837849810927692, -97.7168087836429, 29995.228005273766] 308.15843054\n",
"true: [10, -100, 30000]\n",
"NON-LINEAR:\n",
"estimate: [9.83784561494896, -97.71676464332248, 29995.22792434797] 308.158430541 {'stagnation': False, 'steps': 1, 'lambda': 7.62939453125e-05} iterations: 16\n",
"true: [10, -100, 30000]\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 9,
"text": [
"[<matplotlib.lines.Line2D at 0x30f3110>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n/fv3iYioqqqKZs6cSc7OzjR8+HBat26d/Fqenp40bNgwcnV1JVdXV7p9+zYRET169IhmzJhBQ4cO\nJQ8PD8rJyWk2lhZCbXdlZWUUGBhIZWVl6rlgUhKRhQXR5ctNdnl6ehIAAkCBgYFK72OMPWHrVqJh\nw4jKy4WOpN2oUm4qPKOoqIhSU1OJiKiiooLs7e0pLS2NJBIJHT9+nIiIIiIiaOXKlURE9M0339DM\nmTOJiOjhw4dka2tLubm5REQklUopJSWlyT02b95MYWFhREQUExNDQUFBantxWicqilL6v0C3f7nd\naLOvry8BIIlE0iQJKdrHmK5ZuHAheXp6kq+vb6O/h/qjiUR9+xJlZAgYXftTe1L4o6lTp1J8fDyZ\nmJjIt+Xl5ZFYLCYiori4OJoyZQrV1dXRnTt3yN7eXv6DkUqldP78+SbX9PHxoaSkJCIiqq2tJXNz\n8+YD1YWkQET/fO4ISQzO0PPPPi//xVb0VKL2JxbGtFhzT85Zh3PIVf8yPfj+iMDRtT+NJoXs7Gwa\nOHAg3b9/n8aOHUv79+8nIqINGzaQsbGx/LjZs2eThYUF9ejRg7766iv5dqlUSo6OjuTq6kqrV6+W\nb3dycqKCggL5/4cMGUJ3795tGmgnSApP+xTzpPraehpn+D09iwiuEmKslf745Fx6o4yGGV6nL2cd\nEzo0QahSbio1S2plZSWmT5+O8PBwGBsbIyIiAkuXLsXq1avh7+8PQ0NDAMDOnTtRVVWFoqIilJaW\nYty4cfDy8sLgwYMRFRWFAQMGoLKyEgEBAdixYweCg4Nb1f6xatUq+fdSqRRSqbRV5wtNmVkW9fT1\nYPLcVlw7+j6m9FqHrVsXtXeYjGmt6Oho+fxEPQx7wE9yGZPFlVgU7Sl0aO0iMTERiYmJbbtIS1mj\npqaGJk2aRBs3bmx2f0ZGBnl4eBARUVhYGO3YsUO+b/78+bRnz54m52zfvp2WLFlCRA3VR2fOnCGi\nzl99pGz9f1lZGc2eOIdsutykXa+fascIGescZPUyWuhwjPwszlJddR0RKfek3tmoUm4q7JJKRFiw\nYAHEYjGWL18u337nzh0AgEwmw5o1a7BoUcOnWQcHBxw92rBQ/YMHD5CUlIThw4ejvr4eJSUlAIDa\n2lp8//33cHZ2BgD4+/sjMjISALBv3z54eXm1Lct1YNHR0Up1gzM1NcXO+Ej8EPMABpFfA6dOKXV9\n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\nAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x2fe9f50>"
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: Gaussian fit\n",
"\n",
"Fit an equation of the form:\n",
"\n",
"$$ f(x) = a\\exp(-b(x + c)^{2}) + d\\exp(-e(x + f)^{2}) $$"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class ExpData(L2Norm):\n",
" def __init__(self, x, y):\n",
" super(ExpData, self).__init__(y)\n",
" self.x = x\n",
" \n",
" def jacobian(self, p):\n",
" jac = numpy.transpose(self._derivs(p[:3]) + self._derivs(p[3:]))\n",
" return jac\n",
" \n",
" def _derivs(self, coefs):\n",
" a, b, c = coefs\n",
" derivs = [\n",
" numpy.exp(-b*(self.x + c)**2),\n",
" # Do a numerical derivative for these two because I'm too lazy to do it by hand\n",
" (a*numpy.exp(-(b + 0.005)*(self.x + c)**2) - a*numpy.exp(-(b - 0.005)*(self.x + c)**2))/0.01,\n",
" (a*numpy.exp(-(b)*(self.x + c + 0.05)**2) - a*numpy.exp(-(b)*(self.x + c - 0.05)**2))/0.1]\n",
" return derivs\n",
" \n",
" def predicted(self, p):\n",
" a, b, c, d, e, f = p\n",
" return a*numpy.exp(-b*(self.x + c)**2) + d*numpy.exp(-e*(self.x + f)**2)\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = numpy.linspace(0, 10, 100)\n",
"numpy.random.seed(1)\n",
"a, b, c = 100, 0.1, -2\n",
"d, e, f = 30, 2, -7\n",
"y = a*numpy.exp(-b*(x + c)**2) + d*numpy.exp(-e*(x + f)**2) + numpy.random.normal(scale=5, size=len(x))\n",
"data = ExpData(x, y)\n",
"coefs = fit(data, numpy.array([1, 1, 1, 1, 1, -9]), lamb=10**5, maxit=100, tol=10**-8)\n",
"print 'true:', [a, b, c, d, e, f]\n",
"plt.figure()\n",
"plt.plot(x, y, '.k', x, data._predicted, '-')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"estimate: [99.11974087126981, 0.09720867295485668, -2.0037337226897325, 29.95772769502588, 1.879659155339882, -6.948228224563931] 18.6717544304 {'stagnation': False, 'steps': 1, 'lambda': 4.6566128730773926e-05} iterations: 34\n",
"true: [100, 0.1, -2, 30, 2, -7]\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 11,
"text": [
"[<matplotlib.lines.Line2D at 0x312a250>,\n",
" <matplotlib.lines.Line2D at 0x312a490>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nRLSVAAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x30036d0>"
]
}
],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: Using weights"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = numpy.linspace(0, 10, 150)\n",
"numpy.random.seed(1)\n",
"d, e, f = 300, 10, -7\n",
"a, b, c = -10, 80, 1000\n",
"y = a*x**2 + b*x + c + d*numpy.exp(-e*(x + f)**2) + numpy.random.normal(scale=20, size=len(x))\n",
"data = PolyData(x, y)\n",
"coefs = overdetermined([data])\n",
"print [a, b, c]\n",
"print coefs.tolist()\n",
"plt.figure()\n",
"plt.plot(x, y, '.k', x, data._predicted, '-')\n",
"# Iteratively re-weight based on the residuals\n",
"for k in xrange(100):\n",
" residuals = numpy.abs(data.residuals())\n",
" residuals[residuals < 10**-8] = 10**-8\n",
" data.weights = 1./residuals\n",
" coefs = overdetermined([data])\n",
"print coefs.tolist()\n",
"plt.plot(x, data._predicted, '--r')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[-10, 80, 1000]\n",
"[-11.374210598582058, 98.14592854854794, 973.3061300816588]\n",
"[-10.2954807027229, 84.96441200274532, 989.7157319402121]\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"[<matplotlib.lines.Line2D at 0x3109f90>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nIF4FNJ3mOKlaatxDfeMDTHXhgjJ2pEcPkeRks8OhZmDRxP/111/L4cOH9RL/8ePH5eTJk6LRaPQS\nf3Z2toSEhEhlZaXk5+eLr6+vaG9XoAwePFiybl83xsTESGpqqkWCtzX1leHFx8fLzp0iPXuK/D/P\nl+Vn1zayq1s3uXz0qIjUTtjVSWbEiBG6ihtjKlEcecBUU2uOk6q5N9zrOynVHA8QGRkpcx58UK6+\n+65Jczjs2iXi66tcmPLPyjZZvKsnPz9fL/FXq5n4ly1bJivuqjEfOXKkfPfdd1JSUiIBAQG67Z9+\n+qk8++yzFgnellV/6QYMiJRJk66LWq2UzC3t00cG1UggNRN2XUnGmEoUR67UaWq2fFKt76RUV0Nk\nIG7PCjpwoDKlp5GuXBGZMUNp/aenN8W7oMawWuJ//vnn5eOPP9b9PnXqVPnss8/k4MGDMmLECN32\nr7/+Wh599FGLBG/LysrKRKNZJD163JKpU+8U6BgzX70tJxlHZcsnVWP+XvT2uXRJZONG5RL0N78x\nqVx42zZl5s/nntOt20M2wNTc6QIbs3jxYt2/NRoNNBqN1WKpT2JiInJzc+Hm5oakpCS4u7vrPV5Z\nCbzx11Y4cXwx1v7bCY8+euexpKQkJCYmYs2aNbrj3N3dsXnzZoP7kHXV/H9kS6r/Xtq1a4e4uLg6\n/y5r/U099RQQFwe88w4wdizw3/8Cbdo0+FrR0cCxY8CcOUBoKLB+PfDQQ0357qguGRkZyMjIMP8J\nGjozGNviX758uSxfvlz3+8iRIyUzM1NKS0v1unqSkpLsvqvHUH/viZxb8pf7/y2XWnvJhV1HrRQh\nOSKz70OYuW7j558rlT8LF7Lu39pMzZ3OjTnrKK+nGD16NDZu3IjKykrk5+cjLy8P4eHh8Pb2RseO\nHZGVlQURwYYNGxAXF9eYl7U6Nzc3AEBYWBjWrFkDABABvvjzIVzp/xCmO/0b7vtS0OWR/rpjEhMT\nodFoEBsbi/Ly8lq/EzVWXX+XRmnVyqzXGzMGOHIEOHQIiIwECgrMehqyBkNnhaefflq6desmrq6u\nolarZd26dfLFF1+IWq2Wtm3bipeXl4waNUq3/9KlS8XX11f69OkjaWlpuu3V5Zy+vr4ya9Ysi521\nLMXUUr2a/b0XzlyWVJ/fy88uXlL0t/frrJio2Rpj6SVZmkXvQ1RVKUN5L19ucNdbt0RefVWZNeKz\n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\n",
"text": [
"<matplotlib.figure.Figure at 0x2fd24d0>"
]
}
],
"prompt_number": 12
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: 2D gravity inversion for the relief of a basin"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from fatiando import gravmag, mesher, utils\n",
"from fatiando.vis import mpl"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Gz(L2Norm):\n",
" def __init__(self, x, z, gz, height, npoints, density):\n",
" super(Gz, self).__init__(gz)\n",
" self.x, self.z = x, z\n",
" self.height = height\n",
" self.nparams = npoints\n",
" self.shape = (self.size, self.nparams)\n",
" self.props = {'density':density}\n",
" self._left, self._right = [[x.min(), -height]], [[x.max(), -height]]\n",
" self._xs = numpy.linspace(x.min(), x.max(), npoints + 2)[::-1][1:-1]\n",
" \n",
" def p2vertices(self, p):\n",
" return self._right + numpy.transpose([self._xs, p]).tolist() + self._left\n",
" \n",
" def jacobian(self, p):\n",
" verts = self.p2vertices(p)\n",
" x, z = self.x, self.z\n",
" xs = self._xs\n",
" dz = 10.\n",
" jac = numpy.zeros(self.shape)\n",
" for i in xrange(self.nparams):\n",
" difference = mesher.Polygon([verts[i+2],[xs[i],p[i]-dz],verts[i],[xs[i],p[i]+dz]], self.props)\n",
" jac[:,i] = numpy.nan_to_num(gravmag.talwani.gz(x, z, [difference]))/(2.*dz)\n",
" return jac\n",
" \n",
" def predicted(self, p):\n",
" vertices = self.p2vertices(p)\n",
" return gravmag.talwani.gz(self.x, self.z, [mesher.Polygon(vertices, self.props)])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 14
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def basin2d(data, damp, smooth, **kwargs):\n",
" goals = [data]\n",
" if damp > 0:\n",
" goals.append(Damping(damp, data.nparams))\n",
" if smooth > 0:\n",
" goals.append(Smoothness1D(smooth, data.nparams))\n",
" initial = 5000*numpy.ones(data.nparams)\n",
" for i, step in enumerate(levmarq(goals, initial, **kwargs)):\n",
" p, misfit, report = step\n",
" print 'iterations:', i+1, report \n",
" return mesher.Polygon(data.p2vertices(p), data.props)\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def mean_polygon(polygons):\n",
" x = numpy.mean([p.x for p in polygons], axis=0)\n",
" y = numpy.mean([p.y for p in polygons], axis=0)\n",
" return mesher.Polygon(numpy.transpose([x, y]).tolist()) "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"x = numpy.linspace(0, 10000, 100)\n",
"z = -10*numpy.ones_like(x)\n",
"xs = numpy.linspace(0, 10000, 100)[::-1]\n",
"depths = -10**-11*(xs - 5000)**4 + 6000 - 5000*numpy.exp(-(xs - 7000)**2/(1000**2))\n",
"depths -= depths.min()\n",
"density = -500\n",
"model = mesher.Polygon(numpy.transpose([xs, depths]), {'density':density})\n",
"gz = utils.contaminate(gravmag.talwani.gz(x, z, [model]), 0.5)\n",
"data = Gz(x, z, gz, 0, 50, density)\n",
"estimate = basin2d(data, 10**-10, 10**-9)\n",
"mpl.figure(figsize=(10,6))\n",
"mpl.subplot(2, 1, 2)\n",
"mpl.polygon(model, fill='gray', alpha=0.5)\n",
"npoints = 50\n",
"estimates = [basin2d(Gz(x, z, utils.contaminate(gz, 0.5), 0, npoints, density), 10**-10, 10**-8)\n",
" for i in xrange(10)]\n",
"mean = mean_polygon(estimates)\n",
"mean.addprop('density', density)\n",
"predicted = gravmag.talwani.gz(x, z, [mean])\n",
"for estimate in estimates:\n",
" mpl.polygon(estimate, '-r')\n",
"mpl.polygon(mean, '-b', linewidth=3) \n",
"mpl.ylim(depths.max() + 1000, depths.min())\n",
"mpl.xlim(x.min(), x.max())\n",
"mpl.m2km()\n",
"mpl.subplot(2, 1, 1)\n",
"mpl.plot(x*0.001, gz, '.k')\n",
"mpl.plot(x*0.001, predicted, '-r')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"iterations: 15 {'stagnation': True, 'steps': 10, 'lambda': 80.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 160.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 320.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 12 {'stagnation': True, 'steps': 10, 'lambda': 10240.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 12 {'stagnation': True, 'steps': 10, 'lambda': 2560.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 320.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': False, 'steps': 9, 'lambda': 10.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': False, 'steps': 8, 'lambda': 5.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 320.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 80.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 320.0}\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 17,
"text": [
"[<matplotlib.lines.Line2D at 0x395ce50>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\ngg==\n",
"text": [
"<matplotlib.figure.Figure at 0x31140d0>"
]
}
],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit basin2d(Gz(x, z, utils.contaminate(gz, 0.5), 0, npoints, density), 10**-10, 10**-8)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"iterations: 11 {'stagnation': True, 'steps': 10, 'lambda': 80.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 12 {'stagnation': True, 'steps': 10, 'lambda': 20480.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 160.0}\n",
"iterations:"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 11 {'stagnation': True, 'steps': 10, 'lambda': 160.0}\n",
"1 loops, best of 3: 1.21 s per loop\n"
]
}
],
"prompt_number": 20
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%prun -T inversion.profile basin2d(Gz(x, z, utils.contaminate(gz, 0.5), 0, npoints, density), 10**-10, 10**-8)\n",
"!cat inversion.profile"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"iterations: 11 {'stagnation': False, 'steps': 10, 'lambda': 20.0}\n",
" \n",
"*** Profile printout saved to text file u'inversion.profile'. \n",
" 53414 function calls (53390 primitive calls) in 1.218 seconds\r\n",
"\r\n",
" Ordered by: internal time\r\n",
"\r\n",
" ncalls tottime percall cumtime percall filename:lineno(function)\r\n",
" 574 0.953 0.002 1.148 0.002 talwani.py:29(gz)\r\n",
" 37928 0.192 0.000 0.192 0.000 talwani.py:59(<lambda>)\r\n",
" 1806 0.017 0.000 0.017 0.000 {numpy.core.multiarray.array}\r\n",
" 11 0.011 0.001 0.786 0.071 <ipython-input-14-a30b6bf021a5>:15(jacobian)\r\n",
" 550 0.007 0.000 0.024 0.000 type_check.py:310(nan_to_num)\r\n",
" 12 0.006 0.000 1.217 0.101 <ipython-input-3-0c488aa3c723>:1(levmarq)\r\n",
" 550 0.005 0.000 0.007 0.000 ufunclike.py:51(isposinf)\r\n",
" 550 0.003 0.000 0.004 0.000 ufunclike.py:113(isneginf)\r\n",
" 575 0.003 0.000 0.019 0.000 mesher.py:86(__init__)\r\n",
" 550 0.003 0.000 0.005 0.000 type_check.py:305(_getmaxmin)\r\n",
" 47 0.002 0.000 0.002 0.000 {numpy.core._dotblas.dot}\r\n",
" 23 0.001 0.000 0.001 0.000 {numpy.linalg.lapack_lite.dgesv}\r\n",
" 596 0.001 0.000 0.001 0.000 {method 'get' of 'dict' objects}\r\n",
" 1101 0.001 0.000 0.001 0.000 {numpy.core.multiarray.empty}\r\n",
" 1230 0.001 0.000 0.003 0.000 numeric.py:167(asarray)\r\n",
" 574 0.001 0.000 0.001 0.000 {numpy.core.multiarray.empty_like}\r\n",
" 550 0.001 0.000 0.002 0.000 getlimits.py:91(__new__)\r\n",
" 574 0.001 0.000 0.002 0.000 numeric.py:65(zeros_like)\r\n",
" 575 0.001 0.000 0.001 0.000 mesher.py:47(__init__)\r\n",
" 575 0.001 0.000 0.001 0.000 {method 'fill' of 'numpy.ndarray' objects}\r\n",
" 550 0.001 0.000 0.001 0.000 {method 'copy' of 'numpy.ndarray' objects}\r\n",
" 48 0.000 0.000 0.001 0.000 linalg.py:1840(norm)\r\n",
" 1215 0.000 0.000 0.000 0.000 {issubclass}\r\n",
" 23 0.000 0.000 0.003 0.000 linalg.py:244(solve)\r\n",
" 11 0.000 0.000 0.002 0.000 <ipython-input-5-b05f5f62e4f1>:30(hessian)\r\n",
" 46 0.000 0.000 0.000 0.000 {numpy.core.multiarray._fastCopyAndTranspose}\r\n",
" 92 0.000 0.000 0.399 0.004 <ipython-input-3-0c488aa3c723>:25(<genexpr>)\r\n",
" 36 0.000 0.000 0.001 0.000 fromnumeric.py:445(transpose)\r\n",
" 46 0.000 0.000 0.000 0.000 sputils.py:116(_isinstance)\r\n",
" 24 0.000 0.000 0.417 0.017 <ipython-input-14-a30b6bf021a5>:26(predicted)\r\n",
" 58 0.000 0.000 0.000 0.000 {numpy.core.multiarray.zeros}\r\n",
" 24 0.000 0.000 0.417 0.017 <ipython-input-5-b05f5f62e4f1>:12(at)\r\n",
" 24 0.000 0.000 0.001 0.000 <ipython-input-6-ea9f059183fa>:42(value)\r\n",
" 36 0.000 0.000 0.001 0.000 <ipython-input-14-a30b6bf021a5>:12(p2vertices)\r\n",
" 24 0.000 0.000 0.001 0.000 <ipython-input-5-b05f5f62e4f1>:24(value)\r\n",
" 36 0.000 0.000 0.000 0.000 {method 'tolist' of 'numpy.ndarray' objects}\r\n",
" 36 0.000 0.000 0.001 0.000 fromnumeric.py:32(_wrapit)\r\n",
" 1 0.000 0.000 0.000 0.000 utils.py:494(contaminate)\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-5-b05f5f62e4f1>:36(gradient)\r\n",
" 23 0.000 0.000 0.000 0.000 linalg.py:99(_commonType)\r\n",
" 35 0.000 0.000 0.000 0.000 <ipython-input-5-b05f5f62e4f1>:21(residuals)\r\n",
" 11 0.000 0.000 0.786 0.071 <ipython-input-5-b05f5f62e4f1>:18(precompute)\r\n",
" 48 0.000 0.000 0.000 0.000 {method 'reduce' of 'numpy.ufunc' objects}\r\n",
" 23 0.000 0.000 0.003 0.000 <ipython-input-2-1bc112e6e8bc>:1(safe_solve)\r\n",
" 693 0.000 0.000 0.000 0.000 {len}\r\n",
" 24 0.000 0.000 0.419 0.017 {sum}\r\n",
" 24 0.000 0.000 0.000 0.000 {method 'sum' of 'numpy.ndarray' objects}\r\n",
" 1 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:60(_calculate_hessian)\r\n",
" 48/24 0.000 0.000 0.419 0.017 fromnumeric.py:1379(sum)\r\n",
" 23 0.000 0.000 0.000 0.000 linalg.py:139(_fastCopyAndTranspose)\r\n",
" 100 0.000 0.000 0.000 0.000 {isinstance}\r\n",
" 1 0.000 0.000 1.217 1.217 <ipython-input-15-eee163cd81cf>:1(basin2d)\r\n",
" 71 0.000 0.000 0.000 0.000 {method 'ravel' of 'numpy.ndarray' objects}\r\n",
" 24 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:16(value)\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:49(gradient)\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:22(gradient)\r\n",
" 23 0.000 0.000 0.000 0.000 linalg.py:127(_to_native_byte_order)\r\n",
" 92 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects}\r\n",
" 46 0.000 0.000 0.000 0.000 linalg.py:66(_makearray)\r\n",
" 46 0.000 0.000 0.000 0.000 base.py:548(isspmatrix)\r\n",
" 1 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:2(__init__)\r\n",
" 23 0.000 0.000 0.000 0.000 {method 'astype' of 'numpy.ndarray' objects}\r\n",
" 23 0.000 0.000 0.000 0.000 linalg.py:157(_assertSquareness)\r\n",
" 23 0.000 0.000 0.000 0.000 linalg.py:151(_assertRank2)\r\n",
" 1 0.000 0.000 0.000 0.000 function_base.py:6(linspace)\r\n",
" 82 0.000 0.000 0.000 0.000 {getattr}\r\n",
" 100 0.000 0.000 0.000 0.000 {method 'normal' of 'mtrand.RandomState' objects}\r\n",
" 6 0.000 0.000 0.000 0.000 iostream.py:177(write)\r\n",
" 48 0.000 0.000 0.000 0.000 {method 'conj' of 'numpy.ndarray' objects}\r\n",
" 46 0.000 0.000 0.000 0.000 linalg.py:84(_realType)\r\n",
" 69 0.000 0.000 0.000 0.000 linalg.py:71(isComplexType)\r\n",
" 36 0.000 0.000 0.000 0.000 {method 'transpose' of 'numpy.ndarray' objects}\r\n",
" 1 0.000 0.000 0.000 0.000 <ipython-input-14-a30b6bf021a5>:2(__init__)\r\n",
" 2 0.000 0.000 0.000 0.000 {method 'min' of 'numpy.ndarray' objects}\r\n",
" 1 0.000 0.000 1.218 1.218 <string>:1(<module>)\r\n",
" 4 0.000 0.000 0.020 0.005 <ipython-input-3-0c488aa3c723>:5(<genexpr>)\r\n",
" 23 0.000 0.000 0.000 0.000 {max}\r\n",
" 24 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:9(at)\r\n",
" 24 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:35(at)\r\n",
" 48 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}\r\n",
" 6 0.000 0.000 0.000 0.000 iostream.py:87(_check_mp_mode)\r\n",
" 1 0.000 0.000 0.000 0.000 numeric.py:1830(identity)\r\n",
" 6 0.000 0.000 0.000 0.000 {_codecs.utf_8_decode}\r\n",
" 1 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:56(__init__)\r\n",
" 2 0.000 0.000 0.000 0.000 {method 'max' of 'numpy.ndarray' objects}\r\n",
" 1 0.000 0.000 0.000 0.000 <ipython-input-5-b05f5f62e4f1>:2(__init__)\r\n",
" 6 0.000 0.000 0.000 0.000 {method 'decode' of 'str' objects}\r\n",
" 1 0.000 0.000 0.000 0.000 numeric.py:1791(ones)\r\n",
" 6 0.000 0.000 0.000 0.000 utf_8.py:15(decode)\r\n",
" 1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.arange}\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:19(hessian)\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:46(hessian)\r\n",
" 1 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:29(__init__)\r\n",
" 23 0.000 0.000 0.000 0.000 {min}\r\n",
" 23 0.000 0.000 0.000 0.000 {method '__array_prepare__' of 'numpy.ndarray' objects}\r\n",
" 6 0.000 0.000 0.000 0.000 iostream.py:78(_is_master_process)\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:39(precompute)\r\n",
" 6 0.000 0.000 0.000 0.000 {method 'write' of '_io.StringIO' objects}\r\n",
" 11 0.000 0.000 0.000 0.000 <ipython-input-6-ea9f059183fa>:13(precompute)\r\n",
" 6 0.000 0.000 0.000 0.000 {time.time}\r\n",
" 6 0.000 0.000 0.000 0.000 {posix.getpid}\r\n",
" 1 0.000 0.000 0.000 0.000 {range}\r\n",
" 11 0.000 0.000 0.000 0.000 {abs}\r\n",
" 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}"
]
}
],
"prompt_number": 23
},
{
"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