Skip to content

Instantly share code, notes, and snippets.

Created May 31, 2013 23:15
Show Gist options
  • Save anonymous/5688579 to your computer and use it in GitHub Desktop.
Save anonymous/5688579 to your computer and use it in GitHub Desktop.
Use least squares to find the cubic bezier equation of a hand drawn arc. This ipython notebook uses sympy to derive the equations needed to setup the least squares fitting problem. It then creates some noisy data on an arc and shows that the best fitting process works quite well.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "BezierLeastSquaresFit"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1>Use a method of least squares to find a 'best bezier fit' for a hand drawn arc.</h1>\n",
"<h3>This notebook will investigate the cubic bezier function along with how to perform a least squares best fit to find the optimal control points for a cubic bezier curve that best matches a hand drawn curve.</h3>\n",
"For more background information on bezier curves see : http://en.wikipedia.org/wiki/B%C3%A9zier_curve\n",
"\n",
"For an excellent tutorial on least squared fitting see : http://www.embedded.com/electrical-engineer-community/industry-blog/4027019/1/Why-all-the-math-\n",
"\n",
"Author : Luke Whittlesey \n",
"\n",
"email : myfirstname.mylastname@gmail.com"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>First setup this ipython notebook for symbolics using sympy and inline plotting using matplotlib.</h3>"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# we need some ipython magic commands to \n",
"# 1. allow sympy to pretty print math equations inline\n",
"# 2. use pylab for inline graphing\n",
"%pylab inline\n",
"%load_ext sympy.interactive.ipythonprinting"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].\n",
"For more information, type 'help(pylab)'.\n"
]
}
],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>To make sure we understand what a cubic bezier curve is, let's create one numerically and then plot it.</h3>"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def numerical_cubic_bezier_fn(control_pts, t):\n",
" \"\"\" \n",
" Numerically calculate an x,y point for the bezier curve at position t. \n",
"\n",
" Parameters: control_pts -- list of 4 (x,y) control points\n",
" t -- 'time' value should be between 0 and 1\n",
"\n",
" Return: (xpt, ypt) -- tuple of x,y data on the curve\n",
" \"\"\"\n",
" check = ((0 <= t) and (t <= 1))\n",
" assert check\n",
" # define the actual cubic bezier equation here\n",
" fn = lambda c,t : c[0]*(1 - t)**3 + c[1]*3*t*(1 - t)**2 + c[2]*3*t**2*(1 - t) + c[3]*t**3\n",
" xs = [x for x,y in control_pts]\n",
" ys = [y for x,y in control_pts]\n",
" # now calculate the x,y position from the bezier equation\n",
" xpt = fn(xs, t)\n",
" ypt = fn(ys, t)\n",
" return xpt, ypt\n",
"\n",
"# just to make sure that I understand, lets create a list of numbers for a specific bezier curve\n",
"# arbitrarily define my 4 control points here\n",
"p0 = (0.7,0.2); p1 = (2.3,1.0); p2 = (7.2,0.8); p3 = (10.0,0.0)\n",
"# create a list of 1000 x,y points that traces over the length of this curve\n",
"points = [numerical_cubic_bezier_fn(control_pts=[p0,p1,p2,p3], t=t) for t in arange(0.0,1.0,1./1000)]\n",
"# separate the x's and y's so matplotlib can plot them\n",
"xs = [x for x,y in points]\n",
"ys = [y for x,y in points]\n",
"\n",
"# plot the resulting curve and the control points\n",
"plot(xs, ys, 'b-')\n",
"hold(True)\n",
"for pt in [p0,p1,p2,p3]:\n",
" plot( pt[0], pt[1], 'ro')\n",
"hold(False)\n",
"t=title('example cubic bezier curve')\n",
"#legend(['curve','control pts'])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"png": "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\n"
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>\n",
"Using sympy symbols we will now go through some mathy equations for how to setup the least squares problem of finding the best cubic bezier fit for our hand drawn data points.\n",
"</h2> \n",
"\n",
"<h3>\n",
"First redefine the cubic bezier equation using sympy.\n",
"</h3>\n",
"t must be defined in the range 0 to 1\n",
"\\begin{aligned}\n",
"t \\in \\begin{bmatrix}\n",
"0 & 1\n",
"\\end{bmatrix}\n",
"\\end{aligned}"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sympy.printing.mathml import mathml\n",
"from sympy import Symbol, Matrix, summation, diff, expand, collect, preview, Sum, latex, Eq, factor\n",
"\n",
"t = Symbol('t_i')\n",
"c0, c1, c2, c3 = [Symbol(name) for name in ['c0','c1','c2','c3']]\n",
"\n",
"# the equation for a cubic bezier path b(t) over t in [0,1]\n",
"# Note: the c control points are (x,y) tuples, but we're going to compute\n",
"# the resulting x and y values independantly. x and y are independant of\n",
"# each other, but both are dependant on t which goes from 0 to 1\n",
"symbolic_cubic_bezier_fn = c0*(1 - t)**3 + c1*3*t*(1 - t)**2 + c2*3*t**2*(1 - t) + c3*t**3\n",
"print 'The cubic bezier function B(t) is:'\n",
"B = Symbol('B(t_i)')\n",
"Eq(B, symbolic_cubic_bezier_fn)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"The cubic bezier function B(t) is:\n"
]
},
{
"latex": [
"$$B(t_{i)} = c_{0} \\left(- t_{i} + 1\\right)^{3} + 3 c_{1} t_{i} \\left(- t_{i} + 1\\right)^{2} + 3 c_{2} t_{i}^{2} \\left(- t_{i} + 1\\right) + c_{3} t_{i}^{3}$$"
],
"output_type": "pyout",
"png": "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\nD+3UrIIAXrrRAAAAAElFTkSuQmCC\n",
"prompt_number": 3,
"text": [
" 3 2 2 3\n",
"B(t\u1d62\u208e = c\u2080\u22c5(-t\u1d62 + 1) + 3\u22c5c\u2081\u22c5t\u1d62\u22c5(-t\u1d62 + 1) + 3\u22c5c\u2082\u22c5t\u1d62 \u22c5(-t\u1d62 + 1) + c\u2083\u22c5t\u1d62 "
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>\n",
"Now we define the error for each data point as the difference between what the best fit bezier function gives us and what the actual data point is.\n",
"</h3>\n",
"\\begin{aligned}\n",
"e_i = B(t_i) - d_i\n",
"\\end{aligned}"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"d_i = Symbol('d_i')\n",
"# the error between what the 'best fit' bezier curve produces and the hand drawn point is defined as\n",
"error = symbolic_cubic_bezier_fn - d_i\n",
"\n",
"e_i = Symbol('e_i')\n",
"# where symbolic_cubic_bezier_fn is bezier(t, control_points) and data_i is the i'th hand drawn point\n",
"Eq(e_i, error)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$$e_{i} = c_{0} \\left(- t_{i} + 1\\right)^{3} + 3 c_{1} t_{i} \\left(- t_{i} + 1\\right)^{2} + 3 c_{2} t_{i}^{2} \\left(- t_{i} + 1\\right) + c_{3} t_{i}^{3} - d_{i}$$"
],
"output_type": "pyout",
"png": "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\n",
"prompt_number": 4,
"text": [
" 3 2 2 3 \n",
"e\u1d62 = c\u2080\u22c5(-t\u1d62 + 1) + 3\u22c5c\u2081\u22c5t\u1d62\u22c5(-t\u1d62 + 1) + 3\u22c5c\u2082\u22c5t\u1d62 \u22c5(-t\u1d62 + 1) + c\u2083\u22c5t\u1d62 - d\u1d62"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>\n",
"The penalty function will be the sum of all of the squared errors. I.e. least squares.\n",
"</h3>\n",
"\\begin{aligned}\n",
"M = \\sum_{i=0}^{n} e_i^2\n",
"\\end{aligned}\n",
"This penalty function, M, is what we will want to minimize to call the solution a best fit."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# the least squares penalty function is the sum of all of the squared errors\n",
"penalty_fn = error**2\n",
"\n",
"print 'The penalty function is :'\n",
"i = Symbol('i')\n",
"n = Symbol('n')\n",
"M = Symbol('M')\n",
"Eq(M, Sum( penalty_fn, (i,0,n) ))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"The penalty function is :\n"
]
},
{
"latex": [
"$$M = \\sum_{i=0}^{n} \\left(c_{0} \\left(- t_{i} + 1\\right)^{3} + 3 c_{1} t_{i} \\left(- t_{i} + 1\\right)^{2} + 3 c_{2} t_{i}^{2} \\left(- t_{i} + 1\\right) + c_{3} t_{i}^{3} - d_{i}\\right)^{2}$$"
],
"output_type": "pyout",
"png": "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\n",
"prompt_number": 5,
"text": [
" n \n",
" ____ \n",
" \u2572 \n",
" \u2572 \n",
" \u2572 \u239b 3 2 2 3 \n",
"M = \u2571 \u239dc\u2080\u22c5(-t\u1d62 + 1) + 3\u22c5c\u2081\u22c5t\u1d62\u22c5(-t\u1d62 + 1) + 3\u22c5c\u2082\u22c5t\u1d62 \u22c5(-t\u1d62 + 1) + c\u2083\u22c5t\u1d62 - \n",
" \u2571 \n",
" \u2571 \n",
" \u203e\u203e\u203e\u203e \n",
" i = 0 \n",
"\n",
" \n",
" \n",
" \n",
" 2\n",
" \u239e \n",
"d\u1d62\u23a0 \n",
" \n",
" \n",
" \n",
" "
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>We want to minimize the error in the penalty function for each coef c0,c1,c2,c3\n",
" so take partial derivatives and find where they equal zero to find the minimum (or maximum). </h3>\n",
"\\begin{aligned}\n",
"\\frac{\\partial M}{\\partial c_0} = 0,\n",
"\\frac{\\partial M}{\\partial c_1} = 0, \n",
"\\frac{\\partial M}{\\partial c_2} = 0, \n",
"\\frac{\\partial M}{\\partial c_3} = 0\n",
"\\end{aligned}\n",
"We actually know that this can only be a minimum since the maximum error is infinite and therefore the derivative won't have a zero crossing for the maximum."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df_dc0 = collect( expand(penalty_fn.diff(c0), deep=True), [c0,c1,c2,c3])\n",
"print 'Partial derivative wrt c0 is:'\n",
"Eq(0, Sum(df_dc0, (i,0,n)) )"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Partial derivative wrt c0 is:\n"
]
},
{
"latex": [
"$$0 = \\sum_{i=0}^{n} \\left(c_{0} \\left(2 t_{i}^{6} - 12 t_{i}^{5} + 30 t_{i}^{4} - 40 t_{i}^{3} + 30 t_{i}^{2} - 12 t_{i} + 2\\right) + c_{1} \\left(- 6 t_{i}^{6} + 30 t_{i}^{5} - 60 t_{i}^{4} + 60 t_{i}^{3} - 30 t_{i}^{2} + 6 t_{i}\\right) + c_{2} \\left(6 t_{i}^{6} - 24 t_{i}^{5} + 36 t_{i}^{4} - 24 t_{i}^{3} + 6 t_{i}^{2}\\right) + c_{3} \\left(- 2 t_{i}^{6} + 6 t_{i}^{5} - 6 t_{i}^{4} + 2 t_{i}^{3}\\right) + 2 d_{i} t_{i}^{3} - 6 d_{i} t_{i}^{2} + 6 d_{i} t_{i} - 2 d_{i}\\right)$$"
],
"output_type": "pyout",
"png": "iVBORw0KGgoAAAANSUhEUgAABkAAAAA4CAYAAAClrTQxAAAABHNCSVQICAgIfAhkiAAAG/1JREFU\neJzt3Xu4JEV5x/HvWS7LZdmFBZZFFly5GWBZr4gYIgtrhCBoJCqKIgIKoqKiSwSJ4YgXFEVBUSMq\naUNEvHDxCd6iIkbQKAIqXlAuoiIEhUXERRTC5o93OqdPn+6Z7umq7uo6v8/znGf39MzpqXeq6q2a\n6a5uEBERERERERERERERicxE1wWoYCFwLPAE4G3AzsC2wNbA6zssl4iIiIiIiIiIiIiIyNiOAdYH\nbgQOHWybD9zbWYlEREREREREREREREQa2gTYBvhVZtu+wLe6KY6IiIiIiIiIiIiIiIRuTtcFqOA+\nYCVweWbbc4HPAgvox2W8REREREREREREREREZvg48OLM73dh9wA5tpviiIiIiIiIiIiIiIhIyPqw\nAgRgR+Armd8vA54BfLeb4oiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI\niIiIiIiIiIiIiIiIiIiIiIiIiIiITzcAaz3+vKu9UERERERERERERERERMzzmTpYsQbYpcLfrA8s\nBLYdPH8PYH/gdOAa4OHMPlcDGzkvtYiIiIiIiIiIiIiIyAgfZeqAxQ+BDRvub0vgMODqwT6Pbbg/\nERERERERERERERGR2jYCfsLUQZAPO9rvusCbgesd7U9ERERERERERERERKSW3YE/MXUQ5FCH+z4X\nWOlwfyIiIiIiIiIiIiIiIpUdx9QBkHuB7R3tdxPg8CGPn+PwtYqsCyTAfI+vISIy22wO/Bswp+uC\nOKBxQkREeV1E+k95TCQ+MfVrkVgtAD4DrNd1Qar6LFMHQa7Gbnju07vxe4+QCWzScIDH13gWdjP5\no4DXenydLpwHPIStDvomdtP72eJMYO+uC+HY3tjByFcDFwFP67Y43u2JXYbvdOBSYHm3xYnSJPD+\nrgvRUBvjRFMxjzN5s2nciXGcyYt93IlxnJlEeb2KmPPybMrDeTHm5VjycJ18O4nyWBtiyIMx5Ls+\n5606+WmS/vfrJmLJ5XXEOM+O3RuAC7AxLHibArcydRDkLI+v9VLgYo/7BzgReK/H/T8N64wAS4G/\nENcZGpPAYuxI3myyD3AnsKLjcrj2K+CIwf+PBv4IzO2uOF7NAz6Q+f15wH3Mvrbs20bAb7B83le+\nx4mmYh9n8iaZHeNOrONMXszjTqzjjPL6aLHn5UlmRx7OizUvx5CH6+Zb5TH/YsmDk/Q73/U9b9XJ\nTzH06yZiyOV1xDrPjt36wI3AqV0XpKq9gAeZOghysIfX2BC4HVjmYd+pBcAdwBae9j8Hi+GRmW0+\nL+XVhcmuC9CBBdhR9Svo70SizDJg48H/n4Od6RLroLkceBjYYfD7fCyfHdRZieJ1BDYh871i0Aff\n40RTs2GcyZvsugAtiHmcyYt53Il5nFFeLzcb8vJk1wXoQMx5OYY8PE6+VR7zJ6Y8ONl1ARqIIW/V\nzU997tdNxZDL64h5nh27g7EDdIu6LkhVJzN1AORuYFvH+18FXOV4n3mnAp/wuP/dsPdnH2wp2jnA\n0z2+Xhfeid0b5nDsDJRHdVucVpyIDSRX0N+JRBUXAKd0XQiPJrAlk+nSu7S/9nFZc+gmgO/h93KG\nvvgeJ5qaDeNM3mwYd2bLOJMX27gT8zijvF5uNuTl2ZCH82ZLXu5rHh4n3yqP+RNTHuxzvostb1XJ\nT33u1y71NZfXEfM8ezb4ErkrSq2be8IS4F3Y0f57sRuHvBc7ANG2dwIrBz8LgU9iA9z/Otr/64A3\nOtpXkTnA8diR0bxdsfd5feyo+bew68rdU/M10tUrDwPnA18AbsE65m31i1zZEmyQ27HkcVfxAVwP\nfBpb0noHcAnw2DH2M65HYwfLHgL+Cvgt8HbgB7nnueo7zwS+CPx5/CKPbRVW7tNz213nhcdjR2TX\n0P6y6jbrcy3wnczvJwHvAX46TsFraLN/+la1rGuBD2J5/cNtFrChYeOEC9sCp2Hj5r3YWRBnYH2v\nqq7Gmay283Db406VenKZh7scZ1Jtx9zWuNN2W+1qnMlzkWvyYs7rTd+vtvPyuPOGsnllFX2Z/4Ob\n9t9mXu6iPqHb+T80r6dx8m3MeWxcff8eJM9F/w9x3llF1/NJl59p6+SnLvp1k1jPBF4AbA3sB3y9\nYVnazOXjtlVXMfd9nu267l1osy2fheXTUyh4r9YBbgKOyWx7K/BlbBDswmLseoLpSpC3O9rv7oP9\n+Vwm+QRsEMsvCXs0cCWw3eD3zbBB73rgEQX72YGZyztTz8Di2DCz7Q7g5WOXeriNsTMrfj543SIu\n44PpB+mWDl53h+KnOrcT1v43Gfw+AXwK+APTL51Wt++UxfwI4MWZ36+gvTMpHoklhcncdlexFTkG\nuIbp7dentusz62hskPJ5I6Yu+qdPdcv6VCzurVopnRtl44QLi4BfAE8Z/L4Q+BlwQsFzQxpn8rro\nt22OO1XqyWVsXY4zqbZjzvI57nQ5xkA740wRV7mmSIx53cX71WZerjsWp8rmlakY5v/gpj7bzMtd\n1WdW2/N/cJ+n6uTbGPPYuPr8PUgRV+0qtHlnKuT5pK/PtFXzU5v9ety8nfUq7EDVqLhCyuV12moR\n1zH3YZ5dxEfdj6vNtgwW01rg74oefOFgRxtntu00+IOjKhbGh/2xI/trB//+rYN9ngCsdrCfYU4E\nrivYfglTjTf1FCy+swue/1rgAWCDgse2wd6TeZltt2PLJ13bBbgUOwh1FeVfsLqMbw9ssp027r8Z\n7Kdq5yiynJkrn8q8CTvKmr0HzWHMPBhXt++UxXwkdum3kwY/twPnYhM8387FyjuZ2+4qNrDlg3cy\ntax318F+Dhi30IRdn6mDsAETrC0vrVjeOrron+OoU191y7rN4LFDWyibK2XjhAsXY/WXWgT8kuKb\n9rU9zoTcb32MO8NUqSeXOcnHOFO377QZs49xp0xXYwy4HWd81Geq7pgSY1538X61Of+vOxanyuaV\nqRjm/+CmPtuc/3dRn13P/8Ftnqqbb2PMY+MK/XuQLtpViPPOVMjzSVdtadz81Ga/HjdvZ12IffE8\nStu5fJg6bbWIi5hTfZlnF3H5PjTVZlsGe58fxFbtzPB94PKC7Tdjb3qXzmBqFcj/0PxmXJdQHKtL\nnwPOK9h+J3ADU2cVgVXMA8CPC55/EfCNIa/zRewgEcCWg/37PhKdUP4Fq8v4FgL/nPn9DcB/1ilo\ngYTqCesQbAntX2e2PR+L/R8z2+r2nVF1mrqVds6kOISpuCZzj7mMbQcsWaVnE70A+xJoy3rFnSYh\n7PrcBxssFw9+DgP2qljecSW00z/HLdvSis+tW9YJ7EZs72uhbK6UjRNNPRc7c2/Tis9ve5xJCLff\n+hh3ylStJ19jDLgZZxKq12fbMfsYd8p0NWdwPc4kuK/PVN0xJba87vL9amv+X3cshuHzylQM839f\n7f9W/M3/u6jPruf/LutpnHwbWx5rIvTvQRLab1chzjtTIc8nXbWlcfNTm/16nLyd9xvgbRWe13Yu\nL1O3rRZxETP0a55dxNX74EKbbTl1E3Bt9sXSf5cDHyn5gxU1XsCHU7CG9yTs2o5/bLi/JdiyIZ+2\nwZby5N0EPA478+++wbaHKE8ee2NH08scjp2ptAs24B+ENayuuIxvNfBNbHndjsDm2CS8LRcz88uI\nvbBYLhv8Pk7fGVWnS4DXY23ojdiZLZcNeX4T84ADsSPIn8w95jq2m7Hr9h2PXfNvL2z56O/qFnpM\nbdfn9oP9zsttX1CtuF64zj8+1S3rWmx56DatlM6NsnGiqedg79/vKz4/5HGm7X7b5rhTpZ58jDHQ\n7jiT1XbMbY47XcwZuh5nXOeavNjyusv3q628XHcsHjavzOr7/B/ct/828nIX9dn1/N9VPY2bb2PL\nY03E9D2Iq3YV2rwzK+T5pKu2NG5+arNf1401bwdsRVGVL7dDyeV122qeq5j7Ns/Oc/U+uNJmW07d\nTOaeSukBkK2wo5hFBxbWYNfmmkt3Nzh6ELuu4ELsZksPNNzflsDVI56zM3Z0bzvgRux9qHOEd0vs\nWrF5+2AdKNuItwPmMzVYPBN4Bfa+LwL2xe5gfwkzb7R0F/CaGuXyzXV8XyeMm/WAXff3RdglKn4y\n2Fa17+xP9Zhvwy7TVvW6fk2cTPnNDH3EdknzIjvjuz5vYfrR7RC47p8+VSlr3i00XyFYh69xoqnH\nYqsl98TqcxtsonYiNvGA/o4zbeThtsadKvXkIw9Du+NMVhcxdzXutNFWux5nXOeaIjHldZfvV1t5\nue5YPGxeGdP8H9y3/zbyclf12eX831U9Ncm3MeWxJmL6HsRl/w9p3ll3zO5qPumyLY2bn9rq13Xz\n9uOwL87nYt+fXot9yXxVyf5DzOVV2mqWr5j7MM/O8ln3Lvhuy0VuAlZi91l8ON34BOwo5mkFf3A+\n5Tf4OQ9byl/nZ0WNwqZeiB1Z3GmMvy2yhvLJHMATsaU1B2Z+/y0zr1c2zP3AsRWf+w7sWrP5/R9L\n9Ru8tCmh/BI7RUKKL6H+MuKDsBjuAI7IPVa374RUp4/FPtik8kvb+xBbguozLyHc/pnQbBl/WVlT\nZ1N9+WReQr2ytT1OVLUx9h5dD7wys/0Q4B7s7LIs9dtuVK2nPsSWUK0+Y4p5mL631QS39ZkaN5ZY\n8nofcnNVZWPxqHllKuR2nTWsL6s+p4Rcn6HUUyx5zIc+fk8QSruqow9lTvDzOTGGfp1XFuvTsS/M\nlwx+3wWL/dsV9hlCO4X6bbVvMSf4yTN9ex9SPtpy1gnY/GXawcpllE9qLhw85uPablU8FbiX6ddh\nbWoNcFbJY4/GDrZkr8V4MLYCpc57cD/Tb1ZTZkfsTMA3FzxW5wYvbUqo/gVraPEljD/YrAt8Bbt2\nd5oc6vadUOp0DvBxbPliKh9HH2JLUH3mJYTbPxPGr69hZU2dwfSzM+tIqF62tseJOrbC6v8Bpi/X\nnYNNIj6de776bTeq1lMfYkuoVp8xxVxFX9tqgtv6TI0bSyx5vQ+5uYqysbjKvDIVcrsuUtSXVZ9T\nQq7PUOopljzmWl+/JwilXdXRhzIn+Pmc2Pd+nVcW61LgbmzFYtbd2JfMo4TQTqFeW11K/2JOcJ9n\nltK/9wH8teWsV5L5fDVnsPFn2M1VimyMXYLqrpov5MLO2M1YXka9ZS6j/A67fliR07BlNWdmtv0H\ntnKlzvXthr1GagPseqofBE4teHwF/m9E41Ns8T0EvAVbGvahwba6fWcFYcR8LJZ8y8oO/Y2tqpjq\ncxx96p+jypranHauKd3mOFHX6sG/NzH9MjsPA7djZwROZLavIJx6riKWflu1nvoYW5nZFnMsbbVM\nW7kmlrweQ24eNhZXmVemVhBebMMU9WXV55QVhBdbKpR6iiWPudSnzyF5obSrOvpY5qq6aktt9eus\nYbG+E7tU0EWZbbtilw6qEv+Kis/zrU5bjSXmIrG/Dz7bctYW2AqTu2HqHiAPYndj36zgD+Zhyybr\nXFLFhS2ALwDvYuYR6aZ+x8wlQ2AHhFZi1x9b4+k1UhPAv2LXWHtTweO7YUf9XDbE3bEb20yMeuLA\n94GXj/laXcSX9XHgMQXbtwOeRPGE/mjgmszv22J94oeZbd8f/HsIdmCuTt9xHfO49bkYSyAfGv70\nTmPLU33OFHL/dFFfqVFlzdqC0Qfrm5atrXFi3PbwIHa5jnsKnrMG+5J1M2xSpX7bXBv1FEse7kPM\nTfJw6G01r836bBJLLHm9y9zsYn4xbCyuOq+E8Ns1VO/Lqs/w6zOUOVEseQz8tz9QuxpGnw+m67It\ntdGvs4bFOsHU/Rv+lNm+Avvyd9TZ/aG0U6jeVu8hrJjz2sozbb8PvseApm05bwvs4MfD+QfOBy7O\nbVsHu0HJF0t29hHgezV/9qlQyLlYYFUmXuO4GFtKNCe3fXfsg+eqEX+/DDvD4jjgo9id6PM+B/x8\nyD7eyszKfknm/6/CGn263GkzbEKetZzpk/O2JIw+INY0Pl+xJVRbcrYBdum1h5h+Bky6FO2Pg+dA\n9b7TVcx5L8KW8l+a+fk8FtcNg98PGTw39NgSVJ95CeH2z4T6y31HlTXrSuD9NfefSqhWtqrjBMCm\nWF/bruTxUePEuM4Hflqw/Wrg15nf1W+77bdV6yn02BKq9+tYYs6Lqa0muK/PJrGElNf3xJbpn47N\nlZYXPGdYXg89Nw8zbCyuM68MvV3X7cuqz24+ryaEladGCSmP7Q0cDrwaO7v2aQXP8TU/TfX9ewII\no13V5arM0H2/TnXZltro11nDYt0F6///lHv8M8B3B//fPvdYNvbQvnus0lbrxpwvfyx5po/vg8+2\nnHchxQcUWYUdGcne+OTJgxdfWbIzHyawpTCfxz4QurAx0xPha7G48l9KLcCODB1esI9lwAGD8l3H\n1Ju+H8VHoVZhR/WKYjiS4htgfizz/09hDTv1dmzJT9Zc4FEF+/EtYfgXrC7i8xVbQrWEMwe7gdx1\nTO8Tz8RivzSzrWrf6SrmKpZSfG3f0GNLUH3mJYTbPxPqTfaqlDXr18Ch9Yr0/xKqla3KOAF2hujJ\nWF2U7XfYONHEP2BnTGTPMp/AvmBNMtvUb7vtt1XrKfTYEqr361hizouprSa4r88msYSS1+cBH8hs\nfx5w3+Bvs4bl9dBzc5m6YzGUzytDb9d1+rLqs7vPqwlh5alRQsljAL8Cjhj8/2jsoN7c3PN9zU8h\nju8JIIx2VZerMkP3/Rq6b0tt9OvUqFjnYzeIfn7msQ2xlcXpJfHel/vbbOyhffdYpa3WjTlf/ljy\nTN/eB99tOe+/M383bQXEx7APZC/NbDsK+A7wtdLiu/c27AZeh2JLXFw4jenXTfvq4N/8tS3vxc6E\n2D+3/UDsAMrXsKU3GwG3DB77L+BxzHzDLwfWY+ZBlv2wy3ptD/x75uczTL+5zWqsksHOzPgFU9eB\nS/15sL1taYdYVPCYq/i6ii31MHAWdhm2BwbbFgGvwAa7kzPPrdp3Qo55fu7fVAyxweyqz1j6Z9Wy\npnYDlmA3evSpyjgBtkLy9BH7KhsnmroIO4lgFVPLU4/EltGekHleCPU8TOz9tmo99TG2MrHGHHtb\nLeM714SU17fHVn6nnx2+hI1Ff5P7m2F5vY+5ue5YnCqbV4YUW5E6fVn1Gfbn1VTX9RRSHkt//2zm\nb4oOcvian/bpc8goXbercbgqM3RfB123pbb6NVSL9Q9YH99p8Pt6wNlYPd+B9eVbc/vNxh5anVdp\nq3Vjzpc/pL5ZJrb3oY22nLUFsAe2qrXQztgym48Mfi5gcLf0lhyFnZWwtaP9TQCvAe4E1s899hvg\nmIK/mYstZbsQOAN4N/CCzOMvww56ZP0aODi3bQ52/cyn57bfg51BU/TzlszzdsIq/mzs6Ff2Gmtz\nsPfqXCz5tmERdl24G5kq7z3YMqQXZZ7XND7fsSXUO9r+DOATg5/vYP1iScHzqvSdrmIeZj7wdez6\nlWuxg47fBv4+85yQY0tQfUJ/+mdC9fqqWtbUKuBHY5RpnLKNGieyhq0AKRsnXFiAnVBwMdaWz2Tm\nB1n12+7zcJV6grBjS6hXnzHEXCaGtprgvj7HjSWkvD6BXQIrLftuWH7fJbefUXk95NxcpO5YPGpe\n2Zd2XbUvqz67+byaEE6eGiWkPJZ3AXBKwXZf89OuP4eMktCfdjWuJmWGcPp1122pzX5dNdatgXcA\n5wD/AmwDPBvL2W9l6gB2UeyhffcI1dpqlZjLyh9TnunL+9BGW846HLgfW8AQnJXYQLvMwb42wZYq\nfxl7M88peM7rgB9Qf2nnG7CzvrJuBA4reO6bsCN2rj0b+8LzfOC5HvbfJd+xJdS/3qJvqs/xJag+\n29Q0tgR/9XU5cGyDv0/wU7ZhB0DA3zjRhPptXFSfcYmpPkfFEmpeh6kPoUU0/68vpnZdVcz1CX7j\nSwgnT40SYh57PHAqdmCv7IshzU/96mv/V782IfbrqurG3te2mgot3oRu6j6098GFUWW8EHhPqyWq\naFfs4EfRTbiKrIMd5FiMLUVfji1BPwk7S+UvTD+a9MSCfWwA3IYtZ6/j2diBlaw7KD5DYj52mYMD\nCh5rYpPBvm9j+vVpY+A7tvdh7SYkqs/xqT7b1TQ2X/W1A3ATM1f61eGrbKMOgPgaJ5pQv42L6jMu\nMdXnsFhCzutHY2dXT5Q8rvl/fTG166pirk/wG18oeWqUkPMY2NUwrqE4Ls1P/epr/1e/Dr9fj1I3\n9r621VRo8XZV96G9Dy4MK+Ni4HaKLwvfqa2w63WVLYVp+nP9kNd+CXbgZdMa5X0ktnIktRF2zbGd\nip/O64CfYtcuc+k4bGXLxh723bWYYysTc8wxx1Ym5phDjO1ybPljiEYdAAF/40QTIdazbzHHHHNs\nZWKOOabYymIJNa8fhB0AAfuwtbTkeZr/1xdzbGVijzmW+MaNI7Q8tid2afD03qW7YvPUsoMcmp/6\n1ddY+lruvFj69Tjqxt73Op9t8ZaJ8X0oK+Ol2ErH4HwAuMHjz8tHvP47sOud1XErU9ddOxi4bMTz\nz2P6jaVcuAq7ocuRwLqO9921mGMrE3PMMcdWJuaYQ4vtZdiZFKGqcgAE/IwTTYRWz22IOeaYYysT\nc8wxxVYUS6h5fR/s4Mfiwc9hwF5Dnq/5fz0xx1Ym9phjiW+cOELMYzsAV2L3CgG7P8ifGX7PV81P\n/elrLH0td14s/XocdWPve53PtnjLxPg+FJXxhdg9rmas1A4hiFd2/PonAR/EJgQ3V/yb5wz+7nrs\nDIpXjXj+Mdi13uZjd7V34RvYWRzXAg852mcoYo6tTMwxxxxbmZhjDim2zYAnY5PR0BwBrBj8/yzg\nisG/ZXyME02EVM9tiTnmmGMrE3PMMcWWjyXUvL49dsLTvNz2BUP+RvP/emKOrUzsMccSX904Qs1j\nN2P3Ljoeu3zPXsBTsStilNH81J++xtLXcufF0q/HUTf2vtf5bIu3TIzvQ76M84EDse9i1nZYLhER\nEREREREREREREREREREREREREREREREREREREREREREREZGQLAd+6GA/y4DTsDvBfxR4hIN9ioiI\niIiIiIiIiIiIjGUudjPxJiaA67CbFALsB1zZcJ8iIiIiIiIiIiIiIiKd2hf4Web3dYE1ND+wIiIi\nIiIiIiIiIiIiPbNux68/B3gJ8GTgbODHmccWAidiKzvKPAS8GXgQ2BG4M/fYauyyWL9wVmIRERER\nEREREREREQle1wdAngVchq3e2JXpB0BWAyfX2NdC4P7ctgeATZoUUERERERERERERERE+mdOx6//\nVewgxb7YgZAmfs7M1SLzgLsa7ldERERERERERERERHqm6xUg9wHHAZdiB2PWwy5nBbA5sIrql8C6\nFliceWwjbFWILn8lIiIiIiIiIiIiIiKtuwrYAziS5gdkbgW2G/z/YJqvKhERERERERERERERkR5a\np+sCYDcvXwD8CPhlw31dCRyPHQR5DLY65PcN9ykiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi\nIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIyq/wf/nUU1k19kdYAAAAASUVORK5CYII=\n",
"prompt_number": 6,
"text": [
" n \n",
" ___ \n",
" \u2572 \n",
" \u2572 \u239b \u239b 6 5 4 3 2 \u239e \u239b \n",
"0 = \u2571 \u239dc\u2080\u22c5\u239d2\u22c5t\u1d62 - 12\u22c5t\u1d62 + 30\u22c5t\u1d62 - 40\u22c5t\u1d62 + 30\u22c5t\u1d62 - 12\u22c5t\u1d62 + 2\u23a0 + c\u2081\u22c5\u239d- \n",
" \u2571 \n",
" \u203e\u203e\u203e \n",
" i = 0 \n",
"\n",
" \n",
" \n",
" \n",
" 6 5 4 3 2 \u239e \u239b 6 5 \n",
"6\u22c5t\u1d62 + 30\u22c5t\u1d62 - 60\u22c5t\u1d62 + 60\u22c5t\u1d62 - 30\u22c5t\u1d62 + 6\u22c5t\u1d62\u23a0 + c\u2082\u22c5\u239d6\u22c5t\u1d62 - 24\u22c5t\u1d62 + 36\u22c5t\u1d62\n",
" \n",
" \n",
" \n",
"\n",
" \n",
" \n",
" \n",
"4 3 2\u239e \u239b 6 5 4 3\u239e 3 \n",
" - 24\u22c5t\u1d62 + 6\u22c5t\u1d62 \u23a0 + c\u2083\u22c5\u239d- 2\u22c5t\u1d62 + 6\u22c5t\u1d62 - 6\u22c5t\u1d62 + 2\u22c5t\u1d62 \u23a0 + 2\u22c5d\u1d62\u22c5t\u1d62 - 6\u22c5d\u1d62\u22c5t\n",
" \n",
" \n",
" \n",
"\n",
" \n",
" \n",
" \n",
" 2 \u239e\n",
"\u1d62 + 6\u22c5d\u1d62\u22c5t\u1d62 - 2\u22c5d\u1d62\u23a0\n",
" \n",
" \n",
" "
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df_dc1 = collect( expand(penalty_fn.diff(c1), deep=True), [c0,c1,c2,c3])\n",
"print 'Partial derivative wrt c1 is:'\n",
"Eq(0, Sum(df_dc1, (i,0,n)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Partial derivative wrt c1 is:\n"
]
},
{
"latex": [
"$$0 = \\sum_{i=0}^{n} \\left(c_{0} \\left(- 6 t_{i}^{6} + 30 t_{i}^{5} - 60 t_{i}^{4} + 60 t_{i}^{3} - 30 t_{i}^{2} + 6 t_{i}\\right) + c_{1} \\left(18 t_{i}^{6} - 72 t_{i}^{5} + 108 t_{i}^{4} - 72 t_{i}^{3} + 18 t_{i}^{2}\\right) + c_{2} \\left(- 18 t_{i}^{6} + 54 t_{i}^{5} - 54 t_{i}^{4} + 18 t_{i}^{3}\\right) + c_{3} \\left(6 t_{i}^{6} - 12 t_{i}^{5} + 6 t_{i}^{4}\\right) - 6 d_{i} t_{i}^{3} + 12 d_{i} t_{i}^{2} - 6 d_{i} t_{i}\\right)$$"
],
"output_type": "pyout",
"png": "iVBORw0KGgoAAAANSUhEUgAABZYAAAA4CAYAAABuQK0+AAAABHNCSVQICAgIfAhkiAAAHFpJREFU\neJzt3Xm4HFWZx/FvQiBCQiIxYJDFDGGRLa4MMjJyWUaRTWVUEEUCKBERBzEIDuMYkU0QBRdGEZlS\nRkUEhDGIjoqoKAKDIkEF2SKgEUUQMSjCkPnjrXq6bt2q7lNd2+lzf5/nuU/S3dXV9dZ56639FIiI\niIiIiIiIiIiIlDCl6wlwMAdYDLwQOAXYEtgE2BB4V4fTJSIiIiIiIiIiIiKeOgJYC7gDOCB+bxbw\nSGdTJCIiIiIiIiIiIiJeWxfYCLg39d6uwA+7mRwRERERERERERGRyW1q1xPg4FFgd+Dq1HuvBS4B\nZjMa3XmIiIiIiIiIiIiISMs+C7wp9fpBrI/lxd1MjoiIiIiIiIiIiMjkNQpXLANsDnwz9XoZsDdw\nQzeTIyIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi\nIlLObcDqBv/ObC8UEREREREREREREWnDgfQOAq8Ctnb4zlrAHGCTePgdgJcDpwE3AU+lxvkQsE7t\nUy0iIiIiIiIiIiIinTqf3oHgW4C1K45vfeAg4MZ4nIsrjk9EREREREREREREPLMO8HN6B5c/VdN4\npwHvB5bXND4RERERERERERER8cj2wF/oHVw+oMZxnwfsXuP4RERERERERERERMQTR9I7sPwIsFlN\n410XOLjP5x+v8bfyTAMiYFaDvyEi4rtnAJ8DpnY9ITVQXReRNql+ikjbVHdkMgop70XqMhv4MrBm\n1xPi6hJ6B5dvxB7U16QP0WwfzFOwldieDf5GVa/EHqJ4GHBMx9PStAuAJ7Gr47+P28MiR9VZwM5d\nT0TDdsZOGr0DuBTYo9vJqd2OWHc+pwGXAwu7nZxaLAU+1vVEVORTXQ+5fk+mej2sEOt86HU9q0yd\nX4rqp09Crr9Zk6keh1hXs8rU2aWo7rgIuR6EuPwPWs6XMvp572qybXdVFeL+uavjgS9gNdV7TwdW\n0Du4fHaDv/Vm4LIGxw9wHPCRhn+jij2whQJgPvA3wj6TuxSYh51xCdkuwAPAWMfT0bR7gUPi/x8O\n/BmY3t3k1Gom8InU69cBjzL6ubsO8Gus/o4qX+p66PV7KZOjXg8r1Dofcl3PKlvnVT/9EXr9zVrK\n5KjHodbVrDJ1VnVnsNDrwVLCWv5dlvMQ8t7VZNruqirU/XNXawF3AO/rekJc7QQ8Qe/g8r4N/Mba\nwG+A7RoYd2I2sBKY2+BvVDEVmwfPTr3XZJcgPlja9QS0YDZ2xvEawt8w3g6YEf//NdiZ9FBWhAuB\np4AF8etZWD3cp7Mpqs8h2EZM03ekNMGXuj4Z6vfSrifAYyHX+ZDretYwdV71s3uTof5mLe16AloQ\ncl3NKltnVXeKTYZ6sLTrCahRmeV8lPO+jMm03VVVyPvnrvbFTj5skH7T135jrgP+PfU6Ajap+TeO\nAu4Bbq15vGnHAFcDDzb4G1VsDWyInVk9GOtrevMuJ6gFa2N9eR+Mnbn+u24npxFHAJ/qeiJaciuw\nKv7//sDJwOPdTU6tlmMn2e6OXyc18K5uJqdWnwN+Bxza9YQMwZe6Phnq92So18MKuc6HXNezhqnz\nqp/dmwz1N2sy1OOQ62pW2TqrulNsMtSDkJb/Msv5KOd9GZNpu6uqkPfPXX0VuBb41/Sb0zIDbQyc\niZ3VewTrmPkjwB9amMCsDwK7x39zgC9ity38X03jP5bMzKjZVOBo7KxPEzYBTsLmxyPYWYMz6BUF\nF8nV2k8BFwJfwxaSbYH7a5vSYlsBS7A+m56DFe5TgZ9mhqszL5cDF2O3KK0EvgI8b4jxuHJppzrj\n2w+4im5XBm3H/ALszNkqmr3Nre18XQ1cn3p9AvBh4BdlJ7yiOmpN1mrgXKwOj9JOnGtd3xi7EqJo\nx2I9rD3XwK6cWAO7pei+EtPSZv1+BfBp4Gas3R+PfzdxI73bwrbB8n8tLLYfYv2QPTzE77Zdr4sM\nak/XZb6Odof26nxX7Q7t1fV+2liOh6nzodfPKtpoM+h++xnsCslLsL4Of4f17XpA/Hdbn+8twWrU\naX2GydNmPW47NvBj+xnay2EoV2dDrjtVt3O7qgeDciW07bE69kfKLudt5P2wcZ0FvB47qbEb8J2K\n0zEK211Vcrqu+dXF/rkvOZJ2NlYHTsybjjWAO7GzOImTgW/Q3ZXN87D+b5IuMU6tabzbx+Nr8jaV\nF2LFt4nbCDbArrb+h/j1HOB24J05wy5g4u05ib2x+bB26r2VwFtrm9JiW2C5tW78egrwJeBPjO+e\npGxe9osXxp9MmY/FvyB/0Mpc2qnO+J4FvCn1+hrav5Wv7ZjTjgBuYnw+16WrfE0cjq1A2u4ov65a\nk+el2PL3zIrT2KZBdX0G8DLgl1hseZ6O5c6GqfcWAj/DNqiyiuZrm/X7XfTWw3l/r4iH2wo7g71p\n/Ho9bGdkOVafsnyq13lc2tN1ma+r3dus8121e1qTdb1Im8txWpk6H2L9rKLtNuty+zmRXR5XYQdN\n+nl2PNzSgs/7xdxmPW47Nh+2n7uqO+BeZ0OsO3Vs57ZdD1xyJbTtsTraadjlvMm8LxNXnrdjB8kH\nLbshbHeVzek8dc+vNvbPfcyRZPj0vsC4nZ4DsaPhn0+991mskRc5/kDdfosVgCTBTgD+qYbx7oGd\n2bh70IAV7Iat6Js48/1J4BzsLA1YsX8a1nF41r5YAj6Q89nN2LxdI/VesgE3rIVMvBI+z4FYO4yl\nfvcK7MDdQZnhyuRlv3h3wM7yJAtWcuvCXxymdxgu7VRnfC8HNsKWkxOALbF5ufewAeDenok2Y94x\nfi+5Heta7GzrLiWm11UX+ZpI+mx6NzYv55eZ8Iwm2jPhEktacsvQWInpSSsbSx361fWtsXYfA37f\nZxz7YBtBK1Pv3QJciT0AIqtovjZRv4tsgZ2IXQub51Piv52xK1avioc7HcvTe+PXDwOLsZMvx+eM\nt+16XSZnXNvTdZmvq92bqPNFumj3Jup6E+1eV3umxwfudT60+llFF23W5fZz4l7sjoKLsR3M5wL/\nPeA7J2IPpCpSFHPb289txgbdbz+3ncPD1tkQ604d27ltbo+55kpI22NQTzsNu5xXzft+ysSVZ2fs\n7rFBbRHCdlfZnM5Tx/xK1Ll/3o8POZLnV9hd3LnHZm/G+h/Kugu4zPEHmnIGvbPWv6V65/tfIT/W\nOl0BXNDAeF+LnXl9uuPwlwLf7fP5VVihBVgfS6YqZ+Qi3Bas/bHbg16Seu9ArI3fnXqvbF72i3cO\n4/vuPh74H4dpHYZrO9UZX9YKqq8EI9wLZdsxL8BWfslVCK/HNhzXd5nYkrrIV7CV+uHY3RvzsA2g\nnZyneqKI+tszUSY3wQ5Q/QX4aInvpEU0txIv4lrXI4rPuH8Ye5pu9uqZ07DbubL6zde663eR/8h5\nbybwdcbvyD+A3aa8buq9acBfsR27rLbrdcRwORNR3J6uy3yd7Z62guaurOui3Zuo6xH1t3ud7TlM\nnQ+5flYR0U6bQXfbz4lrSo5/f3rbLUsLhimKuc3tZ2g3tjwraHf7Ofu9pnN42DobWt2pczu3re2x\ntIjiXAlpe6yp/ZEVuC3nVfO+SNm48vwaOMVhuBC2u8rmdJ465hfUv39exJccKXIn8OPkRXLF8jTs\nzMIdBV8YK/kjdTsRuCH+/91YvyJVbIxd6t2kjRr6jddgbfJHx+F3Br7X5/ODgb2wBxsci519cT1T\nUcVlWDv8IPXeTlghWxa/HiYv+8X7EPB97BaPM7AzlfuXnG5XLu1Ud3yJjbG+kTbC+hFv6ymlbcd8\nF9Z30NFYnAdhtyv1O9s5rC7ydbN43OdjV6esxM7ouq48q6q71mStxm7t2ajkdHWpjrr+I6zvsM9h\nt3GBHaTbB7goZ/h+87Wt+n1kzntnYv06PpZ6707sFrUZqfeepHgD1Zd6Pawyy3yd7Q7t1Pku2r3N\nul5FXe05bJ2frPWzirqXwa62n4cxE5vWvDjTimL2uR5XjS2tq+1nV3Xl8LB1NrS6U+d2rm/1IKTt\nsbr3R8ou503lfdm4shZgXUC4HAwMYburbE5n1TW/2tw/9yVHitxFznKxEbbQnJXzhcviz5roE62M\nD2I7b1WvVgY7Q3XugGG2xM56XwC8B3hHyd/4FeOvZKzL7Vhy7IidfYiwK7DTnZzvh11RdD3WdtfG\nrxc3MD1ZEcOdodoOe9BRulsB17zsMt4iLu00CvFFuLdnKDG7GNV8jai3PavGsozyZ0cTEeVrTVt1\nPaL4jPtawDfjz1diOyPLsK4TEr7n/0vIvwJ/GhPPqm+KxfDV+PWo5H/2e3ntWWbbSe0eTruDH+0Z\nav2sIsLvNusnolybXAcch62fzwE+Ru9W5qxT6PWHmr2q18e6E0JsEao7WRF+1R3f96kHiSjOlZDW\nyz60U5W8L+ISV9rz4+E+hC0PbweeYPyB1rRRad/s96rkdNooza8ivufIJ7CD++OeI/XCeGQn5Xzh\nQoo7LL8Auw20zN+Y44SmvQE7a7LFEN/Ns4r+Twx+EXbZ+F6p17+j12m2i8eoPxFnYE+DXA4clXp/\nf6yfmWySLcats+46RZQrJPtgfeasBA7JfFY2L7uIN49rO41CfBFu7RlSzP2Mer5G1NueiWFjOYfh\nz/BGlKs1bdb1iOINI7D5+zV6XTwtI38d61v+J24CXuU47OlYLmXns8/5n/e9vPYsu8yr3cNo90TX\n7Rlq/awiwu826yeiXJvcQa+vU7A7DG5l4g7k87ADcomi7iJ8qjshxBahupMV4U/dGYV96kEi+udK\n1iiul31ppyp5n6dsXC/DuoNNHtK5NRbndQ6/5XP75n2vjpwetfmVZxRy5J1Ye82F3tHlpEP7p3K+\nsGafzw7DVupl/q4pOcEvxa4ufhX5t5sOq2jGbYX1k/QpbMUN9vTdnw/x+3Un5EyszbbAHg6UuBxr\nw1Mzw++KW2fdXVqGdaC/CfBGrK/KZL6VzUtf4nVtp1GNL89kiTnEfM3TVq15nGafpJvwra6/Erut\nbp/4372xFX/2qe4+5sjuWP5f6TDs5tjZ8pPpPXQi4WNsZZVd5tXufsY2rK7bc7LWzyq6brM6bQXc\nl3p9PnaLbrov1KnYjl/eXRVZPsUccmxVdZ3DodSdEPep+xnV9bIv7VR33peJaz7wRWAJ9rwfgF9g\nXcO6XEXtc/tWUZTT8wljfo1Cjvwt/ncK9A4s3576IGsGdgn1gyV/qA5bYh1Jv4XxfZtW9Xt6t01l\nnYRd0p3eUPkqg59UWeY3hvVQ/O+djO9n+ims/6i9GF/0xqj/to2mPAl8AEvs5IFBZfNyDD/idW2n\nUY0vz2SLOaR8zdNWrXkG7fTh5VNdX4TdhXMUdpBue+BsbKPg4sywY/iXI2/DbpN6YsBwT8M2cs7F\n+uTNGsO/2Moqs8wvQu0OfsY2jEV0356TsX5WsYju26xO2RNaT2DzeCz13mLsCrCiOpU2hj8xhxxb\nFYvoPodDqTsh71NnjfJ62Zd2qjvvy8T1QaxbtUtTw22DPVTRJdYxx+FGSb+cDmV+jUKOzMWuqv4D\nWF8lYCvs2+g9CCBtJnbbSZnL0uswFztDeSYTV5ZV/Z78vkmmYlflLMO6y2jiN7YHzsP9rNfNwFvj\n/z+B3YL/cM5wq7Ad2fWwRNwWuzWqqQXjs8Bzc97fFPh78jf0DsdupQW78mk94JbU5zfH/+6PnUwo\nk5dNxDtsW5Vppy7jS6vanqMQc5VlbxTyNa3N9qwSy1wGn7SsGksbdb2MxcC/pF6vwq66uh3bQFo/\n/h2f8j+xJvbU8/MHfHcK8J/Ygcj35nzue/67KrPMq93DaXforj3TQqqfdeTpID60GdSTp1dg82q/\nzHDTsYtywJ5Uvw29k9/9+FR3fI8tS3VnolGoO13uU7dR7xKjvl725dhHUd43fazgYewipq8z/mrS\nMeyA3rUDfs/39h1Gv5yegl/zq43jfl3myFzsoPKEOzcvZOJDWdbAnkJ4VcHIPg38b8m/XRwmcjo2\nE1w2GIZxGfBXMh1NY42/GruMvJ/tsDOpR2I7Ws/KGeYK4JfVJjPXhdil7Vk3Mv62saSz7pnx6/UY\n31/ZQsYfJKtLxOA+dZ4GPIKdiU6fRX4mNv//HA8D7nk5KF5oLuY8ru1UV3xdtmcilJizusjXUWrP\nKrFciz2UZxgRbrG41nWwh0J8E9sgyuNa1yPyT8bOwFa+2YdPgG10/IneA4p8yf+0l1Dcp3DayUzc\n2FuU+v8o5H/2e0Un112WebW7CaXdfWlPn+rnjsD7seeXXI7FldXUdnFahN9t1k+Ee57+hok7gRtg\nsX8jfv1GbH12eervyniY2+LX+8fD+lR3QoktQnUnK6LeurMz9gDDd2BX6u2RM0y/uuP7PvUgEYMv\n/AthvexDO1XJ+yIucW2NtfG/ZYb5MnBD/P/NMp+l4+zq+EhEc30s98vpsvMrG7tvy3oTOVJnzBdR\ncJJgCXbEOd0P0YvjCd29YGRNmIJd2n4ltnNWhxmML6LHYHFlDx7MxlbaB+eMYztgz3j6fkKvgXYj\n/0zAEuwsTV0xJP4ZOxuRvkJqCrYTG6Xe+xKWdIlTscvhE9MpfsJyFRGDC8lU7GEMP2F8vu2Htcvl\nqfdc83JQvNBczHlc26mu+Lpsz0QoMWd1ka+j1J5VYrkPOMBxerIi3GJxqetgV52/B2urovG61vWI\n4g2jG4B9c97fifEPBvEl/9MOYfDO3qHkH4D8TOr/o5D/2e8VtafrMq92D6vdfWhPX+rnTOzJ4InX\nAY/G301rars4LcLvNusnwj1Pz2PiNu6eWOzH9PnefPIfcOdT3QkltgjVnayIerfb7qX3IO3DsQs9\npmeG71d3fN+nHiSi/0G4UNbLPrRTlbwv4hLXLKw/3QNTw6yN3RGXdBPz0cx403F2dXwkopkDy4Ny\nuuz8ysbu27LeRI7UGfOPUr8x7ordz2A7R29OvXcYcD3w7YKRNeEUrMP+A7DLt+twEuP7JvlW/G+2\nz6VHsDOeL8+8vxd2YPrb2GXl6wB3x599D3g+E2f41djto0VXvg3rUuyg+xJ6l9Ufil0q/87UcA9h\nCQV2Bvceen21gCXgPTVPm6unsD7BvoZdOQ52NcLbsMKdfsKza14Oihfajdm1neqKr8v2TIQacxf5\nOkrtOWws22IPm7mmtinO51LXwe7AOW3AuFzrerJC3iDnsw8AZwDPSb23MfZQovROs485ksTzaMHn\nu2HdV20G/Ffq78v0zoSDn7H10689XZd5tbufsfXj83LsU/3cDLuDL9mm/jrW7v+Y+U5T28VpPrdZ\nnc4GPoztj4Dtzx2BXZiTPciQNivzb8KnmEOOzYXPOexT3UleX5L6Tt7B4351Z9T3qfvlSkjr5a7b\nqam8d4nrT1i+bxG/XhM4Jx5+JZbXKzLjTcfp2/GRQarmdNn5lY3dt+WhiRypK+a5wA7Y3UO5tsQu\nuf50/PcFrL+mthyGnX3csKbxTcH6onoAWCvz2a+xDZWs6ditDhdhK+8PAa9Pff4W7GBy2n1MPIM8\nFevX6WXDTPgAs7ED8Jdh7XUWE1eYW2BJdg52BiNJxqnYfD4PK5R1i3A/Q7U38Pn473os57JPNQa3\nvCyKF5qPuYhLO0G1+HxqTwgj5iJt5OsotuewsSwBbi0xLVkR7rEMqutp/a5Y7lfXN8Bu370jHsdq\nrN+rG7DbdtMWYjvJF2MbDRcBL8oM41v+g+3k3Y9dMZTnYXqxZ/8+kBpuFPK/THu6bjup3cNq9y7b\n06f6OQXrCiOJbVtsvm2dGU9T28Wj0maDRJRbP+8AfBLr4/J84Dh6z87JmgV8B+sjdDV24c51wKvi\nz32rOyHEFqG6kxXRzHYb2Hr3xJz3B9Udn/ep87jmSkjrZei2narmfT8ucW0InA58HKuLGwGvxurc\nyfROpuXF2dXxkYj6659rTrvMr6LYfVrWE3XlSN0xHww8Ru8ksFd2xwp/0Y5LGetit6l/A0u2j+cM\ncyzwU8rfknc8djVG2h3AQTnDvhc7y+CTV2ML8IXAaxsYf8Rwtz40qemYu6T2DEtI7TkolquxB9EM\nK6KZWPodWIbu67ryf3gR/tUzV2r34UX41+5VY/a1fkJvxydP1/WzCuVpWNSe5flYd14AvA87qVt0\ngKOpuqPlY3gR/uyPDFI179tSNs4m2zjCv/qX5tO8akvdMV+E3V3knW2wg8p5ne7nWQM7eDwPu/Vu\nIXbL3QnYWeu/Mf4sRvZMLtjDtu7Hbt8r49X0Hh6RWEn+mdBZ2C2ye+Z81pV1sem6n/F9Qtblo1i7\n+KTpmLuk9gxLSO3ZL5YFwJ1MvJOkjKZiGXRgueu6rvwfno/1zJXafXg+tnuVmH2un4djVxdOKfi8\n6/pZhfI0LGrPcnyuO2B3Id9EflxN1R0tH8PzZX9kkDryvi1l42yyjX2sf2k+zau21BnzPOxBu3ld\nlnTqmVi/HUWXtlf9W97ntxdhB7TznrBb5NnYlc6JdbC+R7bIH5xjsac5rlniN5p2JHYV9wz8mq4m\nhRxzyLEVCTnmkGIriuVq7PYaHw06sAzd1/WQciQr5NiqCnnehBxbkWFj9rV+7oMdWAbbCZlfMFzX\n9bMK5WlYQo6tSCh1Z0esq8vkGUfbYNtvRQePm6o7IedQSLGFkveDlI0zpDYuazLOq7pivhy7U8Q7\nnwBua/DvrQN+/3SsT5EyVtDr22RfYNmA4S9gfOfyXfsB1n/ZoRT3WRaakGMOObYiIcccUmx5sbyF\n/g/g6ZrLgWXotq6HlCNZIcdWVcjzJuTYigwTs6/1cxfsoPK8+O8gYKc+w/u2XexKeRqWkGMrEkrd\nWQBci/XFDNb/8uP0fzZUE3Un5BwKKbZQ8n6QsnGG1MZlTcZ5VUfMb8D6tJ9wZ5oPM+Wojn//BOBc\nbAV1l+N3XhN/bzl2pvTtA4Y/AutrZhb25MaufRc70/tj4MmOp6UtIccccmxFQo45pNiysawHvBjb\nWPPNIcBY/P+zsac/n91n+C7rekg5khVybFWFPG9Cjq1I2Zh9rZ+bYRdYzMy8P7vPd3zbLnalPA1L\nyLEVCaXu3IX15X401k3BTsBLsTuRizRRd0LOoZBiCyXvBykbZ0htXNZknFdVY54F7IXtM69uaBpF\nRERERERERERERERERERERERERERERERERERERERERERCsRC4pYbxbAechD3B8HzgWTWMU0RERERE\nREREREQ8NB17CF4VU4CfYA8RAdgNe1qsiIiIiIiIiIiIiEiuXYHbU6+nAauofsBaRERERERERERE\nRFKmdfz7U4FFwIuBc4CfpT6bAxyHXYlc5Eng/cATwObAA5nPHsK6x7intikWERERERERERERmeS6\nPrD8SmAZdrXxNow/sPwQ8J4S45oDPJZ576/AulUmUERERERERERERETGm9rx738LO/i7K3aAuYpf\nMvHq5pnAgxXHKyIiIiIiIiIiIiIpXV+x/ChwJHA5dpB7TaxbC4BnAEtw7wrjx8C81GfrYFcxqxsM\nERERERERERERkcD8ANgBOJTqB7pXAJvG/9+X6ldBi4iIiIiIiIiIiEjGGl1PAPbQvdnArcCvKo7r\nWuBo7ODyc7Grmf9YcZwiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi\nIiIiIiIiIiIiIiIy4v4fRBDBpxTopXUAAAAASUVORK5CYII=\n",
"prompt_number": 7,
"text": [
" n \n",
" ___ \n",
" \u2572 \n",
" \u2572 \u239b \u239b 6 5 4 3 2 \u239e \u239b \n",
"0 = \u2571 \u239dc\u2080\u22c5\u239d- 6\u22c5t\u1d62 + 30\u22c5t\u1d62 - 60\u22c5t\u1d62 + 60\u22c5t\u1d62 - 30\u22c5t\u1d62 + 6\u22c5t\u1d62\u23a0 + c\u2081\u22c5\u239d18\u22c5t\u1d62\n",
" \u2571 \n",
" \u203e\u203e\u203e \n",
" i = 0 \n",
"\n",
" \n",
" \n",
" \n",
"6 5 4 3 2\u239e \u239b 6 5 4 \n",
" - 72\u22c5t\u1d62 + 108\u22c5t\u1d62 - 72\u22c5t\u1d62 + 18\u22c5t\u1d62 \u23a0 + c\u2082\u22c5\u239d- 18\u22c5t\u1d62 + 54\u22c5t\u1d62 - 54\u22c5t\u1d62 + 18\u22c5\n",
" \n",
" \n",
" \n",
"\n",
" \n",
" \n",
" \n",
" 3\u239e \u239b 6 5 4\u239e 3 2 \u239e\n",
"t\u1d62 \u23a0 + c\u2083\u22c5\u239d6\u22c5t\u1d62 - 12\u22c5t\u1d62 + 6\u22c5t\u1d62 \u23a0 - 6\u22c5d\u1d62\u22c5t\u1d62 + 12\u22c5d\u1d62\u22c5t\u1d62 - 6\u22c5d\u1d62\u22c5t\u1d62\u23a0\n",
" \n",
" \n",
" "
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df_dc2 = collect( expand(penalty_fn.diff(c2), deep=True), [c0,c1,c2,c3])\n",
"print 'Partial derivative wrt c2 is:'\n",
"Eq(0, Sum(df_dc2, (i,0,n)) )"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Partial derivative wrt c2 is:\n"
]
},
{
"latex": [
"$$0 = \\sum_{i=0}^{n} \\left(c_{0} \\left(6 t_{i}^{6} - 24 t_{i}^{5} + 36 t_{i}^{4} - 24 t_{i}^{3} + 6 t_{i}^{2}\\right) + c_{1} \\left(- 18 t_{i}^{6} + 54 t_{i}^{5} - 54 t_{i}^{4} + 18 t_{i}^{3}\\right) + c_{2} \\left(18 t_{i}^{6} - 36 t_{i}^{5} + 18 t_{i}^{4}\\right) + c_{3} \\left(- 6 t_{i}^{6} + 6 t_{i}^{5}\\right) + 6 d_{i} t_{i}^{3} - 6 d_{i} t_{i}^{2}\\right)$$"
],
"output_type": "pyout",
"png": "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\nblNERERERERERERERERERERERERERERERERERERERERERERERERERERERESka/0/6gDIVRlUGgUA\nAAAASUVORK5CYII=\n",
"prompt_number": 8,
"text": [
" n \n",
" ___ \n",
" \u2572 \n",
" \u2572 \u239b \u239b 6 5 4 3 2\u239e \u239b 6 \n",
"0 = \u2571 \u239dc\u2080\u22c5\u239d6\u22c5t\u1d62 - 24\u22c5t\u1d62 + 36\u22c5t\u1d62 - 24\u22c5t\u1d62 + 6\u22c5t\u1d62 \u23a0 + c\u2081\u22c5\u239d- 18\u22c5t\u1d62 + 54\u22c5t\n",
" \u2571 \n",
" \u203e\u203e\u203e \n",
" i = 0 \n",
"\n",
" \n",
" \n",
" \n",
" 5 4 3\u239e \u239b 6 5 4\u239e \u239b 6 5\u239e \n",
"\u1d62 - 54\u22c5t\u1d62 + 18\u22c5t\u1d62 \u23a0 + c\u2082\u22c5\u239d18\u22c5t\u1d62 - 36\u22c5t\u1d62 + 18\u22c5t\u1d62 \u23a0 + c\u2083\u22c5\u239d- 6\u22c5t\u1d62 + 6\u22c5t\u1d62 \u23a0 +\n",
" \n",
" \n",
" \n",
"\n",
" \n",
" \n",
" \n",
" 3 2\u239e\n",
" 6\u22c5d\u1d62\u22c5t\u1d62 - 6\u22c5d\u1d62\u22c5t\u1d62 \u23a0\n",
" \n",
" \n",
" "
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"df_dc3 = collect( expand(penalty_fn.diff(c3), deep=True), [c0,c1,c2,c3])\n",
"print 'Partial derivative wrt c3 is:'\n",
"Eq(0, Sum(df_dc3, (i,0,n)) )"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Partial derivative wrt c3 is:\n"
]
},
{
"latex": [
"$$0 = \\sum_{i=0}^{n} \\left(c_{0} \\left(- 2 t_{i}^{6} + 6 t_{i}^{5} - 6 t_{i}^{4} + 2 t_{i}^{3}\\right) + c_{1} \\left(6 t_{i}^{6} - 12 t_{i}^{5} + 6 t_{i}^{4}\\right) + c_{2} \\left(- 6 t_{i}^{6} + 6 t_{i}^{5}\\right) + 2 c_{3} t_{i}^{6} - 2 d_{i} t_{i}^{3}\\right)$$"
],
"output_type": "pyout",
"png": "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\nIgP1f22nO9CIxeBIAAAAAElFTkSuQmCC\n",
"prompt_number": 9,
"text": [
" n \n",
" ___ \n",
" \u2572 \n",
" \u2572 \u239b \u239b 6 5 4 3\u239e \u239b 6 5 4\u239e \n",
"0 = \u2571 \u239dc\u2080\u22c5\u239d- 2\u22c5t\u1d62 + 6\u22c5t\u1d62 - 6\u22c5t\u1d62 + 2\u22c5t\u1d62 \u23a0 + c\u2081\u22c5\u239d6\u22c5t\u1d62 - 12\u22c5t\u1d62 + 6\u22c5t\u1d62 \u23a0 \n",
" \u2571 \n",
" \u203e\u203e\u203e \n",
" i = 0 \n",
"\n",
" \n",
" \n",
" \n",
" \u239b 6 5\u239e 6 3\u239e\n",
"+ c\u2082\u22c5\u239d- 6\u22c5t\u1d62 + 6\u22c5t\u1d62 \u23a0 + 2\u22c5c\u2083\u22c5t\u1d62 - 2\u22c5d\u1d62\u22c5t\u1d62 \u23a0\n",
" \n",
" \n",
" "
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that all of the partial derivatives only have a single power for c0,c1,c2,c3. This means that these equations are linear with respect to the c's. To minimize the error we have to set each partial derivative to zero, to find the minima, and then solve 4 simultaneous equations. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>Now we should have 4 equations and 4 unknowns. We can use linear algebra to solve this for us, but first we need to reshuffle the equations to prepare them for matrix form.</h3>\n",
"We will also factor to reduce some of the terms."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def pull_arguments_by_var(eqn, variables):\n",
" \"\"\"\n",
" For a equation such as : a*2 + b*3*x + 5*x + 5\n",
" this function will return a dictionary of the arguments that are multiplied by each variable.\n",
" So if variables=[a,b], the dict returned would be:\n",
" a:[2],\n",
" b:[3*x],\n",
" 'other':[5*x, 5]\n",
"\n",
" Parameters: eqn -- a sympy equation that has already been term collected\n",
" variables -- a list of variables to search for arguments that are multiplied by each variable\n",
"\n",
" Returns: vardict -- a dictionary containing the arguments for each variable and 'other'\n",
" \"\"\"\n",
" # try to find what is multiplied by the variables in variables and other\n",
" cdict = {}\n",
" for var in variables:\n",
" for arg in eqn.args:\n",
" if var in arg.atoms(Symbol):\n",
" cdict.setdefault(var, []).append(arg/var)\n",
" #print '%s : %s' %(c, arg)\n",
" for arg in eqn.args:\n",
" # test for non-cx arguments\n",
" if not any([(cc in arg) for cc in variables]):\n",
" cdict.setdefault('other', []).append(arg)\n",
" #print 'other : %s' %(arg)\n",
" return cdict "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# from the 1st partial derivative, reshuffle the equations so the c's are on the left and the others are on the right\n",
"# also redistribute the sums\n",
"cvars = [c0,c1,c2,c3]\n",
"arg_dict = pull_arguments_by_var(eqn=df_dc0, variables=cvars)\n",
"leftside = c0*Sum(factor(arg_dict[c0][0]), (i,0,n)) + \\\n",
" c1*Sum(factor(arg_dict[c1][0]), (i,0,n)) + \\\n",
" c2*Sum(factor(arg_dict[c2][0]), (i,0,n)) + \\\n",
" c3*Sum(factor(arg_dict[c3][0]), (i,0,n))\n",
"rightside = arg_dict['other'][0]\n",
"for arg in arg_dict['other'][1:]:\n",
" rightside = rightside + arg\n",
"print '1st Equation:'\n",
"Eq(leftside, -1*Sum(factor(rightside), (i,0,n)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1st Equation:\n"
]
},
{
"latex": [
"$$c_{0} \\sum_{i=0}^{n} 2 \\left(t_{i} -1\\right)^{6} + c_{1} \\sum_{i=0}^{n} - 6 t_{i} \\left(t_{i} -1\\right)^{5} + c_{2} \\sum_{i=0}^{n} 6 t_{i}^{2} \\left(t_{i} -1\\right)^{4} + c_{3} \\sum_{i=0}^{n} - 2 t_{i}^{3} \\left(t_{i} -1\\right)^{3} = - \\sum_{i=0}^{n} 2 d_{i} \\left(t_{i} -1\\right)^{3}$$"
],
"output_type": "pyout",
"png": "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\n4ZT/B72Ij9jP+WqxAAAAAElFTkSuQmCC\n",
"prompt_number": 11,
"text": [
" n n n \n",
" ___ ___ ___ \n",
" \u2572 \u2572 \u2572 \n",
" \u2572 6 \u2572 5 \u2572 2 4 \n",
"c\u2080\u22c5 \u2571 2\u22c5(t\u1d62 - 1) + c\u2081\u22c5 \u2571 -6\u22c5t\u1d62\u22c5(t\u1d62 - 1) + c\u2082\u22c5 \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) + c\n",
" \u2571 \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 i = 0 \n",
"\n",
" n n \n",
" ___ ___ \n",
" \u2572 \u2572 \n",
" \u2572 3 3 \u2572 3\n",
"\u2083\u22c5 \u2571 -2\u22c5t\u1d62 \u22c5(t\u1d62 - 1) = - \u2571 2\u22c5d\u1d62\u22c5(t\u1d62 - 1) \n",
" \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 "
]
}
],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# from the 2nd partial derivative, reshuffle the equations so the c's are on the left and the others are on the right\n",
"# also redistribute the sums\n",
"cvars = [c0,c1,c2,c3]\n",
"arg_dict = pull_arguments_by_var(eqn=df_dc1, variables=cvars)\n",
"leftside = c0*Sum(factor(arg_dict[c0][0]), (i,0,n)) + \\\n",
" c1*Sum(factor(arg_dict[c1][0]), (i,0,n)) + \\\n",
" c2*Sum(factor(arg_dict[c2][0]), (i,0,n)) + \\\n",
" c3*Sum(factor(arg_dict[c3][0]), (i,0,n))\n",
"rightside = arg_dict['other'][0]\n",
"for arg in arg_dict['other'][1:]:\n",
" rightside = rightside + arg\n",
"print '2nd Equation:'\n",
"Eq(leftside, -1*Sum(factor(rightside), (i,0,n)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"2nd Equation:\n"
]
},
{
"latex": [
"$$c_{0} \\sum_{i=0}^{n} - 6 t_{i} \\left(t_{i} -1\\right)^{5} + c_{1} \\sum_{i=0}^{n} 18 t_{i}^{2} \\left(t_{i} -1\\right)^{4} + c_{2} \\sum_{i=0}^{n} - 18 t_{i}^{3} \\left(t_{i} -1\\right)^{3} + c_{3} \\sum_{i=0}^{n} 6 t_{i}^{4} \\left(t_{i} -1\\right)^{2} = - \\sum_{i=0}^{n} - 6 d_{i} t_{i} \\left(t_{i} -1\\right)^{2}$$"
],
"output_type": "pyout",
"png": "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\nSUVORK5CYII=\n",
"prompt_number": 12,
"text": [
" n n n \n",
" ___ ___ ___ \n",
" \u2572 \u2572 \u2572 \n",
" \u2572 5 \u2572 2 4 \u2572 3 \n",
"c\u2080\u22c5 \u2571 -6\u22c5t\u1d62\u22c5(t\u1d62 - 1) + c\u2081\u22c5 \u2571 18\u22c5t\u1d62 \u22c5(t\u1d62 - 1) + c\u2082\u22c5 \u2571 -18\u22c5t\u1d62 \u22c5(t\u1d62 - \n",
" \u2571 \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 i = 0 \n",
"\n",
" n n \n",
" ___ ___ \n",
" \u2572 \u2572 \n",
" 3 \u2572 4 2 \u2572 2\n",
"1) + c\u2083\u22c5 \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) = - \u2571 -6\u22c5d\u1d62\u22c5t\u1d62\u22c5(t\u1d62 - 1) \n",
" \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 "
]
}
],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# from the 3rd partial derivative, reshuffle the equations so the c's are on the left and the others are on the right\n",
"# also redistribute the sums\n",
"cvars = [c0,c1,c2,c3]\n",
"arg_dict = pull_arguments_by_var(eqn=df_dc2, variables=cvars)\n",
"leftside = c0*Sum(factor(arg_dict[c0][0]), (i,0,n)) + \\\n",
" c1*Sum(factor(arg_dict[c1][0]), (i,0,n)) + \\\n",
" c2*Sum(factor(arg_dict[c2][0]), (i,0,n)) + \\\n",
" c3*Sum(factor(arg_dict[c3][0]), (i,0,n))\n",
"rightside = arg_dict['other'][0]\n",
"for arg in arg_dict['other'][1:]:\n",
" rightside = rightside + arg\n",
"print '3rd Equation:'\n",
"Eq(leftside, -1*Sum(factor(rightside), (i,0,n)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"3rd Equation:\n"
]
},
{
"latex": [
"$$c_{0} \\sum_{i=0}^{n} 6 t_{i}^{2} \\left(t_{i} -1\\right)^{4} + c_{1} \\sum_{i=0}^{n} - 18 t_{i}^{3} \\left(t_{i} -1\\right)^{3} + c_{2} \\sum_{i=0}^{n} 18 t_{i}^{4} \\left(t_{i} -1\\right)^{2} + c_{3} \\sum_{i=0}^{n} - 6 t_{i}^{5} \\left(t_{i} -1\\right) = - \\sum_{i=0}^{n} 6 d_{i} t_{i}^{2} \\left(t_{i} -1\\right)$$"
],
"output_type": "pyout",
"png": "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\nrkJggg==\n",
"prompt_number": 13,
"text": [
" n n n \n",
" ___ ___ ___ \n",
" \u2572 \u2572 \u2572 \n",
" \u2572 2 4 \u2572 3 3 \u2572 4 \n",
"c\u2080\u22c5 \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) + c\u2081\u22c5 \u2571 -18\u22c5t\u1d62 \u22c5(t\u1d62 - 1) + c\u2082\u22c5 \u2571 18\u22c5t\u1d62 \u22c5(t\u1d62 - \n",
" \u2571 \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 i = 0 \n",
"\n",
" n n \n",
" ___ ___ \n",
" \u2572 \u2572 \n",
" 2 \u2572 5 \u2572 2 \n",
"1) + c\u2083\u22c5 \u2571 -6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) = - \u2571 6\u22c5d\u1d62\u22c5t\u1d62 \u22c5(t\u1d62 - 1)\n",
" \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 "
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# from the 4th partial derivative, reshuffle the equations so the c's are on the left and the others are on the right\n",
"# also redistribute the sums\n",
"cvars = [c0,c1,c2,c3]\n",
"arg_dict = pull_arguments_by_var(eqn=df_dc3, variables=cvars)\n",
"leftside = c0*Sum(factor(arg_dict[c0][0]), (i,0,n)) + \\\n",
" c1*Sum(factor(arg_dict[c1][0]), (i,0,n)) + \\\n",
" c2*Sum(factor(arg_dict[c2][0]), (i,0,n)) + \\\n",
" c3*Sum(factor(arg_dict[c3][0]), (i,0,n))\n",
"rightside = arg_dict['other'][0]\n",
"for arg in arg_dict['other'][1:]:\n",
" rightside = rightside + arg\n",
"print '4th Equation:'\n",
"Eq(leftside, -1*Sum(factor(rightside), (i,0,n)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"4th Equation:\n"
]
},
{
"latex": [
"$$c_{0} \\sum_{i=0}^{n} - 2 t_{i}^{3} \\left(t_{i} -1\\right)^{3} + c_{1} \\sum_{i=0}^{n} 6 t_{i}^{4} \\left(t_{i} -1\\right)^{2} + c_{2} \\sum_{i=0}^{n} - 6 t_{i}^{5} \\left(t_{i} -1\\right) + c_{3} \\sum_{i=0}^{n} 2 t_{i}^{6} = - \\sum_{i=0}^{n} - 2 d_{i} t_{i}^{3}$$"
],
"output_type": "pyout",
"png": "iVBORw0KGgoAAAANSUhEUgAAAqgAAAA4CAYAAAAxQQo2AAAABHNCSVQICAgIfAhkiAAAEMRJREFU\neJztnXnQHEUZh58vBNAcBCJCuOJnEtFACKUS44UQiKCcFQ/wQBGjIooYSywVLzwAiVIKggcgroWF\noKBWgYo3Cmgp3uCBsRRQ0XgEEUEUFP94d2rn22/O7Z7umc3vqdqqnZ3Z7p5+f9Pd08fbIIQQQggh\nRIuYCBTPfOB44LHAacDuwG7ATsBrA6VBiCpIqyIU0pqIifQXHuV5C3kZsBWwATi6/9s2wJ3RUiRE\nNtKqCIW0JmIi/YVHed5C5gK7ALelflsFfDtOcoTIRVoVoZDWREykv/Aoz2swI1A8dwEHAl9P/fZs\n4HJgHuGmGghRhrQqQiGtiZhIf+FRnreUjwMvTB3/FZt3cXyc5AiRi7QqQiGtiZhIf+FRnlckVA8q\nwBLgK6njq4BDge8FTIMQVZBWRSikNRET6S88ynMhhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIVrO\nL4EHGvy8J9ytiDFHWhWhkNZETKS/8CjPW8hzGGTg3cDSCv/ZCtv2a7f+9SuAg4EzgB8A/0uFuQmY\n5T3VYnNEWhWhkNZETKS/8CjPW8qFDDLxp8CDHcN7KPA84IZ+mPIRJnwhrYpQSGsiJtJfeJTnLWQW\n8HMGhvmIp3BnAm8HbvQUnhDSqgiFtCZiIv2FR3neUvYC/sXAMEd7DPt8bIswIXwgrYpQSGsiJtJf\neJTnLeUEBka5E1jkKdy5wAs8hSUESKsiHNKaiIn0Fx7leUu5nIFhbsAmAY8jT8aEchJwBbA6bnKC\nMU733UWtnoXZYHNgJTasdQbwOWB53OQ40UWtjcJFwP1YD9K1VFsoIpqnS/o7Eltw9GJgXeS0uNCl\nPI9F8PbEtsAtDAzz/qYjjMRtwLH972uBfwJbx0tOMMbpvrum1f2AjcD+kdMRgjnAeanjo4C7gHlx\nkuNM17Q2KqcCC+iuncaVruhvNfZCCjAJ/AfYJlpq3OhKnsckSnviCcB9DAxzeNMRRmAZMLv//VlY\nj0FXG2p1GLf77opW52FvmdeweTRQl2MuVhb3j7fB7HNYtBS50xWtuXBq7ASIXNquvxnA7cDDUr/5\nGhqPRdvzPDbR2hNvZGCUv2F+vsaVS4A3xU5EBMblvrug1ddhD+41bB4N1AlsiH+if7wnZp+uDxl3\nQWsunInNv3sB8D7g4XGTI4Zos/6SZ3w/TD/nAgdFTZEf2pznbSJoe2IG8FUGhrkO2CJU5DnsAXwe\n+ArwPazLfTuH8B4DvA24gO450N0V+PWI/+3yfWfRlFZ3Az6G+cY7C5tPObvwH9kcgb1pQjcbqC5a\nS7gYy8Ou08ZyEfxp9RgGc+1WAz/2krpw+NBqm2lCf77q1aP7adq3f/wQbIHRro7pi00bn3kXm52F\n9XQ/AKzykJZo7YkF2Jy5xDCnh4x8iEdiwljYP94O8yl2I7BzxvWLmT7ckMfLsF0fypzyziT/DaFO\nfC7Mxt5Kf4XZJIu3Yg9VGVXvuwv41uoOwG+BJ/aP5wM3A6/JuLbI9jsDL0wdX0O1Bmqe1kLpDPxp\nbS2wnkFvatdpU7kI/rQKpruESez+FmdfOuU/46LVLuBTfz7r1UP76UnXJ38EXu6QvrbQpme+rs2y\nOBH4N+V1fxPtKK8czGC7rv8BTw0ZeYrPMiiAE56IpevsjOvXAfcCD8o4txITWzJ8tUc/nKcVxL8F\n5rT3UTnni+LzxVJsNfTpwPXkF8Sryc6TUe67jOVMrdRi4lOrn2HqCtQdgFuBl2RcW2T747Ahojf0\nP7djvvAOLYi7SGshdAbuWks4DGugghVckw5pGletueJLqyuwLR6TCmZf7P6KKr1x0moZ46g/n/Xq\nLv20zEn9djvj41apLc98XZtlcSnWyC3DdzuqEdYzeHP4E7B96ARgGfFLzI9Ywkws836Wcf0VwDdz\nwlqMGSeZzPtc7G3ioQXxvwJ4acH5oviaoEd+QQw2pHri0G+j3HeVdEw6/N83PrT6bGz16bYVr69j\n+1so70Et0lponcFoWgObi7YW631YgG359wTHdEw6/N83bSgXfWp1PtbLmPB64Msl4Y2LVquGPTni\nf5vAh/581qsAX8QacmD1ykZgxxHS1Vba8MzXtVkWfwBOq3Cd73ZUI2wJfBczyrdp/o04i+uBe7CK\nLs2dwJ8zrt8IvLMgvDXAycApwJXY20Aec4GfULw6rSw+3/QoLoi3B27CbJemzn1XTcekYxg+8aHV\ny7Dt7qpSxfa7YotO7sMq/bzV7GVaC60zGE1rizC3Ug8MfVxczvQYP6254lurq7ChuvXAR5naGzbM\nuGi1TtiTI/yvKXzoz3e9uj3Wi7cOcze1YoQ0tZk2PPN1bTbMYiz9VRaw+WxHsTvmJuQibFjxpAoJ\nqMqZwAbivDGAvSEM9xIsxDL6yv7xEcDVDAR0Xf/4eMe4Xwm8O+P3puKrQo/ighjgA/jdpi0vHZM1\n/9OkTsFdqzdjb40rsbfMHjassiR1TUitxdQZSGtFxC4XpdWp9GhOqz3GT38x69WuEvuZr2KzNI/G\nyob3Yjo8EesoyVtE2Yi998G6bQ9JHf+Z6XMVRuH5wF+AR3gIyyfvBv7L9Hs8nmoTgKvyReDpBed9\nx1eFHuUF8YnA1wKkY7LG9U3qFNy1OhvT1I1YBZzwDOAOplb8EFZrMXQG0loesctFaXU6PZrTao/N\nQ3+h6tU0F2EeI+p89m8gHWXEfubzyLPZQdhUhMSTwlLMht+pEKY3ez8Sy7T0/KHDsRXDrvMBnoJ1\nHT/JMRzfLMF2LXh7xrmqE4CrMBNzPlvkwsFnfFXpUV4QPxWrqJpOx2TFa5vUKfjR6o5Yvt7L1OHN\nGdiD/qmh60NqLYbOQFrLog3lorQ6nR7NabXH+OsvVL3aRdrwzGeRZ7NJzG/rMUO//43sEeFhvNn7\nMsydwyh+74rYHXvIjvIcrisPwvbGXZ9z/k9UmwBchV2wCqAIn/FVpUd5Qbwb7vP+qqRjsuK1TekU\n/Gl1SyzPbso490OsIEi7SwqptRg6A2ltmLaUi9LqdHo0p9Ue462/kPVq12jLMz9Mkc0uw8qAdA9o\nstK+aEQ4wcneibuLGcCBwFWYixBfbA98AXgP09/ER2UvzMVOVX+IP2a6D7UJzCH11cBbMv6zJ9az\n4Gv16ALsrSmPuvH5yIOq/B6bTD0J/HTEMBI+Duyd8ftC4HHYSuJh1mJ+0aA5nYJfrd6HVSxZPSx3\nYxXOdsAmwmptlLiktXZrDdxsNC5aDalTKNfq5qS/hND1ahM0paM2PfNpimw2gS14vBob6UjYH5sK\nUNYz6s3ee2Et4pMLrlkGvAPbwu5Cyp25bo3dwIdcE9cA72K6MV6U+p5MAE6GvLZj+tZky6leia6g\nuIFaFl+duOrQo7ynACztj2sg/nQ6JitcV0WnCdtiO2QsLLuQZrR6MfCLjN9vAH6XOg6pNd9x1aHH\neGptJTYsdgbmR3N5yfVtLBd9abWudly02pROoVmt9vCrvydjPkJPwtz5rC65vkn9ha5Xh7kA+H7N\nz34jxlWHNj7zCUU2W4pp8M1D5z+N7TwF5mklYdh23p7heZjT2CxnuMuwrtwfpRJzAMWt5wngk9g2\nWr6285rNVLGPynFYQ3uYj6a+X4YVzgmnY/790mxN9T2mk9Vxwy4dqsZXJ6469CgviHfqX9PkTi49\nqhXaZTpNnPu+lMHex2XhNqXV1zJ9ft0E8HfsfhNCas13XHXoMX5amwOcl/r9KMwt1rycMNtaLj4T\nP1qtqx0XrTalU2hWqz38lnW3Acf2v6/FhmPzXHY1qb8Y9WoXaOszD+U22wZb4PSc1LkHY4v0ki2n\nz0mdG7ad8zOcbNl2J/b2dfDQ+UOwjLgf2x/1N/3fv4W5HcgL/DRsgvfRWFewD96BPXwuHIB1sS8C\nPpH6fJqpCwQ2MfAFthrbAnDTUFj/7v9ehY1YPuTtIFUWX5246pCIZYeCax6FpX1jA/HXpUynyara\nC7AerSo0pdVbsULpZAbDMMdhw6np7SNDas13XHUYR60twkaUkm08r8bKkX3Jpq3l4hX40Wpd7bho\ntSmdQju0WrWsOwS4PPWfokZQU/q7hzj1ahdo6zNfpS30D0xnibeBLTH/tBNY2bAQ2zQmYdh2Xp/h\nrTHfbpdik2Xfi3n1B+uR+tbQ9b/DVhQO82LsrW6nqhGXMAG8GisItnIM6w6mO/1OPmlHso/ADHM2\n9vaQnucxA7vH87E5FlW5lnwfYHnxjRpXETtgc0I2MLj3O7Au++GVemAV8LWe4s6jR/WFA0U6Haas\nB7Vprc7DCqjPYMOoZzF9ykFIrTURVxHjrrUJbIg/ycc9sXtcmhFWm8tFcNOqi3bqarUJnUI4rfZo\npqwDuAR4U865JvUXs15tM21+5qvabCdstf65wIexhY1rMBdT78J6WfNsF+wZfj3WO5BmA7btYJoD\nsVVqyzzEORdz9volLNPO9RCmD9ZghdnF2BaBVTkF2wUoRFw+ORsbLm+SHs3srlLUQO2CVqU1//Ro\nbiefpGE3TBe05oKLdupqtQ06hdG12sO//h4DvA0bOZqVcb4L+muLXX3RhTz3RV3bebf1Gixz0vyR\nqdtc7YEZpGySdsIWWMYvwIbIlmNDY28AvoGtcky36vcZMe2+mYu9Nfyees5nd8a2Eyza9s9XXL6Y\ng+3Lmzd31hfnNBRHXgO1K1qV1vzTlNbWYr1cw6tqu6I1F1y0U1ersXUKblptSn9g28v+gOkugbqg\nvzbY1RddyXNf1LWdd1s/DNsvOWEWNn8gmZuwIzaXIK/L2PVzo4+b8MgJ2FvMbOrtx3wq9uYdIi4f\nnE22s+WukNVA7ZpWpbX2cxjWQAUrcCf737umNRdctHMq9bQaU6fQHq2uxIZ7k7UgiX/KZAFV1/QX\n264+6Fqe+6Ku7SpdPzPvxBC3YnOUFmJzKg7EXPhs6J9/K9ZgvblieHU5r/ySoBwDrMNW7V5c439n\nYlv7rcT2qG0yLldWYgvhnlZ2YcfomlaltXazH1YpfR7rATkAq6BuoXtac8FFO3W1Gkun0C6t/hWr\ng2/vH++N9bYlvlS7pr+YdvVF1/LcF3Vt593W+wAfxFq+62luHlcXOB3z8TXKfshzgY8EisuF82l2\nR58mORZzPvwA5ptyXdzkOCGttZdFmFup4V6OLt6LK67aqaPVWDqF9ml1DeZ94RTgSqwB3VVi2lW4\nUdd2srUQQgghhBBCCCGEEEIIIYQQQgghsvC1N/IybKeEE4ALMTckQvhEWhWhkNZETKS/8CjPW4iP\nPXQngB9hiw/AVsRe5ximEMNIqyIU0pqIifQXHuX5mLKKqe4ZZgJ3425sIXwjrYpQSGsiJtJfeJTn\nVPeDWsQM4EXA4zEHxj9LnZsPvI7pu6ukuR9zenwfsARzPJw+twnr6v6th7SKzRtpVYRCWhMxkf7C\nozz3jI8G6pHAVViLfw+mGmUT9fYrng/cM/TbvZiPPCFckVZFKKQ1ERPpLzzKc8/M8BDGV7GMW4UZ\nx4VfMf0NYw62Y4YQrkirIhTSmoiJ9Bce5blnfPSg3oWtMvsc1uDdEuuiBngItstF1W7tH2LbBSbM\nwt4kNpsubdEo0qoIhbQmYiL9hUd53lKuB1YAx+He6L0FWNj/fjjubyJCpJFWRSikNRET6S88ynOP\nbOEpnCXAPOAm4FbHsK4DXoUZZm/sjeLvjmEKkSCtilBIayIm0l94lOdCCCGEEEIIIYQQQgghhBBC\nCCGEEEIIIYQQQkTk/1A0AHb0SzoLAAAAAElFTkSuQmCC\n",
"prompt_number": 14,
"text": [
" n n n \n",
" ___ ___ ___ \n",
" \u2572 \u2572 \u2572 \n",
" \u2572 3 3 \u2572 4 2 \u2572 5 \n",
"c\u2080\u22c5 \u2571 -2\u22c5t\u1d62 \u22c5(t\u1d62 - 1) + c\u2081\u22c5 \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) + c\u2082\u22c5 \u2571 -6\u22c5t\u1d62 \u22c5(t\u1d62 - 1\n",
" \u2571 \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 i = 0 \n",
"\n",
" n n \n",
" ___ ___ \n",
" \u2572 \u2572 \n",
" \u2572 6 \u2572 3\n",
") + c\u2083\u22c5 \u2571 2\u22c5t\u1d62 = - \u2571 -2\u22c5d\u1d62\u22c5t\u1d62 \n",
" \u2571 \u2571 \n",
" \u203e\u203e\u203e \u203e\u203e\u203e \n",
" i = 0 i = 0 "
]
}
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>From the 4 equations above we can start to see the structure of the matrix form.</h3>\n",
"Set the problem up as the familiar multiple linear equations, multiple unknowns pattern.\n",
"\\begin{aligned}\n",
"\\mathbf{A x = b}\n",
"\\end{aligned}\n",
"Where:\n",
"\n",
"$\\mathbf{A}$ is a 4x4 matrix of the summations listed on the left side of the equations\n",
"\n",
"$\\mathbf{x}$ is a 4x1 matrix containing the unknowns c0,c1,c2,c3\n",
"\n",
"$\\mathbf{b}$ is a 4x1 matrix of the summations listed on the right side of the equations\n",
"\n",
"To solve is simply : $\\mathbf{x = A^{-1} b}$"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# build the actual matrices this time in a loop\n",
"cvars = [c0,c1,c2,c3]\n",
"a_vals = []\n",
"x_vals = cvars\n",
"b_vals = []\n",
"for eqn in [df_dc0, df_dc1, df_dc2, df_dc3]:\n",
" arg_dict = pull_arguments_by_var(eqn=eqn, variables=cvars)\n",
" for var in cvars:\n",
" a_vals.append( Sum(factor(arg_dict[var][0]), (i,0,n)) )\n",
" rightside = arg_dict['other'][0]\n",
" for arg in arg_dict['other'][1:]:\n",
" rightside = rightside + arg\n",
" b_vals.append( -1*Sum(factor(rightside), (i,0,n)) )\n",
" \n",
" \n",
"A = Matrix(4,4,a_vals)\n",
"x = Matrix(4,1,x_vals)\n",
"b = Matrix(4,1,b_vals)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print 'A = '\n",
"A"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"A = \n"
]
},
{
"latex": [
"$$\\left[\\begin{smallmatrix}\\sum_{i=0}^{n} 2 \\left(t_{i} -1\\right)^{6} & \\sum_{i=0}^{n} - 6 t_{i} \\left(t_{i} -1\\right)^{5} & \\sum_{i=0}^{n} 6 t_{i}^{2} \\left(t_{i} -1\\right)^{4} & \\sum_{i=0}^{n} - 2 t_{i}^{3} \\left(t_{i} -1\\right)^{3}\\\\\\sum_{i=0}^{n} - 6 t_{i} \\left(t_{i} -1\\right)^{5} & \\sum_{i=0}^{n} 18 t_{i}^{2} \\left(t_{i} -1\\right)^{4} & \\sum_{i=0}^{n} - 18 t_{i}^{3} \\left(t_{i} -1\\right)^{3} & \\sum_{i=0}^{n} 6 t_{i}^{4} \\left(t_{i} -1\\right)^{2}\\\\\\sum_{i=0}^{n} 6 t_{i}^{2} \\left(t_{i} -1\\right)^{4} & \\sum_{i=0}^{n} - 18 t_{i}^{3} \\left(t_{i} -1\\right)^{3} & \\sum_{i=0}^{n} 18 t_{i}^{4} \\left(t_{i} -1\\right)^{2} & \\sum_{i=0}^{n} - 6 t_{i}^{5} \\left(t_{i} -1\\right)\\\\\\sum_{i=0}^{n} - 2 t_{i}^{3} \\left(t_{i} -1\\right)^{3} & \\sum_{i=0}^{n} 6 t_{i}^{4} \\left(t_{i} -1\\right)^{2} & \\sum_{i=0}^{n} - 6 t_{i}^{5} \\left(t_{i} -1\\right) & \\sum_{i=0}^{n} 2 t_{i}^{6}\\end{smallmatrix}\\right]$$"
],
"output_type": "pyout",
"prompt_number": 16,
"text": [
"\u23a1 n n n n\n",
"\u23a2 ___ ___ ___ __\n",
"\u23a2 \u2572 \u2572 \u2572 \u2572 \n",
"\u23a2 \u2572 6 \u2572 5 \u2572 2 4 \u2572\n",
"\u23a2 \u2571 2\u22c5(t\u1d62 - 1) \u2571 -6\u22c5t\u1d62\u22c5(t\u1d62 - 1) \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571\n",
"\u23a2 \u2571 \u2571 \u2571 \u2571 \n",
"\u23a2 \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\n",
"\u23a2 i = 0 i = 0 i = 0 i =\n",
"\u23a2 \n",
"\u23a2 n n n n\n",
"\u23a2 ___ ___ ___ __\n",
"\u23a2 \u2572 \u2572 \u2572 \u2572 \n",
"\u23a2 \u2572 5 \u2572 2 4 \u2572 3 3 \u2572\n",
"\u23a2 \u2571 -6\u22c5t\u1d62\u22c5(t\u1d62 - 1) \u2571 18\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571 -18\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571\n",
"\u23a2 \u2571 \u2571 \u2571 \u2571 \n",
"\u23a2 \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\n",
"\u23a2i = 0 i = 0 i = 0 i =\n",
"\u23a2 \n",
"\u23a2 n n n n\n",
"\u23a2 ___ ___ ___ __\n",
"\u23a2 \u2572 \u2572 \u2572 \u2572 \n",
"\u23a2 \u2572 2 4 \u2572 3 3 \u2572 4 2 \u2572\n",
"\u23a2 \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571 -18\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571 18\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571\n",
"\u23a2 \u2571 \u2571 \u2571 \u2571 \n",
"\u23a2 \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\n",
"\u23a2i = 0 i = 0 i = 0 i =\n",
"\u23a2 \n",
"\u23a2 n n n \n",
"\u23a2 ___ ___ ___ \n",
"\u23a2 \u2572 \u2572 \u2572 \n",
"\u23a2 \u2572 3 3 \u2572 4 2 \u2572 5 \n",
"\u23a2 \u2571 -2\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u2571 -6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \n",
"\u23a2 \u2571 \u2571 \u2571 \n",
"\u23a2 \u203e\u203e\u203e \u203e\u203e\u203e \u203e\u203e\u203e \n",
"\u23a3i = 0 i = 0 i = 0 \n",
"\n",
" \u23a4\n",
"_ \u23a5\n",
" \u23a5\n",
" 3 3\u23a5\n",
" -2\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u23a5\n",
" \u23a5\n",
"\u203e \u23a5\n",
" 0 \u23a5\n",
" \u23a5\n",
" \u23a5\n",
"_ \u23a5\n",
" \u23a5\n",
" 4 2 \u23a5\n",
" 6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u23a5\n",
" \u23a5\n",
"\u203e \u23a5\n",
" 0 \u23a5\n",
" \u23a5\n",
" \u23a5\n",
"_ \u23a5\n",
" \u23a5\n",
" 5 \u23a5\n",
" -6\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u23a5\n",
" \u23a5\n",
"\u203e \u23a5\n",
" 0 \u23a5\n",
" \u23a5\n",
" n \u23a5\n",
" ___ \u23a5\n",
" \u2572 \u23a5\n",
" \u2572 6 \u23a5\n",
" \u2571 2\u22c5t\u1d62 \u23a5\n",
" \u2571 \u23a5\n",
" \u203e\u203e\u203e \u23a5\n",
" i = 0 \u23a6"
]
}
],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print 'x = '\n",
"x"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"x = \n"
]
},
{
"latex": [
"$$\\left[\\begin{smallmatrix}c_{0}\\\\c_{1}\\\\c_{2}\\\\c_{3}\\end{smallmatrix}\\right]$$"
],
"output_type": "pyout",
"prompt_number": 17,
"text": [
"\u23a1c\u2080\u23a4\n",
"\u23a2 \u23a5\n",
"\u23a2c\u2081\u23a5\n",
"\u23a2 \u23a5\n",
"\u23a2c\u2082\u23a5\n",
"\u23a2 \u23a5\n",
"\u23a3c\u2083\u23a6"
]
}
],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print 'b = '\n",
"b"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"b = \n"
]
},
{
"latex": [
"$$\\left[\\begin{smallmatrix}- \\sum_{i=0}^{n} 2 d_{i} \\left(t_{i} -1\\right)^{3}\\\\- \\sum_{i=0}^{n} - 6 d_{i} t_{i} \\left(t_{i} -1\\right)^{2}\\\\- \\sum_{i=0}^{n} 6 d_{i} t_{i}^{2} \\left(t_{i} -1\\right)\\\\- \\sum_{i=0}^{n} - 2 d_{i} t_{i}^{3}\\end{smallmatrix}\\right]$$"
],
"output_type": "pyout",
"prompt_number": 18,
"text": [
"\u23a1 n \u23a4\n",
"\u23a2 ___ \u23a5\n",
"\u23a2 \u2572 \u23a5\n",
"\u23a2 \u2572 3 \u23a5\n",
"\u23a2 - \u2571 2\u22c5d\u1d62\u22c5(t\u1d62 - 1) \u23a5\n",
"\u23a2 \u2571 \u23a5\n",
"\u23a2 \u203e\u203e\u203e \u23a5\n",
"\u23a2 i = 0 \u23a5\n",
"\u23a2 \u23a5\n",
"\u23a2 n \u23a5\n",
"\u23a2 ___ \u23a5\n",
"\u23a2 \u2572 \u23a5\n",
"\u23a2 \u2572 2\u23a5\n",
"\u23a2- \u2571 -6\u22c5d\u1d62\u22c5t\u1d62\u22c5(t\u1d62 - 1) \u23a5\n",
"\u23a2 \u2571 \u23a5\n",
"\u23a2 \u203e\u203e\u203e \u23a5\n",
"\u23a2 i = 0 \u23a5\n",
"\u23a2 \u23a5\n",
"\u23a2 n \u23a5\n",
"\u23a2 ___ \u23a5\n",
"\u23a2 \u2572 \u23a5\n",
"\u23a2 \u2572 2 \u23a5\n",
"\u23a2- \u2571 6\u22c5d\u1d62\u22c5t\u1d62 \u22c5(t\u1d62 - 1) \u23a5\n",
"\u23a2 \u2571 \u23a5\n",
"\u23a2 \u203e\u203e\u203e \u23a5\n",
"\u23a2 i = 0 \u23a5\n",
"\u23a2 \u23a5\n",
"\u23a2 n \u23a5\n",
"\u23a2 ___ \u23a5\n",
"\u23a2 \u2572 \u23a5\n",
"\u23a2 \u2572 3 \u23a5\n",
"\u23a2 - \u2571 -2\u22c5d\u1d62\u22c5t\u1d62 \u23a5\n",
"\u23a2 \u2571 \u23a5\n",
"\u23a2 \u203e\u203e\u203e \u23a5\n",
"\u23a3 i = 0 \u23a6"
]
}
],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>Now we're done with symbolic math.</h3>\n",
"The A and b matrices still look formidable with those summations in there. Do realize however that the summations are computed from the data prior to solving for c0,c1,c2, and c3. As far as the c values are concerned, the summations involving d_i's and t_i's just come out to be numbers computed from your hand drawn data. This means that the matrix math is actually quite simple. You use your d_i and t_i values in the summations to place numbers into the 4x4 A matrix and the 4x1 b matrix.\n",
"From here we can do our matrix math numerically."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>Now it's time to see if we can actually compute a bezier curve from hand drawn data.<h2>\n",
" <h3>This is not a gui program to draw an arc with, so add some noise to our original curve to simulate a poorly drawn line.</h3>\n",
"Remember that when we started this worksheet, somewhere near the top, we had computed a bezier curve numerically. We're going to do the same thing here, but add noise to the output curve data to simulate our hand drawing."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from pylab import randn\n",
"\n",
"# define the control points of a bezier curve we wish to generate\n",
"p0 = (0.7,0.2); p1 = (2.3,1.0); p2 = (7.2,0.8); p3 = (10.0,0.0)\n",
"# create a list of 1000 x,y points that traces over the length of this curve\n",
"points = [numerical_cubic_bezier_fn(control_pts=[p0,p1,p2,p3], t=t) for t in arange(0.0,1.0,1./1000)]\n",
"# separate the x's and y's so matplotlib can plot them; also add some noise\n",
"xs = [x+0.15*randn() for x,y in points]\n",
"ys = [y+0.15*randn() for x,y in points]\n",
"\n",
"# plot the resulting 'hand drawn' curve\n",
"plot(xs, ys, 'b-')\n",
"t=title('noisy (hand drawn) curve')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEICAYAAACzliQjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsXXd4FVX6fm8KhAQIIZUEEnpI6L0KAZQiYAF3BQusCKK4\nimXXtiqIdVFRQBQsPxFFVOwFUWANoVcNXQiQhJaQQIAkJJCQ+f3x+eWcabekQALnfZ48c++dyczc\nuTPv+c77NYemaRoUFBQUFK4KeF3uE1BQUFBQuHRQpK+goKBwFUGRvoKCgsJVBEX6CgoKClcRFOkr\nKCgoXEVQpK+goKBwFUGRvoJHqFOnDlJTUyt0nyUlJYiPj8fRo0cBAP/4xz/wzDPPVOgx7ODJsVJT\nU+Hl5YWSkpJKPivnGDZsGFatWnVZz0Gh+kKRvoJHyM3NRePGjSt0n0uWLEHbtm0RFRUFAHA4HHA4\nHBV6DDtcymNVFO6//3688sorl/s0FKopFOkrXHb897//xeTJky/b8SsiP1HTtArZjzsYMmQI9u3b\nh+3bt1fqcYqLiyt1/wqXB4r0r0I0btwY8+bNQ8+ePREdHY1p06ahqKiodH1iYiJGjRqFFi1aYMaM\nGcjJySld5+XlhYMHDwIA1qxZg6FDh6J+/fpo2LAhZs6cCQBo06YNfvzxx9L/KSoqQkhICJKTk03n\nkpOTg+TkZHTv3l33eX5+Pm699VaEh4djwoQJpdIPAEyZMgXR0dEIDw/HpEmTdPudNm0axowZg3/+\n85+IiIjA3//+d+zZs6d0fVpaGu655x5ERERg4sSJTolN0zR8+umniI+PR4cOHZCUlKRbn5CQgJde\negmDBg1CYGAgDh48iA8//BDx8fGoV68ebrrpJvzwww+l2/fr1w9ff/01AGDt2rXw8vLC0qVLAQAr\nV65Ex44dAQALFixAnz59MH36dERFRWHIkCFYv3697jfo2rUrfvvtN9tz37p1K+677z6EhYWhefPm\n+PXXXwHQb79y5Urd9brzzjsBCPmKZ17XXnstrr/+esydO1e37/bt2+Pbb78FABw/fhzPP/88mjdv\njltvvRUbN260PSeFqgFF+lchHA4H5s2bh9mzZ2PlypX46KOPSgnt0KFDuPnmmzFmzBgkJiZi27Zt\nePjhhy338/DDD2PSpEnIzs7Grl270L9/fwDAuHHj8Mknn5Rut3TpUkRFRaF9+/amfezduxcRERHw\n8/Mr/UzTNLz//vsYPXo0du3ahczMTMybN690fbdu3ZCcnIw///wTgYGBuP/++3X7/Prrr9G+fXvs\n2bMHgYGBeOmll0rXjRo1CnXr1sXOnTsRGxuLL774wlbe+emnn/DMM8/g3XffxcKFC/H222+btp07\ndy6mTJmCU6dOISYmBuHh4fjpp5+QlZWF0aNH49Zbb8W5c+cA0CCRmJgIAFi1ahWaNm1aet1XrVqF\nhISE0v1u3rwZALBz50706NEDjz32mO64zZs3x+7duy3POysrCwkJCejYsSNSU1ORlJSEmJgYAGY5\ny+q7f/rpp/juu++wbNkyjBkzBosXLy5dt3v3bqSnp2PYsGEAyL/g4+ODLVu2YOzYsRg6dCjy8vIs\nz0uhikBTuOrQuHFj7fXXXy99P2nSJO3xxx/XNE3TZs6cqY0ZM6Z03f79+7Xg4GDt4sWLmqZpmsPh\n0A4cOKBpmqZ16tRJe+2117ScnBzd/o8eParVrl1by83N1TRN00aNGqW9+uqrlufy+eefa126dNF9\nNm7cOG3EiBGl7xcvXqx1797d8v/Pnj2rBQQEaFlZWZqmadrUqVO1tm3blq5fv369FhERoWmapmVk\nZGh+fn5aQUFB6fpGjRppzzzzjOW+77vvPt26Dz74QHM4HKXXIiEhQRs/frzl/zL69Omjffnll5qm\nadrKlSu1du3aaZqmaUOGDNHef/99rUePHpqmaVrfvn21b775RtM0Tfvwww+1oKCg0uMcO3ZM8/X1\n1fLy8kr3+/bbb2uDBw+2PObbb7+t3XjjjZbrGjdurK1cubL0/bRp07Q77rhD0zRNO3TokOZwOLSk\npKTS9Xx909PTNU3TtKeeekq7++67NU3TtH379mmxsbG6/d90003aF1984fSaKFxeKEv/KkWHDh1K\nX0dERJTKJ+vWrUPnzp1L1zVv3hzFxcXYtWuXaR8LFy5EcnIymjZtir/97W+lMktkZCR69+6NL7/8\nEqdPn8ayZctw++23W55HTEwMjh07pvvM4XDYnh9A8sewYcMQGhqK6OhoFBQUYMeOHaXr5RlFREQE\nMjMzUVJSgk2bNqF58+a6WUWnTp1sr9GmTZt058HyiwyjLLVmzRqMGTMGMTExqFevHjZt2lSqvffo\n0QP79u3DiRMn8Mcff2Ds2LE4fPgwTp48ic2bN6Nv376l+2ndujW8vOjxbNCgAYqLi5GZmVm6/siR\nI7YO9cTERPTu3dv2e8nQLPwQ8neqU6cOhg0bVmrtf/bZZ6W/5YoVK3Do0CEEBQWV/q1cuRKrV692\n69gKlweK9BV06N27N7Zs2VL6fv/+/fD29kbr1q1N27Zu3RoLFy7E8ePH0bZtW0yYMKF0HUs8S5Ys\nQa9evdCgQQPL48XFxSEjIwPnz5/XfW5FRgBw+PBhPPLII3jqqaeQlpaG9PR01KpVyy0nateuXZGS\nkoKCgoLSz7Zt22a7fbdu3fD777873dbHx0d3zpMmTUK/fv2wbds2nD59Gt26dSs9N39/f3Tu3Blv\nvvkm2rZtC19fX/Tq1Quvv/46mjdvjvr167v8DoyUlBTExcVZruvfvz/WrFljuS4qKgoZGRml73//\n/XeTxCN/JwClEs/69etRWFhYKuMNGDAAzZo1Q05OTunf2bNnMXv2bLe/h8KlhyJ9BR1uuOEG/PLL\nL/j6669x9OhRTJ06FSNGjCi1OhlFRUVYtGgRzpw5A4AIrU6dOqXrb775Zmzbtg2zZ8/G2LFjbY9X\nt25ddOrUCRs2bCj9zBmBZ2VlQdM0REREIDc3F0899ZRpwLBDREQEWrdujalTpyIrKwszZ87UWc9G\nXH/99Vi8eDHWrl2L7du344MPPjBtI5/rhQsXkJWVhfDwcPj5+eHDDz80OTb79euHuXPnol+/fgBI\n53/rrbdK37sDTdOwdevWUvI14pZbbkFiYiI++OAD5Ofn4+jRo/jzzz8BAAMHDsTixYuRnZ2Nb7/9\n1q14/+uvvx5paWmYOnUqRo8eXfp5bGwsateujddeew0ZGRkoKirC5s2bsXfvXre/i8KlhyJ9BZ1z\nr2nTpliyZAk+/vhj9OvXD+3atSuNyuFtGZ988gmaNGmC6OhobNy4EW+++WbpOj8/P4wcORKpqakY\nOXKk0+M//vjjuggRq9h5ft+pUydMnjwZAwYMQN++fdGmTRs0atTIrf8FKCfg1KlTaNOmDfbu3Ytb\nb73V9ryuv/56TJs2DRMnTsTYsWNx3333Od13zZo1MWvWLEyfPh3NmzfHli1bdCQJEOnn5eWVSjl9\n+/ZFfn6+Ttpx9R1+/vlntGzZEu3atbM875CQEKxcuRIbNmxATEwM+vfvj/T0dADAxIkTERoaitat\nW+Ozzz7DPffcY3scRo0aNTBy5EisXLkSt912m27dt99+i6KiIgwcOBANGjTAk08+iQsXLliel0LV\ngENzZ16soFAGTJ8+HSkpKVi4cKHT7UpKStCuXTv88ssvpQlaCvYYNmwYHn/8cd1AoaDgLspF+uPH\nj8dPP/2EsLAwnSONsWjRIsyYMQMA6b/Tpk1Dy5Yty362CtUGJ0+eRLt27fDzzz/bWqQKCgqXHuWS\nd+666y4sW7bMdj3HIScnJ2Pw4MF4/vnny3M4hWqC9957D7GxsRg/frwifAWFKoZyyzupqakYMWKE\npaUvIzs7G506dSrVFhUUFBQULj18XG9SMXj33XcxYsQIy3XVreCVgoKCQlWBp3b7JYneWbFiBT75\n5BO8+OKLtttofxWsuhL/pk6detnPQX039f3U97vy/sqCSrf0t2/fjnvvvRfLli1DvXr1KvtwCgoK\nCgpOUKmWfnp6OkaNGoVFixahefPmlXkoBQUFBQU3UC5Lf8yYMVi1ahWys7PRqFEjPPfcc6UleidN\nmoTp06fj1KlTuPfeewEAvr6+2LRpU/nPuppBrp54peFK/m6A+n7VHVf69ysLqkRylsPhKLM+paCg\noHC1oizcqcowKCgoKFxFUKSvoKCgcBVBkb6CgoLCVQRF+goKCgpXERTpKygoKFxFUKSvoKCgcBVB\nkb6CgoLCVQRF+goKCgpXERTpK1QKNA0YPhwoLLzcZ6KgoCBDkb5CpeDoUeCnn4BDhy73mSgoKMhQ\npK9QKdiyhZa7dl3e81BQUNBDkb5CpWDrVlqqatoKClULivQVKgWK9BUUqiYU6StUODRNyDuK9BUU\nqhYU6StUOI4cAbKy6LUifQWFqgVF+goVDpZ2ACAw8PKdh4KCghmK9BUqHCztAICv7+U7DwUFBTMU\n6StUOGRLX0FBoWpBtUtUqFBoGhAWBmRni/cKCgqVg0veLnH8+PEIDw9H27Ztbbd58skn0bRpU3Tu\n3Bl79+4tz+EUqgEOHwZ8fOh1q1aX91wUFBTMKBfp33XXXVi2bJnt+k2bNmH16tXYsmUL/vWvf+Ff\n//pXeQ6nUA2wdSvQpg29btLk8p6LgoKCGeUi/WuuuQZBQUG26zdu3IhbbrkF9evXx5gxY7Bnz57y\nHE6hGmDLFqBhQ3pdv/7lPRcFBQUzfCpz55s2bcKdd95Z+j40NBQHDhxAs2bNTNtOmzat9HVCQgIS\nEhIq89QUKglbtwJdu9JrFaOvoFCxSExMRGJiYrn2Uamkr2maycngcDgst5VJX6F6QtOI9G++md5f\nStJ/912gb1/lR1C4smE0iJ977jmP91GpIZvdu3fH7t27S99nZWWhadOmlXlIhcuI9HSKy/f66666\nlKS/dCmwatWlO56CQnVFpZP+V199hZMnT+LTTz9FXFxcZR5O4TJj61agc2cgLY3eX0rSdziA1NRL\ndzwFheqKcsk7Y8aMwapVq5CdnY1GjRrhueeeQ1FREQBg0qRJ6NatG/r06YMuXbqgfv36+OSTTyrk\npBWqJhYsAIKDgR076L0ifQWFqgeVnKWAjz8GBg4EIiPLtx+HgxKzatUia3/5cuDaaz3fT0kJUFwM\n1Kjh/v+MGgUcPw6sW+f58RQUqisueXKWQvXHhg3AP/4BbNtWvv3s3EnL5cvLJ+9oGvD3vwMvveTZ\n/zmz9L/5Bjh2zPNzUVC4EqFI/yrG+fPA+PFA7drA2rX03lPs309LDtNs106sk0m/uBi4cMH1/j7+\nGPjqK+DMGc/Ow+EgS9+qEft77wE//+zZ/hQUrlQo0r+K8fzzQGws0LMn8MorwK+/2m+7b5+op8Mo\nKABatqTXVmQrk/7f/ia2tUNqKvDoo8Ddd9Mg4Qk4Yig93bxO0+j8FRQUFOlftfj9d4ptf/ttURTt\ns8/st3/1VeCLL/Sf1axJy6VLafn440B+vljvJd1du3cL2ccOd98N/PvfFAH0VzyA2+D0D7tjVBTp\n//mn5+emoFCVoEj/CsfMmWbrt6iIZJ1XXwUaNCDHKQB8+qn9fry9gZwc8X7YMOqQxa8BoE8fIDNT\nbCP7l+rWFa9XrKBjyzh8GPjf/4DbbqNYfytLX9OABx+0lokcDnIgW+n6FWnpP/ywkooUqjcU6Vdz\nZGaSdGKH//s/4MAB/WczZgAREcDYsfSeSR8A1q+33o+3N3D6tH472aoHyELPyND/D6NOHfF6925z\nlM0LL9By1y6q0mlF+ocPA3PmWCdhORxAdLS9MzclBbh40XqdJ4iIEE5rBYXqCEX61RhZWUDTpoBd\nxer//IdI1CizvPEGMH++kERki3zgQOt9+fgI0j93jqx+uStWRATNGmRCvHBB7Fsm/dxc4ORJ8T4v\nT8wyduygY1lJKMnJtPzmG/M6Jn0reUfT6FzS0mjmUx55pmFDuqYKCtUVivSrMRYsIAKOjrZef/Ag\nLZncL14kWeeFF/T/I1v6BQXAH3+I90yYsqV/9CgtZYmmWzdazpolPuvfH+DCqs5I//PPifivu45I\n307e2b4duPFG4Lvv9OfM3zEmxl7e8fIiiefdd8sXnuoJ6X/yCZ2rgkJVgiL9agpNAx57jF5L5Y10\nYKmFLf1ZswA/P+Cee/TbGQl0xgxanj0LDB1K28ukz1r+l1+K/+nc2Xwuu3cLZ6+s6efl6Un/vfdo\nOXw4zRTs5J3kZJKyAgOBzZv161zJO02aEOm3bw+sXm29jTuIiqKZlTtS0bffipBWBYWqAkX61RTf\nfy9e2xEdkz4nLj36KFm6XoZf3Uj6P/9MunmfPmT5p6QQEbMjly39U6fE/3TuTJEtRnBNfStLX9PI\nsj9yhMI7r7+erPDx40nCkR22mgYsWQI0awbcdBMRqgyHgzKKs7LMjl5No9DUffsoj2D1ahqQ2I/g\nCRo2pHwGo5/ECrt2kXNZQaEqQZF+NcT580Tgd9whPrMiIdnSZ0ni7FnzdkbSr1EDSEigTN0FC2jf\nVpa+jM6dSc4wIjCQlkbSLy6mc3n/feDWWynOn9ssnD1LRB0ZCdx7L5E0O40XLKDSzd9+S4MQDzwO\nBx3/wgVy+BoRG0uDUrt2wJo1lIksD5zuIiqKlq4knvPnycr3hPSfeQZYvNjzc1JQ8ASK9D1ESQmR\nYUXjm2+ohIE7eOstIrEePej9ffcBH31k3o5J2uEQ5Mhyiwxj6Y4TJ2h5551E2hkZ5DtwRvphYWbL\nOSiIBpzhw/VyTW4uLY8eBRYtovo80dF0njwLufZaqtrZuDEwebIYNObPJ1LPzQVuv51CODMzaf/c\nW8I489E0SgxjS//UKbrWcnipuwgOpmvoivT37SMJyBPS37bNOrlMQaEioUjfQ2zfbk2wjGnTBKl5\ngtRUIkBXyMqi7NnXX6dzAUhz/+gjs8XO0DRg0yZ6Xbs2LXfuFORt1KdbtAAmTADmzhWZth9+SKSv\naULekfHDD+bP6tenSJlly/TF0/LyaPnee8IX0LgxLXlQKiggx+wTT5AEdNNN4v9HjQIGDyYZatEi\n4IYbRPTPdddZy11NmhDJh4aSf+Gzz+i9J7WqSkpoUKpf3zXps2/Dz8/9/aenl+3eUVDwBIr0PcT/\n/ud8/YcfUh0bTxEXZx8jL2PqVEpgatWKLGEA6NCBiMiui9qOHcDGjfSaLc9vv6UyDABZ8TIKCykz\n9u23hdV/+jQNDvn51pb+v/9t/qx+fSKyixdpJsDIzaUQzzffBCZOJJKOiaF1jRrR0ngNjQXTOHwT\n0EtbvXqZwzY1jXwSTZvStlwf6Px5a7nLDhwq2qKFa9Ln9Z5Y+unpYkBUUKgsKNL3EK5I39e3bOV9\nW7UiSUCOajFi506KmJk6ld7LoYcNG5KT1gpJSSIjlYuq9e9PZRWys80EduYMWajXXEPJUDJycqj5\nuRFWUSr16wtCDg2lpabpQzZvuIFImknfLvyUZyoAMGiQGPAA/TWLiaHvK583W/OyxMPwROKZPp2W\nDRuSf8BZfSBPSf/0aRqAlKWvUNlQpO8hKov0o6OJINgiN0LTgEceAZ5+WkTEaBrQujW9XrmS4t2t\nLNdFi4ABA+g1V6/s1o2IhslYxoAB5Ox87DHK6JWRlSVeu6p3HxREpO9wAAsX0mdFRWTRFhXRwFKj\nhiB9TaMZgBHGc8jOpsHCCo0bU+SR8XdyOIj02ZnL5y9nELvC9u3k4I6KIodxSor9trt20ferVYuI\n/Ouvne+btXxl6StUNhTpe4iCAqFDW8HXl4i7LFUiY2PtJZ6lS4kY7rtP/3nHjuK8AFEUzajTM+mz\nZStn0xrRty+Rfvfu5nWcbAW41qs/+4xI389PkB6fJyD8BamptN7LS1/a4cQJ4LXXyL8gY9s2ID7e\n+pjsG+CZA2C29Lna54UL7lv6vI9nnyVLH7CXeL7/ngaXRo3oXmjXjiKUnCE9nSQoZekrVDYU6ZcB\nTKBW8PUl4ipLfZZWraxJv6iIQjRnzhRkzTJN27b6bTl+3UhmffvSUrZs7Wr2dOsGvPMO8NtvwKRJ\n+nUsm/j6uqeHHzyolziOHzdvk5ZGUTGAfp+dO5OVP3eu+X9+/NH6eHxdGjQQn3HkEpM+z5QA90mf\nK4mypQ/Yk/6NN9Jy/36KLpozh4wAZ07jtDTyFVxKS/+991Qz+asR5Sb9pKQkxMXFoUWLFphjFIAB\nFBQUYNy4cejYsSP69euH766AvHRXpN+qVdl1/Y0bzVb6O++Q5Tp0qPiMNfTAQH2Y36FDtLRytgJ6\n0r/tNutteDaxfr0YLBgsP8mk6gwc48948UX9+vPnSZMfMYLey81TjhyhGP1Tp0QpCYbdoMqx9/Ix\nt2+nSB9O0JKvl7ukz3p+377Wln5qqjVhJydTyKpdljEjPZ2kuktp6f/xB83oFK4ulJv0p0yZgvnz\n52PFihWYO3cusg2dNj766CMEBATg999/x8KFC/HII49U2364HOXSs6f9NjVqUBcpd0k/P58coydP\nEunn5elLGZw8SfHvM2cCL78skneYcGrWJBmFSZgjV4xhlUzkMunbFVfjxubp6ebIHvl7uoMDB/R+\nAGMC1+HDlITFtXtkS9/fn/wCycl6uUYG+zQYX31lvd3atRRBVFSk9wfIcpUzsCP5yBFrS//224Ff\nfqEQU0ZQkNjW19d557D0dJKsLqWl7+dHg2B5ylIoVD+Ui/TP/GWW9e3bFzExMRg0aBA2GjyRgYGB\nyM3NRVFREU6dOgV/f384jGZbNQE/+JxlagVfX89If/lyGkSaNwdGj6bP2rUjJ+r8+cBdd5EM07o1\nEQMXQ5PjwBctokgbgAaRgwfNpM/nw6Sfn6/PkrVCSgqR/vjx5nXukr6x/LIRqamkw4eH03u57n2j\nRhSTv2SJfakJo8TCv5HRrti4UThzZbhysMr7uuEGOo+ICFHAraiIZgvr11NVU3nAzssT0laNGs6r\ne6alXXpLv1YtkvDGjPEsX0GhesOnPP+8efNmtGrVqvR9fHw8NmzYgGHcVQPAmDFj8MMPPyAkJATF\nxcVYb+OpnDZtWunrhIQEJCQklOfUKgWuIncAIv2mTUmmOH7cLINoml6q6NmTpv179ojSA2zhfvUV\nDQpJSbRtcTGRXEmJIJeUFJI/mMC5HILsMJWRkSHi5u2agUyaRAPOypUkZ1hF+DhzBMvw9nZenIwj\nd6zsgC5d3EtYs4JsMQcFUahpcbE5gc0dsuPfna+xjw/9ridPksy2fj0NAnFxlET244+0X45QAtyz\n9Fu3vvSWPifbpaSQT0GhaiMxMRGJdgk5bqJcpO8O3nrrLfj4+OD48ePYsWMHhg0bhrS0NHgZqn7J\npF9V4S7pFxcTma9fD4wcKdadOgV06iQKmAEiq/bNNynTFiDr+sknKelq+XJhLRcXAz/9RJ2ndu0i\n4vn6a5ohcKvDDh2I9K0ibwAifW9vIlmeWRghT9amTtVLFgx3Lf3gYIrC6dLFOr5fjtE3IiqKiKl5\nc6Hh+/o6t5hr1ybilBO0YmOp1s6uXWUrq8x6Pjs9i4vp3C5epH1+/z1l/A4cSL+XPJDwbV6jhj3p\nFxXRNWrRggZrzvx1B4cOUcXRv//d8+/l50c+lZo1KbFPkX7Vh9Egfu655zzeR7nkna5du2Kv1MFj\n165d6MEFYf5CUlISbr/9dvj7+6N79+6IjIzEvmrapdqdTFu26Hr3Nks8r75K0pCPNNSy4/W//9Vv\ne+oUEBJCr1nnZkdgWhr9X0wM9bpt3VqUL2AL3K7RCMs7ISH2mv4ff9C+OZ6dByMZxtLGduCM3jZt\nrNfv329P+vXrU1in3LHLVSjsggV0fWXS5+u9YYP1/7iSoJKSaDBl53hhITlzucTz8uUkG/XpQzMT\nafJbCmeD1ZEjJBnVqEGSi9X5fPAB5WkYsWIFZTV7klnM8PMjf0toKMk8ClcHykX6gX+J20lJSUhN\nTcXy5cvR3WBiDhw4ED/88ANKSkpw8OBBnDp1SicJVTd06aJ3TBrBD3evXnrSz8wEZs+mQmIyfv9d\nvJbLCWzcKGQV1nmZ8NasIeLhJilpacI5mZxMhdKsiMPXlwaTzz4j0r//fvvvERVFWbsVhQULrD/f\ntk3E1hvByU9MthERruWYEyeAfv3MPoAmTWiWZIXZs/UZvlZ4+mnxurCQrk+9etSjoKCAZgEcPmuV\nYObM0k9PFwMfz1SMOHiQymIYk8mOHaPt7bKxnYH9Dd7eZOkrXf/qQLmjd958801MmjQJ1157LSZP\nnoyQkBDMnz8f8+fPBwCMHj0a3t7e6NKlC+677z7MklsrVUOkpzuvw84Ou65dSbrhBKRXXiHZxkj6\nssUsNyZfv95s6bM2ztmtJ06QNfzDDyLkMTmZIkmswKSzaBGRnFVrQUZUFFmuQNkIxQ7+/vr3+/aR\nH8MKHEUkn5MrpKXReR89KgZJTSNL3aooHAA89RTJaYxz54QfhZccXQQQybOlz9c0P19IMnIDeYYz\nSz89XZSfqFPH2pl7+jRZ5sbH59gx4O67SR505jOwgpxcd/x4xTWPV6jaKLem369fP+wxxL1NkjJ6\nAgMDqz3RA8IK6tXLeYQFP9z+/uTY27qVrLh582gdR9kwZAvz9dfF6/XrgYAAep2ZSQQod6piNGlC\nVmCfPnQcOdHJDpzYZFUtk9GwIUlUgLW8U1ZYtTk8fNhaEjHG4nOEjzOkpVFcfFgYESKTaYcOZslr\n4kTRtWvlShpEa9akbNqbbiKrmovSybMwlnfs6urIzWUYziz9tDRxnnaW/pkzJO/MmkU+Fo4gO3aM\nMpYPHqRw3nHjrI9hBSZ9dqL/9hv5PxSubKiMXDfB0+rYWHPsuqYJCcLXlxqPnzghJJ7Jk4koiooE\nkVtBTkzatEkQ5MGDVFfHClu3AkOG0HE7dKDPrDpYGdGsmXXEDCMqSkQesYxUEeCZT0AAEVejRvqe\nvDKMEhX7LeSZgbEGT0oKEajcL1fT9O0aGXITmpISGlTbtKHfIScH+PVX0szj4/V1dljekbOCIyPF\nzMSK9F03rHMNAAAgAElEQVRZ+izv2Fn6Z85Qq8ehQ8mAYBw7Rufy2GNUssITiUYetGrVsq/SqnBl\nQZG+m+D4b39/MxmtXCkkFV9fiuhITSXSf+wxvazgrCQvSx/e3kRCPIE6eFAQuoyxY2nJxNe+PS2N\nBcqMCAykRjCGPDoduHZ+ZaFlS5KvGjYUpO/K1cOWujxbMNYi2ruXCLRxY/oNTp6kgffhh837405d\njM8/F/H3gEiEe/ZZM+k3bKgPRY2NFVnAhYUUJgoIonel6btj6derBzz+OEk5PHgePUoDznXX0fGX\nLbM+hhVkS795c6XrXy1QpO8mOLqhuNhs6W/aJEIYOXrG21uEKHbtKghZtlKNFmFcHC27dSPS4JSG\ngwdFYTUZTHhDhlA0D4cW/uVOscWDDxLhOiP9F16wb7heEahTx0z6csljZ5CdmUbizsuja8ykb2Xh\nM4wO+aQkIuD9+ynih30st9yiLx1dWGj2QyQlif0FBwtdn1s3OkvOMso7dpp+YCA5izt3pqY5RUU0\nqIWFEXH/618UIeYuZNL38SFr390MZYXqC0X6boJj9IuKzJb+1q1CtmHJ5B//EIXCnnuOHKwBAcIC\nBMw16Pl9RgZZdRs2EDnm5FDClxE8qCxdah2XbxcmyeGgzqKQAOv4/IqCptE5BASIWjh2senOwgnl\n68n4+mvSvqdO1edJGGE1kAL0u8mhofIADhDpG/vw1q0rPpMLunFIrl1ylqaZHbl2ln5gIJV6eOAB\nYMYMsvJDQ0VI6q230ozEVSQSg+Udh4PkyYQEJfFcDVCk7yZ27CAitrL0t24VbQjZaq1Zk6bcAPW0\nbdiQBosVK8T/GaMlOErn0CE61vr1guyt9PcHHqDl7bebnbxt2lgXJevThwaVkBAiEGewq2RZUQgO\nprovXCbZbhDi3sFGKQeg6yQjJITKS/P1ciZ3TJhg7Rw25gIwMTMKCwFj3cDgYDEzkh3pTPp2lv6p\nU7SOZyTO5J3AQBqIT5wgf8ucOfoZh68v8NBD7lv7fn50n164QPvv1UvF618NUKQvYd060ZXKCgMG\nECHIlv7JkzQ9Dwggi5sfmieeIEv9kUfoc5YhPv5Y/K+Vw5ULiK1eTVNtK0sW0Ffc/Owzc8Pz55+n\nfr1GNG1K0UAhIebByyiVMKzizssLtvRTUoTFbUf6L71ES2MIJ2BOEgsNJYu1QweygHkwtsIHH1Bt\nH1eQ8g8BEOnL4bUAHYf9NfJAxM5kO0tflnYAa0duSQl9Vrcu3X9jx1Ki4MyZZplp4kQyLHiwcQY/\nP5qVZGbSb9yiBeUblEfXT0khmUmh6kKRvoQ//nA+Ne7f3yzv8PbvvksPHOuk06eT023mTHrfrBk5\nGJm4TpwwlxkG9PHgvXvbE6FcNyczk/wKnTqJz6KirJ2/miYsfSMGDbI+FoduViQ0TVjEfJ7OfAwA\nXesmTfSf9eqlfx8WRr/TgQNEkM5i1zVNzMaMhdgYI0aQlAIIGUUufMf44w9y2AcH63sGHDpE57B0\nqbWlL0fuANaWfl4eOfl9fMx1jIyzuTp16D584w3r7yPDz48GlMBAmm14edH/u+r/6wxHj7pXrkTh\n8kGRvoSMDOtSwly8rFcvs7wjT4fPnBFxzjt26OWIwkKK0d+9m/ZhN6OQ5YamTZ0/gI8/TsspU4j0\nZfKIitI3D2ecOkWkJOvOAFmidvV67MoVlwdr14qBp2NHImBXpD9ihHlGM2WK/v2qVSRbMfE6q9MD\nCAf7xInW6++8U2QT82/j7HrUrKmv77NzJ+UNnD9vPQDJej5g7chlJy6gJ/1Gjawt+kmT3CtUV6uW\niETifIn+/csn8Tgc+rIZClUPivQlZGRYV6fkB6tpUyHv8BRYLi+Qn68n2kaNxOtPPyVSvXCBNH45\n1lqGPKDI+r8VbrhBzBYSE/X/W6uW9cBy5AiRrbEOTVCQmVArG1zLqG1b8me4Ov4jj5h9G1Z5fytX\niteuSH/JEloaHbOM4cPFayb99ev1Mf4yjh3Tv9++XfgkrM7FSt4xWvqs5wNE+pyZzA1ujL/l+fP2\nsqAMPz+RcwDQvdG/f/mcuQ6HPt9EoepBkb4EO0ufIzfq1aMHt6REWG1+fqK0glE/PnlS/54dr1Yx\n4wzOEAX0MoFVA+/u3YV1fuSIvm+s0ZIHiCT27aMKoEZpKSjI/cqOZQVnI7//Pi25nMQjj4haQ8YQ\nyy5dxOsaNdwLKezc2XowsAIPjHZ1eWQCk2dhVjODrl2dH8vO0g8LEx28rCx9mfSLiynkFiCJcOhQ\nc7E+Z5VLZbATNzJSH8GzapU5c9pdMOmreP+qC0X6EuwsfVmj5MiO/Hwi9ZMnReaq0bp69ln9e3f6\nkRYU6OP6GdwGUIa3t95KfO015/s+doyIKzKSsk1lBAXpWwxWBrhD04ABNPAwcaanU+2b0FBRQwig\nmZXcpczdZvMxMcDgwe5ty0lOcpkFGdxoHtA7tI29iQH9uRvh7W2v6a9eLaS6gADhM8rLo7IKp08L\n5/DFiyIZb8UKusfWrtUPhmlp9kXsZDgcRPwhIYL0o6LIYLBymrsDh4PO0VXlUoXLB0X6EuwsfZn0\n+cHNzyfttmNHMR02SgRDhujfy7KDMwwbZi6ja6cjyxKSK0s9JYWiSdi5LKMyLX2jbBMcTJYgO0Ov\nuYYS0EJC9MTZqJE+SsZVXgFjyRLryKWyYPFi4ZyXk+mMoaKAffQTQERoF73jcAiSPHFCVFf9/nua\nDe3Zo5d3uJmLplEmLcftAzSI/fabe5a+wyEc6kz6QMXE6yuJp+pCkf5f4KiWggJytn7wgVh3+LCw\nqNnaPHeOokk6d7bXg42dqThj1hWGDTNb+kbLHKDBSK6UKINJwIhu3UhOMKJePeekb1f7xx0YrU4m\nLY58atyYrNnQUCqLzFi1ihypDLkUtDMp5ZdfRNkMV3DVuXPDBjEb4Nj8G26w/j8fF+ULjZZ+YSEl\n3pWUiGMcPCgilBYvJgf76tV60pdnZMHBNAPhHIEFC+j/3CF9gPR/bhnJpF8eZy5fF0X6VReK9P9C\nTg49lKdO0Q1vdLQOGEBLWd7ZulWf9WrM/vQkJV5Gp072IYQybr9dnzQkR3ZYyRUNG1LMu1WHpKAg\n8cAaZygAZRV7ArmzlpH0S0rEHx8bINI3DkiyxS7XyB8zxvnxuXmLK5RFe7Yr8exqJmJsCs9ySkaG\nIP1Dh0jWOnWKSjuMHasn/eJiPeknJVFpaDZSOGzXXdIHSB4qLiap8sIFsvSTksqm6/M9pCJ4qi4U\n6f8F2VGamkoJOZomSIEbirC1tngxZcHKU36j87Sw0JpAXcHLyz2p5aGH9LH5TPStWlnX38nMJAv5\njz/0vgCAiJejRqwyXz2twyM3YDHKO19/LSp3tmkjHOChoebvbdeEnpPYrNC7d8X3muXeAgDJLlbZ\nzIsWOU8G272biP7YMfrt2OH688+iVs+hQ2Tpf/UV/SYffGDW9GXST0gAXn6Zth8xgmaegOtZhxHH\nj5O/59gx8lGFhVmH/LqCsvSrPq440s/K8sxCWbuWulfJkTL79hFpHDkiLEYuBlZcTDc2d7ySHww5\n25bhTg14Iy5eFFNtZ7j9dn2EEGvkVk5GgCJjCgtpFmEMLQwKEtdAbihihB0JGyGTojHz+OWXRUx+\neLioW2TVgB2w7v8aHGzvrF2zhqzf8oDJkyG3Izx6VEQgyVi/Xp8pbYV33gHGj6cSF+npghy57tLB\ng2TpP/WU0PsBvbxjJPS33qJ6QdzoHLAuwWEHLy86Tt265Zd4FOlXfVxxpP+Pf9iH31lh4UKy2LlB\neb16ZOUHBJADja1nliiKi+kBZOtVnrKfP2/ev53m7gzLlgk/gbOIkMOHgXvuEe+Z9O307Lp1iex7\n9zZHwtSrJ66Bs9IE7j7MstRlJH3W9AHSo2VL32r/c+aYPwsIsG/sDpibsFv5MZyBy1Yz+NowZCNB\nhh3pc7juSy+RdBIURKTPxsPZszQgZ2WRwz07m+Q4jurh4mhGSx8gX8ff/kbJgxwR5SrHQzaMSkpE\ngpZM+mVx5ip5p+rjiiP94mL7phxWyMwkImSna0AAWfoDB9J0nJ2NPL0uKiLSd9ZqUAYXQvMkq3X4\ncKHVOztOejpl7LLF+/bbzv/Hz49Ix1hLBiDHNMfNe6rfW+Huu62tYUBITz4+ZOnLpM+dqmRYEfZH\nH1F3KyucP292fLur8TNcySM7duh1cz5HuYyGDNlHExtLpG/0u6SlkabOeR9+fkTmgJiZXbyov78b\nNqSZwfr1FN7KspYxiEDGyZMiL4AhJ2gB5FBfvdpc9sEVlKVf9XHFkb63t2dT2xMn6IHirEm2ohwO\nshaNdUSKi8litiuP0Ly5/j3LL65KDBgxbhxZ5EYLU0ZuLhEAW4Pyg2ZsywjQ7GTTJmsrkBN+APdD\nI52hqMi+rANb+g0a6C397Gwicys0bqxP3HrvPXvdXk5WMvou3IWr6J+zZ/V+CzYK2CFrBIee1q1L\nv1lQkFkO5H68ADVKKSgQxeh4IL9wQQwEAJVcWLyYDJWOHcV5WIUeMzp1omQ4GUZLn/M5eCbiLhTp\nV32Um/STkpIQFxeHFi1aYI7VPBzA5s2b0bVrV8TFxSEhIaG8h3QKLy/PEksyM/W9Ypmkv/+eHHNW\npO9M17br/rR4sT6ixR1wmQI75OYSqbVtq08Me/BBfSs8DoP083PuAGUrVZZNunWjWY+njsHiYkHm\nXC6geXOySpnA/PyI9Llj2PPPA//5j17Dv3CBrNbTp4WuHh5OzmYe7IyYOlX0ArjxRs/Om2E3+MiQ\nC9FxIICxRwKDG+J8+CEtrTKLWaoLDSXSHjFCkGhampBk5D62I0aQs7d9exrUrZrGFBVRy84tW2i/\n6enmbHGjpQ+ULV5fkX7VR7lJf8qUKZg/fz5WrFiBuXPnIttg0mqahvHjx+Pll1/Gnj178KVVd+8K\nhLc3WT1W+rqMM2fIijlxQm+15+cTOTNRnT2r7+jEZRgAso6MsCp/ANBA5E5yljsDA2epvvQSWdPB\nwXoLs2lTPUlzR66aNc2leGWwU5q7fwHUNeqaa/Qx8u6gqEgUVOPIn5deosFo3Tp6f+IEETj/VseP\n03EGDhT7OXuWrFl5BhUcTKQuW8ZG3H03LW3skAqB3CmLByRXMhJ3unJmmIweTQOd7M9JSxMhwPKg\nzPcmD/qyw7m4mCLRYmPJgfzrr+Qo9vYW0UIMuegaoyzOXKXpV32Ui/TP/DWc9+3bFzExMRg0aBA2\nGuaNW7ZsQbt27XDtX0JliFVN3wqElxfpkK5qtGzbBvToYS0RhIbqiZ5j9AF6kLhf6uTJ+v8bNMie\n9G++2b0QOHccjvzwZ2eTJe5wkMU/ZAhFxjzwgJ702ZKuWdM5KTH5ylmw//43DYBM1O6iqEiUtOCf\nnK163teZM/QZE83LL5MPZNIksZ833qD1co324GDyvdgloAHCUW2MwnEHzjJrZXBsPGdP9+7tmvQz\nMvSzD6vze/tt0tNl+ejPP4VsJd9HTLJsucv+nGnT6P7gYILDh8mPEBRkbnYfFUUDkSxr9etHkVDu\nlr+Qz0dZ+lUX5SL9zZs3o5WkZ8THx2ODoeTfL7/8AofDgWuuuQYjRozALzbtmqZNm1b6l1iOHHBv\nb7KWXen6LVqY0+J52mxMEpKn8cXF4sE2RrlkZpotKEavXtblD4wwOtisINeAYd08JoYGnORkGvhk\naz0/n6b9tWubQzWtYBy4unf3vMZ6cbGoYMmO26IisvRZ6gDI0meZ5tlnifjlAeall8gJynXvufEH\n4Dx6h2c38nVguJJ8jDX7rVC/vnDEsgx3/fWu/SFvvaUvqif3b/D3J9L95z/p/Z9/6h2pL75IA7cs\nOfKskyfYaWkicurFF4Gnnxbd15j069c3d1qT5UHORQkNJWNCLhXtCor0KxeJiYk6riwLKt2RW1hY\niD/++ANLlizBrFmzMHnyZBRYVDWTv0h5dH8vLyJvV7q+VVZljx60NJK+3J9WHiiMWbPJyfYPyJEj\ntF9XfWeNqfpcXEtGcLAoQ8BWfHQ0Pbgc2SGTXV4erQsNNbdoZMhSlXHg8fcXZSHkMgnOcOyYkIQ4\ndjwzk0hfToQ7d06UN+jenUhQLrIGUHQSZ+PGxgor1eHQz8KsYCw7DNj3xmXIurhd+YkOHcT9snQp\nLVu10lv6svbOcDXTatJE+JiiovQySXg4DQJyCOy+feQQP3GCiD89XS8LpaRQkAKXC2HSNw5O8oxX\nbpPpqcTjcKia+pWJhISEy0v6Xbt2xV4p/m/Xrl3owU/CX+jZsyeGDh2KiIgING3aFF26dEGSMzG2\nnPDyImelFelrGkkfeXnWtVPYiRUaqk8UkssIyKUArMDHNbbx+/FHkiisSiQ7w113mT978UVR/uGR\nR8h5uHw5kfPevWRlsQQFCNKvX1+v+cqQe75atXHkaCB3SxY//TQR/AMPiP1lZAjLlK11OYJl8mRr\ny3zIEDGY9uhBxMbkKcf8y+jSxdqpCdiXUWDINoldZrSm6cMzu3Wje0Ym0+uvd34cIy5epHP+8ku6\nP0NDhXR0333kgzJKLevWETEPGEDO59q19YPmnDlkqPTtS9eN5R0jsrOFP0mW19iZaxeVZITDQb+J\nsvSrLspF+oF/hbEkJSUhNTUVy5cvR3dDnF6PHj2watUqnDt3DqdOncLvv/+O3pXRf+8veHtTXXk7\nS3/hQoqSsKq5wv/z6ad6srV6SOyyRxlGX0FWFun6npK+VVp/To6IAvn5Z4o0SksThDx1qj45KS+P\nSJa/s9U+69UTFjA3E+dZBKCPwHEXEyfSDGTfPop4yswU0S1cvmL1atru2mvtQzD79SPSDwykgaRv\nX2F9Wsl4a9fS4Gc1gAD2fhO+deWBXa5tJOPkSb3T87bbaL+yJW9snu4OWLrRNJKCFi6ke61TJxE+\nWbOmGPRXrSLpcPhw2j4mxvo36tKFZhLJyfrILsbevaJEeFaWOFa/fmRQhIS4d+9yZq8i/SoMrZxI\nTEzUWrVqpTVr1kybNWuWpmmaNm/ePG3evHml27z99ttaXFyc1rdvX23x4sWmfVTAaZTijjs0bcEC\nTQsI0LScHPP6tm01rW5dTXv7bU2rUYOr6zj/27tXPlfxZ3zv6k/TNK19e8/+Z/p06/3cf7/+s+ho\n+3306KFpo0Zp2qOPim0dDv02Cxdq2qefivehoZrm56dpJSV0vJwc+jwrS/9/fn7idXKyeP3YY3TM\nzz/XtBEj6G/cOPO53XSTphUV0fKrr+yvc/fumvbNN5p2+LCmvfmmpk2caH/9NU3TOne2vx7r1ll/\n3r8/LWvVEp/de6/1trVqaVpcnHi/fLmmnTypafXqmfdXnr9p0zStTx/z576+tPT21rRt2zTt+HF6\nP2KE+brUr69p69drWtOm9P6f/9S0gQPNv0Pv3vTcAJo2cqT4LfienTDB9fO3fbumtWqlaV5emlZc\n7Hp7hfKhLNzp+X9UAiqS9MeN07QPP9S0bt00bfVq8/oRIzRtxgxNCwlx/8GbMUM+V/F36JD7+zh9\nmv4/PNz5duHh9CA720bTNO2LL9w/dps29MA++CC9b99e02JjxXqHQ9PuuUfTzp8Xn914IxFbbq7+\nuy9dqt93t27i9cmT4vXLL2ta165ENrGxdA2HDKF1LVuK7c6do33fcQcNPIzQULFNUZGm+ftr2tmz\ntG7HDiKwc+fM3/Waa2ibf/3L/npcf73158OGmX8fd4n7lVc07eJFTfPxEZ8dOOD8f+rX1783ErFM\n7s7++Lrwb6tp+msMaFpGhqY1a0avp06lwURe37Klpv3975rWsaP4bPt22teUKeI+ueYaTdu61f75\n27GDBsO6da2NLoWKRVm484rLyOWQzbZtrSWemBia9jsL9zOCyxsY67k4i/J44QX9ex8fUb7WGZo1\n05drtkNwsP69s05RrOmzkzgoSB/ap2kUmifnCHB9e6PDz+jUk9My5PIARUUkjURGklzSu7eQB9iZ\n3KOHkBpq19bLO9wmsX17kh4aNRL6fevWFJEkl2wwOpjtYgHeeMM+O/rcOX01TcC6ZIUV5s2j6yhL\nYnJdJCvIFVoBOi/Zf9SqlfXvavRVjBsnonw4g9tY5jssTAQhBAWZfTtpafR7y74uvoc5dNThIDlO\nTmY0ghuz+PnZdyNTuLy44kjf25uchXak37gx3eB2eq8VUlNpn//5j/5zK2fwQw/R0kg6XbuSczcg\nwLoIG1fj3LBB6OfOYCT9qCj7ZthM+vzQBwaaHXOHD9OAxFFBo0e7R/oZGcLZ+cwz4vPcXPI9FBTQ\nuUVHm8lCjm4xkj5nPbdoQQX05PgAjtp5+WXxfsoUes0tGeUyFLJDtUMHsY0Rhw/rjwPYF1YzokED\n0vBlMpV7FlvBmLKSnEzRWvzbPv005X7IIbqAvhWhlxdFDz30EEVgsZ1urAHkcIjfv359cx/exo3p\nt3I46F7096dyHbt3i/uRq6E6qyPFpH/iBA3c995L5aIVqg6uONJnS79NG2snX0wMZXLKHZncwc6d\n5iJemmbe7pZbaGlsoBIUBHz7LT1sVv1L2flWUmLfiQsQ1riR9L/5hqzqRx81/w+TPtdj4XC6uXPF\nNj16UCQIO3kLC82k7+Vlnu2cO0cOakAfX3/oEJFQSgqFtoaFiX1xoTR2HAJEKDLpszV+9Cj1/jWG\nujIZP/MMDaKyc7KkRG8Ny9nZTZrYZz2npJgJ1l1MnmzO23jjDftkPQB45RXzZyNGiES0khJyiBrD\nHy9eFIZDUBDw2GPkxOXos+Rks6Wfk+Oc9Fu2pAHL4aDr07o1DZAvvkjH6NhR/M9HH9lnvBsNoZAQ\nMiTGjXN/1qRQubjiSN9o6RuJuXFj59NTO7gbqlhcTDHRxgzWjRspAqOkxLr+jRxx4axcAz+4TPo1\nalD0xsCBlEAl5xEwERYWEglyOQRu0M6lCgCSX9asEYlT77xDD6xM+nK+ggy5Ty9j/36y7v/8kwhF\nTtTmnACZYGvX1luwTPrr19OsQ65pVFQkasI89hidp5zEZLRE5cQyDtdkcjKWrq5b1z3i//e/9e+t\nsnhzcvQDmxFWM7O+fYVlzJnlVuGSPKidPEkkP3y4WMeDsIzvv9fLO8ZInMBAGmBKSmjdLbfQdV2+\nnH5DOTsYoNmAldHDlj7nsLzwghj4e/ZUxF8VcMWRPlv6YWFEiEaCb9zYdV0eGSwN/N//ubd9aio9\nkMYSDb17C1Kzih93lvpv1YiFCb1jRwp35CxOmTjvuEO89vUlcmDCrVGDQv9YBmjYkEi/sJAklZo1\nSR+WSf+zz+zPj+UVxs6dIlzz/HkxA2rWTMTBG0mfLf3CQn2ewdSp+n3L0llqKpGTHL8+dSrdA6yv\nywTH5SmYlIxdwurWNev6VpCJtWtX674HJ0+aM5nlUF+r3JoaNYj0w8MpdFYuiSFDDg09f16f7W2V\nS7Jggd7SNya9+/uTpX/iBBkU/fqR8XHvvZQVbZQrz5zR+0ZmzKDwYSZ9Nmw0jcKB//Mfyrcw5q8o\nXHpccaTPlj5gresHB5vLLzgDZ1u6i19/JWIxOvEGDhSShDHrFtCTvjz1XrVKnyxktEKbN6f696y7\nyoOT7GhmHwZbuOPG0ZLJuKBAJED17EmDiJH0O3em/XfooD+HsDDq4iXj4kWS0vbto7IDs2ZRSeDr\nrhPfR7aCZdJfs0bvzDZq3+vWicJxK1cSkfJv3r8/WbKffaavn2QE18I3OnXtSN9ZA/WiIiJ4Y4VN\n2cfBkK+n8d7kUhOHDtHvalfe2ZhcVlzsvJQyQCQvO/KNOHWKZmNHjtAg+cQT9J1+/pl8KlYJbTwj\nKSykukBnztB12r9f5ELI37dNG8/LeShUPK440mdLHxC6/vnzok6Lw2GtqVcEevWiNoE+PqIhCUMu\nP1BUJKQS1mZleefVV0UWq6+v3vFrnJZz8pDDYc4AlbNJWcdmfwFb/IMG0XLlSiEjBAYSiQcGmssG\n9OtnLtMQHi569cqzmOhoGujeeIOu/xdf0KyE6xPJ5HPhgjjfZcucO9qzsug3nDCBzjskRFRHdTgo\nque558yDu3w9WJIykn7t2takz9eJIUc/9elD9e+NDnquPQSYv49VWej+/enePXyY7g87B6gx+aqo\niM7HeI6ewFiLhwfgLVvIALDyP/D5ffMNDRoNGojBkaOIZP9U69ae9bpQqBxccaRvZemfP081VNjC\nlDseVSTGjBEhmcY+swsXEgH6+NADNWwYfc5ELUs4EREiCuT7751HgcjkY+wLK1tZTDphYUS2TPrc\nT/f778W2ubnkWB0/3hy906SJuTRBeDhd99BQffRKdDRZq3KDFn9/cc7yfnbuFNb9L7/oi7IZUasW\nSVX/+Y9oPZidLQaRAQPIMjXWQZLLE3BzFWMIbVqaCBeVYUwil2eAb71F0TNWvg2GcYZm1WHL359q\nFtWvL6Qpq0gv9skwkpKoiJwx0MAOVkX3Jk6k37ZOHcpMvvVWsW7SJP0AxmDS5wJykZGC9Pn3k0nf\nLrhC4dLiiiP9evUEUTHpczcs1vcr09IHrFvV7dxJVnpsLDlU2fHGxCeXgs7MFNUXX3uNKkZaFe8C\n9GUCuLIk79eq69bkySQlMenz8eWeqSwvPfqovksTQA+1sSsXD1jPPEMDBSM62lwbp1YtoTnLksmO\nHfR7HTlC18oYOilj7VryZTRuTMdITSXSr19f7NOq7aJM+kzQxkHNzlo2lq744gvxuk0bGsRnz9bL\nUmPGiNfGaKstW8ydxQoLiUjlgVWWAocMsT43QMgvxqgdK1gFCqSl0f2Tmyu6xjF+/NFaKjt0iHwv\nO3eSMSNb+gyZ9Js0oettjBxiFBSQY16hcnHFkb6s47durS8eduSIKEpVVhijGGSEhQkLzUqeOH6c\nyDYrS2jw/FDI1SAzM4XDq7iYHkY5ZJGn3sYmLrLVGhGh14yZaO+7j5q5O/sevP+oKGo0b4Qxj4Cd\nkzuyhLsAACAASURBVAMG6OP4rSzfWrWE/iwTxPbtRCxsrTorQ/3bb+L8Bw4UvoegILFPK4mGB2VA\n+BOs4vCtfD7Tp+vfczDAkiXkt8jPJwe4PNORK5oau60lJdF3kGedhYVUQbRpU0H6clSS0W/Cv3+n\nTsKg+fJLkmKc3eNWDvn0dP2MUo62eu01637EqanUB/nGG+l3rV3bOel7e1MUFkeRnTmjv64sBXra\nl1fBM1xxpN++vWgyERBADzdPQ48epWgIYwy9J3BWZpbb3PGxjcjIIBJv21ZM23//nTRaufCoTPoA\nkT43ywZEZItRplqzhpZ16tBUOyNDWNosL4SF0axBHpRYagKIuOwsMYbR0ufvEh+vdzpbXQOrYl+Z\nmWTRRkaSnn/HHRQRY2ftJyaKaJKBA4lY2NJ3BrlhCTsajc7SBx+0HrDlqCgZI0dSJNCxY2Tlyz4Q\nedA1znh27SKylsN3ZUufZ6cyjP1++fvyIDVtmiBduVKmEXINfwZb+gANXHIE0L591n0e9u2jqKBh\nw4Rj3Uj6cvtFQO/MXb1a3xsgP5+eD0+LEip4hiuO9GNiyFJlB13btsKyOHLEWkutKBjLGAB6ueDc\nOXpA5eiXCxdoG5nkDx4kYucHNy5Ob8XzoGZH+q++KhxvTAglJaImvhHy5717uyZ9Ox+DO/Xt5TIF\nTBA7dpCV73AQCXKmrWyZMzgMkqWavn2JIFnTdxZlI0eg8OyEyezPP4lsrcpKA2YdHSDL28uLQkSP\nHqX916wp1sszBiPp9+tnjuMvLCSLOybG7Dfp2VNYwGwd87FYJ58wgWaMTzwBvP669fewQ0GBGAj5\neQGAoUNpyY1wZKSmkpFQp474Hnz9uSwGW/pFRfQbyc7cTZuETwkQA6tdZVOFisEVR/oOBxEI69lt\n24qb7MgRs45akbDSSo2JMkVF5iYeUVH6hixr1hCxsoQRGamPMvn6a1oaLb81a8j6u3hRSDAsQ6Sn\nW4eKAvqQyB49XJO+XY15wDXpW1n6rOcDRKAsW1iR/uefk2XJ+6lblwZyo7xjBdl6NpbGjoykwdeq\nyUzduuZZR3y8SE4aOZJkCR60rGAk/WuvpdmB3LOYST862nyNjx8nBzcg/EHG2UDPniTH+fsLsnYX\n/v7WTuOePclPZofhw+ncjL2X2ZBgQ2TTJioxITtzN27Ukz7PkhXpVy6uONIH9BIP32Te3mSNcW0Z\nT2FMsbfCiy/qteTBg80ZmXl55ICUk5lq1zbr5F27ivDHjAw96XOkjWzp5+XRdpMn00NjlCgOH3aP\n9AMD7aUMGXbJZHJTcyvIpC+H91k5Cpn0ZSfzwoXA2LHmY7oj78ix7EaCq12bSD811Zy8FxVlljd6\n9SJpQtOIoCdOpM/tiuUZf49WrcykP28e7bNRIzPp33CD6JHL4bHGrmA//kgBAc89p3fquwNfX5Hg\nJ6NxY72hJGdx87kcO2a29OXB9+JFGiQ3baJruWsXXbdNm/S/u7L0Lw2uSNI3WvocwXPkCD0QZYGz\nIlOMtDR9tMvs2eZQvZ07gb//nabTHMpYu7ZZJ5edc4mJ1pUhZdKvXZus1NhYfew+QFZcerp9Ulr3\n7kQoPj5kMcs6qx2sCAJwHRllRfqypS+Drx37MPbtI1LmJCbGwIEk+wQGOrf0XTV3HzCA/l/OBgaI\nqIwzgP376bvIUVeAIH3ZCvfxMTsnr7uOQh2tsmfHjtX7AwYOpP7BrsASGWfFeoIzZ0jaMs5Ci4v1\nkpXVDES29K1IPzOTZmFNmtC1zc0lOfP0af3MSJH+pcEVSfqypd+iBZHnhQtE+u+84/5+uN5LWJgo\nr+wMDz5INzs/ANHR1nVcfv0VePddoe1bkX6zZoJQfvxRkL4x+UlGeDgNBBwHz47Ldu2cyzstW1Ko\nXI8eFA7pTmlnq9IQjAkTzN+HYbSwub6M1TGNMd8ff0wdqriUAqNnTyJgTs4C9MXbmIBZarBDvXo0\nABp1/YYNzZ+tWkUDs1HS43tGHpBDQmi2wpFQI0eKmR5b7zLuvltIOQAN5MbkKUBfZkOGw2Fuq+gO\nnnjC/LvJ/jHAnKyXmkqWPkcn8fUvLhbXnb9Lly5UubN1a+r81rSpXvbKz6f9OCs4qFB+XJGk36YN\nFXYqLqZpK+vl7pbJZXBxqIsX3Usqad6cjsnT7/XrzeQ4ZoyQmNixWLu2WWOuX1+Q/g8/CEcuT4dP\nnBBTatmCj44WlhKfR/v2zuUdxnXXEem7A9Z5rdpGDhhgfyyHgwbCsDBhVUdEOA8xXLuWSPPjj83S\nDkCW6J9/0myBJR5Zjjl6lL6/1f8a8fLL1j4X/i3kQevXX/WzoqVLheNebsnIBeFefZXOr21bIreI\nCHN0C0AkKvtGvvySEsCMhPzJJ9bfweEom7VsJQvl5elzGeRZUJ06FG30xRc00POxAbLmeSB4801a\ndulC16x1a+CDD8yzu/x8Or6y9CsXVyTpBwTorTN3LFdnOHnSPUt/9Woi/dhYyshduVKQxPDhZN0x\nEQN60jciO5uIJjiYHiC2ttiC/eEHQbxyP9LISBECyeTVrh0RiTukf+SIe5YWH9uqiuRNN1lbsIwD\nB0RMt52eL2PdOrq2devaRyBFRREpLlpE7+Wwv/Bwuh+MVUKNeQ4ARZ0Ym+M0bCgiWjhq6I476HNu\nGt6oETmY2cKX/RBM+jk5JHOEhdFAlJ1N5xYYqLd4c3P1g8mJE2R0cB+Ap5+2vgYyPG1g4u1NMyU5\nMqtGDbOlL9fOuftuc6kIJv2zZ+keqV1bSK1JSRSZFhBA92K7dhRlxMXfzp1zTvonTpiL7yl4jiuS\n9AG6oVjikS0KY5RBRWL5ciJ9Hx+KzlixQqw7cIA6S8nhmkw6/MDLIYWHDhFxse7PD15GBvkNWrYU\n+qpsLfr6EpHIU+6YGHr4XBWaY+exO9a+M9Ln5uV2kMM27fR8Gbt2CQeuM81ehjux3uyMtmuUzmDn\nIyBI3+GgnI/Tp+n7HjlCOQZcdE2OgAoOJtI/dYpIPzycvndICN0rXImSMXOmdbE2gCQ7riNlB4fD\n83IHPIuQSd/Li0ifayUZ8c9/2pP+mTN0/3EU0fffiwAElh/btqVn4scf6X1+Pt2r+fnWwQQpKSSL\nKpQP5Sb9pKQkxMXFoUWLFpgzZ47tdps3b4aPjw++5njDSoamCb1VJhWjDu4KVmFsdti7l8jGx4ei\nO3btElY4k75sqbI+z1ahXDBt9WryR9x4I71nLTUjg6bT8lTfGLrHuj5/3qULEZwrS9/Hh8JEPSF9\nZ+USnEHT3Lf0ASrqddtt7u+fSf+77+y34cJlzmrm+PgQSfPAynV5OnUSUg63ohw8WDhQ8/JE7oWV\npb99uzBANM1c+VKO9pFrF+3fb65yypgyRXS/8hR8veRILi8vvZVvzCqWpUSGbOkHBor/4fsYoMER\noOfSy0tcp/x8Mk4aNbKebRYU0HnKCYAKnqPcpD9lyhTMnz8fK1aswNy5c5FtEWZy8eJFPP744xgy\nZAg0T8MKyoCiIopl5zLDfJOMGKF38DFGjNCTuxytID9wrtCtG1n7Pj60v+7dyeEXHk5WtlG7l60i\nQK+n/vYbvWdpimctgL6pRkmJmTT5YfTyIqdheLggfVeX311dn0lKvlaegknflaUP0LX1ZJbGJGZX\nswhwj/QbNiTCZvIKDaXSCw8/TFr3ypVkwbNzmQfw3FwxQLAjl0k/PJx+Q/n7GGPh5SgZDjXduZOk\nOyunbrt2tK5TJ8ry9hRW/q5z50Q9/+uu04ct9+tnnblslHfkwAOu3sohsXXr0vZbt9I1zs8n6cdq\nMAHEc5yWRpLQJaCSKxLlIv0zf7FV3759ERMTg0GDBmGjXLTjL8yZMwe33HILQq28fpWAxYv177nM\nca1a1olHfn5kVTPkOG1jHXFnU+s+fUiHZwIYOJBIgWUEo4OQwaTP2n5YGFk6cXFmKz4wUC9dWFl1\n/NDIFUdZz3ZV1+S662iAcZWg5edHhG9VLsAdaBodIzPTXCrYCu44YWVkZtLvYNftCxC/i5H05UF1\n/36ydln2uOYaktc6dCApz5iMJpM+g+WdnBxy5LKcJFv6Mulz7D/j/fdp2bo1XfcbbzTXTvL3p5o6\nzz5L9aU8Bd+Dsi9CRr9++ugn43Y8gzbKOzJ5x8ToY/737qXvmZ9P/rf8fPoedqTPg19qKiU9WjnB\nFVzDx/Um9ti8eTNaSX3s4uPjsWHDBgyTirkcPXoU3333Hf73v/9h8+bNcNjMPadJbYQSEhKQYGzV\n4yZKSigCgxuRZ2cLTTI729rSN0YoyDA2UfnpJ/tjs+Qik/748WR9rVtnnpbzg8Pnx6QfF0dyTlyc\nOY47MpKsMmfx8DExJCW1bi1IngnuwgVzyKOMFi3Iut20yXWiVb16zrNznUHTSP6Kj3c+cHTtSgOp\nVcEvZ8jIIMJ3VpffjvTl0sM+PhSjL2vXq1bZ+yzY+mzXTryWST8oiMiwRg17eefsWfN1NdazN856\nOFFrzBgatJ050o3w9xeEKttsQUHi3ty+XZ+rwDkkvr40g+T70eEQXbgCAvQDUHa2Pjly1y6RV7B5\nM52DO5Z+aioZcAcOOJ+lXYlITExEorHtmYcoF+m7g4ceegivvPIKHA4HNE2zlXdk0i8L7roLeOAB\nuiHq1KF46c2b6Wa9+WbSyO1If+NGmqJbwVhgzZkFzPV2+Ibt3JkeDh4MjKTPN/H06aKWOSDCDidM\n0MtONWqQvOAq9DQ6mpxmsqXPBOdK13c4hMTjDumX1dIH3HPi1qhBlrXs/HUHXMbaGXgWZ/TzHDki\nmsIXFopG5QB9ZuzkJYOvd1KSmDHWri1IPzycrnFYmHCCa5ooTtekCZ278boaO7FZdbJasoSulbGM\nsx28vOh8IyNFKKZswUdHC9KXS0kD+oZAgIhacjiIkE+fFhFvDRrQPZudrc9f2LmTtudnVZZ3OFJJ\nBj8vhw7R/ZCSYm7jeKXDaBA/V4Zs03LJO127dsVeqdPxrl270MPg2du6dStGjx6NJk2a4KuvvsLk\nyZPxvdyxoxzQNGGhHD9Onv0XX6QB4OOP6fPkZFFj/Phx6/64doQPuK4lI4O7IfFA7O1N02KOVjCS\nfl4ePfzvvAPceSc1BQHIaQmQlXTsmMgGbtmSbnx3SJ81faOl74r0Afd1/fKQvqbRQ+/Kidupk/OK\nkXbIyNA3U7cCk7eRJI8eFXJOmzZ07dato3N2RviAIE0/P/r7+We6RrKlDxD5y5Y+38cNG9Lva7T0\njY5eK9KfPJlkEr7fXPEBz4Lk2Ht5Iu6srIUxrFUmfU0T992oUWIG6+OjD0XduJG+Z+fOetJv1Mje\n0g8LI8PO39/zsFQFQrlIP/Av71ZSUhJSU1OxfPlydDdUNDt48CAOHTqEQ4cO4ZZbbsE777yDG264\noTyHLcW2baKxRHAwVQI8e1ZP7MnJ4oa0k3CcgSMNZNjFivPDJqfmDxwotEfjg5KXRw/E0KE0I+F4\n5uXLSZ8dOZIeTNa827Yl4vCE9JmEGjakh84d0h882D6jVkZ55R13LP3Zsz0vkqdp7ln63t5E6HJ1\nVIB+Lw7RnDKFdH25AYurY/v4CAltyBBr0n/1VVGJkv0bAJFaRob+ulp9D2OobIMGZPDccovIKXBl\nsBgNoJISfbQODwDGRjoPPWT+X5n0+R6LjCRnLT8XN9yg7+6WnEzbd+hABsDp067lnbg4Yekr0i8b\nyh298+abb2LSpEm49tprMXnyZISEhGD+/PmYb1WLtYKRkyO0RbZKWrfWRzdYdY8CXMdmO0OLFvqq\nmAzZImWyHTiQbs6QEDNBMukD+oiLGjX07erYSo+Pd4/0AwOJaM6eFefh40MPnLOKiYx69dxLAAoK\nKp+8k5bmXrimp8jJIeJxRfoAfVdjWK6/v3CUjhjhWQhkSYm5kijLbDLp9+8v5DyZ9IOCiPTlY1oV\nTzP+jnl5VPStQwchSXp6j585o89k5pmA0eJ/801zfSLZkcvfZfx4IvILF+i7jhplJvNjx+h6BwfT\nQOvvL0I2jc7ic+foGWBN33gOCu6h3KTfr18/7NmzBykpKXjwr/jGSZMmYZLFnPzDDz/ESHf6ubmJ\nwkJhmbDKdPCgvh743r1EAMaGHsYaIu6Ap/a1a4uHjmu/A1RIjcGDTVwckXB2ttnKZtLPz6cHlnuN\nGpOoAgKIGOLj6SFyp5xEdDRZrHK0znPPWZc2LisSEjyv5sjQNJI4KiOgy51wTcZnn+mbqwDA/fcL\nDdvT2WFQkL7fMGBt6cuQSb9ePT3pd+hg7bQ3Wvr5+fQ/8+aJz7j8gbvIydE/O1wW/JdfgH//W3zO\nr9ngAoSlz6HF3PKRo4KaNLEu97x7N5E7u/ouXCDir1PHfO0LCuhaZGWRhHrggArbLAuqdUZuYSFZ\ns0VFIvt1xw59DfCGDUX1yfKCm1fUqSOm7507i8iKw4eFdcTn43AIh6hxoGHSf+YZal7Cg4adBBMf\nT+ThCenbheBVBCZNKrsjTdMqx8oHiDSDglzr7wBJZ85mK54aBw6H+ZqUhfSZzJo3N8uCgLm0CP/O\nAQGUHzB9umfFBQEyKJi0a9USPofjxykvgcH+Mlk+Yr/I/ffTMj6ergVHPUVGCt9ZQIDI7zh4UCTq\n8XvAWuIpKNA79M+eNTe2V3CNak/6gCBYnkQUF4sSB1xxszwyBIMfrNq1BelHRACPPEKv33qLNFX5\nnABB+sbSAHl5pBcvXkxNOHg2IseJy2jWjAYVd0g/JsZs6Vc1uJOUVRawE7csmalGWLUJ9BRlIX2O\nBDt3znW5ahkXL1K4rpzd7QrcTe7UKUH6BQVCfho/Xp+El5FB2dGcfAaIbfl7ZGbSDIFJf+NGEQ6a\nn68f8EtKhPTJkg2TfkkJ1bHSNDon40xV6fqe44og/UcfpYgTdqAePSrid7m2/smTnpdgMEK2PHgQ\nqV9fWPdbttDNOWqUPmTPjvRzc+mhmDWLrFLep1xATYavL/kTTpxwXTr3Ulj65UFlW/oVMbN7/nnP\nyNMOXl50L5w7Z+6gBTgn/dRUa0vfDi+8QPcG36tGJ7UVxo2j5fz5whqPjtZXmZUTs/7xD7pfZa2f\nBwV+7rZs0Td5ycnR9yOWfx85eol9W0z6DgclV27caLb0AaXrlwXVmvQ5bnfPHnJS7tlDN/CZMyK+\nmC39gwfLV7LVz09U7SwoEPH+RufsuXMU7TBggLASGzUisjZa6DVr0szAGB3hbMrKbfpcyQ5Wmn5V\nQ2VZ+nXrisiY8uDpp637IXgKb2/R5MUu2kkm/ePHBfmmprpv6a9cSc3RAYrkAfSZ5nZgSUYOgGjT\nRhgpX3+t7xH82mvk83jrLf1+3nhD9D6wwpo19P0TEvT3b1aW0O+57EN0NMmlLI9++ik9W7VqCX9G\nzZrK0i8LqjXps6Xfrp2w4kePphK3bGXI1TbLg+HDBekXFooHQm7BB5ATz9eXKgfKM4trrzV3vxoz\nhh4eowzhLG+A48fdCds8frzqWvrvv28f+lpeTJggGpZUBciN262gaXTP+PnRTODUKUGCtWpZzw4A\nsxP99ttFpNfWrTT7teq4ZsQ//0lO1sGDxWetW1Pte4AGHZn0g4OJ4GX8+KOQOe2wfj35KO64Q+wb\noAFKLsVx8aI+Vn/gQOqNnJtLAwff+5GRivTLgmpN+kzCo0cLy7t/f5qmMurU8bx5ihW6dxf6pEz6\nViVgrcocPP+8aDQhw0p3rgjSj4mhaX5VtfSHDq0YP0t1gLc3yTXOSD86mqz8oiKSTfjedmbljx6t\nj0qbMEGvec+YYY5ak/Hqq7QcOJAGHbl0Q2SksNqDgignBhC+MmPtnxEj7GdFcoRW27b6ipsMeQA7\ncEDvyB04kGYGiYn65K4GDZS8UxZUa9L/4ANalpRQQhNgbmvnTgSHO4iKEtPKwkIRYWO09AF97RZG\ncLD751IRpN+ggb4Mg8LlAw9uzki/USMi/cJCIk+OYnGm5wcFCd/OpEkk7ch19Dt0IJmGm7YbwbMA\nPz86rtyvVg6XPHpUZAAzsVtVSOckLCPkuknt2lk/B61aieu0fbue9Bs2FHkxsiykLP2yoVqTPt8k\nWVlUdwQw1ygBKByyvAgOFs4nuZ43W/py9Qm7Nnbuwhnpc/MUV6Tv7S3KAitcXrgifYBILjBQkD7D\nmaUvk358vPUMMyDA2gjx8RENX2rVouPK991LL4nXu3cL0ucS05Mn6/e3c6d9IiTnnwD2fpxWrUS+\nRFISXYOcHCHhcjDE0aPienp5UdimVT0tBXtUa9IfP56Ws2aJcDCLys4VEroXHCysDTmkkklfrh7I\nPV3LCmeO3Jo1Sf+0epCNiIlRln5VADtvrWrZcDw+yzuFhfrEK2eWfr16NKj/9BPVm5LBGdUBASLh\n6r77xPr+/QXp+/mRIeMs0IEj1M6f10flMOLjiaxdwS5iKzJS+C7+7//omkVFiRImcvG/hx6i5Rdf\n0PVR1r5nqNakb2xuwdiwQV8VUA43syqf4A5kS18mfZZ3jCnv3LWrLHBm6QP0gLmboKUs/csPZ5Y+\nk75R3mG4svQB6uBldPY+9hgta9cWvig5I7ZnT6GHs7zjLOCBjYf8fOs6RA6HdWVMI5o0sc6izcuj\nAWr4cGFIBQRQD91Jk/SZwuHh4nXz5or0PUW1Jv3Nm0VMe1aW0Lu7dBEJJ0aUNX47JMRM+hER4gaV\nk1duu034G8qCiiR9ZelffrhD+nbyjitNHxASj+xf4kFAduTKYaw9ewqZkuUdJv0+fczH4vh5u65c\nmuYe6Xt5kYPZiC1b6Dqx3t+8OUlG8+ZRoqMcny8nzNWurUjfU1Rr0jeSI1sD3t7WpWeBstXcAejh\n4VkCO8BGjxYzDZn0x46l6pxlSRH39nbdtUpZ+tUL7lr6d91FMoZM+nL9eSOMpL91Ky3l2Hwu6AdQ\n/gI3XJf3y/IOh2W+9JK545ixLy3PJACaZe/dS/e73XPHyM8HnnjC/Pl//0slxblp0YQJVOPniSfo\nOZf7I7/+uni9fLmYsXz7rT60VMEa1Zr027UT2YQy4uP1JVxllDV80+EQ00q2LGbOFGUXZNIPCaFp\nalkcus5qmDPi4ylk1JUVrzT9qgF3HLmNGlEwQKtWetJ31jyG98eRZBxx8+GHYhtjyCY3hJGtcpZ3\n2BEbEyOih6zAuTCMW28Ver6ryp7OSnb7+orksiefJAfwK69QuKtdZFBWljD2br5ZX51WwRrVmvRT\nUkQ7Nlmv/Ogj+2qSZcnK5ebOxph82UEsk76PD3D33ZSA5GkVQHdS7mNjyYJ3NZNQpF814Iz0fXzI\n5yTfr+5mAXOjFrb0b76Z7lE5Wk229AExi/zmG7GO5R2GXQP6Rx8V62WZp0kTMYi4asrubH1REdUN\nYshOX56hyOAeyLLPzlV5EoVqTPpFRRR9MHw4PSRyuFr79q67BtkhNNTsFOOprrPQMCPp9+tHU+LN\nmz07/tKlzq0sgKy/Jk1cz1patRJduBQuHzh6x87SN4YUM+m7k9fRv7/oB8D9aWUYLf2zZ4m0164V\n9zXLOwy7Hspyc3qZvGNi7PV8Z/WujKWWX3iBEivZp/Dss2Kd3KOYERoqMoO5HLkifdeotqTPZDp1\nKj0ccozw7Nn2lSoB4ZC10hYffdTcoOLzz2npTGuXH1wfH3rQx4/33KEbHOyetT9njll3NcLhADp2\n9Oz4ChUPd+QdGewncifSbOlS+zINgCB9nq3m5hLp9+0rssp9fPQzUrvS3nI5Z5n08/PFDPruu/X/\nYzeznjHDPCBwWCiHYrNk5OVlbQgVF5PRB1BRNv5MwTmqLelzrQ6uTcKaX2Qk6YByM2sZCQmUtevl\nZX2DdOggHhAGP3yypW+Uj6KjRZgm190fN46SxqxKNZQX119vnrorVE14SvosG1ZEpVC+RwYNouXZ\ns3R/jxwpghq4mTlACVJ2zlA2pM6f1xtZsrwiN3FxhnvuMZM+N2W57jpazpxJS7nJilzOOStLzKLY\ngFOk7xrVlvTZYXTypIhaAMhSHjQImDvX+v94sIiNBRYsMK8PDRWWlhG5ucKq+u4783p2Un36KclL\nkZE0A+BsYYWrE97eRE7OLHIruOpx6w5Y7mEi5Xt4xAixzcWLogTz4MH6yBx5pjp7Ni2NkTyccfv4\n466lSYbVM8YSDkcA5eWZm8XIDmRADAYcuq1I3zWqLekz9u8H7rxTvD950nmcO3f4CQ+3rkAYEmK2\n9Bl5eSJV3KqNHk9PZ8wAvvqKQs7KIvEoXFmoU4dCED1pIr9+vbnkdlnA8g7PVtnSDw0Vnx08qM8s\nl6Wbn38Wr7lDnJ10Onw4NU5xBf5exrINHBUnB0gYQ1aNPSm4ZwXX8Vchyq5RbtJPSkpCXFwcWrRo\ngTlz5pjWL1q0CO3bt0f79u1x2223Yd++feU9pA779+sjVI4do6QOO6JlyyAx0Xq9Fenz/+TmkhUS\nHm7fO/X++8lqSkwk59ZPP5GcZCwEp3D1oEYNfeVXd9Cjhz44oKzg2QWHAp89Kz4bPZqWu3YJRyiH\nJT//PBk4LFk2aiTKNluRvp8fSS9cD98ZnnySlsYMYA69lInbKAEZHboPPEDLyMirp2preVFu0p8y\nZQrmz5+PFStWYO7cucg2mM9NmzZFUlISkpOTMXjwYDz//PPlPaQOKSmihgijpERfT112iLlKzvL3\nN5M+34Q8NY6Nta9T3rgxNb6oX58yCffvp5mHsvYVLgdY02fSz80V9zfHtO/aJbbnoIVhw2gg4Br5\nZ84IK/7wYf0xatSgAcLPz7oujxH799PMgjtzGUNE5fLJrkj//fdFkxq7qCMFPcpF+mf+EtL69u2L\nmJgYDBo0CBsNFc969uyJwL8EvGHDhmFVBaXMsfW9bx/9yTh+HPjhB/Fejvc1RhdYgR8K1jlZJ+RG\n5i1b2lv6jRsLp3KdOjQ9vu46yh2wi4pQUKgssLzDTmTZ0mfLfccOsf2sWbSMiaHIGyb9s2fFLdTM\nNgAAHfBJREFU82AMQ3Y4KMxSjtRx1qZx2TK9hCQXDywooMbrnFxpjKQzGngANWVJTfVMPruaUa6x\ncfPmzWjVqlXp+/j4eGzYsAHDjN6Wv/Duu+9ihOxBkjCNU/EAJCQkICEhwemxeTq6fz9NN2vUEJ8B\n+hLLchu4hx8WryMizBohIEg/NJQiClirZ0s/PNy+LVxMDN2ADH9/Sg9/9VWaMfC+FBQuBWrUoMxw\ndujm5opGKHwvyqQPULw8l20uLgY6daImKkYLn+FwUMCCHKsvP4syBg8m0ueyCv7++ppBmzdT97l9\n+6gchBykYQeHg863IpolVXUkJiYi0U6bdhOXbEK0YsUKfPLJJ1i3bp3lepn03UFh4f+3d+5hUdX5\nH3+jIrqWqCDC/nDwAnFVwYRBS8QVyFLDwjK3dDMqpadHrXyqLdvKXa3VSmszo1zSUts1q13bUhcf\nHTA3uWy1EpJohuItL4RyLYTv74+P3845M2cGGEaGmfm8nmeeGWYOh+/onM98vp/L+0PG2deXPozD\nhtEWVP7Hnz1LcVHz7eYtt5C4E0ClaS+/DLz1lvJ6U5Ni9Hv0oBi9jBXW1irzbrdt01+XDO+o8fFR\npG4ZprO5+27lsUzkAopnrFawBKhpysuLPuuVlWR8J0+m2bh6tLQA48ZZlz5Rc+utFJKVM3xTU7WV\ncE88QbsGWZ2nHqtojcpK2rV4gtE3d4ift6MLtUMbovj4eHwrA3MASktLkaieJnKFAwcOYP78+di2\nbRv6me/X7KSxkWKI0qNoaNDKKw8YYFkfHxyseOhpaRSmMW9e2rNHa/TV8X3p6Y8bp50GpMbfnyoK\nZAkZw3Ql1GXHEvMqIRkOldOr5M96Jc4AlUH7+VHRgkR9LZozebJSSCFDTJL9+4GMDHr8f/+n39xl\n/jtFRbb/HqOlQ0Zfxurz8/NRUVGB3NxcGI1GzTHHjx9HRkYGNm3ahFD19OMOIo2+7JI9f14pxwRI\nlOzHH7W/c+IEVdE88QTNvAVIzEnN1q3Wjb6M6fv5WR8C7eWljeszTFdC7elL1EV3RqOSEJVGPzDQ\nthDgjTfSzlo2VwHanJf6sj99WinDHDZMX6ZBdtlu3Kg/Cc/8up440frULsaSDqc+Vq9ejXnz5iEl\nJQUPPfQQ/P39kZ2djewrNWpLly5FVVUV5s+fj7i4OCRYE7pvJ9Loy3hgU5O2Q/Xzz/Xr9bOyqLRM\nfkiqq7U64x9/rMQ/u3fX9/Rbg40+01VRJ3Il6vi7Wg/HYKDQiZcXjTm01ix2ww1KF7pk9GjlsbqZ\n6/RpJRl79CigF+2VXntysr6Glvl1/dvfsqZ+e+hwTH/ChAkoKyvTPDdv3rxfHq9btw7r1q3r6J+x\noKFBEZrq1o28b1lG6etL4RX5Yevblz7sAHn7t9+uNfqTJlF8PyiItpRSudPHx9LTb4vRN0/mMkxX\nQV2yKZHXBqDVkFJLi8TEWO+2DQiw7IBX5wnUO4CjRylxvHIlNS+qJ9xJjh2ja2jfPsuBLuPGWX5R\nWKkNYazgskVOjY3kNQwaRMbfx0eJ18t4uyzrlB/qhASqQ/75Z5q+c+kSGX05dOL0aUryStmEyZO1\nAylqatqmd6OXzGWYroCep19RQYa7Tx8l7AlQIlfG1GNilHm15ixYYPmceQOXjMPv2UN5NFn0p9PP\niTfeoPtduyxfk9Px1FjrmWH0cWmjf+4c6d1ERmqNrDWd+RdfBJ5+mso2o6Koc7e6Wru9lUNZAgOp\nakF9EbTV02ejz3RV9Dz9o0fJcIaHaz/fMqYP2Db606aRM/XBB9avj+RkJYz6wAOK9683BEmOU9TT\nz9Iz+lITyBwhqGN33z791z0Vlzb6AG33RoxQnjcYrBv9fv2oBPP0aYoB/u9/ZPRV0SisX0+JJ736\nffb0GVemuZlCnuYa+0ePUtmleSglOJiMc0sLEB1tmUCVrFgB3Hkn7Z5jY5Xnzefz3n47PU5PV8I6\n6nm56q51IfQbIKOjLZ976SWtgFtxMbBpE4VpX3/dupaWp+IWRl9++/v50YdFT2ph/XraUnp705by\nxx+pPGzpUss6ZSnhYK6f3x5PnxO5TFejtpYMsXnnqpQ2MB/m0qsXNT398APdq+ffygEnBQVKH0tl\npZLANRioP0B64RMm0E3KRUupBXW8f+5c5bHUKjKfuSu1geT6JOoS6bNnqS/m4Ydp3XpfFJ6MSxt9\nHx+KD0oxs7Fj6V4vkx8fT3X7LS1U4hUQQIMX0tLISEuEIK8F0LaKt7RQpZC5l6THwIF0bGsDzhmm\nM9Er1wSUBK250Qe0IZ7XX1c+/wMG0GN1lc7lyzScBQBeeIE07qUq7eDBFCI6cwbIyVH0sGT8HlCu\nTYCq7ADtlwKg7Wj/6CP6QjJn8GDaaSck0O6F5Rm0uOw/R2MjlV56e1NbN0AGWypuyuk7kowM8jJ8\nfCheL3cDRiPJ3kq+/15J3qqTTPX1NGiiLR8gLy+qPmBvn+lK6CVxAfrMDxli6VUD2mTu9OlKL4yP\nDzlZapGzl15SQjhGI02AkzNvT56kHUFiIhl0qY6pdox69FAmYAH6a1Ub/VtuUSQl1Eh9rbAw24PY\nPRWXNfqxscCiRdoO2lOnKEbfty/FCmW9fXAwUFZGsf76evLg5YexsFA5LjlZeTx4sFazp63xfAnH\n9Zmuhl4SF6Cwzw03UP17WRldU++/D6xeTY6LuitWhlRuvFE7bMUc6XzJzlvZuC+NtNTeef99uo+M\npPuXX1bOoTcgXi1RnpSkP7e6qIje58aNys6DUXBZMdLYWLpNnkyjETMzyZh7e1N4pbqatpBff00J\nocpKMuTe3lSPHxREzSa7dytxwk2blA/aV19p1Tvb2pgl4bg+09W4dImqdJYsoTCLOjSyaRPJKAQG\n0vUQGEi3jAxKvEqk0Y+JsZxqpUYIuuXlkcjaoUNASorSmCUTr+vW0fU6cSJ94axerZxDT1FTXdf/\n61+ToJyfn2XxRlgYibWpw08M4bJGH6Dqm5ISEmySWzq5/bxwgRK3JSUUllEnfSQJCWTMn3mGflZ7\n8n5+So4AUCQY2gp7+kxXIyKCdPJ9fCj8MmgQfQEkJlLFi4y/22L+fKV50RYtLeTd9+6tGP3mZiqT\nBpQy6ZISYOFCMuA+PnS8uTSKmvfeUx7LL4577lEkoSXyC41VbS1xaaO/ciV9YNQJV19f8mik0W9u\nBmbM0BdkGjmSvAmpD24rSdteTz8kRFHzZJiugMFgWdN++TKFNc2FB62RlaUkWW0hvfzkZMqlbd9O\nQ1ikDo+85qSEQ48epInVr5+yK28N2XSp59CpNfolP/9M63LERDJXxmVj+seO0Qdpzhxq8Jg0iZ4/\ndIj+Yy9cUOqOFy3SP8fIkSTHID/EtsattbVcE6AviJ9+Yk+f6fr06EExfEdXuLS0kNGXZZqHDtEA\n9fvvp+vy88/puNtuo/i7zKWdPaudeWELqcGjV6Ld0qKcU2I0WvYieCIu6+mvXk0hnRUryEu55x7S\nCZGGuaqKRNgmT7Zep3vddeRV9OxJM0FtYZ7Ira9XRjWWl9O9vNXUkEdz002Oea8M42q0tFASd9ky\n2vWePUs/v/sukJurOFrqvED37pQcHjVKW0RhDRnHtzYCVa26C1B+Ty2u6Km4pNGvqqK44htvkMRx\nSYkyteeNN0iQ6fx58ixeecX6eby9KQSUl6ftytWjtpa2pBMnkmG/cIGkYcPC6DZ2LO06wsIoPunl\n5bj3yzCuxqFDdH0NHUrXwvDhlDu49loK6UhDra6+mTCBiitkhZG6R0DN9ddTklYafb1afYD+xtGj\nJB8hq3hkSakn45JGf+1aqgR4+ml67OenJH98fMiQr1lDHnxKiu1zjRpFXyD+/raPS0uj+GdoKBn2\n4GDb4SCG8WT27CEjLp2fBx9UrkW1Nr+6Tr9vX+qslRU6aoOfkqIIsMnyTxnesZY7GziQlDx//lnR\n0JJa/Z6My8X0Gxupaer8efIYZDmZNPolJfQlUF5Ou4DWPG45Fag1o28wUOVCSgptV9ngM4x1TCZK\n4koWLFDkUnbuVJ5XG31fX/LO337b8nyjRimP6+rIoNfVkSNmjeHDqWu3okJJHKu77z0VlzP6775L\nW8Lycm2ZVnU1NXiUlCjbPdkAYou2Gn2GYdrOwYPW4+fvvUfd9IBWy79vX7q++/Qhp0rm5/Q6b319\nqdJH6gbp5c9k6KiigoYjASzJALiY0W9uplbvujryBvr3V16rrqaW65ISpZW7LaVZbPQZ5upgPstW\nCBqMvmWLUjpqHt7Zv592BU89pbx28aK+wmdLi6LhM2WK5ev//S/de3tTExhDuJTR/+c/KYmamakd\n6waQ0Y+PVyST29pIFRAAPPccD1ZmGEdy3XWWodWPPwY++YQey05Z9dA9aeSfeYYk0CXffad49JIj\nR7RjE6113vbrR18Yly4pCp+ejssYfSGoPHPwYK0+h6S6WvHWhw5t3zbu2Wc5Rs8wjsRc8+byZfLe\nJS++SPdSLBEgpw6grlx11V11taX8uTl6wmuAVr/ntttsn8NT6LDRz8/PR2RkJMLCwvAXvdlnAH7/\n+99j2LBhuP766/GtTL23k88/J+3unBztwARJdbUSzrn9dqqjb2qy608xDGMnckTp7Nna5995h6po\n/P2pjPL11+l5KccgBDVcyiFI6nBMSIgSqtEjKMi6zpX6+dTU9r0Xd6XDRn/hwoXIzs7Grl27sGbN\nGpw3G1hZWFiIvXv3ori4GIsXL8bixYvt+jsrVlBDh7USzOpqEowCyKvo31+7/WMY5upTUUHetVrS\nuL6eQqgjR9KsiqFDqWlLjZxvHRlJ8X51vk5PUkFNdLSimmuOurpHPe/ak+mQ0b94ZVxNUlISQkJC\nkJaWhoKCAs0xBQUFmDFjBgYMGIBZs2ahTB3EawepqdrRauZUV5NS4OLFlMwdMMD62ESGYa4OslRT\nHc9/7TWacHfzzYpMinqGRU0N7QSmTqVGqtdeUwa7yNcB6+JpUVFa/S016t2+tRCQp9Gh5qyioiJE\nyLH2AKKiorB//35MUaXSCwsLMVu11xs4cCC+++47DDdL7T/33HO/PE5OTkayusgXlNG3RXU1bQMX\nLSJZhrAw9vQZprORejuSqirKwe3bRx3sf/kLsG0b9ddkZ1Mn/O7dwIcfAps3KwUa06cD//iHcp4l\nS4A//YkemyvYRkdTk2ZruEOXvMlkgkkOKbCTq96RK4SAkIG+K3jp/OurjX57aW6msq7HHiMJhMuX\n6caePsN0LiYTjUmUvPACqdzK0spVqyhMO3kyden260eyKYmJFM+X7NmjPe+4ccrjP/6RcgZTp1KX\n7k03WRdVVCOE6xt+c4f4+eefb/c5OhTeiY+P1yRmS0tLkZiYqDnGaDTioCr1fu7cOQwbNqwjf9aC\nlhbyHGbOpP/UESMoDshGn2E6j4oK6piXpZHHj1PhhRyiDlCYNipKaay8805K0t57rzZ5u3mz0oXb\nvTvw978rr8m5uWPGUFf+jz8qk7psYZZu9Fg6ZPR9r5TR5Ofno6KiArm5uTBKkYsrGI1GfPjhh7hw\n4QI2b96MSDkXzYF4e9NWUFbvjBgBnD7NRp9hOhMZ2vHyIq/6kUeo3j4oSHvcyy9Tfu7MGaqu+fpr\n6sJdtYpev3CBunBlQ1ZEhHZwi6z8OXmSjv36a5Iyt8Xo0Sx1LulweGf16tWYN28empqasGDBAvj7\n+yM7OxsAMG/ePCQkJODGG2/EmDFjMGDAAGzcuLHDi26NESMo5MMxfYbpPNTx/C1bSBht0ybL48LC\ngLlzSTBxyBAKxaqF0GTCVupplZaSjtYrr1BVkFTUPXyYrnGZxE1MpI5ePWQeID6+g2/SHRBdAEcv\nY98+mtD5wAMOPS3DMDYYNkyIb74R4ocfhBg0SIiCAuvHVlcLERgoRM+eQsycKUTfvkJs3SpEUJAQ\nJ04IcfmynLIrxOOPC7F9Oz2+6y7leUCIPn2ESEqix489pn1NfXv0USFWrOi8f4vOwh7b6TIdue1B\nDmbg8A7DdA6VlVRaGRUFPPQQxegTEqwf7+tLCdmYGOD996kzNyNDkVdWz8ldtoxKPQFK+qqpqwPy\n8+mxqpDQgqFDObwjcUuj37cvlW+y0WeYziEvj6QXPviAwjFtKcabO5cSsFu20BAiQJlxLeP5K1fS\nSMeSEvpZb6gKAEybZvtvqRU5PR23NPoAxfU5ps8wnYPJRF7+ggXA+vX6w8rN6d6dqngefxxoaKDn\n+vbVGn05SP2bb2yfKynJUj/LaKQ5uePHk04/e/qEWxt99vQZpnPIyyMv/3e/U6ZUtYWkJDr+pZfo\nZ19frZSy7OGUnn5AAN0PHAjcfbdynvHjyZtX88wzlMAdO5aq+SoqFG0gT8btjT7/JzPM1eXkSZI6\nBgA7eoWwYgWwejVJMJh7+rKlp76e7uVs3d69qUtXMnq0pdFvaqLfT0ykkNOvfgWcO9f+9bkbbm30\nf/pJ2TYyDHN1yMsjKfN33mlbWMecIUOoS/fJJ7VGPyiI6vfVjtvIkRTjF4ISt598AkyaRGWeapE2\ngEJCQ4cqpZwhIRziAdzY6IeH0weBQzwMc3U5dIji8mbN+O3iyScpL3DwoBLekaEdOf4UoF2BWiM/\nP1/R7jc3+l9+SZ5+UBB9mTQ1sdEH3Njoe3tTwwcPR2GYq8uzzwLLl3fsHNdcQzo9ubmKpy+NvlR6\nSUkB0tKAQYMU73/vXpJiAJTwTr9+JNH81Vfk6QMU1z9zho0+4MZGHwA++ogE2BiGuXp06+YYIbO7\n76bafmn0ZeWONPorVtDfkclcgLp5b76ZrvNJk+i57t3J8FdUKDmBxESK53PZppsbfYZhXIdu3Uh0\nbepUMubR0fT8kSPAPfeQZDqgNfpFRZTkLSwE1qyh5558UpmuJz19GXpiT78TpJUZhmHayogRdJsy\nhRK2ANX+q0ekBgRok7s9etCAFDkkJSZGmaJ3zTV0HxdHgoxs9NnTZximC+LtrYSMDAat0R80yPrv\n7d9P8s3mjZk9eypKm55exs1Gn2EYl8Lc01djNFJMX9b5q0lMJL1/WevvqbDRZxjGpVDH9K2hJ8Ei\n9X08PcTDRp9hGJfCVnhHUldn+Rwncwk2+gzDuBQhIUBsbOvHmTdrBQdTaaenl22y0WcYxqXo31+p\nzrGFnLEr8fKiEA97+gzDMG6EnJcrm7XUJCay0WejzzCMW3HsGN1HRVm+xka/A0a/pqYG6enpMBgM\nmD59Ompray2OqaysxMSJExEdHY3k5GRs3ry5Q4tlGIZpDRmzv+46y9fi44EHH+zc9XQ17Db6a9eu\nhcFgwOHDhxEcHIw333zT4hhvb2+sWrUKpaWl2Lp1K5YsWYKampoOLZhhGMYW5eV0L7V71Pj4AI8+\n2rnr6WrYbfQLCwuRmZkJHx8f3HfffSgoKLA4JjAwELFX0uz+/v6Ijo5GcXGx/atlGIZphd276d4e\nbX9PwG7tnaKiIkRcGT8fERGBwsJCm8cfOXIEpaWlSEhI0H39OdUk5eTkZCQnJ9u7NIZhPJgdO5y9\ngquHyWSCyWTq0Dm8hLCuRJGamoozZ85YPL9s2TI8/PDDKC8vR69evVBfX4/IyEgckxkUM2pqapCc\nnIw//OEPSE9Pt1yElxdsLINhGKbNeHmRRLNO8MHtsMd22vT0c3Nzrb62YcMGlJWVIS4uDmVlZYiP\nj9c9rqmpCRkZGZg9e7auwWcYhnE0kyc7ewVdF7tj+kajETk5OWhoaEBOTg4SdWalCSGQmZmJmJgY\nLFq0qEMLZRiGaQ0ptDZunHPX0ZWx2+hnZWXh+PHjCA8Px8mTJzF//nwAwKlTpzBlyhQAwL59+7Bx\n40bs3r0bcXFxiIuLww53DrgxDONUZLlmeLhz19GVsRnT77RFcEyfYRgHsGEDcO+9NHnLE+Zj22M7\nuSOXYRi34d//pntPMPj2wp4+wzBug58fael7ijlhT59hGI+mqopm7DLWYaPPMIxbweWatmGjzzCM\nW9DcTPdpac5dR1eHjT7DMG7ByZN0bz48hdHCRp9hGLdAyn/5+zt3HV0dNvoMw7gFO3fSvZeXc9fR\n1eGSTYZh3ILBg4ETJzynXBPgkk2GYTyYEyeA4cOdvYquDxt9hmHcBi7XbB02+gzDuA033+zsFXR9\nOKbPMIzLU1sLXHstcOkS3XsKHNNnGMYjyc+ne08y+PbCRp9hGJdHlmsyrcNGn2EYlyckhObiMq3D\nMX2GYRgXhWP6DMMwjE3Y6HcCJpPJ2Uu4arjzewP4/bk67v7+7MFuo19TU4P09HQYDAZMnz4dtbW1\nVo9tbm5GXFwcpk2bZu+fc2nc+YPnzu8N4Pfn6rj7+7MHu43+2rVrYTAYcPjwYQQHB+PNN9+0euyr\nr76KqKgoeLESEsMwjFOx2+gXFhYiMzMTPj4+uO+++1BQUKB73IkTJ/DZZ5/h/vvv52QtwzCMsxF2\nYjAYRENDgxBCiLq6OmEwGHSPmzFjhvjyyy+FyWQSU6dO1T0GAN/4xje+8c2OW3vpARukpqbizJkz\nFs8vW7asTV77v/71LwQEBCAuLs5mbK0t52IYhmE6jk2jn5uba/W1DRs2oKysDHFxcSgrK0N8fLzF\nMf/5z3+wbds2fPbZZ2hsbMSlS5cwZ84cvPvuux1fOcMwDNNu7I7pG41G5OTkoKGhATk5OUhMTLQ4\nZvny5aisrMT333+Pv/3tb/jNb37DBp9hGMaJ2G30s7KycPz4cYSHh+PkyZOYP38+AODUqVOYMmWK\n7u9w9Q7DMIyTaXcWwMHk5eWJiIgIERoaKl577TVnL8ehHD9+XCQnJ4uoqCgxYcIEsWnTJmcvyeFc\nvnxZxMbGWk3SuzK1tbVizpw5IiwsTERGRoovvvjC2UtyKG+99ZYYO3asGD16tFi4cKGzl9Nh5s6d\nKwICAkRMTMwvz126dEnceuutYvDgwSI9PV3U1NQ4cYUdQ+/9LV68WERERIi4uDixcOFCUV9f3+p5\nnN6Ru3DhQmRnZ2PXrl1Ys2YNzp8/7+wlOQxvb2+sWrUKpaWl2Lp1K5YsWYKamhpnL8uhuHMPxrPP\nPguDwYADBw7gwIEDiIyMdPaSHEZVVRWWL1+O3NxcFBUVoby8HDtdXKpy7ty52LFjh+a59vQTdXX0\n3l9aWhpKS0tRXFyMuro6bN68udXzONXoX7x4EQCQlJSEkJAQpKWlWa33d0UCAwMRGxsLAPD390d0\ndDSKi4udvCrH4e49GLt27cJTTz2FXr16oUePHvD19XX2khxG7969IYTAxYsX0dDQgPr6evTv39/Z\ny+oQ48ePt3gPbe0ncgX03l9qaiq6deuGbt264aabbkJeXl6r53Gq0S8qKkJERMQvP0dFRWH//v1O\nXNHV48iRIygtLUWCG+m/PvLII1i5ciW6dXP6htHhnDhxAo2NjcjKyoLRaMSf//xnNDY2OntZDqN3\n795Yu3YthgwZgsDAQNxwww1u9dmUqG1MREQECgsLnbyiq8fbb7/dJqkb97tauyA1NTWYOXMmVq1a\nhT59+jh7OQ5B3YPhjl5+Y2MjysvLkZGRAZPJhNLSUmzZssXZy3IY586dQ1ZWFg4ePIiKigp88cUX\n+PTTT529LIfjjp9NPZYuXYprr70Wd9xxR6vHOtXox8fH49tvv/3l59LSUt3ST1emqakJGRkZmD17\nNtLT0529HIchezCGDh2KWbNmYffu3ZgzZ46zl+UwQkNDER4ejmnTpqF3796YNWsWtm/f7uxlOYzC\nwkIkJiYiNDQUfn5+uOOOO5AvZw66EfHx8SgrKwMAq/1Ers769euxc+dObNy4sU3HO9Xoyxhpfn4+\nKioqkJubC6PR6MwlORQhBDIzMxETE4NFixY5ezkOxRN6MMLCwlBQUICWlhZ8+umnSElJcfaSHMb4\n8eNRXFyMqqoq/PTTT9i+fTvS0tKcvSyH05Z+Ildmx44dWLlyJbZt24ZevXq17ZeuUnVRmzGZTCIi\nIkIMHz5cvPrqq85ejkPZu3ev8PLyEqNGjRKxsbEiNjZWbN++3dnLcjgmk0lMmzbN2ctwOIcOHRJG\no1GMGjVKPPbYY6K2ttbZS3Io77zzjkhKShJjxowRS5YsEc3Nzc5eUoe46667RFBQkOjZs6cIDg4W\nOTk5blWyKd+ft7e3CA4OFn/9619FaGioMBgMv9iXrKysVs/TJcYlMgzDMJ0DJ3IZhmE8CDb6DMMw\nHgQbfYZhGA+CjT7DMIwHwUafYRjGg2CjzzAM40H8P/v9hiKZU6MaAAAAAElFTkSuQmCC\n"
}
],
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h3>Now it's time for the numerical code for all of those summations that we computed symbolically above.</h3>\n",
"First we have to define what $t_i$ and $d_i$ are... \n",
"\n",
"We used $d_i$ to represent each of our drawing data points in sequence, but you might be confused on how we are going to use (x,y) points for each $d_i$. The answer is that we will compute only for x and then we will repeat the process only for y. This should give us the x portion of the control points and then the y portion of the control points. Note that x and y are orthogonal and so they are independant of each other, so we can get away with calculating them independantly.\n",
"\n",
"For $t_i$, just imagine that someone is drawing the curve starting at one position and ending at another position in one continuous line. For this case we will assume it was drawn from the left and was finished on the right. $t_i$ is simply the time at which each data point was drawn. Remember that $t_i$ needs to go from 0 to 1 for the bezier equation to work. So, we assume that it took 1 second to draw the entire curve and each data point is drawn at the same relative speed. Of course time actually has nothing to do with anything, it's just a mental model of tying a $t_i$ to a $d_i$."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# we already have out d_i's in xs and ys from above\n",
"# make a t_i list\n",
"ts = arange(0.0, 1.0, 1.0/len(points))\n",
"\n",
"# make the summation functions for A (16 of them)\n",
"A_fns = [None for i in range(16)]\n",
"A_fns[0] = lambda time_list, data_list : sum([2*(t_i - 1)**6 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[1] = lambda time_list, data_list : sum([-6*t_i*(t_i - 1)**5 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[2] = lambda time_list, data_list : sum([6*t_i**2*(t_i - 1)**4 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[3] = lambda time_list, data_list : sum([-2*t_i**3*(t_i - 1)**3 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[4] = lambda time_list, data_list : sum([-6*t_i*(t_i - 1)**5 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[5] = lambda time_list, data_list : sum([18*t_i**2*(t_i - 1)**4 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[6] = lambda time_list, data_list : sum([-18*t_i**3*(t_i - 1)**3 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[7] = lambda time_list, data_list : sum([6*t_i**4*(t_i - 1)**2 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[8] = lambda time_list, data_list : sum([6*t_i**2*(t_i - 1)**4 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[9] = lambda time_list, data_list : sum([-18*t_i**3*(t_i - 1)**3 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[10] = lambda time_list, data_list : sum([18*t_i**4*(t_i - 1)**2 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[11] = lambda time_list, data_list : sum([-6*t_i**5*(t_i - 1) for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[12] = lambda time_list, data_list : sum([-2*t_i**3*(t_i - 1)**3 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[13] = lambda time_list, data_list : sum([6*t_i**4*(t_i - 1)**2 for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[14] = lambda time_list, data_list : sum([-6*t_i**5*(t_i - 1) for t_i, d_i in zip(time_list, data_list)])\n",
"A_fns[15] = lambda time_list, data_list : sum([2*t_i**6 for t_i, d_i in zip(time_list, data_list)])\n",
" \n",
"# make the summation functions for b (4 of them)\n",
"b_fns = [None for i in range(4)]\n",
"b_fns[0] = lambda time_list, data_list : -1.0 * sum([2*d_i*(t_i - 1)**3 for t_i, d_i in zip(time_list, data_list)])\n",
"b_fns[1] = lambda time_list, data_list : -1.0 * sum([-6*d_i*t_i*(t_i - 1)**2 for t_i, d_i in zip(time_list, data_list)])\n",
"b_fns[2] = lambda time_list, data_list : -1.0 * sum([6*d_i*t_i**2*(t_i - 1) for t_i, d_i in zip(time_list, data_list)])\n",
"b_fns[3] = lambda time_list, data_list : -1.0 * sum([-2*d_i*t_i**3 for t_i, d_i in zip(time_list, data_list)])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 20
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From the generated 'hand drawn data' create a function to fill the A and b matrices using the summation functions we just defined and then solve for the unknowns. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def solve_for_cs(time_series, data_series):\n",
" \"\"\"\n",
" Take an input series of t_i values and the corresponding d_i values,\n",
" compute the summation values that should go into the matrices and\n",
" solve for the 4 unknown variables.\n",
"\n",
" Parameters: time_series -- t_i in increasing values\n",
" data_series -- d_i corresponding to each t_i\n",
"\n",
" Returns: solution -- matrix containing the 4 solutions from solving the linear equations\n",
" \"\"\"\n",
" # compute the data we will put into matrix A\n",
" A_values = []\n",
" for fn in A_fns:\n",
" A_values.append(fn(time_series, data_series))\n",
" # fill the A matrix with data\n",
" A_numerical = Matrix(4,4, A_values)\n",
"\n",
" # compute the data we will put into the b vector\n",
" b_values = []\n",
" for fn in b_fns:\n",
" b_values.append(fn(time_series, data_series))\n",
" # fill the b vector with data\n",
" b_numerical = Matrix(4,1, b_values)\n",
"\n",
" # solve for the unknowns in vector x\n",
" x_numerical = A_numerical.inv() * b_numerical\n",
" #print 'A = \\n', A_numerical\n",
" #print 'b = \\n', b_numerical\n",
" #print 'x = \\n', x_numerical\n",
" return x_numerical"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now solve for the 'best fit' solution.\n",
"We will start with the x data from the (x,y) data points and then the y data."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# solve for the best fit in the x dimension\n",
"x_solutions = solve_for_cs(time_series=ts, data_series=xs)\n",
"# solve for the best fit in the y dimension\n",
"y_solutions = solve_for_cs(time_series=ts, data_series=ys)\n",
"\n",
"# place the solutions into control points\n",
"best_fit_control_pts = [(x,y) for x,y in zip(x_solutions, y_solutions)]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 22
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>Now for the test... did it all work?</h2>\n",
"Use the best fit control points to create the best fit bezier curve over top of the 'hand drawn' curve."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# create a list of 1000 x,y points that traces over the length of our best fit curve\n",
"best_fit_points = [numerical_cubic_bezier_fn(control_pts=best_fit_control_pts, t=t) for t in arange(0.0,1.0,1./1000)]\n",
"# separate the x's and y's so matplotlib can plot them\n",
"best_fit_xs = [x for x,y in best_fit_points]\n",
"best_fit_ys = [y for x,y in best_fit_points]\n",
"\n",
"# plot the original noisy curve\n",
"plot(xs, ys, 'b-')\n",
"hold(True)\n",
"# plot the best fit curve over top\n",
"plot(best_fit_xs, best_fit_ys, 'r-')\n",
"hold(False)\n",
"t=title('best fit cubic bezier curve')\n",
"\n",
"# just for comparisons sake, print the 'clean' control points and then print the best \n",
"# fit control points taken from the noisy data\n",
"print 'Clean Control Points = ',\n",
"print [p0, p1, p2, p3]\n",
"print 'Best Fit Control Points = '\n",
"print best_fit_control_pts"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Clean Control Points = [(0.7, 0.2), (2.3, 1.0), (7.2, 0.8), (10.0, 0.0)]\n",
"Best Fit Control Points = \n",
"[(0.680235809341125, 0.199169722342596), (2.30586285000266, 1.03398096289025), (7.22739062250292, 0.753866347077646), (9.99219893606198, 0.00672263149211805)]\n"
]
},
{
"output_type": "display_data",
"png": "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\n"
}
],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 23
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment