{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Numpy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[http://www.numpy.org/](http://www.numpy.org/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Errors" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.3333333333333333\n", "1000000000000000000000000000000\n", "3.333333333333333e+29\n", "333333333333333316505293553664.000000\n" ] } ], "source": [ "x = 1.0 / 3.0\n", "print(x)\n", "\n", "y = 10**30\n", "print(y)\n", "\n", "print(x * y)\n", "print('{0:f}'.format(x * y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basics" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3, 4])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([1,2,3,4])\n", "x" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3, 4],\n", " [5, 6, 7, 8]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([[1,2,3,4], [5,6,7,8]])\n", "x" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 1., 1.],\n", " [1., 1., 1.]])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.ones([2,3])\n", "x" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 0., 0.],\n", " [0., 0., 0.]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.zeros([2,3])\n", "x" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1. 2.]\n", " [3. 4.]]\n", "[[5. 6.]\n", " [7. 8.]]\n" ] } ], "source": [ "x = np.array([[1.0, 2.0], [3.0, 4.0]])\n", "y = np.array([[5.0, 6.0], [7.0, 8.0]])\n", "\n", "print(x)\n", "print(y)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 6. 8.]\n", " [10. 12.]]\n" ] } ], "source": [ "print(x + y)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[-4. -4.]\n", " [-4. -4.]]\n" ] } ], "source": [ "print(x - y)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 5. 12.]\n", " [21. 32.]]\n" ] } ], "source": [ "print(x * y)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[19. 22.]\n", " [43. 50.]]\n" ] } ], "source": [ "print(np.matmul(x, y))" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 1. 4.]\n", " [ 9. 16.]]\n" ] } ], "source": [ "print(x**2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Types" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('int32')" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([[1, 2], [3, 4]])\n", "x.dtype" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('float64')" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([[1.0, 2.0], [3.0, 4.0]])\n", "x.dtype" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('float64')" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([[1, 2], [3.0, 4.0]])\n", "x.dtype" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ True False]\n", " [False True]]\n" ] }, { "data": { "text/plain": [ "dtype('bool')" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([[True, False],[False, True]])\n", "print(x)\n", "x.dtype" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 0],\n", " [0, 1]])" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.astype(int)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Slicing" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2,\n", " 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3, 2.4, 2.5,\n", " 2.6, 2.7, 2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8,\n", " 3.9, 4. , 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5. , 5.1,\n", " 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6. , 6.1, 6.2, 6.3, 6.4,\n", " 6.5, 6.6, 6.7, 6.8, 6.9, 7. , 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7,\n", " 7.8, 7.9, 8. , 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9. ,\n", " 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.arange(0.0, 10.0, 0.1)\n", "x" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(100,)" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.shape" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],\n", " [1. , 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9],\n", " [2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9],\n", " [3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9],\n", " [4. , 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9],\n", " [5. , 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9],\n", " [6. , 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9],\n", " [7. , 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9],\n", " [8. , 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9],\n", " [9. , 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9]])" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = x.reshape([10, 10])\n", "x" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[0]" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:,0]" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.3000000000000003" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[2,3]" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[4.1, 4.2, 4.3],\n", " [5.1, 5.2, 5.3],\n", " [6.1, 6.2, 6.3],\n", " [7.1, 7.2, 7.3]])" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[4:8,1:4]" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1. 2.]\n", " [3. 4.]]\n", "[[5. 6.]\n", " [7. 8.]]\n" ] } ], "source": [ "x = np.array([[1.0, 2.0], [3.0, 4.0]])\n", "y = np.array([[5.0, 6.0], [7.0, 8.0]])\n", "\n", "print(x)\n", "print(y)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 2.],\n", " [3., 4.],\n", " [5., 6.],\n", " [7., 8.]])" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.vstack([x, y])" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 2., 5., 6.],\n", " [3., 4., 7., 8.]])" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.hstack([x, y])" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1. 2.]\n", "[[5. 6.]\n", " [7. 8.]]\n" ] } ], "source": [ "x = np.array([1.0, 2.0])\n", "y = np.array([[5.0, 6.0], [7.0, 8.0]])\n", "\n", "print(x)\n", "print(y)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 2.],\n", " [5., 6.],\n", " [7., 8.]])" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.vstack([x,y])" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "all the input arrays must have same number of dimensions", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhstack\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;32m~\\Anaconda3\\lib\\site-packages\\numpy\\core\\shape_base.py\u001b[0m in \u001b[0;36mhstack\u001b[1;34m(tup)\u001b[0m\n\u001b[0;32m 284\u001b[0m \u001b[1;31m# As a special case, dimension 0 of 1-dimensional arrays is \"horizontal\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 285\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0marrs\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0marrs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 286\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_nx\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0marrs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 287\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 288\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0m_nx\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0marrs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mValueError\u001b[0m: all the input arrays must have same number of dimensions" ] } ], "source": [ "np.hstack([x,y])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tutorial" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[https://docs.scipy.org/doc/numpy/user/quickstart.html](https://docs.scipy.org/doc/numpy/user/quickstart.html)" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 132, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQsAAAD8CAYAAABgtYFHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJztvX90W+WZ7/t5ZUmJIzmOA7EdQ10S4wCBAA0uP0rSekrbQCad0jOHmrbrlmTlhgboXZzTOXcKc7Nup2tlTpk5c9rLrLZAct2E3sUtpj9up5NJSymD24S2QAgkgaTEcUJd4tjmh+NYioOl6L1/7B/ekvVjS9qS9pbez1patra2pHdL2t/9PM/7vM8jpJQoFApFLnyVHoBCofAGSiwUCoUtlFgoFApbKLFQKBS2UGKhUChsocRCoVDYomRiIYS4VQjxhhDimBDigVK9j0KhKA+iFHkWQog64CjwSeAt4CXg81LKw46/mUKhKAulsiyuB45JKY9LKaeBJ4HPlOi9FApFGfCX6HUvAv5suf8WcEOmnYNijpxLqERDUSgUAJOMvyOlXFTo80slFiLNtiR/RwhxN3A3wFzmcYO4pURDUSgUAL+WP/5TMc8vlRvyFvABy/2LgWHrDlLKbVLKLillV4A5JRqGQqFwilKJxUtApxBiiRAiCNwJ/LxE76VQKMpASdwQKWVcCPEV4GmgDvi+lPL1UryXQqEoD6WKWSCl3A3sLtXrKxSK8qIyOBWOU9fURF1TU6WHoXCYklkWCu/i1Ile7OucHx93ZBwKZ1BiUaN44cqfbYxKSMqPEosqxwuiUAiZjkuJSOlQYlFlVKs42CX1+JV4OIcSCw9T68JgByUezqFmQzyKEorCUJ9b4SjLwkOoH7ozKGujMJRYuBglDuXB+jkr4ciMEgsXokSicijhyIwSC5egBMJ9GN+JEg0NJRYVRolEdkRTY0HPk+MTjo1BWRsaSiwqiBKK2RQqDtlex2nhqFXBUGJRZpRAJOOUOOTzHsWKR626J0osyoQSiRkKFYjzTfbqtNaNR/N6/0LFo9bcEyUWJUaJRPHWgyES0fYwAMGJuPlYYOJcxv1ziUbq+IqxOGrB2lBiUSKUSDgnEgCxxrmML6sj2hGjeU+QYCQBQOSi+TQdPpP1+fmKBhRnbVSrYCixcBglEs7EIVKFAqDp6HlCw37eu22KOQfmEQtL5p0SRNvDBCfiaa0M62vZFQ0oztqoVvekqLUhQog3hRCHhBCvCiH26dsWCiGeEUIM6H9r5uypdaEQTY2OC0UqwUiCOQfm8Z27H+WxLzxGcHKmw4QhKk5SjgCsVyiqfaEQ4k2gS0r5jmXbPwHvSSkf0nucNkkpv5btdeaLhdLrfUNqWSicPKHSCYUhAtONmiE8HfZxepn22IKjmC5JrlgG5GddWCl2BsUNFsav5Y9fllJ2Ffr8Uqw6/QzwuP7/48DtJXgP11Dr9SZLLRRWrGIAEA9LphsE0+HZP+NY49ykm933yESxVlM1/E6KjVlI4FdCCAk8JqXcBrRIKU8BSClPCSGaix2kG/H6F18MpTDNCzmJfS3nOMNc/BHBgqM+wD9LUAwMwQhMnON8U6hgC6PYmRMvz5oUa1ncLKVcCdwG3CeE+KjdJwoh7hZC7BNC7IvxfpHDKC9KKJwlH6EwxCAQEWy/4QcM9jwKQLRNszCmG/0Zb8fv9JmiUaiFYVDs5+DF31BRloWUclj/OyaE+P/QuqePCiEW61bFYmAsw3O3AdtAi1kUM45y4cUv2CkqFehLDVoacYvgze+y6YUv0RCeItExpV9u5sGwdv0z4hjm88I+/OH3mW6cA8wt2sIA7TMpNjfDSxZGwZaFECIkhGgw/gc+BbyG1qbwLn23u4B/LXaQbkAJRWko5AofjCSIHliIb7Ce8ZH5rFo6SEN4Kmmf6bAv6RZtE/gG6834hrIw8qcYN6QF2CuEOAC8CPy7lPKXwEPAJ4UQA8An9fuexktfqJM4NRWaiXxPVOtsyLxTgnmnBMFRP3uPd7C2/TDfuftRLeCp3z75N3uJtglOL4P3rzlLPCx54R8fcfw4akUwCnZDpJTHgWvSbH8X8PY8qI5XvsRSUGq3o9grenBSmwkJRATRSIBPNLzO42/fzNnFkkBEEAtLdg8t5zt3P0p3fYI1R9Yxtred1fd9mSBa3CPW6Iw7As64JODuwKcq2JsBJRSlw65QWOMVhlWRSmASfNE6Njy7kVWNAyQ6poh2xHhjo2ZBbHh2Ix19mzn5q/akBK5Cx5QNJz43N//uVLp3Gtz8hZUSL2YrxhrAHxEQ8fPQK7cy0L2TLWMr6Oxfj2+wnlBEEJjULJHUoCfMWBeAKywMcK+VoSwLC9WQOFMIpY5NWHHSqkglHgkA0Hf4OhKjcwlERMnGlw2nPku3/RaVWCjKRiEnYqpQpMvWNFjWcQpg1sxIrtdMxU2C4SaUWOi4TcXLgRstCsi8IMwqFNMNglgDxMJSS/tuibO980kAfnZtr/Y64cwxCq8IhpusXSUW1K5QlItChcJ6QqcTiqnWBG9sfITGjnGaWs/wTPRSADYN3EkidJ54WBLtiKV9jUzvWei4M1FNLknNBzjd8CWUGy8JxXTYx3RDcuzBEAoj1Xt/Vx/9Uz6667UA5tNX7GJDaDU72vfQ2b+eWEOA4CTm6xmBzunGzGtJUsdfyUxPg0pnfNasZeEm865clNPtAOeE4i/v3sPZxVJzOxpm3IvO/vVsGFoNYAqFwY72PQAMdO8E9LUjuugYWZ2lOpZ0VIOFUZNiUWsiAeUPuBUjFGaatu5u9B2+jse+8BhTrQmmWhPEw5JE6DwN4SlTFNKxcl8PS3ZtMsUl1qC5MEZWZ2RxnSlMdgrnnG8KOeKaFEulfr8174bUAl4RCgNDJEBzNxrDUywNnCEROm/uY8x8WN2PdPjDMeLROvP+VKsmHL6Wc8Qi8+CU7aGaFJqP4ZQ7ApVxSWpOLGrNqnCrUKQVCd2quPZLh/hG2y8AaPeHGYpHOB6bT1PrGSYj9SxteYenr9iV8z2uaR5mVecAD71yK3G09/voTa+zqnGA7w58DDk5L48jS8aJBK5iKbdgFFVWzynKVVZPCUXpKEYkIDlOEW0TTLUmSITO4w/HzLiDYUXksiZS2TC0mr3HO2gIT7G/q4/O/vUkRucyf8BnZnaadTIylOPLRiGi4WSXNLuC4cayeq6kloTCjYHM1PJ2VlJzHgKTaCfyqJ/E6FyG4hFgJoiZj1AAfKPtFwx072Rt+2EAHvjQLxnseZS/vHsm3mGNXeRb+LfSsYxy/bar3rKoJZEA97kduU68dLkUxqyFMfNxyUf+bMvtsEPvRCtb93wagOCoP2PBXyi9leGkdQG5LQxlWShMym1NZBKKdIVy05Epi9K6OjQelrwdDdE/5cxP9ZOhYwRH/YQGA8w7lZy/kTqeQloL5GNhOP19lfrCWNViUWtWRbnIdkLYPcHsLg5r7BhnUSjK0kD6rmP5csverzjyOtlww/RqKaja2ZBaEgo3xCfyuQrnEgrTDQlLdl/bS7s/DIRtv34meidaaQhPMRHWK31PziRpZcrqtFYFzwcnMj8LoZQzJFVtWdQC5VwIlqkBkBNCkS6j8o2Nj7DtvZvsDzIHGxtH2N/Vx0dvep14novM7LpWqeSyMkrx/ZXqQlmVYlErVkU5hMIJkbCW40/7eMoiMdCCm5f13sMTL95opnQ7Qe9EKzva92gFczKMwRhzJlIbGOX6HKpFMHKKhRDi+0KIMSHEa5ZtafuZCo1/EUIcE0IcFEKsdHzEOagFoSjH1GixIpFLIMz9MgiFgS9alzWlOx/6p3w89MqtXNZ7j1ans4GkRWr5CEYquQSkEnEMp88FO5bFTuDWlG0PAM9KKTuBZ/X7oDUb6tRvdwPOl1LOQq0IRSnJNcsByUJgvUUuCpq3XFgXcxnVuCFZKJzGmp9hrXWRKhhJY7MheJlIFY5sguGFYjk5xUJK+VvgvZTNmfqZfgb4gdT4A7BAbzRUcpRQFI4hELmmQg1BSO3JMR32EVlcxwv/+Ainl2H2H816s5TsN9/HIhTWk7mzfz29E61FH+fKfT1m6b3U97SOx7xZrR6bomEVzvcun8PQ/3qe6UZ/kmBk+pzd7o4UGrNI6mcKGP1MLwL+bNnvLX3bLLzcvrASlFIo7GKuBL3jveSrsWXh1x2f3ssrW76X/XWMKlcpNwNDKIzVpaAFJ4tlMlJvvq71fdJxpjNhtkRMGnsWwUj3WEN4ymyrWEjehptwOsCZrkJq2m9ESrlNStklpewKMKeoN612q6JU/UXtZF9aXY9om1ZbYjJSb55MC9b/mTOd2tJxgCVz3uay3nvM+hHpbmc6E7x2//eIdsS4/fN7CN78LrGwJBaW5hJ0q1A0hKdYc2RdUdbFhqHVNISn8Ie1ylnGe7x/zdnkWhn6zddyjts/v2emh2oa1yT1ZmAVmInBJsZWx213QnOzdVFonkWmfqZvAR+w7HcxMFzMAGsZp384xRajCQ1LfvjczXz0ptfZ0b2H/ikfg9PNPAVmOvZ3Bz6W+TVT4hEn1m0HYGvzIZaMbAJgy+p/M62Ilft6uK/zN+yd6OSiuacBGIpH9LwL+/RP+bTnN8NwqJEPL/8Tu4eWMxmpZ6B7J0OrIvzFT/4b/ohguiXOiXXb2TK2gq3Nh3jpUx/k5K/aCQ1r1zzjpE/XVsD6uGE9NXaMMz4yP9ndcrC5kV3qmppmBxPyxNbaECHEJcAuKeVV+v3/AbwrpXxICPEAsFBK+bdCiL8EvgKsBW4A/kVKeX2u1y9mbUi1WhVOCkW+kfhMzYhTV4QaJ7vByn09TEbqSYxqz/dHxKxy/NZyeAZD8Qi3v7qRRaGoY2tA7NA70Zrk3izZtYmm1jOzxtHRt5n5A7pIZGlUZGAIRbQjxol121m5r4fAjxamXd2aSSycXjcC8PR720u7NkQI8UPg98BlQoi3hBAbydzPdDdwHDgGbAfuLXRgdlBCkZlcQctM5ONXW9dr9E/5uK/zN6xaOsilV79F719t4yOffI2p1oTpYsR012LNkXVJr9PuD7O/q48HL9md11iLxSoUW8ZWsKzjFPu7+mYJ1mDPo9kDoSk3a+m/LWMr2N/Vpz1Xj11Y8VJquKdXnVabWBQrEsX+8DIVpDH/D/t4Z6XU3JD2PWYMITX4aK03MRSP8LFf/ld8erUqX8s528Vr3ED/lI8Nz24kOOqfZSUZlsOSXZs4sW77TP6GHg8BTWg6+jZTP+IjMAmnr43RvMdP+OR0Ugp5qoXhScvCrVSbUBRLua5Ql179lpkktXeikxPvL5q1jzWfYdPAnfjDMRKh86ZQtIWcPxFKRabcDMAUQMMde2PjI0n7GAHaROg8U60Jzi62f2F2Y95F1S4k8xKF/jCcEoh8XI+Tv2qn4+BmQLMSVi0dzLr/01fsYg3reDscMs1xL7FlbAVNrWfYv06rsBUbrDcfM1yqBy/ZbXZqT3RM0RCeYjJST6PeGe2L1/+BTzS8zldfvwMOLKzUoRSNJ92QarIqChEKJ62IbEKRqTCN4ZNPt8RZ1nEqp0vRO9HKifcXsbX5kDODriBLdmmzNka5v9TZGSNomlr6b8muTYQGA4SGZ8r4pa5kTRfsdNIdKdYN8ZxlUS1Cka9IlMLNKDZJyB+O2Yo9aDGN4pOq3IC1aDAwaxrXiN8YQrFhaDUHxtrMmEY23FAEOBuejVl4lXwWgRU6o2GHQsrdpbL9hh84OiYvsL+rj1VLB20HaHe072FisImOvs0kOqYy5md4AU+JhdetinxFolQUalGkthHc8OxGJ4bjOeyugt0ytoIluzZRP+Jj/oCPhb/Q4h25WiZacVOg01Ni4WXsfOmVrhKdjmxt/nzROlbu6ynjaLzFS+9+EMi+BsVLeEYsvGpV2HE7yiUS+dSigMy1Jqw//slIPRuGVpvl+hUzPHjJbk6s284bGx+Z1Z8E0lt46X4HbrEuPBfg9Ap2LYlykW8h3VShMDIYU/MIjOlBxWyMIOdVD99LKP16Sk+hxMJh7FgR5aYQobBaEsGb3+W1rj6W7NqUlIl5Qu8UplF8Qd1qwlgn4xusZ97kzPbUgsB2cbJPaqF4Qiy84IJUg0jAzGKx9685S2J0Ln936894alibmm9qPcP4yHz84RgNyqLIyMp9PUwMNqVdSOdlPCEWbqUQV8N6AhfS8coOxVbbjnbEONG900ws2ti4i6F4hG9d+SO6uxKOFtCtNtYcWcf4yHyCWUTCal0Yy9W9gOsDnG61KvIVinTBxULLy2ejGKEw3I/QYICV+3qSMhDb/WHz/l2LnmdV44AzA64yPnzBn/CHY1lbDRRKpQOdyrLIk3xEwqhbCbnn1tOd5HavOPmKTTprInWKNNs6ju76BN311ZGR6TRbmw9pxXx2bWI6BPFwHYFJPVU+SzMjK27N5FRikYN81DzVkohcFDQDhUH9h5JPcMtJiyNr7cg0uRQdfZtnFalR2KN/ymeuRF25r4fpkQsI6kHOdILhFVfE1W5IpVwQIzeiGKEArfRarEGrYTC2Ok5kcZ2tMvnFkq0+5Kx9MyRd+SOCJbs20dm/vkSjrF6s7ptZ+CZDu4FC2wxUAteOtNxC4dQy8VRrQKvdGCDaEaP5r4cY+0k7kYuCrlgjkC070yC1dL4iPzr71+MLS7Ra1slBT6MQTjCPGdFKTqG62rIoJVbrodBl4nanQ0PDEl+0jrejM/vbOVGtGFei4Y8KIovrkqpNF0K651qTr+JhiT8cwx+OqdmPImgITzHdEue1+7+XVEX87GLt833vtinPtAkotH3h3wshTgohXtVvay2PPai3L3xDCLGmVAMvhkqUr/voTa+zKJQctLJ7sltrSXz+L55PqpJdjGBkwiiqu7TlHZa2vONY+8BaZFEoarYfMCppGbVABrp38sCHflnhEdrHjhuyE/gOkLoe+dtSyn+2bhBCLAfuBK4E2oBfCyGWSSnPOzDWonBq2imbUGS6OkTbBP0HLwcg1AAgzCrR2UrLpwpBrAGeePFGTtz/PT609V5br5HrNc3tulVhrb5d7gK61cjn2vax8YqZmaNEh5bM1r10kM7+9YT3ziNMxU8PW+QUCynlb/VWAHb4DPCklPJ94IQQ4hhwPVp1cNs4Fa+oZDl9g9PLIHTNu9zefpgnXrwRMPpnpCbtZLYQjBP5ok8N0Raa0ArAWl4jl2jksj7M1O6w5Lm//meM1G1roE5RGKnFjAe6d5rVtFaOtTHROZfwKe0xu7MilYpbFGPDfkXvlP59o4s6Lmlf6HSX8UKFYjrsY94pwfTzF9B3+Dq+eP0fZkrjW1r2xRo0UTm9jLSdvIz9nr5iFwfG2kiEzpuvAWnK06f0Fc04vjQNiTcN3FnQsSrsYwjIolCU+hHvhA0LHekjQAdwLXAK+J/69oq0L4TCpjvtYFcoMjXmCU5KLcCpF3pt7BhnuiXO+9ec5f1rznKmUxOPSz7yZ+JGfw1r3099Sbix2nN/Vx8n1m0n0THFRZ8a4vS1saS2e2cXy4yik3qzvofB0cHFs/p6KErDsYMXazU5C1hYVgkKmjqVUo4a/wshtgNGjbGi2xfm64K4oWFwJoKRhHllD0QEP/q3VSQ6psyuV9s7nwTg9lc30haaoO2mCfoPXk48XMdUq5brYBAPS7Nj1n2dv2FAX/G5MtpDdFSrGG203gP0eo+CgGXFYzqsQmHMgDx4ye5ZBWcVzrFhaDW/e+Yq5p8SBCPeiFdAgZaF3t/U4LOAMVPyc+BOIcQcIcQSoBN4sbghVgeBSU0wEqNzGR+Zz9HBxXx9+Dba/WHWth82Zxz84RiXXv0WvpbMvqvVD/7WlT9iuiVOPCzZcUsvW8ZW0Nm/fqZTeEOmV0n/2ED3Tj2dWwmF0wzFI6ZQzDslbLVCzEQl1onktCz09oXdwIVCiLeArwPdQohr0VyMN4EvA0gpXxdCPAUcBuLAfaWaCXGzRZEtK69+xEcsLIiHJd9o+wW9E5eaJfJ3tO9hy9zTbG0+xMpoD+MtWkKUPxwjEQngD8e4pjnZUOuuT9B99R/Ze7yDX09eqTXzffeDHI0sJhY2LJNkCyNVJGKW7lmK0rDmyDqODi4mNBhg3qS9nqluw3V9Q3K5IaVU1EKFIlO8wryfUkzGODkTHVNZW/mt3NfD2vbDnDy3wNyWLudhy9gKcx/r40axGl/LOXyD9WlrKxhjiYcll179lmfaCnoRo3dIQBcLY9bKGrPI1TA5lXxmRWqqb4gXhSIT8bAkEQnQtjTzl722/TBL5rydszlPpsetDYA6RjdnHQvA8dEL6b9ExSpKzczUuS9pmtvti8lcJRbZrAo3CkUqdoViuiVOU+sZIHtZ+WI7eFmTqhKh88TRSuIZgdN4Sj3Njy4dVEJRIvqnfPjDMWJh7Tcy1SqZP+Aj6KE6x56Y5PWCUGQiXZ6DL1rHNc3DfOvKH5X0va0nfvfVf6T3r7Zx6dVvmQFRg0ToPP5wTKV1l5Du+gQD3TsJXfMeiY4pev9qG69s+Z75uNutCvCIWLgVqwuSdRl4mnjF3uMdfPPNtfROtJZ2kDp3LXqe7voEH77gT4AmEMbNWLuwZWxFWcZSy6xtP8wq3YK76uF7Kz2cvHCVG5ION896GGQSCqtVkdpvIx4J8HY4xIn3F1GOPqCGlbG1+RC7W5czPjIfwBSKhvBUVTQudjvWzzhXDozbcK1lUYpsTAMnhMKwKnIJxellmFmaoMUJfC3n8IdjrG0/zN0L81o24wj7u/poaj1DU+sZGsJTNISnZq2IVZQGq/UWnCw+e7Oc+RautyycptRCYbUmom2CQATu+PRe+g5fRzwSMGcoNgyt5u6Fv5/VhbtcrG0/bLbXA2gLVbYnRbXTO9HK1j2fJjQY4Ges1tK8XVAAKR9cIxbWmZBKVzHOhDVGka08XmoD4R8+dzPP/fU/JwmDFkysXGOerc2H2AKcPLeAi+aeZsmctys2llpgY+MI/11v0JTqfnghuAkudEPcOPNhLdc/3ejnvcvnmAu1rKQu0IKZOMXHfvlfXVdx6u6Fv2dV4wBL5rxNR3Cs0sOpenwt59h93z8B9mqPuA3XiUWpKEQosvX0MMqkpVvFmYqR1+C2qcl2f5iO4BgdwTGWBs5UejhVT8/yl5OsS6+sNjVwjRtSSnIJRa76h6nt/YKTko6+zfg6pohF5pmPpa6/sAY1/eEYa46sY3vnkxWLU6RjJhfDPWOqVrY2H+Ky3ntY4MF1IeAysSiFC5Kr+nYusuVP9Cx/mSciNxIcNfYRxMJyVjcqX8s5Brp3MhSPuEooFOXDWBeyQA9ses2qgCp3Q3K1D8xGun4b1sK59SM+nnjxRrqv/qOZEWkIxWDPo/hazplJT6DVMFBCUZtsGVvBjlt6tQVkKbEKrwQ3wWWWhVNY2wfmSz5NX4KjfvYe7zALznT2r8eHJgwN4SnQ8xfejoa4a9HzeY9FUR143f0wcI1YpHNBMsUaMi3fLUYkwF6Lv3SBzA1Dq9nRvoee5S9z8twCdrTvYagtwvHYfJYGzvD14dsYnG5W/UFrkDVH1vHm7z6gFbvRq2J50QUBF4mFlVwByULK8efCjkWRTigawlPm/9ZU3nZ/mHZ/Aghr4hGPoIKItcfn2vbx7Ui7J4vdpOI6sShECKYb/UyHfZxeBs37089fZ1PzXEJhLV5jMNWqvc9kpJ4DtNG/KHsdCBWvqD0Mq2LBcPpCN05RrtYArhKLTEKRTSTM/xsE8XCCyOI6wqdmV/Kzs9hr1mOWMvxWjEY8K/f1sCgUVdWlFGkx3I8MBe49h50anB9A60bWCiSAbVLKh4UQC4E+4BK0Opyfk1KOCyEE8DCwFjgLrJdS7s/1PsUIBWh5Df6IdnJPT/qSKmvPeq7FSkg1D1NL5MfCktA17zEx2GQmVyVC51m5r4f9XX30T/nUlKgiCWOa1Ku1NjNhx7KIA38jpdwvhGgAXhZCPAOsB56VUj4khHgAeAD4GnAbWlXvTuAGtB4jN+R6E0MUrFNJ0fbkE9Aw4VLXZZxeBtMtMZpaz7C/q0/r2DVSl5QkFZyUSS36wBCXzJmXxlTo/q4+loxsYjqklao7PnqhWThXcz2UUCg0Ovo2ExrxJf/2PJjanQ477QtPoTUSQko5KYQ4gtZl7DNoVb8BHgf60cTiM8APpFYJ+A9CiAVCiMX662QlclEQLgoy3SDMk9tAu8prHb6ME9680ndMcULvowFaI58JmgjePE70wEKmW+JahexRTZAuvfotPte2j617Pk2iI0Y8EqCp9QyTkXrikQBbVv8bAN8d+JhZzWrHLb2AJg6qTqUiFaN6dzBNUeRqIa+kLL3n6YeAF4AWQwD0v836brZaGJayfaFCoXAe260AhBBh4DfAP0gpfyqEOC2lXGB5fFxK2SSE+Hfgm1LKvfr2Z4G/lVK+nOm154uF8rpb/hYoxg2Jp7ghPltuSLry+AbWjMwluzYBM27IqqWDrlsYpqg8qb89a8l/mD0bkimD024rAAM7syFlaQUghAgAPwGekFL+VN88argXeocyY41zQS0M031ooaFI2gBn+OR0UoCzeT+MLwsQHV3IVc/fy4XDkmDk/KwAZ3BSEpyEwKQvaZuV5ClS7f+V+3rwRevwRwRvjn6AeEucA2Nt0K5VbV4aOKMCnAoA88Ji9AcBffFhFcQt7MyGCKAXOCKl/JbloZ8DdwEP6X//1bL9K0KIJ9ECmxN24hV149G0MyKBiXNpBSM4EU8SjMCkVl5dy5TT57QzfEHW8uvpBGUGAWhd0OstW+PhOvZ39ampU0VaUvvNVsuMiB3L4mbgfwEOCSFe1bf9HZpIPCWE2AgMAXfoj+1GmzY9hjZ1usHuYLIJBsyeRjVMuulGP8FJiT8i0uZYWPedvT1zDkYwApyanZQVmPTR0ac17ZlsqWdltIdvXfkjFfRUJHHJR/7Mm7/7AEGPFebNhJ3ZkL0Y9vhsbkmzvwTuK3RAmQQDMvt3gQkIAU2HC0v3TrVSZj0eSQDJgqH1LJWEOqa4pnk4p1CoXIza4+krdtHb1sq3d/4nGNZzfxr9jmdxliN7E1y6RL1uPJo1wGM8nnqDwpf82vnlmprSAAAfDElEQVQC05mTk5EZB2XL2AqzdN5QPGImbG0YWs0z0UsLGpfC2zw13EUsLLNWUvMKrkn3luMTs1ae5hsRTt0/Xysjm4VhZISm5n/ATLm8vsPXAZrfdWCsDUAtUa9xnr5iF1yhxS+Ck6WzLsqBKy2LYjEsjcDEOfNml+BE3PYXOd0SZ9XSQZbs2qSV2RusJzE6lx3te5iM1DM+Mp+jg4uZjNTz+Ns3F3o4Co+zZWwFj33hMc9bF1UpFgZWS8MJ0TBnWSYlU60Jvnj9H+g/eDnBUb+Zs+GPCDr6NpMYnYsvWodPL/8+s0xdUWtsbT7Ehmc3auuWUmbfCi2pUAlc44ZAelekWFIDpukEI9sXls016Tt8HaHBwMxrT0JgUptuTSrYy1w6+9eztOUd1xXsVZQH63TqgqM+wHuuSFVbFga5Yh9WdyWd62JYGcGJuOZzNgitzuZgvS4QaRrHTGJmh/ojgngkwNNX7HKdUPRP+cxArKK0bBlbwRsbH/GsO1ITYgH5B0shu+ty1cP3aglgk9K8ZcKo9u22JkND8QiD080MTjdzPDa/0sOpevoOX5ckyvnUe3UDrhttKVwRg2w5HNmwJoUFJ+IsnIinbV9oCEZSAldEEA9LfnPrt11nVWx77yazfSGgaoSWmMToXNZ+928J4M0UcNdYFufHx83/y5Vkki9WSyN8clrr/5ByA2ZZGp//i+e5Ze9XWLJrE2uOrAM0K6OSpv+WsRW89O4HGY428tK7H2TvRGfFxlIL9E60mm0hUquveSXIaXvVaSmZLxbKG8QtZWuOXOpO6jAT9T69TO9Ipscv4mGJr0UTnJ7lL1esk/rKfT1J99Ual/KwZWyFWdj5hq/dQ/jkNDA78J6P22z34lqWVaeVwPgASiEahbojVowFbplmS4wkrgVHYbrBZ86O+COCOHNJhM6ze2g5kFwVvBys3NfD+IgWo/CHY2V971rH+l1PN4iiE7TKaYW7xg3JRKk+jFwp5fmQcZGaxSe1zo6AdpIuCkVZMudtR8aQi/4p7aveMrbCFAqAeESb+p2M1LNlbEVZxlLLWJcEpCsG7WZcLxZuJnV6NRNG/MIqGKuWDvLgJbvZ2FieoOLjb99M/5SPl979IICZMOaL1pmCUW4LpxbZPbScvcc76J/y8dr936v0cPLCtW6IFTfOkNglXZXxROg8B8ba+OrYHezv6ivZe/dPzdQK7T94Ob+NXqmPaSZ+AppwxJnprKZwnv4pH5te+BK+wXp8wMbRu5k/4COMHvRsnOv6vqeusiysMyKplNI3K7U7Mmu/UT8Tg02Mj8zPmnuxZWwFvROtBY/nm2+uNf83Kn35ra6Q5b4vWmde8RTO012fIB4JENCXBcwf8HmuKI4nLAsDN1oYqZW8ctXGMPBHBImWGMPRzMeze2g5a9sPs2FoZloz3ZV/y9gKTp5bMOvxo4OL6Ti4GV/LuYz1Rs2ga1iytOUdVcCnDAQmZ9fmBPdbF54SC3DnLEmm0n+QvHDIGtCKhyXPrfrOrDoXxtSaMWPxxMiN+MNauwJ/OMYGZgvGyXML2Hu8g57lWk1ksyz9qPb1BkbmJaWjW8cRiAhTMNTUaekw8musFJuYVe58JM/anHJ8oiQflhOzJNnckanWBNMtcRKh83x9+DY2No6YsxAbhlbTd/g61hxZx2SknuCon+CoX/Nz9UCkUSfDoH/KR//By0mMzuUTDa+zZWwFx0cvxBetM03etOtWLNuM/YxSgQrnefqKXfzm1m/z4c8e4uxibxbDySkWQogPCCGeE0IcEUK8LoS4X9/+90KIk0KIV/XbWstzHhRCHBNCvCGEWFPKA/AKRp6Fr+UcTa1nWNZxim+0/YKheITdQ8vN2EU8EuDYwYvNhkjpsMYxvvr6HeYS+Q3PbmRr8yEGuneasYhUobCS7rHO/vXm4jKFs7T7w+xo38NHPvla0YJRiSznnBmcepn/xdb2hcDtwOeAiJTyn1P2Xw78ELgeaAN+DSyTUqavpMtMBqeBNZPT9oGUKJZh1y1JdUOMzu4Gp5fBHZ/ey+6h5YyPzDeToRKjc/FHBJd85M8cO3ixGVswTmTrUvc3Nj5ivp6x5P3o4OKkZfLGvuksioxjb5h57nRLnGUdp5RLUgY6+jZz4X5hZnHCzHR8Luu2ELEoeQZnlvaFmfgM8KSU8n3ghBDiGJpw/L7QQdrB+uE5KRx24xhpA53hoNnYKNFxFoCJwSaCEUFAP8EDk9rJ+ubvPoCf2Se59v/MFciIZQRH/Zw80M6CWS6GUXo+d6TduLIZYwCUUJSRS69+i5Mj7QQj3qhtUUz7QtD6gxwUQnxfCGGYA7baF5YSp+MZhcYwgpEEZxdLgje/S8/yl3nixRu1blW6IBiiEJiEBUe1W2hYJi17D05Kc781R9ZxTfPwTDzC2vXKekuzuC3t+CwL3ozX2t75ZEHHqrCP4Ua+HQ2Z3fG8gG2x0NsX/gT4L1LKM2jd0TuAa9Esj/9p7Jrm6bMuc9l6nWbLt8gHQzScEI5CA58LjsL08xfwxIs3mtvMqbMsJ3hSy7tJSWhYcvJX7fQfvJzBnkeTXsPcL4M45BIOUzAigr/4yX8zt6vYRfGk5sl09q/noVduZcPQaiYj9cwfmPl87U6bVmpVtq1fQrr2hVLKUSnleSllAtiO5mqAzfaFUsptUsouKWVXgDnFHIMtnBKObIKR6csODUu6r/4jyzpOmSe5QdaTOOWxwCR88fo/cNXD99p+jVyvaW7XLZj6kZkGSt98c21SYpcif54a7qKzf7153zdYj2+wnv6DlzPQvZOv/G8/zfxkl2FnNiRt+0I98GnwWeA1/f+fA3cKIeYIIZYAncCLzg25eEopGJn47e+v5O1ocuwjnxMctBP6h8/dnNzwuQQFVAzBOD56IcdHL3RdhS8v8XY0ZK69uaz3HnOaOjjqN60Mr1BM+8LPCyGuRXMx3gS+DCClfF0I8RRwGIgD92WbCakUqYKRb1DUEAw7wc9omyARirMoFGWMC4D8T3Jj/7bfAhT/caZbs6JZK1pA1h8RTIe0H7laL1I4Rr7MVQ/fy7ykwLXgdEuA5j1+ghPTrs7cNCimfeHuLM/5B+AfihgX58fHC5pCLZRCZ1NSRSN1ViTaJoh2aNOkYz9pJzgpk6bKSoHd2o7pBCMVVe+iOAa6d3LVgXtnuZ+AJhR5XjQqWUXO1ene5RYMg0KEwzrFagjGdNinzXS8GtCDmOfLMkWW7j1ydVpLJR6WZvl6RX5YV/saFclSY0zm/x6YMjVwtVi4gXzcFauVEZg4R5iZk7SQH4Vd09RODUfr+6cKRzrBGOx51NZ7K2bTXZ9gya5NgLaad36GGJPxnXjBBQElFnljZyFbcic07W+uE7qYH4z1ufkIh1U0UgVj5b6ejLU2+qd8DE43l61wj5fYMraCvsPXmSUBrCt97VoUTpVMcBrXT6I7lXPhNHZ8x1ztEwvpxZqLfFs0Jt2PJAhOSqIdMfZ39SXlWBhd4UGruqWqgafnpXc/qK0QTlMOoFgqXfVeWRZFYCe2kS4AWmqsfU5yka7+RmgwQGf/ehKjc/m7W3/GU8NdPH3FLm5/9Q5zXUtDeAraSzJ8T/P0FbtYGe1hItqUUTCsIu0VFwQ8IhaVCnTmQy73JJ+pVqewKxpWtyQYScCwj8DkPAC+PfKfCN78LgDjI/PxRetIROuwuUatJtnf1cdKepiM1BMbrNf733ofV/UNyYbbxSIVO7Mo5RQOu41sDCvDGr8wFsPBzKpWgOmWOE2tZ7imeZhvtP3CdR3X3MJVD9+rrfmJJGa5fuksi3QxCydckGJXnbo+ZuFV7KSWO9mOIBd2zV3jx5y6NsVsAG0xrX3ROiYj9c4OtIowYjxeq+KdCU+4IeANVyQd+cyelNrSyMctMVwSw8IITmrFWowl84aF0RCe0jM8lVWRyjffXMsGvbzhvAaBdm32Z50yLZVV4QTKsigTdmdP3DZtli3DMBE6X9JWBl7nwxf8CSBtoWQv4imxcOs0ql3sXiFKLRqFRuBT05V33NLrxHA8h92FdVubD3Fi3XamWhOc6Uzw3m1TgP10fHCPVQEeE4tqIJ9l8oZolEI4cgmGNRCXybrY9MKXHB2TF1i5r4e9xzvSVutOx4ah1TR2jDPY8yi+wfqca3HcjOdG7nXrwiDf2hqlEI5i5/jjkYCtk6Z3orVq+qiOj8wnHglwfPRCQEtWs2IUuzGCmzva97C/q48luzbldEfc5oKm4jmxgOoRDCjMzHRSNLIJRjrrItagtTOIhyX+cIy2UO7xPzXcZXaM9xpbxlaYi8E6+9cntWdYsmsTmwbuNIVhzZF1PPTKrazc18OmF75kPm/L2Ap23NJL8OZ3Ob2MtNaFmwObBp6ZDalmCm2cZP2BFTOTkk/G50WfGjIL+m4YWs1Fc09n3X/NkXUcH72QeCRgViRvC014pkbG1uZDPPHijVzWew8+koOV8XBdUnHjp6/YxWW/u4co9STCknG96M0TL97ID6M3azVCWuJw1JunnSctC6gu68IJymXCHjt4sRngW9U4wJI5b8/ax7qmZHvnk8QjAS3zc3Qux0cvzNqy0W1YjyXVjUiEtCJExgpToxKWgS9aZ/6tH/Ex75T9WRG3WRXgoQzOdHgx78IOTrQyKNTSSGddWLM6o22CqdYEidB5dtzSO9OlXV+Juneik+FoIw9espvH376Z3/7+yqQ1Etn6kljrQJSbLWMreOndD2Zsg3DVw/fm1YfF6MHyxev/wNbmQ9zwtXsAzCxOq/tXLhek5H1D3IxXE7Vy4UQD6EJdlGx9W1Oxntjd9Qm++vrHmIzUkxidy8aDd+OPCOpTrsappjtoQcLbX93IolCU7jL2LOmdaDWX2W9tPsSSF29kZbSHRaFo0hg7+jabNSnsdT4XgGC6BbNvbQDSpnu7PahpxU7B3rlCiBeFEAf09oXf0LcvEUK8IIQYEEL0CSGC+vY5+v1j+uOXlPIAqtUdcbrvST4/ymxBz6nWBB+96XVOrNtO/5SP3olWc0Zkf1cfDeEpTSR0s9tME9dPNmv1cIN2f5jxkfkcHVycVDp/5b4eeida2TC0mi1jK+idaJ01+2CH/ikfW8ZWsGFoNWuOrDODlkax3KF4hI6+zQRH/YyPzOfpK3aZszdrjqyjfsSXse1CuvYNRnp8aDBgNoWabhC2CyC50QUBe+0LBRCSUkb0lgB7gfuBrwI/lVI+KYR4FDggpXxECHEvcLWUcrMQ4k7gs1LKnmzvUagbYlCN1oWVUrRmtGNtWC2M6UY/48vquP3ze+g7fB2J0bnUj/i46FNDHDt4MaBV1+qdaOWffvzZrO0Tz3QmGOx5lCW7NvHF6//A7qHlRA8sBLRyfgZGTKCp9QyLQlE+17av4II7G4ZWc2CszbR8DHwt5/AN1s+KR7x/zVl6lr/Mz364mtBw+pJ4mTBmO6YbBGc6NZeteY/frL2aq0VhKcTi/Pg4v5Y/LsoNyStmIYSYhyYW9wD/DrRKKeNCiJuAv5dSrhFCPK3//3shhB8YARbJLG9UrFiAEoxCyUc0Ihdp7RjFre8if3mBeaU1VqW+dv/32DK2IslHT4d1FWva99MFIx6WJELn8YdjDHTvtH9QGejsX28GW83G0RlE7UxngvoRn7la1EomC8GamTkd9pmfVeBHC2fFKsotFEDRYmErZiGEqENriHwp8F1gEDgtpTQ+NWuLQrN9oS4kE8AFwDuFDtIO1Rq/MCh0ejUXdmIbRhwjfHJaOyF2LCC5HYGP4KQ2GzDvlOCZyVVJz7eebNNhw6QnbRfxWEPK9CR1NLSecST4abSQzCQUVjfjwv2CYGTmGO24EMn7+AEfVFgonMTW1KneeexatO5i1wNXpNtN/1t0+0JFZbDTbS3dSWP46wuOzpxwmVompvr2dgKG+7v6HJkl2dp8KGNrA3uBS/sEJ+KET04TPjltSyhKhZMxvbxmQ6SUp4UQ/cCNwAIhhF+3LqwtCo32hW/pbkgj8F6a19oGbAPNDSn4CCxUu3UBzsyUZCPbcnnDwsh0lQ1aLoy5FksZgmFYGoC5BD6bi1IMmXImMpXph+JK9acGirMJhdutCrA3G7JICLFA/78e+ARwBHgO+M/6bncB/6r//3P9Pvrj/5EtXuE01To7YsXpLvHpyDSDYrfAcHAibt6y7pdSZAdIcg0SofOOtU/srk/wwId+yRsbHyEWlmn7ziaNLQ+hsBZfTvcZVWKK1OlzwY5lsRh4XI9b+ICnpJS7hBCHgSeFEFuBV9D6oaL//X+EEMfQLIo7HR2xDWrBwoDSWxmQ2dLItyiwQTqLI1ORndfuf8QMmDrFxsYRNgyt1mdd0pfpTx1zKvkuwMslFKUMajqJpzM4s1ELYmFQasGwkikIajeRCzK7KNYpR4CziyXP3PU/HKvt2TvRyncHPsbEoFZ5e94pkRRjMUgnFIWu0HWTUBQ7G+LZtSG5qAV3xKAcbolBph9/Pv1PcromhjsSEdz+6kbWHFlXUDJWKhsbR5iM1OfV/KfQvi6VqnpWyt991YoF1JZglBM7sya5sBsPmBhs4u1oiOOx+bb2z8Wzq77jyOtkw0sp3PlQ1WJRa5Qzop7tymm301rG5CZL/oU/IrQ1Iw4tMHsmeinTLXGiHTHOLk52we2U6c9FPkLh9PdV6otj1YvF+fHxmrIwyj0Fl+vkyCUa2cr3xcKSeFiyvfPJosZouDBbxlawsXGELav/jRPrtnPHp/dmHXe+VLNQgMdXneZDrcyQQOmyPTNRNx7NmTaebfYktYWiUY3LSPU2ApxGFme+2ZxfH76Nvcc7aAhPsbX5EA+9civ/fXQu8wd8BPV8wWI6mlfa7SjXxbBmxAJqSzCgPFOrBnZ7n2QSDatgfPizh/hG2y8AbUXqUDzC8dh8vvr6HUxG6lna8o6tpewbhlazqnGAvcc7SIzOZWJ0LhuaV/PAh37Jdwc+hhy4IGnZuNNTounwokVhUFNiAUowSo0dKwPSi4Z20vp59QcrWNugLRGfak3Q2DHOz67tZXxEC3IejSxmDdqy+Acv2Z3Ryjgw1mYKhbEe5Le/v5LfciW+lnPMaQBOFX6clabc7nXNiUUt4lbBgPTFdpIXmvmYbKnneGy+WaYO4OjgYppaz+R0R+KRAEHLVOm8U9qK11ik3nblq1QKFQonrYpKxOGqPsCZjloKeBq4LfBpxWr+ByfiM4vQ9CIyPctf5sv/75epH/FRP+LDHxFmn9VsqeD7u/o4sW67KRRGendoWLLgKIRPnc/LBXFLx7hK/X5rUiyg9mZJoLzJW1CcYACmYPz7ttXJVbf0k3+ge6dZJdy6SAxmuoZ19q8H0OpSpKyILdWxpMOpz72Sv9maFQuDWhMMKH8+hl0yCUb41HlzObthbVjL863c18NXX7/DLMm35sg6+g9eTkffZuKRQHLNihxp3enGr4RCo+bFAir/JVQCLwkGzF6dagjGZb33MDHYxPjIfD4ZOgZo7QeMalihwUDa18j0noWOOxPVIhSgxMLEDV9GuXHDmpJ0ZDp50wlGICLwRwTBUT+bBrQFzre/ulF7nSztAnNZFW4RCje5y0osFGWjkBMw9aTOFms4OrgYgMlIfV6vmYpbhMJtKLGw4CYVLydutDAyuSPZMErm9Sx/GV/LObPwbynGl41qcj2sqDyLNNRa4pZBudPEnSAwCVOtWhXwLR/6pVnB+8S67awMaz07jPaBDPtmWSa5OoPli1OuhxtRlkUG3PqFlYNylOyzgx3rItaA2Upx70QnvsF6QoMBLuvVWhHsuKWXwZ5HuehTQ2mriec7pmxUs1CAEous1KpbAu4RjEwYJ34sLPGHY/x68kruWvS8mY8x75RgbfthvrJtM5f13sPx0Qs505lgz3cfM1/DyYrbxX5eXvit2elINhf4LTAHzW35sZTy60KIncDHAONTWi+lfFXvYPYwsBY4q2/fn+09SlFWz2lq0S0xKKVbkistPDUV3FhsNrZSL8HXEqf76j9yYKyN6ecvSOoeZiXaJoiF9cxNm53B7OKEUJSDcjQZeh/4uLV9oRDiF/pj/7uU8scp+98GdOq3G4BH9L+eplbjGFDatSX5rCMxmA77CF3zHpOReprCU+w93gFoVzODWbMmwz7eu22K4H5tr1oTCifI6YZIDaMAYkC/ZTNHPgP8QH/eH9D6iywufqiVxwumYqkod6q4QWrOhRG7mH7+Arbf8AP2d/XhG6xnzoF5ZqvBdNOrwUhCW1TmYMOfWhIKsBmzEELUCSFeBcaAZ6SUL+gP/YMQ4qAQ4ttCCEPYzfaFOtbWhlWB175kJymFYORz0hpuSCws2fTCl8yUb1MoLP1KUm9Ln0wooSiCgtoXCiGuAh4ELgc+DCwEvqbvXhPtC5WV4aylUcjJm9CrXS04SlIRm3RYy/sVIxTFHreXfzd5zYZIKU8D/cCtUspTuqvxPrADrQcqzLQvNLC2NrS+1jYpZZeUsiuQ5G16Cy9/+U5QTsFI7Tfij2h9P9K5HZm6gxVTi6JWRcKg0PaFfzTiEPrsx+3Aa/pTfg58SWjcCExIKQusR+QdvP5DKAYnrQw7J3O0TfDYFx7jsS/MTINa61I4vTCs1kXCoJj2hf8hhFiE5na8CmzW99+NNm16DG3qdIPzw3YntTxjAs5lgGabIZkO+3j/mrN8ZdtmYmHJvAZBUA+/F9o1LBvVuMajUHKKhZTyIPChNNs/nmF/CdxX/NC8iXEVUaJRnGhYBcMovTe+rI5oR4zmX9QTjJwH9GnUoezdyspdWLdaLIlU1NqQEqFEo3jRsFYMD0yco+mon6ajPoIT0+Y+oaHM1kS+IlHt6drFosSixCjRmH0S5isexklvN3VLiURpUGJRJpRozGA9OfMRDqeK5VbrEvJSo8SizFh/YEo4irc6CnmPYqk1kTBQYlFBan32JB1OiUepZjFqVShAiUXFUe5JdtwwdVnLAmFFiYVLUO6J+1AikYwSCxeirI3KoQQiM0osXEzqD1eJR2lQAmEPJRYeQrkqzqDEoTBUDU6Pon7whaE+t8JRloWHSffDVxZHMkocnEOJRZVR63EOJQ6lQ4lFlZPp5PG6iChRKD9KLGqUbCebW4RECYK7UGKhmEWxJ6khNupkry6UWCgcR4lEdaKmThUKhS2UWCgUClvYFgu90dArQohd+v0lQogXhBADQog+IURQ3z5Hv39Mf/yS0gxdoVCUk3wsi/uBI5b7/wh8W0rZCYwDG/XtG4FxKeWlwLf1/RQKhcex277wYuAvgf9bvy+AjwNGU+TH0XqHgNbr9HH9/x8Dt+j7KxQKD2N3NuT/Av4WaNDvXwCcllIa/eKs/UzNXqdSyrgQYkLf/x3rCwoh7gbu1u++/2v549eoTi4k5dirhGo9LqjeY7usmCfnFAshxDpgTEr5shCi29icZldp47GZDVJuA7bp77FPStlla8Qeo1qPrVqPC6r32IQQ+4p5vh3L4mbgr4QQa4G5wHw0S2OBEMKvWxfWfqZGr9O3hBB+oBF4r5hBKhSKypMzZiGlfFBKebGU8hLgTuA/pJRfBJ4D/rO+213Av+r//1y/j/74f+hdyhQKhYcpJs/ia8BXhRDH0GISvfr2XuACfftXgQdsvNa2Isbhdqr12Kr1uKB6j62o4xLqoq9QKOygMjgVCoUtKi4WQohbhRBv6BmfdlwWVyGE+L4QYkwI8Zpl20IhxDN6duszQogmfbsQQvyLfqwHhRArKzfy7AghPiCEeE4IcUQI8boQ4n59u6ePTQgxVwjxohDigH5c39C3V0VGcikzrSsqFkKIOuC7wG3AcuDzQojllRxTAewEbk3Z9gDwrJ7d+iwzcZvbgE79djfwSJnGWAhx4G+klFcANwL36d+N14/tfeDjUsprgGuBW4UQN1I9Gcmly7SWUlbsBtwEPG25/yDwYCXHVOBxXAK8Zrn/BrBY/38x8Ib+/2PA59Pt5/Yb2mzXJ6vp2IB5wH7gBrQkLL++3fxdAk8DN+n/+/X9RKXHnuF4LkYT8I8Du9Bynhw7rkq7IWa2p441E9TLtEgpTwHof5v17Z48Xt1E/RDwAlVwbLqp/iowBjwDDGIzIxkwMpLdiJFpndDv2860xsZxVVosbGV7VhGeO14hRBj4CfBfpJRnsu2aZpsrj01KeV5KeS3alfh64Ip0u+l/PXFc1kxr6+Y0uxZ8XJUWCyPb08CaCeplRoUQiwH0v2P6dk8drxAigCYUT0gpf6pvropjA5BSngb60WIyC/SMY0ifkYzLM5KNTOs3gSfRXBEz01rfp6jjqrRYvAR06hHbIFqG6M8rPCYnsGaxpma3fkmfObgRmDBMerehrxTuBY5IKb9lecjTxyaEWCSEWKD/Xw98Ai0g6OmMZFmOTGsXBGXWAkfR/Mb/o9LjKWD8PwROATE0td6I5vs9Cwzofxfq+wq02Z9B4BDQVenxZzmuVWhm6UHgVf221uvHBlwNvKIf12vA/6lvXwq8CBwDfgTM0bfP1e8f0x9fWuljsHGM3cAup49LZXAqFApbVNoNUSgUHkGJhUKhsIUSC4VCYQslFgqFwhZKLBQKhS2UWCgUClsosVAoFLZQYqFQKGzx/wMX5Wsr3gS+AAAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as pl\n", "\n", "def mandelbrot(h, w, maxit=20):\n", " \"\"\"Returns an image of the Mandelbrot fractal of size (h,w).\"\"\"\n", " y, x = np.ogrid[-1.4:1.4:h*1j, -2:0.8:w*1j]\n", " c = x + y * 1j\n", " z = c\n", " divtime = maxit + np.zeros(z.shape, dtype=int)\n", "\n", " for i in range(maxit):\n", " z = z**2 + c\n", " diverge = z * np.conj(z) > 2**2 # who is diverging\n", " div_now = diverge & (divtime==maxit) # who is diverging now\n", " divtime[div_now] = i # note when\n", " z[diverge] = 2 # avoid diverging too much\n", "\n", " return divtime\n", "\n", "pl.imshow(mandelbrot(400,400))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }