Files
simpeg/notebooks/Bound Constraint Problem.ipynb
T
2013-11-07 01:20:03 -08:00

702 lines
74 KiB
Plaintext

{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"import SimPEG\n",
"from SimPEG.mesh import TensorMesh\n",
"from SimPEG.regularization import Regularization\n",
"import SimPEG.inverse as inverse\n",
"from SimPEG.inverse import Minimize\n",
"import numpy as np\n",
"import scipy.sparse as sp"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from SimPEG.forward.LinearProblem import example as LinExample\n",
"\n",
"prob, m_true = LinExample(1000)\n",
"M = prob.mesh\n",
"\n",
"reg = Regularization(M)\n",
"opt = inverse.InexactGaussNewton(maxIter=100,debug=False,LSreduction=0.3,maxIterLS=50)\n",
"inv = inverse.Inversion(prob,reg,opt,beta0=1e-4,maxIter=1)\n",
"m0 = np.zeros_like(m_true)\n",
"\n",
"mrec = inv.run(m0)\n",
"\n",
"# plt.figure(1)\n",
"# for i in range(prob.G.shape[0]):\n",
"# plt.plot(prob.G[i,:])\n",
"\n",
"plt.figure(2)\n",
"\n",
"plt.plot(M.vectorCCx, m_true, 'b-')\n",
"plt.plot(M.vectorCCx, mrec, 'r-')\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"============================== Inexact Gauss Newton ==============================\n",
" # beta phi_d phi_m f |g| LS \n",
"----------------------------------------------------------------------------------\n",
" 1 1.00e-04 6.06e-01 2.68e+04 9.57e+02 1.01e+04 0 \n",
" 2 1.00e-04 8.27e-02 2.29e+04 3.29e+00 1.66e+01 0 \n",
" 3 1.00e-04 4.60e-02 2.28e+04 2.37e+00 1.61e+02 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 4 1.00e-04 3.80e-02 2.28e+04 2.33e+00 8.23e-01 0 \n",
" 5 1.00e-04 3.09e-02 2.28e+04 2.31e+00 6.80e-01 0 \n",
" 6 1.00e-04 2.91e-02 2.27e+04 2.31e+00 5.15e-01 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 7 1.00e-04 2.59e-02 2.27e+04 2.30e+00 3.81e-01 0 \n",
" 8 1.00e-04 2.53e-02 2.27e+04 2.30e+00 3.56e-01 0 \n",
" 9 1.00e-04 2.34e-02 2.27e+04 2.30e+00 2.73e-01 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 10 1.00e-04 2.31e-02 2.27e+04 2.30e+00 2.72e-01 0 \n",
" 11 1.00e-04 2.17e-02 2.27e+04 2.30e+00 2.17e-01 0 \n",
" 12 1.00e-04 2.15e-02 2.27e+04 2.30e+00 2.25e-01 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 13 1.00e-04 2.04e-02 2.27e+04 2.29e+00 1.84e-01 0 \n",
" 14 1.00e-04 2.03e-02 2.27e+04 2.29e+00 1.96e-01 0 \n",
" 15 1.00e-04 1.93e-02 2.27e+04 2.29e+00 1.59e-01 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 16 1.00e-04 1.93e-02 2.27e+04 2.29e+00 1.78e-01 0 \n",
" 17 1.00e-04 1.85e-02 2.27e+04 2.29e+00 1.40e-01 0 \n",
" 18 1.00e-04 1.84e-02 2.27e+04 2.29e+00 1.50e-01 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 19 1.00e-04 1.77e-02 2.27e+04 2.29e+00 1.24e-01 0 \n",
" 20 1.00e-04 1.77e-02 2.27e+04 2.29e+00 1.30e-01 0 \n",
" 21 1.00e-04 1.71e-02 2.27e+04 2.29e+00 1.08e-01 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 22 1.00e-04 1.72e-02 2.27e+04 2.29e+00 1.15e-01 0 \n",
"------------------------- STOP! -------------------------\n",
"1 : |fc-fOld| = 2.0822e-04 <= tolF*(1+|f0|) = 9.5809e+01\n",
"1 : |xc-x_last| = 7.3609e-03 <= tolX*(1+|x0|) = 1.0000e-01\n",
"1 : |g| = 9.5181e-02 <= tolG = 1.0000e-01\n",
"0 : |g| = 9.5181e-02 <= 1e3*eps = 1.0000e-02\n",
"0 : maxIter = 100 <= iter = 22\n",
"------------------------- DONE! -------------------------\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"[<matplotlib.lines.Line2D at 0x10eb75fd0>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nXHrhBXjySXMtgQsKfvE3h2WFauxaSQ6HgwpSioSRGjXM7MY1anjwpNOnzc1Zdu2CGwJ816utWyEp\nCXJzoU4dl6ucPw/165uvItfyJjvVjpCw53F7ok4dczHX4sUBqaeE6dMhPb3U0Ae1+MX/vD6cTp06\nxV133UXz5s25++67OX36tMv1WrZsSVxcHPHx8SQmJnpdqIg3vOrqARg1ChYs8Hs9Jezcaa4UfvTR\nMlfTVbvib14H/6xZs2jevDk7duygadOmvPHGGy7XczgcZGRksGHDBrKzs70uVCSohg2D9evh0KHA\nbePFF03o16tX5mq6alf8zevDKTs7m4ceeogaNWowZswYssq4iYX67iVUvG7x16wJ99wDc+b4uyTj\nn/+EJUtMN0851NUj/hbh7RNzcnKIjY0FIDY2ttTWvMPhYODAgbRq1YoxY8YwYsQIbzcp4jGHAxYu\n9PDk7iWRLR+h18uj+Kjl7/yevL1e/ldODHqSrSsjy133zBkFv/hXmcE/aNAgDh8+7PTzF154we1W\n/FdffcWNN97I1q1bGT58OImJiTRu3NjlulOnTi3+d1JSEklJSW5tQ6Q0v/mND0PyrQTaXqjL9tmf\ns7nRbX6rqXX+OgZ99xV/aDKHC26eP374Yb9tXiq5jIwMMjIyfHoNr4dzjhw5kmeeeYb4+HjWr1/P\niy++yMKFC8t8zqRJk+jQoQOPPPKIcyEazikV0euvmzn633/ff685aBCkpEBamv9eU2wrqMM5e/To\nwdtvv825c+d4++236dmzp9M6Z8+e5dSlOxrl5eWxYsUKhg4d6u0mRYLv/vvhs89gzx7/vN5HH8G+\nfaVepSsSDF4H/7hx49i3bx/t27fnwIEDjB07FoCDBw+SnJwMwOHDh+nbty9dunRh1KhRPPnkkzRr\n1sw/lYsEw/XXm36Wl17y/bXOnYMJE2DmTJdz8ogEi67cFSnPoUPQsaMZidOwofevM3UqbNkS3Okg\nJOx5k50KfhF3pKdDYSG89pp3z9+2zdzQ/dtvoWlT/9YmtqbgFwmUY8cgNhbWrIF27Tx77oUL0KsX\nPPIIXOoSFfEXzdUjEihRUfD00zBunLmiyhPPPgtNmmgUj1QYCn4Rdz3+uJm5s5TpSVx6/32YNw/+\n53804Y5UGOrqEfHEtm3Qrx/87//CrbeWvW5mphmvv3IldOkSnPrEdtTVIxJosbHw17/CL38JGzaU\n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\n",
"text": [
"<matplotlib.figure.Figure at 0x10eb75850>"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n",
"\n",
"def Quadratic(x, return_g=True, return_H=True):\n",
" A = sp.identity(2)\n",
" b = np.array([-5,-5])\n",
" f = 0.5 * x.dot( A.dot(x)) + b.dot( x )\n",
" out = (f,)\n",
" if return_g:\n",
" g = A.dot(x) + b\n",
" out += (g,)\n",
" if return_H:\n",
" H = A\n",
" out += (H,)\n",
" return out\n",
"\n",
"\n",
"f = Quadratic(np.array([1,2]))\n",
"print f\n",
"n = 30\n",
"l = -10\n",
"u = 10\n",
"I = np.zeros((n,n))\n",
"X = np.linspace(l,u,n)\n",
"for i, x in enumerate(X):\n",
" for j, y in enumerate(X):\n",
" f, g, H = Quadratic(np.array([x,y]))\n",
" I[i,j] = f\n",
"\n",
"contourf(X,X, I.T)\n",
"\n",
"GN = inverse.GaussNewton()\n",
"xopt = GN.minimize(Quadratic,np.array([0,0]))\n",
"print xopt"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(-12.5, array([-4., -3.]), <2x2 sparse matrix of type '<type 'numpy.float64'>'\n",
"\twith 2 stored elements (1 diagonals) in DIAgonal format>)\n",
"=============== Gauss Newton ==============="
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" # f |g| LS \n",
"-------------------------------------------\n",
" 1 0.00e+00 7.07e+00 0 \n",
"------------------------- STOP! -------------------------\n",
"0 : |fc-fOld| = 2.5000e+01 <= tolF*(1+|f0|) = 1.0000e-01\n",
"0 : |xc-x_last| = 7.0711e+00 <= tolX*(1+|x0|) = 1.0000e-01\n",
"1 : |g| = 0.0000e+00 <= tolG = 1.0000e-01\n",
"1 : |g| = 0.0000e+00 <= 1e3*eps = 1.0000e-02\n",
"0 : maxIter = 20 <= iter = 1\n",
"------------------------- DONE! -------------------------\n",
"[ 5. 5.]\n"
]
},
{
"output_type": "stream",
"stream": "stderr",
"text": [
"/Users/rowan/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/scipy/sparse/linalg/dsolve/linsolve.py:87: SparseEfficiencyWarning: spsolve requires A be CSC or CSR matrix format\n",
" warn('spsolve requires A be CSC or CSR matrix format', SparseEfficiencyWarning)\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nTp06pVOnTqm1tdX2SN55+eWX1dXVpWPHjmnHjh26fPmy7ZG8lslk1NPTo1OnTqmvr8/2ON5ZvXr1\nmM3azp07VV1drXPnzqmqqkq7du0a9z7KHvna2lrdd999Y66/9U1Ujz322PCbqFAYTt+Kd+XKFUlS\nS0uL5syZo2XLlqm3t9fyVP7jZ7J4ixYt0p133jniur6+Pq1du1ZTp07VmjVrJvwZLXvkc8n1JioU\nprOzU83NzXr77bd5kCxQf3//iHdyz58/XydPnrQ4kf8ymYyWLFmitrY27d+/3/Y4Qbj157S2tnbC\nTsb+jlfJ3zdR+SDX93br1q3asGGDXn/9dV29elUdHR3q6urS5s2bLUwJXHfixAlVVlZqYGBAy5cv\n18KFCzVr1izbY3mt0H8ZJRL5o0ePFnybpqYmHTt2bPjy2bNn1dhYhl/G4pl8vrczZszQSy+9pPb2\ndiJfgMbGRnV0dAxfPnPmDM9rlKiyslKSVFdXpxUrVujAgQNat26d5an81tjYqIGBATU0NGhgYGDC\nTlo9rhn9JqrDhw/r0qVL6unpyfkmKuT2/fffS5KuXbumv/3tb3r66actT+SXGTNmSLr+CpuLFy/q\n6NGjampqsjyVv37//ffhI8Off/5Zhw8f5kEzBk1NTeru7tYff/yh7u5uNTc3j3+Dgn+PQYn27t0b\nVVVVRXfccUdUUVERtba2Dn9u27ZtUU1NTVRXVxcdP3683KN57/nnn4/q6+ujhx9+OHrllVeiX375\nxfZI3unp6Ylqa2ujmpqa6L333rM9jtcuXLgQLViwIFqwYEG0ZMmS6KOPPrI9kneeffbZqLKyMpoy\nZUpUVVUVdXd3R1evXo1WrFgRzZ49O1q5cmU0ODg47n3wZigACJgzr64BAMSPyANAwIg8AASMyANA\nwIg8AASMyANAwIg8AASMyANAwP4fypiXapu5o/wAAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x10f7ee5d0>"
]
}
],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n",
"\n",
"class ProjectedGradient(Minimize):\n",
" name = 'Projected Gradient'\n",
"\n",
" maxIterCG = 10\n",
" tolCG = 1e-3\n",
" \n",
" lower = -0.4\n",
" upper = 0.9\n",
" \n",
" def __init__(self,**kwargs):\n",
" super(ProjectedGradient, self).__init__(**kwargs)\n",
" \n",
" self.stoppers.append({\n",
" \"str\": \"%d : probSize = %3d <= bindingSet = %3d\",\n",
" \"left\": lambda M: M.xc.size,\n",
" \"right\": lambda M: np.sum(M.bindingSet(M.xc)),\n",
" \"stopType\": \"critical\"\n",
" })\n",
" \n",
" self.stoppersLS.append({\n",
" \"str\": \"%d : probSize = %3d <= bindingSet = %3d\",\n",
" \"left\": lambda M: M._LS_xt.size,\n",
" \"right\": lambda M: np.sum(M.bindingSet(M._LS_xt)),\n",
" \"stopType\": \"critical\"\n",
" })\n",
" \n",
" self.printers.append({\"title\": \"itType\",\n",
" \"value\": lambda M: M._itType,\n",
" \"width\": 8, \"format\": \"%s\"})\n",
" self.printers.append({\"title\": \"aSet\",\n",
" \"value\": lambda M: np.sum(M.activeSet(M.xc)),\n",
" \"width\": 8, \"format\": \"%d\"})\n",
" self.printers.append({\"title\": \"bSet\",\n",
" \"value\": lambda M: np.sum(M.bindingSet(M.xc)),\n",
" \"width\": 8, \"format\": \"%d\"})\n",
" self.printers.append({\"title\": \"Comment\",\n",
" \"value\": lambda M: M.projComment,\n",
" \"width\": 7, \"format\": \"%s\"})\n",
" \n",
"\n",
" def _startup(self, x0):\n",
" # ensure bound vectors are the same size as the model\n",
" if type(self.lower) is not np.ndarray:\n",
" self.lower = np.ones_like(x0)*self.lower\n",
" if type(self.upper) is not np.ndarray:\n",
" self.upper = np.ones_like(x0)*self.upper\n",
" \n",
" self.explorePG = True\n",
" self.exploreCG = False\n",
" self.stopDoingCG = False\n",
" \n",
" self._itType = 'SD'\n",
" \n",
" self.aSet_prev = self.activeSet(x0)\n",
" \n",
" def projection(self, x):\n",
" \"\"\"Make sure we are feasible.\"\"\"\n",
" return np.median(np.c_[self.lower,x,self.upper],axis=1)\n",
" \n",
" def activeSet(self, x):\n",
" \"\"\"If we are on a bound\"\"\"\n",
" return np.logical_or(x == self.lower, x == self.upper)\n",
" \n",
" def inactiveSet(self, x):\n",
" \"\"\"The free variables.\"\"\"\n",
" return np.logical_not(self.activeSet(x))\n",
" \n",
" def bindingSet(self, x):\n",
" \"\"\"\n",
" If we are on a bound and the negative gradient points away from the feasible set. \n",
" \n",
" Optimality condition. (Satisfies Kuhn-Tucker) MoreToraldo91\n",
" \n",
" \"\"\"\n",
" bind_up = np.logical_and(x == self.lower, self.g >= 0)\n",
" bind_low = np.logical_and(x == self.upper, self.g <= 0)\n",
" return np.logical_or(bind_up, bind_low)\n",
" \n",
" def findSearchDirection(self):\n",
" self.aSet_prev = self.activeSet(self.xc)\n",
"# print 'fsd: stopDoingCG: ', self.stopDoingCG\n",
" if self.explorePG or not self.exploreCG:\n",
"# print 'fsd: doingCG'\n",
" self._itType = 'SD'\n",
" p = -self.g\n",
" else:\n",
" self.f_decrease_max = -np.inf # Reset the max decrease each time you do a CG iteration\n",
" self._itType = '.CG.'\n",
" iSet = self.inactiveSet(self.xc) # The inactive set (free variables)\n",
" aSet = self.activeSet(self.xc)\n",
" bSet = self.bindingSet(self.xc)\n",
" shape = (self.xc.size, np.sum(iSet))\n",
" v = np.ones(shape[1])\n",
" i = np.where(iSet)[0]\n",
" j = np.arange(shape[1])\n",
" Z = sp.csr_matrix((v, (i, j)), shape=shape)\n",
" def reduceHess(v):\n",
" # Z is tall and skinny\n",
" return Z.T*(self.H*(Z*v))\n",
" operator = sp.linalg.LinearOperator( (shape[1], shape[1]), reduceHess, dtype=float )\n",
" p, info = sp.linalg.cg(operator, -Z.T*self.g, tol=self.tolCG, maxiter=self.maxIterCG)\n",
" p = Z*p # bring up to full size\n",
" aSet_after = self.activeSet(self.xc+p)\n",
" return p\n",
" \n",
" def _doEndIteration(self, xt):\n",
" aSet = self.activeSet(xt)\n",
" bSet = self.bindingSet(xt)\n",
" \n",
" self.explorePG = not np.all(aSet == self.aSet_prev) # explore proximal gradient\n",
" self.exploreCG = np.all(aSet == bSet) # explore conjugate gradient\n",
" \n",
" f_current_decrease = self.f_last - self.f\n",
" self.projComment = ''\n",
"# print f_current_decrease\n",
" if self._iter < 1:\n",
" self.f_decrease_max = -np.inf\n",
" else:\n",
" # Note that I reset this if we do a CG iteration.\n",
" self.f_decrease_max = max(self.f_decrease_max, f_current_decrease)\n",
" self.stopDoingCG = f_current_decrease < 0.25 * self.f_decrease_max\n",
"# print 'f_decrease_max: ', self.f_decrease_max\n",
"# print 'stopDoingCG: ', self.stopDoingCG\n",
" if self.stopDoingCG:\n",
" self.projComment = 'Stop SD'\n",
" self.explorePG = False\n",
" self.exploreCG = True\n",
" # implement 3.8, MoreToraldo91\n",
" #self.eta_2 * max_decrease # where max decrease\n",
" # if true go to CG\n",
" # don't do too many steps of PG in a row."
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"opt = ProjectedGradient(maxIter=20,maxStep=0.2, maxIterLS=20)\n",
"\n",
"opt.lower = np.array([-1,-1])\n",
"opt.upper = np.array([1,1])\n",
"opt.minimize(Quadratic,np.array([0,0.2]))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"=========================== Projected Gradient ===========================\n",
" # f |g| LS itType aSet bSet Comment\n",
"--------------------------------------------------------------------------\n",
" 1 -9.80e-01 6.93e+00 0 SD 0 0 \n",
" 2 -2.86e+00 6.65e+00 0 .CG. 0 0 \n",
" 3 -4.67e+00 6.38e+00 0 .CG. 0 0 \n",
" 4 -6.40e+00 6.10e+00 0 .CG. 0 0 \n",
" 5 -8.05e+00 5.82e+00 0 .CG. 2 2 \n",
"------------------------- STOP! -------------------------\n",
"0 : |fc-fOld| = 9.4851e-01 <= tolF*(1+|f0|) = 1.9800e-01\n",
"0 : |xc-x_last| = 2.0254e-01 <= tolX*(1+|x0|) = 1.2000e-01\n",
"0 : |g| = 1.4142e+00 <= tolG = 1.0000e-01\n",
"0 : |g| = 5.6569e+00 <= 1e3*eps = 1.0000e-02\n",
"0 : maxIter = 20 <= iter = 5\n",
"1 : probSize = 2 <= bindingSet = 2\n",
"------------------------- DONE! -------------------------\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"array([ 1., 1.])"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"opt = ProjectedGradient(maxIter=50, maxStep=0.3,debug=False, maxIterLS=20, tolCG=1e-5, maxIterCG=1000)\n",
"opt.lower = -0.4\n",
"opt.upper = 0.9\n",
"inv = inverse.Inversion(prob,reg,opt,beta0=1e-4)\n",
"m0 = np.zeros_like(m_true)\n",
"\n",
"mrecB = inv.run(m0)\n",
"\n",
"\n",
"plt.figure(2)\n",
"\n",
"plt.plot(M.vectorCCx, m_true, 'b-')\n",
"plt.plot(M.vectorCCx, mrecB, 'r-')\n",
"\n",
"plt.figure(3)\n",
"\n",
"plt.plot(M.vectorCCx, m_true, 'b-')\n",
"plt.plot(M.vectorCCx, mrec, 'r-')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"=============================================== Projected Gradient ===============================================\n",
" # beta phi_d phi_m f |g| LS itType aSet bSet Comment\n",
"-----------------------------------------------------------------------------------------------------------------\n",
" 1 1.00e-04 9.56e+02 5.53e-03 9.57e+02 1.01e+04 10 SD 0 0 \n",
" 2 1.00e-04 5.34e+02 1.46e+03 9.56e+02 9.45e+03 0 .CG. 0 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 3 1.00e-04 2.33e+02 5.85e+03 5.34e+02 7.06e+03 0 .CG. 0 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 4 1.00e-04 1.35e+02 9.13e+03 2.34e+02 4.66e+03 1 .CG. 18 18 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 5 1.00e-04 1.29e+02 9.13e+03 1.36e+02 8.72e+03 10 SD 18 18 \n",
" 6 1.00e-04 1.10e+02 1.30e+04 1.30e+02 3.33e+03 1 .CG. 59 0 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 7 1.00e-04 6.32e+01 1.30e+04 1.11e+02 2.29e+04 9 SD 59 59 \n",
" 8 1.00e-04 6.02e+01 1.34e+04 6.45e+01 1.14e+03 4 .CG. 79 9 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 9 1.00e-04 5.86e+01 1.34e+04 6.15e+01 4.44e+03 11 SD 77 77 Stop SD\n",
" 10 1.00e-04 4.10e+01 1.59e+04 6.00e+01 1.56e+03 2 .CG. 117 17 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 11 1.00e-04 4.06e+01 1.59e+04 4.26e+01 2.11e+03 12 SD 106 106 \n",
" 12 1.00e-04 4.06e+01 1.59e+04 4.22e+01 8.79e+02 14 SD 13 13 Stop SD\n",
" 13 1.00e-04 4.06e+01 1.59e+04 4.22e+01 3.39e+02 15 .CG. 117 116 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 14 1.00e-04 4.06e+01 1.59e+04 4.22e+01 3.61e+02 15 SD 116 116 Stop SD\n",
" 15 1.00e-04 3.03e+01 1.89e+04 4.22e+01 4.18e+01 2 .CG. 152 152 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 16 1.00e-04 2.86e+01 1.89e+04 3.22e+01 4.58e+03 11 SD 128 128 \n",
" 17 1.00e-04 2.85e+01 1.89e+04 3.05e+01 1.39e+03 13 SD 9 9 Stop SD\n",
" 18 1.00e-04 2.85e+01 1.89e+04 3.04e+01 1.06e+03 16 .CG. 30 30 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 19 1.00e-04 2.85e+01 1.89e+04 3.04e+01 1.06e+03 13 SD 131 131 Stop SD\n",
" 20 1.00e-04 2.84e+01 1.90e+04 3.04e+01 4.37e+02 8 .CG. 152 39 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 21 1.00e-04 2.84e+01 1.90e+04 3.03e+01 1.22e+03 13 SD 30 30 Stop SD\n",
" 22 1.00e-04 2.84e+01 1.90e+04 3.03e+01 1.22e+03 16 .CG. 37 17 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 23 1.00e-04 2.83e+01 1.90e+04 3.03e+01 1.22e+03 13 SD 131 131 \n",
" 24 1.00e-04 2.83e+01 1.90e+04 3.02e+01 2.77e+02 16 SD 34 34 \n",
" 25 1.00e-04 2.83e+01 1.90e+04 3.02e+01 4.10e+01 17 SD 146 146 Stop SD\n",
" 26 1.00e-04 2.74e+01 1.99e+04 3.02e+01 6.13e+01 4 .CG. 155 155 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 27 1.00e-04 2.60e+01 1.99e+04 2.94e+01 4.10e+03 12 SD 29 29 \n",
" 28 1.00e-04 2.60e+01 1.99e+04 2.80e+01 7.89e+02 13 SD 12 12 \n",
" 29 1.00e-04 2.59e+01 1.99e+04 2.80e+01 7.15e+02 14 SD 34 34 Stop SD\n",
" 30 1.00e-04 2.59e+01 1.99e+04 2.79e+01 5.00e+02 15 .CG. 46 29 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 31 1.00e-04 2.59e+01 1.99e+04 2.79e+01 5.00e+02 14 SD 118 118 Stop SD\n",
" 32 1.00e-04 1.27e+01 3.53e+04 2.79e+01 2.46e+02 0 .CG. 248 117 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 33 1.00e-04 1.25e+01 3.53e+04 1.63e+01 1.88e+03 12 SD 167 167 \n",
" 34 1.00e-04 1.24e+01 3.53e+04 1.61e+01 1.08e+03 14 SD 12 12 Stop SD\n",
" 35 1.00e-04 1.24e+01 3.53e+04 1.60e+01 1.45e+02 16 .CG. 148 148 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 36 1.00e-04 1.24e+01 3.53e+04 1.60e+01 1.49e+02 16 SD 156 156 Stop SD\n",
" 37 1.00e-04 1.24e+01 3.53e+04 1.60e+01 4.08e+01 14 .CG. 233 233 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 38 1.00e-04 1.24e+01 3.53e+04 1.60e+01 7.16e+01 18 SD 176 176 Stop SD\n",
" 39 1.00e-04 1.24e+01 3.53e+04 1.60e+01 2.20e+01 12 .CG. 243 241 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 40 1.00e-04 1.24e+01 3.53e+04 1.60e+01 1.63e+02 16 SD 185 185 \n",
" 41 1.00e-04 1.24e+01 3.53e+04 1.60e+01 2.89e+01 19 SD 206 206 \n",
" 42 1.00e-04 1.24e+01 3.53e+04 1.60e+01 2.48e+01 18 SD 221 221 Stop SD\n",
" 43 1.00e-04 1.23e+01 3.54e+04 1.60e+01 3.12e+01 6 .CG. 243 242 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 44 1.00e-04 1.23e+01 3.54e+04 1.59e+01 1.25e+03 13 SD 84 84 \n",
" 45 1.00e-04 1.22e+01 3.54e+04 1.59e+01 1.16e+03 13 SD 20 20 \n",
" 46 1.00e-04 1.22e+01 3.54e+04 1.58e+01 3.53e+02 15 SD 26 26 \n",
" 47 1.00e-04 1.22e+01 3.54e+04 1.58e+01 2.58e+02 15 SD 43 43 Stop SD\n",
" 48 1.00e-04 1.22e+01 3.54e+04 1.58e+01 1.18e+02 12 .CG. 211 100 "
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
" 49 1.00e-04 1.22e+01 3.54e+04 1.58e+01 1.04e+02 16 SD 187 187 \n",
" 50 1.00e-04 1.22e+01 3.54e+04 1.58e+01 7.87e+01 17 SD 137 137 Stop SD\n",
"------------------------- STOP! -------------------------\n",
"1 : |fc-fOld| = 1.6468e-04 <= tolF*(1+|f0|) = 9.5809e+01\n",
"1 : |xc-x_last| = 2.6492e-05 <= tolX*(1+|x0|) = 1.0000e-01\n",
"0 : |g| = 1.6964e+01 <= tolG = 1.0000e-01\n",
"0 : |g| = 7.2505e+01 <= 1e3*eps = 1.0000e-02\n",
"1 : maxIter = 50 <= iter = 50\n",
"0 : probSize = 1000 <= bindingSet = 120\n",
"------------------------- DONE! -------------------------\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 17,
"text": [
"[<matplotlib.lines.Line2D at 0x10f7fd690>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nfiIim/l/mikG4O8fFLYAAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x10fe0b110>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEACAYAAAC08h1NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8FGWex/FPQwC5BGICiNzhCCiBQAggV0C5jKAzxFky\nXi9QJ4BCFHFGZtwVHEVmd91V0UF0VpkRcFDA5XBHBDVBRZKAKIcwQDjlDESQU0JS+8cDgdCdpO9O\nur7v16teIenqrl+K6m+efuqppxyWZVmIiIhtVAl1ASIiElwKfhERm1Hwi4jYjIJfRMRmFPwiIjaj\n4BcRsRmfg3/MmDE0atSITp06uXw8IyODevXqER8fT3x8PM8//7yvmxQRER9E+PoCo0ePZsKECTzw\nwAOlrtO/f3+WLl3q66ZERMQPfG7x9+3blwYNGpS5jq4RExGpOALex+9wOFizZg1dunRh0qRJ5Obm\nBnqTIiJShoAHf9euXdm/fz85OTl07NiR9PT0QG9SRETKYvnB7t27rVtuuaXc9YqKiqyGDRta58+f\nd3osJibGArRo0aJFiwdLTEyMx5kd8Bb/kSNHivv4ly1bRlxcHDVq1HBaLzc3F8uytFgWzz77bMhr\nqCiL9oX2hfZF2Ys33ec+j+pJTU0lMzOTY8eO0axZM6ZNm0ZBQQEAaWlpLFy4kFmzZhEREUFcXBwv\nvfSSr5sUEREf+Bz87733XpmPP/roozz66KO+bkZERPxEV+5WQElJSaEuocLQvrhC++IK7QvfOCzL\nskJdBJhhnxWkFBGRSsOb7FSLX0TEZhT8IiI2o+AXEbEZBb+IiM0o+EVEbEbBLyJiMwp+ERGbUfCL\niNiMgl9ExGYU/CIiNqPgFxGxGQW/iIjNKPhFRGxGwS8iYjMKfhERm1Hwi4jYjIJfRMRmFPwiIjaj\n4BcRsRkFv4iIzSj4RURsJiLUBYjNnDkDy5fDzp3QogWMGAHXXx/qqkRsRS1+CZ4VK6B9e3jnHTh9\nGt5/33y/ZEmoKxOxFbX4JTgWLID0dHjvPRgw4MrPv/4aRo6En36C++8PXX0iNuKwLMsKdREADoeD\nClKK+Ft2Ntx5J6xaBXFxzo9v2wb9+pmWf69ewa9PpBLzJjvV1SOBdeoU/OpX8NZbrkMfIDYW/vIX\nuO8+OHs2uPWJ2JBa/BJY6emmG+edd8pf9957oVkzmDEj8HWJhAlvslPBL4GzcSMMGgTffw833FD+\n+ocOwS23wHffQdOmga9PJAwo+KViGTECBg6Exx93/zm/+x2cOAGzZweuLpEwouCXiiMrC+65B7Zv\nh+uuc/95+fnQpo35tKBWv0i5dHJXKo4ZM0zr3ZPQB4iMNCd5//znwNQlImrxSwDk5kKPHrB3L9Su\n7fnzd+yA3r1hzx6oVcvv5YmEE7X4pWJ49VV4+GHvQh+gbVtITDRX9oqI36nFL/518iS0auV7H/3i\nxeYPSEaG30oTCUchafGPGTOGRo0a0alTp1LXmTJlCq1bt6Zbt25s27bN101KRbZggZmSwdcTs3fe\nCVu2wK5d/qlLRIr5HPyjR4/m448/LvXx7OxsvvjiC9atW8fkyZOZPHmyr5uUiuydd2D0aN9fp3p1\nSE2Fv/3N99cSkRJ8Dv6+ffvSoEGDUh/PysoiJSWFyMhIUlNT2bp1q6+blIpq61ZzQnfoUP+83r33\nwt//DuoCFPGrgM/OmZ2dzf1XzboYHR1Nbm4uMTExgd60eKmoCL78EgoKPHtezFtzoN/95Gb66bAq\n6k7v/DN8+/b3nGl5s1cvERMDLVv6pxyRcBHw4Lcsy+nEg8PhcLnu1KlTi/+dlJREUlJSACuT0mzd\nCnfcYUZkusthFfHemnn8rssn7J3ur0qqML7GSE69sIh3W3ke/MeOmXu9LF3qr3pEQi8jI4MMHwc9\n+GVUz549exg+fDibNm1yemzmzJlcvHiRJ554AoCYmBhyc3OdC9Gongrju+/ggQfMV7d9+SWMH29G\n8/jTF1/Ao4969br/93/w2mvmq0i4qpDj+Hv06MGiRYs4fvw48+fPp0OHDoHepPjIsqCUD2Wle/99\nM/2yv916K+TlmakfRMQvfO7qSU1NJTMzk2PHjtGsWTOmTZtGwaXO4bS0NBITE+nTpw8JCQlERkYy\nd+5cn4uWwPI4+AsLYeFC+Pxz/xdTtSrcdRcsWwZPPunRUx0OnRcWccXn4H/vvffKXWfGjBnM0Bzr\nlYbHwf/VV9Cwobl/biDccQe88oqCX8RPNGWDOPE4+APVzXPZwIHm9o2nTgVuGyI2ouAXJx4Ff1GR\nmV4hJSVwBdWpAz17wqefevQ0tfhFXFPwixOPwnL9erj+emjXLmD1AKa7x4vhOQp+EWcKfnHiUYt/\n2TJzp61Auxz8HiS5xyOTRGxCwS9OPAr+pUuDE/zt2pkRPh4M61RXj4hrCn5x4nbw79sHBw5Ar14B\nrwmHw5zk/eyzwG9LJMwp+MWJ28G/bJnpgqlaNeA1AR4Hv1r8Iq4p+MWJR8E/fHjA6yk2YIC5SKyo\nyK3VFfwirin4xYlbwX/qFKxZA0OGBKUmwNzcJTISXMwJJSLuU/CLE7eC//PPoXt3qFs3KDUV86C7\nRy1+EdcU/OLEreBfuRIGDw5KPSUo+EV8puAXJxU6+JOSYPVquHgx+NsWCRMKfnFSbvDv2wf5+dC5\nc9BqKtawIdx0k1v9/Grxi7im4Bcn5Qb/ypVw221QJUSHT+/e5sYvblDwizhT8IsTt4I/FN08l/Xp\n41bwa8oGEdcU/OKkzOAvKoJVq2DQoKDWVMLl4C+nOa+uHhHXFPzipMzg37ABoqPNmPpQad3a/AHa\nu7fcVRX8Is4U/OKkzOD/5JPQdvOAKc6Nfn519Yi4puAXJ2UG/8qVoe3muaxPH3PLxzKoq0fENQW/\nuOQy+M+cgZwc6N8/6PU4cfMEr4g4U/CLk1Jb/KtXQ9euwZ+mwZXOnWHPHvjxx1JXUYtfxDUFvzgp\nNfgrSjcPQLVqkJhoJoorhYJfxDUFvzipFMEP5gYwWVmhrkKk0lHwixOXwX/woLnbVkJCSGpyKTGx\nzOBXi1/ENQW/OHEZ/KtWmZkxg3W3LXf06AHZ2aXemEXBL+Kagl+cuAz+itbNA9CoEdSrBzt3hroS\nkUpFwS9OnFrJlhX6+XlK06NHqd09avGLuKbgFydOLf5Nm6BOHWjVKmQ1laqcfn4Fv4gzBb84cQr+\nijBNQ2ku9/O7oCkbRFxT8IsTp+CviP37l3XtClu2wPnzTg+pq0fENQW/OCkR/OfPm4ukBgwIaU2l\nqlUL2reHb791+bCCX8SZgl+clAj+L7+ETp2gfv2Q1lSmxESX3T3q6hFxTcEvTkoEf0Xu5rmslJE9\n6uoRcU3BL07CJfhFxDUFvzgpDv6jR2HXLhOsFVlsLOTlwfHjJX6sFr+Iaz4H/+rVq+nQoQNt27Zl\n5syZTo9nZGRQr1494uPjiY+P5/nnn/d1kxJgxcH/6adm7v1q1UJdUtmqVDFzCF3Tz6/gF3EtwtcX\nSE9PZ/bs2bRo0YIhQ4aQmppKVFRUiXX69+/P0qVLfd2UBElx8FeGbp7LuneHdetg2LBQVyJS4fnU\n4j958iQA/fr1o0WLFgwePJgsF32tlppdlYplgQOrYl+4da2EBBP8V1GLX8Q1n4I/JyeH2NjY4u87\nduzI2rVrS6zjcDhYs2YNXbp0YdKkSeTm5vqySQkCy4Kmp7eZmTjbtg11Oe7p1g3Wr3f6sYJfxFnA\nT+527dqV/fv3k5OTQ8eOHUlPTw/0JsVHlgWdj1xq7VeWwfAtW8K5c3DoUPGPKkvpIsHmUx9/9+7d\neeqpp4q/37JlC0OHDi2xTt2r7s/60EMP8Yc//IGff/6ZGjVqOL3e1KlTi/+dlJREUlKSL+WJlywL\n4g6vgCFjQl2K+xyOK63+O+8s/pFa/BJuMjIyyMjI8Ok1fAr+evXqAWZkT/PmzVm5ciXPPvtsiXWO\nHDlCw4YNcTgcLFu2jLi4OJehDyWDX0LHceFnYvO+gIFzQ12KZxISSgQ/KPgl/FzbKJ42bZrHr+Hz\nqJ6XX36ZtLQ0CgoKmDhxIlFRUcyePRuAtLQ0Fi5cyKxZs4iIiCAuLo6XXnrJ101KgEX98ysO1LuZ\nNpGRoS7FM926wZw5xd+qq0fENYdVQYbcOBwOjf6pIDbf+Tu277uOX270vCURUnv3mhuwHzwIwObN\nMGqU+SoSrrzJTl25K06abPqEzTdWkmGcV2veHC5cKA5+UFePiCsKfinpyBFqH9vD7ujEUFfiOYfj\nSj8/6uoRKY2CX0pauZLDsQMoqlrBp2koTbduxRdyaVSPiGsKfinpk084cPPgyttavqrFDwp+EVcU\n/HKFZaZp+OHmIZU3+C+3+C2r8v4OIgGm4JcrNm6EunU5FdUq1JV4r1kzKCoqPsGrFr+IMwW/XHFp\nUjanm61XJpev4F23rvL+DiIBpuCXKz76CO64A6jEwQ/F/fw6uSvimoJfjB9/hG++gYEDK3eLH0qM\n7FHwizhT8IuxYoW521bNmpU/+C+3+FHqi7ii4Bdj+fLiyc0qffDfdBMA1Y78oBa/iAsKfoHCQvj4\nY0hOBsIg+C9dwVtj0zoFv4gLCn6BtWvNMMimTYEwCH6Abt24bovzHblERMEvUKKbB8Ik+BMSuG6z\nWvwirij4JWyDv8bm9VhFSn6Rayn47W7PHjhyBLp3L/5RWAR/kyZY1arR5OK+UFciUuEo+O1u8WIY\nMQKqXDkUwiL4gZ9v6Uann9eFugyRCkfBb3eLFkFKSokfhUvwX+iUoOAXcUHBb2cHDsC2bTBwYIkf\nh03wxyXQ6YKCX+RaCn47W7zYnNStXr3Ej8Mm+Dt1o9OF9Zq3QeQaCn47W7jQqZsHwif4ixo25qyj\nNuzeHepSRCoUBb9dHTli5t8fNMjpoXAJfocDNlW/MmGbiBgKfrv68EMYNgyuu87poXAJfoCN1RIU\n/CLXUPDb1fz58C//4vKhcAl+hwM2Vlfwi1xLwW9Hu3bB1q2mxe9COAX/dxHdzH0GiopCXY5IhaHg\nt6O5c2HUKKfRPJeFS/ADHK8SDfXrQ25uqEsRqTAU/HZjWfDuu/DAA2WuEg7BX/w7dNMJXpGrKfjt\nZu1aqFrV3KWqFOES/HBpCH+C+vlFrqbgt5s5c0xrv4xkD5fgL77ZuoJfpISIUBcgQXTyJLz/vjmx\nW4ZwudC1RFfPhg3mBG8VtXVE9C6wk3ffNRdsNW5c5mrh0uKHS3/EIiMhOhq2bw91OSIVgoLfLiwL\nZs2C8ePdWjUcgr+4qwd0glfkKgp+u/j8c5OC/fuXu2o4BX8x9fOLFFPw28Wf/gRPPulWoodL8MNV\nLX4Fv0gxndy1gw0bYPNmWLrUrdXDJfhL/A5du8K330JhoRnOKmJjCn5fFRaaaX8PHzajZmrUMCcT\n27SB668PdXXGn/4EkyaZ2twQTsFf3OKvXx+aNDE3nrn55pDWJRJqPgf/6tWrSUtL4+LFi0ycOJEJ\nEyY4rTNlyhQWLFhAgwYNmDdvHrGxsa5fbM8eaNas4rfINm2CZcvgH/8wremoKLjpJqhXD37+GY4f\nhx07zO8yeDDccw/07h2aoYTffQcZGfDWW24/JVyCH64Zmnr5BK/dg//QIXPOZ8sW2L/fNF6qVIEb\nb4SWLc1+io8vdUoPqfx8Dv709HRmz55NixYtGDJkCKmpqURFRRU/np2dzRdffMG6detYsWIFkydP\nZvny5a5frG9fOHYM2raFAQNg6FBzMrJWLV/L9F1Bgbk/7csvmzfOXXfBM89Az54m8K918aJ5Yy1b\nZkbSFBTAE0/Agw+6nAo5YJ5+2tRZt67bT7Gs8Bju7vTH63I//4MPhqSekCoshAULzMiuLVsgKQm6\ndDHvs+rVzfF68KBpyLz5JuzcCb16wd13w4gRphFTWV28aBpjeXmQn28aZwUF5ufVq5t8qV3bvEca\nNTKf1MOl5VMKn4L/5MmTAPTr1w+AwYMHk5WVRXJycvE6WVlZpKSkEBkZSWpqKs8880zpL7h/P5w5\nA99/D6tWwYwZ8Otfw8iRMHo03Hpr8P9D8vPNG+H11033zZQp5naF5X0qiYiAzp3N8oc/QGYm/Pu/\nm9/pxRfNlMiB/l0+/dS8gX/zG4+eFrYt/oQEc9cxu/nsM0hPNw2USZNg+HCoVq3s55w6BStXwpIl\n8G//Bu3bw/33m+M2MjI4dXvq3DnIyYHsbHPNxo4d5uvRo9CggbmWIzLSdHlWq2beoxcumMw5c8b8\nzkeOmD+SN95ougZbtzbv+7Ztzdc2bUy3YSXnU/Dn5OSU6Lbp2LEja9euLRH82dnZ3H///cXfR0dH\nk5ubS0xMjOsXrV0bunc3y5QppnX97rvw0EPmXfzww+aPwFWfKgJi61Z45RXTSrrrLtNy79LFu9dy\nOEwLKynJdLtMngwzZ8Jf/gIdOvix6Kv8/DNMmGD+2HjxkT0cgr9EHz+Y7ouNG01rr7zgCwcXLsDv\nf2+O4VdfNa13d/9j69aFX/7SLAUF8Mkn8Le/mU+Qt99upv0YNiy03UF5efDVV/Dll+brxo2mG69n\nT/N//atfmcBu2tSz7uPTp805uwMHzKyuO3eaT/s7d5qlRg1o184sbdte+XebNia/KoGAn9y1LAvr\nmjkAHKUcfK7fizcCvwXrKXrxNY/8bjbDf9uGjxzDmV1lHF/Ty28p5bCKGGytYIL1Cp2tb3nTMZY3\nq2zlyLzGMM8vmwCScFjZpFlv8GzHvrxa5XH+0/FbChz+fQP9a+GLxNGee+65GzzcPYWF5m9eZed0\nWFx/venD3rzZBEMlkprq2YeVetYJPij6JWepxUNVNnD8V740lKoByUAy9awTjPzfhdy3+CVieZgP\nHSNZ5Egh05FEoSOAcWJZtOef3Gp9dWn5koYcZa2jF2scvVnDdHIciZzdUBs2+LqxOkCbS8s1171Y\nFo3PHaZN9g7aZu2grbWdNrxHW2s7MeRynBvY4WjHTtqy3dGOHbRjv6M5h7iRY0RhOfzbh9qunXfP\nc1jXprIHTp48SVJSEhs2mD09YcIEhg4dWqLFP3PmTC5evMgTTzwBQExMDLku5kZ3OBw888yzxd/3\n759E//5Jrjd8/DhV/jaHKm+9ATVrUZQ2jqLUez3qxy7h2DGqzHmbKn+ZDdfXo/CxiVi/GhX4vvh9\n+6j62FgcBw5w8S/vQHxXv7ysY+3XVE25m4tZ35iTzl6IiKj8rf78fIiJgR9/vOqHDz1kunzGjQtZ\nXd4YMMA03pOS3Fg5L4+IIbdR1D+Jov/878ANlti9myqLPsCxeCGO3buwRtxN0bBkrH79fe8OOn0a\nx/p1OLLW4lj7NY61a6B2baxevbF696GoV2/Tuq9IA0EKC+GHH3Ds2I5j5w7Ysd38e/9+OHwIfvoJ\nGjbEatQYbrgB6tSFunWx6tY1/65d27zxqlY1S2GhOQ9xzZKxZzeZ+/aauadq1uSPqzOdGtfl8Sn4\nAeLj43nllVdo3rw5Q4cO5csvv3Q6uTtp0iSWLFnCihUrmD9/vsuTuw6Hw+PiKSoy/ZezZpn+yKQk\ncyJq4EBo1ar05LIs85Hts8/MR7isLPjFL0wYJCYGN/Euz48/eTI88ojpT3Vz2KVLeXkm2GbONPvC\nxn780RwGJ05c9cO33jJdA3/9a8jq8kb//vDcc25ceH3ihDn+77gD/vjH4B3Le/bA4sWmS2jNGtM3\nnphowrljR9MAiY42fe2XRw6cOWMGc+Tlwd698M9/muG2mzaZ92fnzqbbpkcPMyquadPg/C6BcuGC\nOYdw6JBplZw6dWX56SezPwoLzVJUZMI/IuLKcu33ERFwww047rsv+MGfmZnJ2LFjKSgoYOLEiUyc\nOJHZs2cDkJaWBsDTTz/NggULiIyMZO7cuXRw0a/tVfBf7ccfzfDKpUvNG/vsWejUyZykadDA7Mwz\nZ64cYLVqmVFEd99t+ipD3Td36JAZ/bN9O7z9tjnYPXXqlHnTDx1q3vQ2d+KE6dkpEfybNkFKijkG\nKpG+fWH6dPO1VAUFZhK+uDjTVxeqj2wFBbB+vVm2bDHnyw4dMgF/4sSVEy81a5o/BlFRJtQ7dIDY\nWPPHIi5Ow0nd5E12+hz8/uJz8F/r8GFz0B05Yg62iAhzoLVoYU7CNGniv235i2WZaZPT0+G++0zr\n392LwI4eNSehO3c2n4Aqez+NH5w4Yf67Lw0+MwoLTUNg927zcbuS6N3bnKfv3buMlSZMML/X0qXh\nMR5X3OJNdobvlbuNG5c7/XCF43CY4XIDB8JTT5kRA08/bUYylXX+4pNPzJDNBx6AqVMV+pc4jeoB\n83G5e3fTvXfHHSGpyxvl3kpgzhxzHGRlKfSlXOEb/JVZdLR5I2/aBNOmmW6bX/wChgwxLfr69U0f\nYVaW6aveuxfeeMN08UixUv/+9expbkEZLsG/Y4c5R7R6dViMMZfAU/BXZJ06mTF8P/xgvr77rrkY\n7ORJczFO166QlmbGWqs/1CWXn4B79jQnvyuRUoP/4kVzYdXUqeYkqogbwrePX2zv1Clzbv/06Wse\nOHrUDIDOz6803SLdupkLyLt1u+aB5583Lf2PP640v4v4l/r4RdzRsKE5sbttW6VpJbts8e/YYeaO\n2rBBoS8e0dEiYcvlyd3LLvfzVxJFRdecs7AseOwxM61JZZ5ATUJCwS9hq8zBTZUs+J1mTF240Mym\nOXFiyGqSykvBL2EtnFr8xcF/5oyZZXPWLHtMNid+p+CXsFVmV0/nzmbmxZ9+CmpN3ioR/P/1X9Cn\nj1lEvKDgl7BVZldP9epmTqOvvw5aPb4oDv6jR80J3RdeCHVJUokp+CWslTnKrW9f+OKLoNXii+Lg\nf/55uPdeMwmaiJc0nFPCVpldPQD9+pkgrQSKiqD6/lyYP99MeibiA7X4JWyVO2VRr17wzTdw/nxQ\n6vFFURFEvfKvZgK/6OhQlyOVnIJfwlqZLf66dc1UwDk5QavHWy1+3k7Nr1bC44+HuhQJAwp+CVvl\ndvVApenn/83Jf+f0/eO9v8ucyFUU/GJvlSH4f/iBYWcXc+YhXawl/qHgl7DlVou/Tx9zq8DCwqDU\n5JWXXmJBrdFYkZXnxjFSsSn4JWy5FfzR0eZ+sN99F5SaPJaXB3/9K2/UmqR52MRvdCiJ9OsHmZmh\nrsK1V1+FlBQOOm5S8Ivf6FCSsOVWix/gttvg008DXo/HfvrJzMfz29+Wf+tFEQ/oUJKw5fathwcM\nMCd4CwoCWo/H3ngDBg+GNm0U/OJXOpQkrLnV4o+KgjZtzD2MK4pz5+C//xuefhpw42brIh7QoSRh\ny+0WP8Dtt8OqVQGrxWPvvGMmkYuLAxT84l86lCRsVdrgLyiA//gP+P3vi3+k4Bd/0qEkYc+t7p4+\nfcyQzlOnAl5Puf7+d2jZ0swldImCX/xJh5KEPbeCv2ZNSEwM/bDOoiJ48cUSrf3LP1bwi7/oUBK5\nbMgQ+Mc/QlvD0qVQq5bperqK083WRXyg4Jew5vZYfoA774Tlyz14gp9ZFkyfblr716S8083WRXyg\nQ0nCmkfB36EDVK0KmzYFtKZSffqpOcdw991OD6mrR/xJh5LIZQ4HDB9uWv2hMH06TJniMuEV/OJP\nOpQkrHnU4gfT3bNsWcDqKdXatbBrF6SmOj1kWWZRH7/4i4JfwprHwd+/v7mn7dGjAavJpRdfhKee\ngmrVnB66HPoKfvEXBb/I1apXNyNqPvooeNv87jtz+8cxY1w+rG4e8TcdThLWPG7xA4wcCR98EJB6\nXHrhBXjySXMtgQsKfvE3h2WFauxaSQ6HgwpSioSRGjXM7MY1anjwpNOnzc1Zdu2CGwJ816utWyEp\nCXJzoU4dl6ucPw/165uvItfyJjvVjpCw53F7ok4dczHX4sUBqaeE6dMhPb3U0Ae1+MX/vD6cTp06\nxV133UXz5s25++67OX36tMv1WrZsSVxcHPHx8SQmJnpdqIg3vOrqARg1ChYs8Hs9Jezcaa4UfvTR\nMlfTVbvib14H/6xZs2jevDk7duygadOmvPHGGy7XczgcZGRksGHDBrKzs70uVCSohg2D9evh0KHA\nbePFF03o16tX5mq6alf8zevDKTs7m4ceeogaNWowZswYssq4iYX67iVUvG7x16wJ99wDc+b4uyTj\nn/+EJUtMN0851NUj/hbh7RNzcnKIjY0FIDY2ttTWvMPhYODAgbRq1YoxY8YwYsQIbzcp4jGHAxYu\n9PDk7iWRLR+h18uj+Kjl7/yevL1e/ldODHqSrSsjy133zBkFv/hXmcE/aNAgDh8+7PTzF154we1W\n/FdffcWNN97I1q1bGT58OImJiTRu3NjlulOnTi3+d1JSEklJSW5tQ6Q0v/mND0PyrQTaXqjL9tmf\ns7nRbX6rqXX+OgZ99xV/aDKHC26eP374Yb9tXiq5jIwMMjIyfHoNr4dzjhw5kmeeeYb4+HjWr1/P\niy++yMKFC8t8zqRJk+jQoQOPPPKIcyEazikV0euvmzn633/ff685aBCkpEBamv9eU2wrqMM5e/To\nwdtvv825c+d4++236dmzp9M6Z8+e5dSlOxrl5eWxYsUKhg4d6u0mRYLv/vvhs89gzx7/vN5HH8G+\nfaVepSsSDF4H/7hx49i3bx/t27fnwIEDjB07FoCDBw+SnJwMwOHDh+nbty9dunRh1KhRPPnkkzRr\n1sw/lYsEw/XXm36Wl17y/bXOnYMJE2DmTJdz8ogEi67cFSnPoUPQsaMZidOwofevM3UqbNkS3Okg\nJOx5k50KfhF3pKdDYSG89pp3z9+2zdzQ/dtvoWlT/9YmtqbgFwmUY8cgNhbWrIF27Tx77oUL0KsX\nPPIIXOoSFfEXzdUjEihRUfD00zBunLmiyhPPPgtNmmgUj1QYCn4Rdz3+uJm5s5TpSVx6/32YNw/+\n53804Y5UGOrqEfHEtm3Qrx/87//CrbeWvW5mphmvv3IldOkSnPrEdtTVIxJosbHw17/CL38JGzaU\n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\n",
"text": [
"<matplotlib.figure.Figure at 0x10fee6dd0>"
]
}
],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}