├── .ipynb_checkpoints ├── Data Generation and Likelihood Fit-checkpoint.ipynb └── Untitled-checkpoint.ipynb ├── Data Generation and Likelihood Fit.ipynb ├── Datasets ├── Exp_Dataset.csv ├── Lin_Dataset.csv ├── Log_Dataset.csv └── Quad_Dataset.csv ├── LICENSE ├── README.rst ├── dynamiclogit.py └── styles ├── bmh2_matplotlibrc.json ├── bmh_matplotlibrc.json ├── custom.css ├── custom2.css ├── matplotlibrc └── outputonly.css /.ipynb_checkpoints/Untitled-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# I. Importation of the modules" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "%matplotlib inline\n", 19 | "import pandas as pd\n", 20 | "import numpy as np\n", 21 | "import scipy.stats as stats\n", 22 | "import itertools\n", 23 | "from math import exp\n", 24 | "from IPython.core.pylabtools import figsize\n", 25 | "from matplotlib import pyplot as plt\n", 26 | "import seaborn as sns\n", 27 | "figsize(12.5, 8)\n", 28 | "pd.set_option(\"display.precision\", 3)" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "# II. Notations and definitions\n", 36 | "\n", 37 | "## 1°) Number of states and state transitions\n", 38 | "\n", 39 | "In this paper, the agent observes each bus at a given time $t$, and makes a decision regarding the replacement of the engine or its maintenance as a function of the observed state of the engine (i.e. its mileage).\n", 40 | "\n", 41 | "As in the original paper, we discretize the number of states into intervals of length 5000, and define a transition density which governs the evolution of mileage from one time period to another: \n", 42 | "\n", 43 | "$$ p(x_{t+1} | x_{t} , i_{t} , \\theta_{3}) = \\left\\{\n", 44 | " \\begin{array}{l l}\n", 45 | " g(x_{t+1} - x_{t}, \\theta_{3}) & \\quad \\text{if } i_t = 0\\\\\n", 46 | " g(x_{t+1} - 0, \\theta_{3}) & \\quad \\text{if } i_t = 1\n", 47 | " \\end{array} \\right.$$\n", 48 | " \n", 49 | "Here, the function g is defined by a multinomial distribution on the set {0, 1, 2}. In other words, the probability that a bus' mileage will increase by a value x between now and the next maintenance decision is:\n", 50 | "* $\\theta_{31}$ if $x \\in [0, 5000[$\n", 51 | "* $\\theta_{32}$ if $x \\in [5000, 10,000[$\n", 52 | "* $\\theta_{33} = 1 - (\\theta_{31} + \\theta_{32})$ if $x \\in [10,000, +\\infty[$\n", 53 | "\n", 54 | "## 2°) Decision criteria\n", 55 | "\n", 56 | "The utility function of the decision maker for a single time period is:\n", 57 | "\n", 58 | "$$ u(x_{t}, i , \\theta_{1}) = \\left\\{\n", 59 | " \\begin{array}{l l}\n", 60 | " \\qquad \\enspace -c(x_t, \\theta_1) + \\epsilon_t(0)& \\quad \\text{if } i = 0\\\\\n", 61 | " -RC -c(0, \\theta_1) + \\epsilon_t(1) & \\quad \\text{if } i = 1\n", 62 | " \\end{array} \\right. \\quad \\text{(Errors are I.I.D. standard Gumbel)}$$\n", 63 | "\n", 64 | "The agent will chose the decision which maximizes its utility. If the agent is forward looking (i.e. if $\\beta \\neq 0$), he does not only maximize his utility in the present time period, but also his future utility discounted by $\\beta$.\n", 65 | "\n", 66 | "Since $\\beta$ cannot be estimated without knowing the utility function, we will later set $\\beta$ to its true value.\n", 67 | "\n", 68 | "## 3°) Cost function\n", 69 | "\n", 70 | "A functional form has to be imposed on the cost function $c(x_t)$. \n", 71 | "\n", 72 | "Here, we assume that the true cost function is a quadratic function of the current state of the bus:\n", 73 | "\n", 74 | "$$ c(x_{t}) = \\theta_{11}x + \\theta_{12}x^2$$" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "# III. Data-generating process\n", 82 | "\n", 83 | "## Bus mileage\n", 84 | "\n", 85 | "The generation of a fake dataset can be done in two different ways:\n", 86 | "* Generating monthly mileage increase from a continuous distribution, discretize the mileage, and recover the state transition parameters ($\\theta_3$) using a maximum-likelihood estimation (as done in the paper).\n", 87 | "* Set the vector $\\theta_3$ to an arbitrary value, and generate discrete states transitions with corresponding probabilities. \n", 88 | "\n", 89 | "The advantage of the first method is that this is closer to what is actually done in the paper: indeed, the focal goal of the paper is to recover RC and the cost scaling vector of parameters $\\theta_1$. If the decision of the agent is based on the discretized state (and not on the actual mileage), then this approach is not noisier than the second one.\n", 90 | "\n", 91 | "For this reason, we will adopt the first approach, and assumes that:\n", 92 | "\n", 93 | "$$\n", 94 | "(M_{t+1} - M_{t}) \\sim \\Gamma(5000, 5000)\n", 95 | "$$" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 137, 101 | "metadata": { 102 | "collapsed": false 103 | }, 104 | "outputs": [], 105 | "source": [ 106 | "a = stats.truncnorm(a=0, b=100000, loc=3000, scale = 6000)\n", 107 | "\n", 108 | "lower, upper = 0, 100000\n", 109 | "mu, sigma = 5000, 6000\n", 110 | "a = stats.truncnorm((lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 139, 116 | "metadata": { 117 | "collapsed": false 118 | }, 119 | "outputs": [ 120 | { 121 | "data": { 122 | "text/plain": [ 123 | "[]" 124 | ] 125 | }, 126 | "execution_count": 139, 127 | "metadata": {}, 128 | "output_type": "execute_result" 129 | }, 130 | { 131 | "data": { 132 | "image/png": [ 133 | "iVBORw0KGgoAAAANSUhEUgAAAv8AAAHhCAYAAAD5z9FUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n", 134 | "AAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xl0VdXh9vHvvZnniYRAGEPIDmRgVBQURFFABUScrVpb\n", 135 | "ta1Kbe3b2uX762942/5sa7UVrdo61DorIIgiOMskDoxJGA4QwhxC5nm+9/0j0VILBjE35w7PZ60u\n", 136 | "Es7dN8/ZzZLnnHvOPg63242IiIiIiPg/p90BRERERESkd6j8i4iIiIgECJV/EREREZEAofIvIiIi\n", 137 | "IhIgVP5FRERERAKEyr+IiIiISIAI/rqNxhgn8CiQB7QAt1iWVXTc9lnAr4B24GnLsp482RhjTAbw\n", 138 | "DOACCoE7LMtyG2NuBW7reo/fWJa13BiTADwLxAONwK2WZR3owf0WEREREQk43Z35vwwItSxrIvBL\n", 139 | "4IEvNhhjQoAHgQuBKcBtxpiUrjFhJxjzIHCvZVmTAQcwxxiTCswHJgLTgfuMMaHAvcA6y7LOBf4A\n", 140 | "LOiJnRURERERCWTdlf9JwEoAy7I+BcYft20EsMeyrBrLstqAtcDkrjErTjBmrGVZq7u+XgFMA86g\n", 141 | "s+S3WZZVC+yh8xODkV/8XOBjOg8uRERERETkW+iu/McCtcd939F1Wc8X22qO21YHxJ1kTBCdZ/tP\n", 142 | "9NoTvccWYHbX380GIrvdExERERER+Vpfe80/nSU+5rjvnZZlubq+rvnKthig+iRjOowxruP+LvYk\n", 143 | "r40BqoD7gAXGmFXAcuBgdzvidrvdDoeju5eJiIiIiPiSHi243ZX/dcAsYKEx5iwg/7htO4HhXTfn\n", 144 | "NtB5yc/9gPskYzYbY6ZYlrUKmAm8D3wG/NYYEwaE03kpUSGd9xE8YVnWemPMPGBNdzvicDgoK6s7\n", 145 | "lX2Wbyg5OUZz6yGaW8/R3HqW5tdzNLeeo7n1HM2t5yQnx3T/om+gu/K/BLjQGLOu6/ubjTHXAtGW\n", 146 | "ZT1hjLkbeJvOy4eesiyrxBjzb2O6/vwZ8ETXDb3bgUVdq/0soLPcO+m8IbjVGLMT+IcxxgFUHvce\n", 147 | "IiIiIiJymhxut9vuDD3FrSNOz9DRvOdobj1Hc+tZml/P0dx6jubWczS3npOcHNOjl/3oIV8iIiIi\n", 148 | "IgFC5V9EREREJECo/IuIiIiIBAiVfxERERGRAKHyLyIiIiISIFT+RUREREQChMq/iIiIiEiAUPkX\n", 149 | "EREREQkQKv8iIiIiIgFC5V9EREREJECo/IuIiIiIBAiVfxERERGRAKHyLyIiIiISIFT+RUREREQC\n", 150 | "hMq/iIiIiEiAUPkXEREREQkQKv8iIiIiIgFC5V9EREREJECo/IuIiIiIBAiVfxERERGRAKHyLyIi\n", 151 | "IiISIFT+RUREREQChMq/iIiIiEiAUPkXEREREQkQKv8iIiIiIgFC5V9EREREJECo/IuIiIiIBAiV\n", 152 | "fxERERGRAKHyLyIiIiISIFT+RUREREQChMq/iIiIiEiAUPkXEREREQkQKv8iIiIiIgFC5V9ERERE\n", 153 | "JECo/IuIiIiIBAiVfxERERGRAKHyLyIiIiISIILtDiAi3snlctPS1kGHy33C7aHBTkKCnTgcjl5O\n", 154 | "JiIiIqdL5V8kQDS1tFNR00x5bTOVtc3U1LdS19RGfWMrdY1t1DW10dTSTmtbBy1tLto7XN2+pwMI\n", 155 | "DQkiNMRJaHAQURHBxESGEhMZQkxE55/x0WEkxYWTFBdOYkwYwUH6wFFERMQuKv8ifqS9w0VpZSMl\n", 156 | "FY0cqWjgSHkDRysbqahppqG5/WvHRoUHExEWTHxMGKHBQYSFOAkNCSI4yMlXz+273G7a2l1fHii0\n", 157 | "tnfQ3NrB0cpGDpTWn/RnOBwQHx1GcnwE/ZMi6ZcURf8+UfRLiiQhJkyfIoiIiHiYyr+Ij2pr7+Dg\n", 158 | "sQb2Ha1l39E69pXUUVLR8G+X6YQGO0mKCye9f1znGfjYzjPxcVFhnWfoI0OJjggmyNkzZ+Rb2jqo\n", 159 | "a2ylvqmNusY2qupaKK9ppqKmmYrazj93H6pm18HqfxkXERbE4L4xDEmNZUi/GAanxpASH6EDAhER\n", 160 | "kR6k8i/iI+qb2th9sBrrYGdxPnis/l+KfmiwkyGpMfTv88XZ9Cj694kkMTYcZy8W6LCQIMLiIugT\n", 161 | "F3HS17S1d3C0somSrk8njlQ0crisHutANTsP/POgIDIsmIwBcWQOjCdzYDxDUmN02ZCIiMi3oPIv\n", 162 | "4qVa2jrYub+Kwr2VWAerOFTW8OW2IKeDQX1jGNrvn2fK+yVF9tjZe08LCQ5iYEo0A1Oi/+Xvm1ra\n", 163 | "OVBa1/lJxtE6io/Ukl9UQX5RBdB5gDMsLY6swQnkpScxsG90rx7YiIiI+DqVfxEv4Xa7OVrZSEFR\n", 164 | "BQXFlVgHqr+86TY02MmIwQlfngFP7x9LWEiQzYl7XkRYMGZQAmZQwpd/V1XXwu5D//zEY8f+Knbs\n", 165 | "r2LJ6r3ERoWSMzSRnPREcoYmER0RYmN6ERER76fyL2Ijt9tNcUktG3YeY6NVxrHqpi+3DUyJJic9\n", 166 | "kbz0JIalxQXs5S4JMWGcOaIvZ47oC0BdYyvb91VRuLfzIOnjwqN8XHgUp8OBGRTPOJPM2MxkkpNj\n", 167 | "bE4uIiLifVT+RXqZy+1m75HOwr9lTznHqjoLf1hoEONNMrnpSeSkJ5EQE2ZzUu8UExnKhJF9mTCy\n", 168 | "Ly63m4Ol9RTsrWDLnvIvPxV44Z1dZA1JZFR6IuOzUkiMDbc7toiIiFdQ+RfpJaVVjawrOMr6wqNU\n", 169 | "1DYDEBkezNnZfRlvUshJTyQk2P8u5fEkp8PB4NTOlYEunTiEytpmNu4qY6NVxs79lezYV8krH+wh\n", 170 | "a3ACE3NSGZuZTESY/rMnIiKBS/8KinhQY3M7n+8sZV3hUfYcqgE6z/BPzEnljKwUppwxiOqqRptT\n", 171 | "+o/E2HAuHD+QC8cPJDg8hPfW7+OTbUe//ETguXcsxmUmMzGnHyMGJ+B06mZhEREJLCr/Ij3M3XVZ\n", 172 | "zwebDrPBOkZbuwsHMHJIApNy+jE2M5mw0M4z/DrT7zkJMeGcNyaN88akcay6iU+67g1Yv62U9dtK\n", 173 | "SYoNY/LoNCbn9SMuWpdYiYhIYFD5F+khLW0dfLq9lA82HfryKbd9EyKYlNuPiTmpuu7cRinxEcw+\n", 174 | "ZyizJg2h6HAtawtK+HR7KUtW72XZ2mLGZiYzdUwaZlC8HiomIiJ+TeVf5Fs6VtXIB5sOsza/hMaW\n", 175 | "dpwOB+Myk5k6No0RgxNUJr2Iw+EgY0AcGQPiuPr8DNZvO8qHmw/z+c5jfL7zGP2SIpk2bgATc/v5\n", 176 | "5VKqIiIiKv8ip2nvkVpWfrqfjVYZbiA2KpRZ44YwZXR/neX3ARFhwZw/dgBTx6Sx+1ANH24+zIad\n", 177 | "x3junV0sWVPM+WPTOH/sAGKjQu2OKiIi0mNU/kW+AZfbTX5RBSs/PcCug9UADO4bw/QJAxlvUgJ2\n", 178 | "LX5f5nA4vnx42jXnZ/D+psN8uOkQy9bt461PDjApN5WLzhhIv6Qou6OKiIh8ayr/Iqegw+Xis+3H\n", 179 | "eHP9PkoqOlfnyUlPZOaZg8jSpT1+Iy46jMsnp3PJWYNZW1DCO58fYNWWI6zacoRxJplZE4cwqK8e\n", 180 | "HiYiIr5L5V/ka3xR+pd9vI/SykaCnA7Ozk5lxoRBDEyJtjueeEhYaBAXjOu8JGjTrjJWdF3etdEq\n", 181 | "Y8zwPsyeNJTBqToIEBER36PyL3ICJyr9U0b355KzBtMnPsLueNJLnE4H47NSGGeSKdhbybJ1xWze\n", 182 | "Xc7m3eWMzujD7HOGMCQ11u6YIiIip+xry78xxgk8CuQBLcAtlmUVHbd9FvAroB142rKsJ082xhiT\n", 183 | "ATwDuIBC4A7LstzGmFuB27re4zeWZS03xkQCLwHxQCvwHcuySntwv0VOyOV2s2HnMZasKVbply85\n", 184 | "HA7yhiWRm57ItuJKXl9XzJY95WzZU87YzGTmTUnXPQEiIuITujvzfxkQalnWRGPMBOCBrr/DGBMC\n", 185 | "PAiMBxqBdcaYZcA5QNgJxjwI3GtZ1mpjzGPAHGPMJ8B8YBwQAaw1xrwL3AjssCzrl8aYW4CfA/+n\n", 186 | "R/dc5Ct27Kvk1Y+K2H+07p+l/+zB9IlT6ZdODoeDnPQksocmsn1/FUtX72XTrjI27y7j3Lx+zDkn\n", 187 | "nYQYPTBMRES8V3flfxKwEsCyrE+NMeOP2zYC2GNZVg2AMWYtMBk4G1hxgjFjLcta3fX1CuAioANY\n", 188 | "Z1lWG9BmjNlD5ycGTUBS12vj6Dz7L+IRB0rrWPRREYXFlQBMGNmXuecOJSUh0uZk4q0cDgfZQxIZ\n", 189 | "OTiBzbvLWbyqiNVbS1i/rZRp4wdw8VmDiQoPsTumiIjIv+mu/McCtcd932GMcVqW5eraVnPctjo6\n", 190 | "i/qJxgQBjpO89qvvEQssAX5pjNkGJNB5UCHSoyprm1m8qohPtpXiBkYMTuDKqcN0DbecMofDwdjM\n", 191 | "ZEZlJPFxwVGWri1mxScHWL3lCLMnDWXq2DQt/yoiIl6lu/JfCxy/pMUXxR86S/vx22KA6pOM6TDG\n", 192 | "uI77u9iTvDam633/CDxoWdYTxphcYDEwqrudSU7W6hue4k9z29LWwZKP9rDog920tHaQ3j+Omy4d\n", 193 | "yZjMZFuW7PSnufU2vTm3l/eN45IpGSxfu5dX39vFS+/vZk1BCbfMyWFcVt9ey9Gb9LvrOZpbz9Hc\n", 194 | "eo7m1jd0V/7XAbOAhcaYs4D847btBIYbYxKABjrPzt8PuE8yZrMxZoplWauAmcD7wGfAb40xYUA4\n", 195 | "nZcSFQJR/PPTgzI6Dxa6VVZWdyovk28oOTnGL+bW7Xaz0SrjlQ/2UFHbTGxUKNdNG86k3H44HQ7K\n", 196 | "y+t7PZO/zK03smtuz81JZVR6IkvXFLNqy2H++4lPyBuWxDUXDCc10X8uJdPvrudobj1Hc+s5mlvP\n", 197 | "6emDqu7K/xLgQmPMuq7vbzbGXAtEd52Vvxt4G3ACT1mWVWKM+bcxXX/+DHjCGBMKbAcWda32swBY\n", 198 | "0/Ue91qW1WKMubfrtXd0Zbylh/ZXAtTBY/W89N4udh6oJsjpYOaEQVw6cQgRYVrtVnpebGQoN043\n", 199 | "TB2Txkvv7SK/qIJtxZVMGz+A2ZOG6vdORERs43C73XZn6CluHXF6hi8fzTe3trN0TTHvbjiI2w2j\n", 200 | "us7A9vWSM7C+PLfezlvm1u12s2lX5ydO5TXNJMSEce0Fwxln7LnMrKd4y/z6I82t52huPUdz6znJ\n", 201 | "yTE9+o+FTj+J39q8q4zn391FVV0LKQkRXH9hJrnpSd0PFOlBDoeDcSaFvGFJvPXJAZav38ejSwvJ\n", 202 | "G5bE9RdmkqznR4iISC9S+Re/U1nbzAvv7mLz7nKCnA5mTRzCpRMHExIcZHc0CWAhwUHMOWcoE0b2\n", 203 | "5bm3LfKLKti5/1NmTRrC9DMHaVUgERHpFSr/4jc6XC7e33CIJWuKaWnrIHNgPDdON/TvoyevivdI\n", 204 | "TYzk/1wzmk+3l/Ly+7tZvGov67eVcuN0Q+bAeLvjiYiIn1P5F79w6Fg9T721g/1H64iOCOH6CzOZ\n", 205 | "lJvq09dUi/9yOByclZ1K7rAkFq/ay6rNh/n9C5u4YNwA5k0ZRlioPqUSERHPUPkXn9be4WLFpwdY\n", 206 | "traYDpebs7NTueaCDGIiQ+2OJtKtqPAQbpxumJidytNv7eC9jYfYWlTOzTNHkDU4we54IiLih1T+\n", 207 | "xWcdOlbPU8t3sL+0jvjoUG6akcWojD52xxL5xjIGxPHfN5/B62uLWfnZAf7w0mamjk3jiinDtCyo\n", 208 | "iIj0KP2rIj6nvcPFik/2s2zdPjpcbiblpnLNBcOJCg+xO5rIaQsNCeLKqRmMMyk8/dYOPtx0mPw9\n", 209 | "FXz34iyyhyTaHU9ERPyEyr/4lMPlDTz5xnad7Re/ld4/lv/67hksW1fMik8O8MDLW7hg7ACumDqM\n", 210 | "sBDdCyAiIt+Oyr/4BLfbzQebDvPqh3toa3cxKSeVa6bpbL/4p5BgJ/OmDGOcSebJN3fw/qZDbN9f\n", 211 | "yW2zshmc2rOPeRcRkcCihaXF69XUt/Dnhfm88O4uwkKCuPPyXL5/6UgVf/F7Q1Jj+c+bxjNt3ABK\n", 212 | "Khr5zbMbeOuT/bhcfvNkdhER6WU68y9ebfPuMv7+1k7qm9rIGZrI9y4ZQXx0mN2xRHpNaEgQ112Y\n", 213 | "SV5GEk8t38Gij4rIL6rglktH0CdOTwcWEZFvRmf+xSu1tHbwj5U7eXhxAc2tHVw7bTg/uWqUir8E\n", 214 | "rJyhSfz6+xMYl5nMroPV/NfTn/HJtqN2xxIRER+jM//idQ4eq+expYUcrWxkQHI0P5g9krTkaLtj\n", 215 | "idguOiKE2+fmsK7gKC+8t4u/vbGd7furuH5aph4MJiIip0TlX7yG2+1m9dYjvPjebtraXVx0xkDm\n", 216 | "TRlGSLA+oBL5gsPh4Jy8fmQOjOOxpdtYm1/C3iO1/GhOtg6SRUSkW2pV4hWaWtr52xvb+cdKi9Bg\n", 217 | "Jz+el8c1FwxX8Rc5iZSESO69YRzTxg3gSHkDv/7HBtZsPYLbrZuBRUTk5HTmX2x3oLSOx5YWUlrV\n", 218 | "xLC0WH44O4ekuHC7Y4l4vZBgJ9ddmEnW4ASeXr6Dv6/YyY4DVdxwkdGTgUVE5IT0r4PYxu1289GW\n", 219 | "I7z03m7aO1zMnDCIuZPTCQ7S2X6Rb2JsZjKDUqJ5fNk2PtlWSvGRWm6fm8vAFF0GJCIi/0otS2zR\n", 220 | "0tbBE29u57m3LcJDg7jrijyunJqh4i9ymvrER/DL68cy48xBlFY18dtnN7BeqwGJiMhX6My/9Lpj\n", 221 | "VY088lohh8rqGdY/lh9dlkNirC7zEfm2goOcXHV+BhkD4nhq+XaeeGM7e4/UcvX5OrAWEZFOKv/S\n", 222 | "q/KLKvjbsm00trQzdUyabuoV8YCxmcn073MGj7xWwPsbD7G/tI4fzckhIUbPyRARCXRqXdIrXG43\n", 223 | "y9YV89DCrbS2u/jexSO4YbpR8RfxkNTESP7jxnGcOSKFPYdq+H/PfM6ug9V2xxIREZupeYnHNTa3\n", 224 | "8cjiApauKSYxNpx7bxjLOXn97I4l4vfCQ4P5wexsrjk/g7rGNu5/aTPvfn5Qy4GKiAQwXfYjHnW4\n", 225 | "rJ6HXyvgWFUTI4ck8IPZ2cREhtodSyRgOBwOLjpzEINTY3hsaSEvvb+bfUdr+e7MLEKC9VRgEZFA\n", 226 | "ozP/4jFb9pTzm+c2cqyqiYvPGszdV41W8RexiRmUwH/dfCbp/WNZv62U372wmer6FrtjiYhIL1P5\n", 227 | "lx7ndrtZ8el+Hl6Uj9vl5odzsrnivGE4nQ67o4kEtISYMO65bgxnZ6dSXFLLr/+xgeKSWrtjiYhI\n", 228 | "L1L5lx7V1t7BU8t3sPDDIuJjwvjld8Zy5oi+dscSkS4hwUHccukIrpw6jOq6Fn73wiY+21FqdywR\n", 229 | "EekluuZfekxNfQuPLCmg6HAtQ/vFMn9eLvHRWlpQxNs4HA5mThhM/6Qo/rpsG4+/vo1DZfVcdm46\n", 230 | "Toc+oRMR8Wc68y89Yv/ROn797AaKDtdy1si+3HPdGBV/ES83KqMP//fG8aTER/Dmx/v5y2sFNLe2\n", 231 | "2x1LREQ8SOVfvrWNVhn3vbCRytoW5k1J59ZZIwkN0SoiIr4grU8U/3HTeLIGxbN5dzn3Pb+Jytpm\n", 232 | "u2OJiIiHqPzLaXO73bz92QEeXVKAAwd3Xp7LJWcPwaHLBkR8SnRECHdfPZrzxqRx8Fg9v3l2AwdK\n", 233 | "6+yOJSIiHqDyL6fF5XLzwru7eOWDPcRFh/LL68cyNjPZ7lgicpqCg5zccFEmV03NoLq+lfte2ER+\n", 234 | "UYXdsUREpIep/Ms31tLawSOvFfDBpsMMSI7iP24cz+DUGLtjici35HA4mDFhELdfloPL5WbBonw+\n", 235 | "3HzY7lgiItKDtNqPfCPV9S08tCif/UfryB6SwO1zc4kI06+RiD8Zn5VCQkwYCxbn89zbFmXVTZ3P\n", 236 | "6tAlfSIiPk9n/uWUHS6r57fPbmD/0TrOzevHXVeOUvEX8VPD0uL4vzeOJzUxkpWfHuDxpYW0tnXY\n", 237 | "HUtERL4llX85JTv2VfK/z2+ioraFyyen892ZWQQH6ddHxJ+lxEdw7w3jyBwYzwarjPtf2kx9U5vd\n", 238 | "sURE5FtQe5Nurd58iAdf3Upbewe3zRrJpRO1oo9IoIiOCOFnV4/mrJF9KTpSy33Pb6SiRkuBioj4\n", 239 | "KpV/+VrvbjjI/c9vJDTEyd1Xjeas7FS7I4lILwsJdnLLrJFMP3MgJRWN/Pa5DewvqbU7loiInAaV\n", 240 | "fzkht9vN4lVFvPTebhJiwrjnurFkDU6wO5aI2MTpcHD1+cO/XAr0nr+sZdfBartjiYjIN6TyL/+m\n", 241 | "w+Xi7yt2snz9flISIvjD/HMZ1FdLeYoIzJgwiFsvHUlzSzsPvLKFzbvK7I4kIiLfgMq//IuWtg7+\n", 242 | "8loha/NLGJwaw73fGUdqUpTdsUTEi5ydk8qvvj8Bp8PBI0sKWLVFzwIQEfEVKv/ypfqmNh54ZQtb\n", 243 | "9pSTPSSBX1w7htioULtjiYgXGpfVl59fO4ao8BD+sdJi2bpi3G633bFERKQbKv8CQGVtM79/YRN7\n", 244 | "DtUwYWRfreEvIt1K7x/LvTeMo09cOEvXFPP8u7tw6QBARMSrqfwLpZWN3Pf8Rg6XNzBt3ABunTVS\n", 245 | "a/iLyClJTYzk3hvGMSA5mg83HeapN7fT4XLZHUtERE5CDS/AHTpWz30vdD68a+7kdK6dNhyn1vAX\n", 246 | "kW8gPjqMe64fw7D+sazfVsqjSwppa9fTgEVEvJHKfwArLqnl9y9uorahleumDWeWHt4lIqcpKjyE\n", 247 | "n10zmhGDE9i8u5yHFuXT0qoDABERb6PyH6CsA1X84aXNNLa0872LRzBt/EC7I4mIjwsPDeYnV+Yx\n", 248 | "OqMP2/dV8cdXNtPY3GZ3LBEROY7KfwDKL6rgwVe30t7u4kdzcjgnr5/dkUTET4QEB3H73BzOGtmX\n", 249 | "osO1/P7FzdQ2tNodS0REuqj8B5gNO4/x8OJ8AObPy2N8VorNiUTE3wQHObll1kjOG5PGwWP1/O6F\n", 250 | "TVTWNtsdS0REUPkPKGvzS3js9UJCgp3cfdUo8oYl2R1JRPyU0+HghosymTlhEEe7VhQrrWq0O5aI\n", 251 | "SMBT+Q8Q7288xNNv7SAyLJifXzsGMyjB7kgi4uccDgdXTs1g3pR0Kmpb+N0LmyipaLA7lohIQFP5\n", 252 | "DwDvfH6QF97dRWxUKPdcP5ah/WLtjiQiAeSSs4dw7QXDqalv5fcvbuZwWb3dkUREApbKv59b+ekB\n", 253 | "Xn5/N/HRodxz3RgGJEfbHUlEAtCFZwzkOxdlUtvQyh9e2szBYzoAEBGxg8q/H1u+fh+vfriHhJgw\n", 254 | "7rl+LP2SouyOJCIB7PyxA7hxhqGusY37X9rMgdI6uyOJiAQclX8/9ca6Yhav2ktSbGfx75sQaXck\n", 255 | "ERHOG53GzTOzaGjqPADYd7TW7kgiIgFF5d/PuN1ulq7Zy5I1xfSJC+ee68aSEh9hdywRkS+dO6o/\n", 256 | "37tkBI0t7dz/0haKjtTYHUlEJGCo/PsRt9vNkjV7WbZuH8nx4fziujH0UfEXES80Kbcft146kubW\n", 257 | "dh54eQt7DukAQESkNwR/3UZjjBN4FMgDWoBbLMsqOm77LOBXQDvwtGVZT55sjDEmA3gGcAGFwB2W\n", 258 | "ZbmNMbcCt3W9x28sy1pujLkHmNH1YxKAvpZl6TG0X8PtdrNoVRErPjlASkIEv7h2DImx4XbHEhE5\n", 259 | "qbOyUwkKcvLX17fxwKtb+OmVo8gcGG93LBERv9bdmf/LgFDLsiYCvwQe+GKDMSYEeBC4EJgC3GaM\n", 260 | "SekaE3aCMQ8C91qWNRlwAHOMManAfGAiMB24zxgTalnW7y3LmmpZ1lTgIHBDz+yuf3K73bz64R5W\n", 261 | "fHKAvomR3HPdWBV/EfEJZ2Sl8KPLsmlvd/Hgq1uwDlTZHUlExK91V/4nASsBLMv6FBh/3LYRwB7L\n", 262 | "smosy2oD1gKTu8asOMGYsZZlre76egUwDTgDWGdZVptlWbXAHjo/MQDAGHM5UGlZ1nunv4v+ze12\n", 263 | "s/DDIt7+7CD9kiK557oxJMSE2R1LROSUjTMp3D43h44ON39emM/uQ9V2RxIR8Vvdlf9Y4PilGDq6\n", 264 | "Luv5YtvxF2nWAXEnGRNE59n+E732RO/xhV8C/9NNxoDldrt5bfVeVn52gH5JkfziurHER6v4i4jv\n", 265 | "GTM8mR/OyaG9w8WDr26l6LDuARAR8YSvveafzhIfc9z3TsuyXF1f13xlWwxQfZIxHcYY13F/F3uS\n", 266 | "18YAVQDGmJFAtWVZe09xX0hOjun+RX7kxbd3snz9fvr3ieK+O87x6KU+gTa3vUlz6zmaW8/q6fmd\n", 267 | "kRxDTEw4f3h+A39auJVf/2AimYMSevRn+Ar97nqO5tZzNLe+obvyvw6YBSw0xpwF5B+3bScw3BiT\n", 268 | "ADTQecnP/YD7JGM2G2OmWJa1CpgJvA98BvzWGBMGhNN5KVFh1+unAW99k50pKwucB8a88fE+lqze\n", 269 | "S3J8OHdfNYqOljbKyto88rOSk2MCam57k+bWczS3nuWp+c3sH8Otl47kb29s41ePf8zPrx3D4NTA\n", 270 | "KhT63fUcza3naG49p6cPqrq77GcJ0GyMWUfnjbs/NcZca4y5tes6/7uBt4GPgacsyyo50Ziu9/oZ\n", 271 | "8D/GmI/pPOhYZFlWKbAAWEPnwcC9lmW1dr0+Ezjls/6BZMWn+1myei9JseH8XKv6iIifmTCyL7dc\n", 272 | "OpKmlnb++LKeBCwi0pMcbrfb7gw9xR0IR5zvfH6Ql9/fTUJM55N7e+MBXjqa9xzNredobj2rN+Z3\n", 273 | "XUEJTy/fQVRECL+4dgwDUqI9+vO8hX53PUdz6zmaW89JTo5xdP+qU6eHfPmQ9zce4uX3dxMfHcov\n", 274 | "rhujJ/eKiF+blNuPm2ZmUd/Uxv0vb+ZweYPdkUREfJ7Kv4/4aMthXnh3F7FRofz82jH0TYi0O5KI\n", 275 | "iMdNHtWfG2cY6hrbuP+lzZRU6ABAROTbUPn3AWvyj/DsSouYyBB+fu0Y+iVF2R1JRKTXnDc6jesv\n", 276 | "zKS2oZX7X9rMseomuyOJiPgslX8v98m2ozzz1k6iI0L4+TVjSOuj4i8igeeCcQO4+vwMqutb+eNL\n", 277 | "m6mqa7E7koiIT1L592Kbd5Xx5Js7CA8L5mdXjw6Ym91ERE5k+pmDuOycoZTXNPPHlzdT29Da/SAR\n", 278 | "EfkXKv8zg1kXAAAgAElEQVReatu+Sh57vZCQYCc/vWpUwK1zLSJyIrMmDWHGmYMoqWjkwVe20Njs\n", 279 | "meebiIj4K5V/L7TnUA0PL84HHMyfl0tGWpzdkUREvILD4eDKqcM4b0waB47V86dXt9Lc2m53LBER\n", 280 | "n6Hy72UOlNbxp4VbaW93c/tlOYwckmh3JBERr+JwOPjORZmcnd2XoiO1PLy4gLb2DrtjiYj4BJV/\n", 281 | "L1JS0cADr2yhuaWdW2aNYPTwPnZHEhHxSk6Hg+9dMoKxmcns2F/FX5YU0t7hsjuWiIjXU/n3EuXV\n", 282 | "Tfzx5S3UNbZx4wzDWSNT7Y4kIuLVgpxOfjA7m5yhieQXVfDEG9txufzmqfUiIh6h8u8FqupauP/l\n", 283 | "zqXrrj4/gymj0+yOJCLiE0KCndxxeS6ZA+L4fOcxnlmxE5dbBwAiIiej8m+zusZWHnhlC2XVzcye\n", 284 | "NITpZw6yO5KIiE8JCwniritHMSQ1hrUFJbz03m7cOgAQETkhlX8bNbW08+CrWzlS3sBFZwxkzjlD\n", 285 | "7Y4kIuKTIsKCufvq0aQlR/H+xkO8sW6f3ZFERLySyr9N2to7WLAon/1H65g8qh9Xn5+Bw+GwO5aI\n", 286 | "iM+Kjgjh7qtG0ycunKVri/lg0yG7I4mIeB2Vfxt0uFw8/vo2rIPVjDfJ3Dg9S8VfRKQHJMSE8bNr\n", 287 | "RhMbGcIL7+zi0+2ldkcSEfEqKv+9zO128+xKi827yxkxOIFbZ2XjdKr4i4j0lL4Jkdx99WjCw4J4\n", 288 | "8s3tFO6tsDuSiIjXUPnvZYtX7WVNfglDUmO48/JcQoL1f4GISE8b1DeGH8/Lw+l08MiSAooO19gd\n", 289 | "SUTEK6h59qK3PzvAW5/sp29iJD+5ahQRYcF2RxIR8VtmUAI/nJNNe7ubPy/cyuGyersjiYjYTuW/\n", 290 | "l6wrKOGVD/Z0Xo969ShiI0PtjiQi4vfGDE/m5ouzaGjuXF2tvKbJ7kgiIrZS+e8FW/aU8/e3dhIV\n", 291 | "HszdV42iT1yE3ZFERALGpNx+XDU1g6q6Fh54ZSu1Da12RxIRsY3Kv4ftOljNY0sLCQ5ycNeVo0hL\n", 292 | "jrY7kohIwJkxYRAXnzWY0spG/vTqVppa2u2OJCJiC5V/Dzp4rJ6HFuXjcrm5fW4uGWlxdkcSEQlY\n", 293 | "86akM3lUP/aX1vHw4nza2jvsjiQi0utU/j2krLqJB1/dQlNLO9+7ZAR5w5LsjiQiEtAcDgc3TDeM\n", 294 | "y0xm54Fq/rZsOy6X2+5YIiK9SuXfA2obWnnglS3U1Ldy7QXDOTs71e5IIiICBDmd3DZ7JFmD4tm4\n", 295 | "q4wX39uF260DABEJHCr/Pay5tZ0/L9zKsaomLjl7MBeeMdDuSCIicpyQ4CDuvDyPAclRfLDpMG99\n", 296 | "st/uSCIivUblvwe1d7h4bOk29h2t45zcflw+Od3uSCIicgKR4cH89KrRJMaGsXjVXtYVlNgdSUSk\n", 297 | "V6j89xC3282zKy0K9laQm57EjTMMDofD7lgiInISCTFh/PSq0USFB/PMip0U7K2wO5KIiMep/PeQ\n", 298 | "19cWs7aghMGpMfzosmyCgzS1IiLeLq1PFPPn5eF0Onh0SSH7jtbaHUlExKPUUHvAR1sOs2zdPpLj\n", 299 | "w/nJlaMIDw22O5KIiJyizIHx3DYrm9a2Dv786laOVTXaHUlExGNU/r+lLXvKee5ti+iIEO6+ajRx\n", 300 | "UaF2RxIRkW9onEnm+osyqW1s48FXt1LbqKcAi4h/Uvn/FoqO1PD40kJCgpzcdWUefRMj7Y4kIiKn\n", 301 | "6fyxA7jk7MEcq2rioYVbaWnVQ8BExP+o/J+m0spGHlqYT1uHix9elsOw/np6r4iIr7t8cjqTclIp\n", 302 | "LqnjsdcL6XC57I4kItKjVP5PQ01DKw++uoX6pjZunG4YndHH7kgiItIDHA4HN83MIic9kfyiCv6x\n", 303 | "0tJDwETEr6j8f0NfPMSrrLqZ2ZOGMGV0mt2RRESkBwUHObn9shwGp8awNr+EpWuK7Y4kItJjVP6/\n", 304 | "gS8e4rX/aB3n5PVjzjlD7Y4kIiIeEB4azE+uHEVKfARvfLyP1VuP2B1JRKRHqPyfon97iNd0PcRL\n", 305 | "RMSfxUWF8tOrRhEdEcKzKy0K9RAwEfEDKv+naNm6fawtKGGIHuIlIhIw+iZG8uOuh4D9ZWkhB0rr\n", 306 | "7I4kIvKtqMGegnUFJby+tpg+ceHcpYd4iYgElIwBcdw6ayQtrR08tCifytpmuyOJiJw2lf9u7Nhf\n", 307 | "xTMrdhIVHsxPrxqlh3iJiASgM7JSuGpqBlV1Lfx5YT5NLe12RxIROS0q/1/jcHkDj7xWAMCdl+fS\n", 308 | "LynK5kQiImKX6WcOZOqYNA6V1fPo0kLaO/QMABHxPSr/J1HT0MpDC7fS1NLO9y4egRmUYHckERGx\n", 309 | "kcPh4LoLh5M3LIltxZU8/46eASAivkfl/wRa2jpYsGgr5TXNXHbuUM7OSbU7koiIeIEgp5Mfzslm\n", 310 | "cN8YVm8tYfn6/XZHEhH5RlT+v8LlcvO3ZdsoLqljUm4qsyYOsTuSiIh4kfDQYO66Mo+k2DBeW72X\n", 311 | "T7YdtTuSiMgpU/n/ilc/3MPm3eWMGJzATTOytJa/iIj8m/joMH5y5SgiwoJ4+q0dWAeq7I4kInJK\n", 312 | "VP6P8/7GQ7zz+UH694nijrk5WstfREROKi05mjvm5uJ2wyOvFVBS0WB3JBGRbqnddtmyu5wX39tF\n", 313 | "bFQoP7kij8jwELsjiYiIlxs5JJHvzsyiobmdP726lZqGVrsjiYh8LZV/YN/RWh5fVkhIkJO7rsij\n", 314 | "T3yE3ZFERMRHTMrtx5xzhlJe08yCRVtpaeuwO5KIyEkFfPmvqGnmoYX5tLW5+MHsbIb2i7U7koiI\n", 315 | "+JjZk4YwKSeV4pI6nnxjOy4tASoiXiqgy39jczt/Xtj5Me0104YzJjPZ7kgiIuKDHA4HN83MImtQ\n", 316 | "PBt3lfHaqr12RxIROaGALf/tHS4eXVrA4fIGpo0bwIXjB9odSUREfFhwkJPb5+bSNyGCtz7Zz5r8\n", 317 | "I3ZHEhH5NwFZ/t1uNy+8u4vt+6oYndGHay4YbnckERHxA9ERIfzkylFEhQfz7EqLHfu1BKiIeJeA\n", 318 | "LP/vfH6QVVuOMKhvND+YnY3TqbX8RUSkZ/RNjOTOy3MBeHRJAUcrG21OJCLyTwFX/rfsLufVD/YQ\n", 319 | "Hx3KXVeMIiw0yO5IIiLiZ8ygzgdFNnTdW1bf1GZ3JBERIMDK/4HSOv66bBshwU5+fEUeCTFhdkcS\n", 320 | "ERE/dU5ePy45ezDHqpp45LUC2jtcdkcSEQmc8l9d38KCxfm0tHVw66yRDEnVkp4iIuJZcyenM94k\n", 321 | "s+tgNf9YsRO3lgAVEZsFRPlvaevg4cX5VNa2cMV5wxhnUuyOJCIiAcDpcPD9S0cytF8M6wqP8tYn\n", 322 | "++2OJCIBLvjrNhpjnMCjQB7QAtxiWVbRcdtnAb8C2oGnLct68mRjjDEZwDOACygE7rAsy22MuRW4\n", 323 | "res9fmNZ1nJjTBDwIDAOCAX+07Kslaezgy63m6fe3E5xSR2TclOZOWHQ6byNiIjIaQkLCeLH8/L4\n", 324 | "9bMbWLxqL30TIhmfpZNQImKP7s78XwaEWpY1Efgl8MAXG4wxIXQW9AuBKcBtxpiUrjFhJxjzIHCv\n", 325 | "ZVmTAQcwxxiTCswHJgLTgfuMMaHADUCwZVnndL3fiNPdwaVritlglZE5MJ6bZmThcGhlHxER6V1x\n", 326 | "0WFfLjLxxJvb2Xuk1u5IIhKguiv/k4CVAJZlfQqMP27bCGCPZVk1lmW1AWuByV1jVpxgzFjLslZ3\n", 327 | "fb0CmAacAayzLKvNsqxaYA+dnxhcBBw2xrwJPAG8fjo7t77wKG9+vI+U+AjumJtDcFBAXOUkIiJe\n", 328 | "aGBKND+ak017h4sFi/OpqGm2O5KIBKDu2nAscPzpiY6uy3q+2FZz3LY6IO4kY4LoPNt/otee6D36\n", 329 | "AMMsy7oU+D3w91Pam+PsOljN31fsIDIsmLuuzCMmMvSbvoWIiEiPyhvW+WDJ2oZWHlq0laaWdrsj\n", 330 | "iUiA+dpr/uks8THHfe+0LOuLtcpqvrItBqg+yZgOY8zxa5zFnuS1X7xHBbAcwLKs1caYzFPZmeTk\n", 331 | "zrc6WtHAo0sLcbnh3u+eSV5m8qkMl6/xxdxKz9Pceo7m1rM0v6fn2hkjqG1qZ/m6Yv6+0uI/bj6T\n", 332 | "oK98Mq259RzNredobn1Dd+V/HTALWGiMOQvIP27bTmC4MSYBaKDzkp/7AfdJxmw2xkyxLGsVMBN4\n", 333 | "H/gM+K0xJgwIp/NSogI6LyG6GHjNGDMKOKXlEcrK6mhsbue3z22gtqGVG2cY+ieEU1ZWdyrD5SSS\n", 334 | "k2M0hx6iufUcza1naX6/ncsmDWZ/SQ0bdpTyyCubue7Cf57j0tx6jubWczS3ntPTB1XdXfazBGg2\n", 335 | "xqyj88bdnxpjrjXG3Np1nf/dwNvAx8BTlmWVnGhM13v9DPgfY8zHdB50LLIsqxRYAKyh82DgXsuy\n", 336 | "Wum8zt9hjFkPPA788FR2psPl4rHXCympaOSiMwZy3ui0U50HERGRXhPkdPKjOTmk9YnivY2H+GjL\n", 337 | "YbsjiUiAcPjLA0fcbrf7Ty9u5MNNhxk1LIn58/JwOrWyT0/Q0bznaG49R3PrWZrfnlFW3cSv/7GB\n", 338 | "ppZ27r56NCMGJ2huPUhz6zmaW89JTo7p0ULrN8vfvLm2mA83HWZAcjS3zc5W8RcREa+XHB/BnZfn\n", 339 | "AvDokgJKqxptTiQi/s5vyv+TrxcQGxXKXVfkERHW3a0MIiIi3iFzYDw3Tjc0NLezYFE+9U1tdkcS\n", 340 | "ET/mN+U/OMjJ/Hm5JMWF2x1FRETkGzl3VH8uOmMgJRWN3P/cBjpcru4HiYicBr8p//9969kM6x9n\n", 341 | "dwwREZHTctXUDPKGJbHJOsYrH+yxO46I+Cm/Kf+5GX3sjiAiInLanE4HP5idzcC+Mby34RCrtAKQ\n", 342 | "iHiA35R/ERERXxcRFsx/fn8C0REhPP/OLnbur7I7koj4GZV/ERERL5KaFMUdc3MA+MuSAo5pBSAR\n", 343 | "6UEq/yIiIl7GDErghq4VgB5alE9jc7vdkUTET6j8i4iIeKHJx60A9Ndl23C5/OOhnCJiL5V/ERER\n", 344 | "L3XV1Axy05Mo2FvBqx9qBSAR+fZU/kVERLzUFysA9UuK5J3PD7J66xG7I4mIj1P5FxER8WKR4cHc\n", 345 | "dUUeUeHBPPe2hXVAKwCJyOlT+RcREfFyKQmR3DE3F4C/LCnkWHWTzYlExFep/IuIiPiArMEJfOei\n", 346 | "TOqb2liwKJ+mFq0AJCLfnMq/iIiIj5gyOo1p4wdwpLxBKwCJyGlR+RcREfEhV5+fQU56IvlFFSxa\n", 347 | "VWR3HBHxMSr/IiIiPiTI6eSHs7NJTYxk5acHWF941O5IIuJDVP5FRER8TGR4CD++Io+IsGD+vmIn\n", 348 | "e4/U2h1JRHyEyr+IiIgPSk2M5EdzsulwuXjktXyq6lrsjiQiPkDlX0RExEflpCdx5XkZVNe38shr\n", 349 | "BbS1d9gdSUS8nMq/iIiID5t+5kAm5qRSXFLLMyss3G6tACQiJ6fyLyIi4sMcDgc3zTCk949l/baj\n", 350 | "vP3ZQbsjiYgXU/kXERHxcSHBQdwxN5f46FAWfrSHgr0VdkcSES+l8i8iIuIHEmLCmD8vjyCnk8df\n", 351 | "30ZJRYPdkUTEC6n8i4iI+Imh/WK5eWYWTS3tLFhcQGNzm92RRMTLqPyLiIj4kbNzUpkxYRCllY08\n", 352 | "vmwbLpduABaRf1L5FxER8TNXTBlGbnoShXsrWfRRkd1xRMSLqPyLiIj4GafTwQ9mZ5OaGMnKzw7w\n", 353 | "cWGJ3ZFExEuo/IuIiPihyPBgfnxFHhFhwTyzwmLvkVq7I4mIF1D5FxER8VOpiZH8aE42HS4XD7+W\n", 354 | "T1Vdi92RRMRmKv8iIiJ+LCc9iaumZlBT38ojrxXQ1t5hdyQRsZHKv4iIiJ+76IyBTMxJpbiklmdW\n", 355 | "WLjdWgFIJFCp/IuIiPg5h8PBTTMM6f1jWb/tKG9/dtDuSCJiE5V/ERGRABASHMSdl+cSHx3Kwo/2\n", 356 | "kF9UYXckEbGByr+IiEiAiI8OY/68PIKcTv66bBslFQ12RxKRXqbyLyIiEkCG9ovl5ouzaGppZ8Hi\n", 357 | "Ahqb2+yOJCK9SOVfREQkwJydncrMCYMorWzk8WXbcLl0A7BIoFD5FxERCUDzpgwjb1gShXsrWfjR\n", 358 | "HrvjiEgvUfkXEREJQE6ng9tmZZOaGMnbnx1kXUGJ3ZFEpBeo/IuIiASoyPBgfnxFHpFhwfxjpcXe\n", 359 | "I7V2RxIRD1P5FxERCWCpiZH8cE42HS4Xj7yWT3V9i92RRMSDVP5FREQCXE56Eleel0F1fSuPvFZA\n", 360 | "W3uH3ZFExENU/kVERITpZw7k7Oy+7D1Sy7MrLdxurQAk4o9U/kVERASHw8FNM7IY2i+GdYVHeffz\n", 361 | "g3ZHEhEPUPkXERERAEJDgrjz8jziokN55cM9FBZX2B1JRHqYyr+IiIh8KSEmjDvn5hLkdPD40m2U\n", 362 | "VjXaHUlEepDKv4iIiPyLYWlx3DQji8aWdhYsyqeppd3uSCLSQ1T+RURE5N9Myu3HheMHUlLRyBNv\n", 363 | "bMelG4BF/ILKv4iIiJzQVecPI3tIAlv2lLNk9V6744hID1D5FxERkRMKcjr5wZwcUuIjWL5+P5/t\n", 364 | "KLU7koh8Syr/IiIiclLRESHMvyKP8NAgnl6+g/1H6+yOJCLfgsq/iIiIfK20PlHcNiubtnYXD7+W\n", 365 | "T21Dq92RROQ0qfyLiIhIt0YP78Nlk9OprG3hL0sKaO9w2R1JRE6Dyr+IiIickkvPHswZWSnsPlTD\n", 366 | "C+/uwq0VgER8jsq/iIiInBKHw8H3Lh7BoJRoVm05woebD9sdSUS+oeCv22iMcQKPAnlAC3CLZVlF\n", 367 | "x22fBfwKaAeetizryZONMcZkAM8ALqAQuMOyLLcx5lbgtq73+I1lWcuNMQ7gELCr60ettyzr3p7a\n", 368 | "aRERETk9YaFBzJ+Xx//7x+e89N5u+idFkTU4we5YInKKujvzfxkQalnWROCXwANfbDDGhAAPAhcC\n", 369 | "U4DbjDEpXWPCTjDmQeBey7ImAw5gjjEmFZgPTASmA/d1ve8wYKNlWVO7/qfiLyIi4iWS4sK5Y24u\n", 370 | "AI8uLaS8usnmRCJyqror/5OAlQCWZX0KjD9u2whgj2VZNZZltQFrgcldY1acYMxYy7JWd329ApgG\n", 371 | "nAGssyyrzbKsWmAPMAoYB6QZYz4wxiw3xmR+y/0UERGRHpQ5MJ7rL8qkvqmNBYsLaG5ttzuSiJyC\n", 372 | "7sp/LFB73PcdXZf1fLGt5rhtdUDcScYE0Xm2/0SvPdF7HAH+17Ks84H/BZ4/pb0RERGRXnPe6DSm\n", 373 | "jknjUFk9Ty3fgUs3AIt4va+95p/OEh9z3PdOy7K+WNur5ivbYoDqk4zpMMYcvyZY7EleGwNUATvo\n", 374 | "vAcAy7LWGWP6n8rOJCfHdP8iOS2aW8/R3HqO5tazNL+e40tz++Nrx1JW28xGq4wPtpRw7UXG7khf\n", 375 | "y5fm1tdobn1Dd+V/HTALWGiMOQvIP27bTmC4MSYBaKDzkp/7AfdJxmw2xkyxLGsVMBN4H/gM+K0x\n", 376 | "JgwIp/NSom3AfwOVwP3GmFHAgVPZmbIyPXXQE5KTYzS3HqK59RzNrWdpfj3HF+f2lktG8OtnNvDi\n", 377 | "2ztJiAxhnEm2O9IJ+eLc+grNref09EFVd5f9LAGajTHr6Lxx96fGmGuNMbd2Xed/N/A28DHwlGVZ\n", 378 | "JSca0/VePwP+xxjzMZ0HHYssyyoFFgBr6DwYuNeyrBbgd8BkY8yHwB+B7/bYHouIiEiPio0MZf68\n", 379 | "XEJDnDz55nYOHau3O5KInITDjx7Q4dYRp2foaN5zNLeeo7n1LM2v5/jy3G7YeYxHlxbSJy6c//zu\n", 380 | "GURHhNgd6V/48tx6O82t5yQnxzi6f9Wp00O+REREpEeMz0ph1sQhlNc089jSQto7XN0PEpFepfIv\n", 381 | "IiIiPWbOuUMZM7wPO/ZX8coHe+yOIyJfofIvIiIiPcbpcHDLpSNJ6xPF+xsPsXrrEbsjichxVP5F\n", 382 | "RESkR0WEBTP/ijyiwoN57m2LPYdquh8kIr1C5V9ERER6XEp8BLdfloPbDY8sKaCyttnuSCKCyr+I\n", 383 | "iIh4yIghiVxzQQa1Da08/FoBrW0ddkcSCXgq/yIiIuIxF4wbwDl5/dh/tI6/r9iJHy0xLuKTVP5F\n", 384 | "RETEYxwOBzdcZMhIi+PT7aWs+PSA3ZFEAprKv4iIiHhUSLCTO+bmkBATxuKPisgvKrc7kkjAUvkX\n", 385 | "ERERj4uLDmP+vFyCg538ddk2Sioa7I4kEpBU/kVERKRXDEmN5eaZWTS1dLBgcQGNzW12RxIJOCr/\n", 386 | "IiIi0mvOyk5l5oRBlFY28viybbhcugFYpDep/IuIiEivmjdlGHnDkijcW8mij4rsjiMSUFT+RURE\n", 387 | "pFc5nQ5um5VNamIkKz87wMeFJXZHEgkYKv8iIiLS6yLDg/nxFXlEhAXzzAqL4pJauyOJBASVfxER\n", 388 | "EbFFamIkP5yTTYfLxcOL86mub7E7kojfU/kXERER2+SmJ3HleRlU17fyl9cKaGvvsDuSiF9T+RcR\n", 389 | "ERFbTT9zIGdn96XoSC3Pvm3hdmsFIBFPUfkXERERWzkcDm6akcWQ1BjWFRzl3Q2H7I4k4rdU/kVE\n", 390 | "RMR2oSFBzJ+XR1xUKK98sJtt+yrtjiTil1T+RURExCskxIRx5+W5BDkdPL60kNKqRrsjifgdlX8R\n", 391 | "ERHxGsPS4rhhuqGhuZ2HFxfQ1NJudyQRv6LyLyIiIl7l3Lz+TBs/gCPlDTzxxnZcugFYpMeo/IuI\n", 392 | "iIjXufr8DEYOSWDLnnKWrtlrdxwRv6HyLyIiIl4nyOnkh3NySImP4M2P9/PZjlK7I4n4BZV/ERER\n", 393 | "8UrRESHMn5dLWGgQT7+1gwOldXZHEvF5Kv8iIiLitdKSo7lt1kja2lw8vDif2oZWuyOJ+DSVfxER\n", 394 | "EfFqY4Ync9nkdCpqW3h0SQHtHS67I4n4LJV/ERER8XqXnj2Y8Vkp7DpUw4vv7rI7jojPUvkXERER\n", 395 | "r+dwOPj+xSMYlBLNR1uO8OGmQ3ZHEvFJKv8iIiLiE8JCg7hzXi4xkSG8+N5urANVdkcS8Tkq/yIi\n", 396 | "IuIz+sRFcMfcXAD+sqSQ8uommxOJ+BaVfxEREfEpmQPjuf7CTOqb2liwuICW1g67I4n4DJV/ERER\n", 397 | "8TnnjUnjvDFpHCqr56nl23G73XZHEvEJKv8iIiLik66bNpzMgfFssMp44+N9dscR8Qkq/yIiIuKT\n", 398 | "goOc3D43h6TYcJauKWbzrjK7I4l4PZV/ERER8VmxkaHMn5dLaIiTv725nUNl9XZHEvFqKv8iIiLi\n", 399 | "0wb1jeGWS0bS0trBw4vzqW9qszuSiNdS+RcRERGfNz4rhVkTh1BW3cxjSwvpcLnsjiTilVT+RURE\n", 400 | "xC/MOXcoY4b3Ycf+Kl55f4/dcUS8ksq/iIiI+AWnw8Etl44krU8U7208xKoth+2OJOJ1VP5FRETE\n", 401 | "b0SEBTP/ijyiI0J4/p1d7NxfZXckEa+i8i8iIiJ+JSU+gjvm5gDwlyUFlFY12pxIxHuo/IuIiIjf\n", 402 | "MYMSuHG6oaG5nQWL8mls1gpAIqDyLyIiIn7q3FH9mXHmIEoqGnns9W10dGgFIBGVfxEREfFbV5w3\n", 403 | "jFHDkthWXMmTrxfaHUfEdir/IiIi4recTge3zc4mLTmKN9cV88GmQ3ZHErGVyr+IiIj4tYiwYO6a\n", 404 | "l0dcdCgvvrubbfsq7Y4kYhuVfxEREfF7feIjuPe7Z+J0wmNLCimpaLA7kogtVP5F/n97dx5nRXnm\n", 405 | "bfw6vbI1ewNiEBXwYW0WiSJJgExcopG4ErfExAScqDEazEeNmcy8mU8S500iLuOSxfhqxBVG1Ghc\n", 406 | "oqNR0KhRFlvxQRBcEBGUfemml/ePc9AOaWig+1B9uq/vP/Q5VXW867Y4/Kq66nkkSa3C4IO68a1j\n", 407 | "B7K5Ij0C0MYtjgCk1sfwL0mSWo2xQ/fjK0f0ZeWaLdx0fzlVjgCkVsbwL0mSWpWTxh3MyAHdWfj2\n", 408 | "Gu78yyJqa2uTLknaZwz/kiSpVclLpZgycTAH9OjA0/Pe54mXHQFIrYfhX5IktTptigr4/qlldGxf\n", 409 | "xN1Pvsmrb32UdEnSPmH4lyRJrVLXjm248JRh5Ofl8ZsHylm+2hGA1PIZ/iVJUqvVr3cnvv2VgWyp\n", 410 | "qOa6mfPZsLky6ZKkrCrY1cIQQh5wI1AGVACTY4xL6iyfCPwEqAJuiTHevLNtQgj9gVuBGqAcuCDG\n", 411 | "WBtCmAKcm/mMn8UYH67z+QOBvwE9Yoz+bZQkSU1uzOBerFi9mT89t4wbZpXzw9NHUJDv9VG1TA0d\n", 412 | "2ScCRTHGscDlwFXbF4QQCoFpwFHAeODcEEKPzDbF9WwzDbgixjgOSAEnhBB6ARcCY4FjgCtDCEWZ\n", 413 | "z++Y2XZrU+yoJEnSzpzwhYMYHUpZ9O5a/vhYdAQgtVgNhf/PAY8CxBhfAEbXWTYIWBxjXBdj3AbM\n", 414 | "BsZltnmknm1GxRifyfz8CHAk8FlgToxxW4xxPbAYKAshpIDfAj8CtjRuFyVJknYtL5XiO8cPpm+v\n", 415 | "EmYvWMFjL76bdElSVjQU/jsC6+u8rs7c1rN92bo6yzYAnXayTT7pq/31rVvfZ/wH8HCMcUHm/brb\n", 416 | "SpIkNbniwny+f0oZnTsUMeOpxcxdtCrpkqQmt8t7/kmH+JI6r/NijNunwlu3w7ISYO1OtqkOIdSd\n", 417 | "Qq/jTtbd/hlnAe+FEL4D9AIeAyY0tDOlpSUNraK9ZG+zx95mj73NLvubPfY2exrqbWlpCf8x+Qgu\n", 418 | "v3E2v3vodf7r/M/Tv0/nfVRdbvO4zQ0Nhf85wERgRghhDLCgzrI3gAEhhC7AJtK3/PwKqN3JNnND\n", 419 | "CONjjH8FjgWeBF4Efh5CKAbakL6V6NUY44Dt/5EQwlLg6N3ZmVWrNuzOatpDpaUl9jZL7G322Nvs\n", 420 | "sr/ZY2+zZ3d726lNPuceP5jr73uV/3Pz8/zk7NF07dhmH1SYuzxus6epT6oauu1nFrA1hDCH9MO3\n", 421 | "PwghnBFCmJK5z38q6avyzwF/iDGuqG+bzGddAvw0hPAc6ZOOmTHGlcB1wLOkTwauqGdUH5+4kSRJ\n", 422 | "+5pY4ZMAABdXSURBVNTIQ0o57V/6s25jJdfMWMCWiqqkS5KaRKoFPc1e6xlndng2nz32NnvsbXbZ\n", 423 | "3+yxt9mzp72tra1l+uOLeGrucsr6dftkQjD9M4/b7CktLWnSZ189giVJkuqRSqU486gBDD2oKwuW\n", 424 | "fMTdTy5OuiSp0Qz/kiRJO5Gfl8d5Jw5l/9L2PPnyezzxd4cAVW4z/EuSJO1C2+ICLjq1jI7ti7jr\n", 425 | "yTeZv3h10iVJe83wL0mS1IDundry/VPKKMzP4zcPvMY7K72/XbnJ8C9JkrQbDu7dkcnHD6ZiWzXX\n", 426 | "zlzAmg0VSZck7THDvyRJ0m4aPbAHkyb0Y82GCq6buYCKyuqkS5L2iOFfkiRpD3z58AMYN3w/3l65\n", 427 | "gd8++Bo1NS1m2HS1AoZ/SZKkPZBKpfj60YFBfbswb/Fq7n3KIUCVOwz/kiRJe6ggP48LThrKft3a\n", 428 | "8fhL7/LU3OVJlyTtFsO/JEnSXmjXppCLJw2npF0hdzy+iPK3Pkq6JKlBhn9JkqS9VNq5LReeUkZe\n", 429 | "Xoob7y/nvQ83Jl2StEuGf0mSpEbov38nJh8/iK2V1Vwzc75DgKpZM/xLkiQ10mGDenLK+IP5eH0F\n", 430 | "186Yz5aKqqRLkupl+JckSWoCx43py4QRvXnnw43cdH85VdU1SZck/RPDvyRJUhNIpVKcdfQhlPXr\n", 431 | "RvnSj5n+eKS21jkA1LwY/iVJkppIfl4e3z1hCH17lvDM/BU89PzbSZck/QPDvyRJUhNqU1TARZPK\n", 432 | "6NaxmFnPvMXz5R8kXZL0CcO/JElSE+vcoZiLvzaCtsUF3PLnhSxc9nHSJUmA4V+SJCkr9u/engtP\n", 433 | "HgbA9bPKWb7KOQCUPMO/JElSlgzs24XvfGUQWyqquHqGcwAoeYZ/SZKkLBozpNencwDMdA4AJcvw\n", 434 | "L0mSlGXHjenLuOG9eWflRm56oJzqGucAUDIM/5IkSVmWSqX4xjGHMPTgrpS/9TG3P+YcAEqG4V+S\n", 435 | "JGkfyM/L47wThnJAzw48M38FDzsHgBJg+JckSdpH2hYXcNGpw+nWsZj7nANACTD8S5Ik7UNdSoq5\n", 436 | "eNLwT+YAeN05ALQPGf4lSZL2sf1LO3DhycNIpeD6+17lnZUbki5JrYThX5IkKQED+3Zh8vGDqais\n", 437 | "5up757Nq7ZakS1IrYPiXJElKyGGDenL6kQNYt6mSaffMY8PmyqRLUgtn+JckSUrQUaP7cOyYA1i5\n", 438 | "ZgvXzlxARWV10iWpBTP8S5IkJezU8f04Ykgv3np/vZOAKasM/5IkSQlLpVKcc9xAhh7UlQVLPuK2\n", 439 | "R50ETNlh+JckSWoGCvLzOP+kofTtVcLsBSuY9ezSpEtSC2T4lyRJaibaFBVw8aTh9OjcloeeW8ZT\n", 440 | "r7yXdElqYQz/kiRJzUin9kVMPW04Je0Kmf74Il6Oq5IuSS2I4V+SJKmZ6dGlHRdPGk5RYT6/ffA1\n", 441 | "Fr27NumS1EIY/iVJkpqhg/bryAUnDaW2tpbrZi5g+aqNSZekFsDwL0mS1EwNPbgb5xw3kM0VVUy7\n", 442 | "dz4fr9+adEnKcYZ/SZKkZmzs0P04dUI/1myoYNq989m4ZVvSJSmHGf4lSZKauWMPP4AjR3+G91dv\n", 443 | "4poZ89laWZV0ScpRhn9JkqRmLpVKcfqXBnDEkJ689f56bphVTlW1swBrzxn+JUmSckBeKsU5xw2i\n", 444 | "rF83Xlv6MTc/9Do1Nc4CrD1j+JckScoRBfl5nHfiUAZ8phMvLvyQO55YRG2tJwDafYZ/SZKkHFJc\n", 445 | "mM9Fp5bxmdIOPPXKch6YvTTpkpRDDP+SJEk5pl2bQqaeNpzSzm14cM4y/vL3d5MuSTnC8C9JkpSD\n", 446 | "Onco5pLTR9KpfRF3PfEmz7/2QdIlKQcY/iVJknJUj85tmXraCNoWF3DLwwuZv3h10iWpmTP8S5Ik\n", 447 | "5bA+PTpw0all5OeluOn+ct58b23SJakZM/xLkiTluEP6dOb8k4ZSXVPLtTMW8O6HG5MuSc2U4V+S\n", 448 | "JKkFKOvXnW9/ZRCbK6qYds88Ply7JemS1AwZ/iVJklqII4b04owjB7BuUyVX3T2XNRsqki5JzYzh\n", 449 | "X5IkqQU5anQfvvq5A1m1ditX3TOPDZsrky5JzYjhX5IkqYU54fMHcdToPry/ehPT7pnP5q1VSZek\n", 450 | "ZsLwL0mS1MKkUilO/1J/vlC2H2+v3MA1M+dTUVmddFlqBgz/kiRJLVAqleKbXx7IYYN6sPi9dVx/\n", 451 | "3wK2VdUkXZYSZviXJElqofLyUkw+fjAj+nfntWVr+M0D5VTXeALQmhXsamEIIQ+4ESgDKoDJMcYl\n", 452 | "dZZPBH4CVAG3xBhv3tk2IYT+wK1ADVAOXBBjrA0hTAHOzXzGz2KMD4cQ2gN3Ap2BSuCbMcb3m3C/\n", 453 | "JUmSWoWC/DzOO3EI18xYwNw3V3PLwwv5zvGDyUulki5NCWjoyv+JQFGMcSxwOXDV9gUhhEJgGnAU\n", 454 | "MB44N4TQI7NNcT3bTAOuiDGOA1LACSGEXsCFwFjgGODKEEIRMBl4KcY4HpgOXNoUOytJktQaFRbk\n", 455 | "c+Epw+i3f0eef20l0x9fRG1tbdJlKQENhf/PAY8CxBhfAEbXWTYIWBxjXBdj3AbMBsZltnmknm1G\n", 456 | "xRifyfz8CHAk8FlgToxxW4xxPbAYKIsxXgv8IrNuX2DN3u+iJEmS2hQV8INJwzmgRweenrucGU8v\n", 457 | "8QSgFWoo/HcE1td5XZ25rWf7snV1lm0AOu1km3zSV/vrW7e+zyDGWBNCeBK4ALh/t/ZGkiRJO9Wu\n", 458 | "TSFTTxvBft3a8egL7/DQc8uSLkn72C7v+Scd4kvqvM6LMW5/SmTdDstKgLU72aY6hFD36ZKOO1m3\n", 459 | "hDpX+WOMXwohBOBhoH9DO1NaWtLQKtpL9jZ77G322Nvssr/ZY2+zx95CaSn84vzPc9kNs5n17FK6\n", 460 | "d23PV8f1a4LPtbe5oKHwPweYCMwIIYwBFtRZ9gYwIITQBdhE+pafXwG1O9lmbghhfIzxr8CxwJPA\n", 461 | "i8DPQwjFQBvStxK9FkL4EfBejPH2zGfv1swUq1Zt2J3VtIdKS0vsbZbY2+yxt9llf7PH3maPvf1H\n", 462 | "UyeVceUdr/D7B8rZVlnFuOG99/qz7G32NPVJVUO3/cwCtoYQ5pB+cPcHIYQzQghTMvf5TwUeA54D\n", 463 | "/hBjXFHfNpnPugT4aQjhOdInHTNjjCuB64BnSZ8MXBFjrAD+AJwZQniK9Kg/5zTdLkuSJKlHl3b8\n", 464 | "8PSRdGhbyG2PvMGcV1ckXZL2gVQLetCj1jPO7PBsPnvsbfbY2+yyv9ljb7PH3tbvnZUb+NVdc9m8\n", 465 | "tYopEwczZkivPf4Me5s9paUlTTomq5N8SZIktWIH9Czhh6ePpG1xATc/tJCX3vgw6ZKURYZ/SZKk\n", 466 | "Vq5vrxKmnjaCosI8fvfga8xdtCrpkpQlhn9JkiRxcO+OTP3aCAry87jx/nIWLFmddEnKAsO/JEmS\n", 467 | "AOj/mU5cPKmM/LwU199XTvnSj5IuSU3M8C9JkqRPhAO68P1Ty0il4L//51UWLvs46ZLUhAz/kiRJ\n", 468 | "+geDD+zK904eRm1tLdf+zwIWvbs26ZLURAz/kiRJ+ifDDu7G+ScOo7q6lqtnzGfx8nVJl6QmYPiX\n", 469 | "JElSvUYM6M53TxjCtm01XH3vPJauWJ90SWokw78kSZJ26tDQg3O/OpitldVcdbcnALnO8C9JkqRd\n", 470 | "OmxQT6YcP5gtlVX82hOAnGb4lyRJUoPGDOnFlOMHs7Wyil/fPZcl7/sMQC4y/EuSJGm3jBnSi3Mn\n", 471 | "DmFrZTXT7pnHEh8CzjmGf0mSJO22wwf35F+/OoSKyhquumeeowDlGMO/JEmS9shhg3ryrycMoXJb\n", 472 | "DdPumcfCpU4ElisM/5IkSdpjnx3Yg+9mTgD+4/fP8eZ7TgSWCwz/kiRJ2iuj65wATLtnvjMB5wDD\n", 473 | "vyRJkvba6IE9uOzs0VRV13D1vZ4ANHeGf0mSJDXKEcN6c96JQz85AYjvrEm6JO2E4V+SJEmNNuqQ\n", 474 | "Us6vcwLwmg8BN0uGf0mSJDWJkYeU8r2Th1FTC9fOnM+8N1cnXZJ2YPiXJElSkxnevzsXTyojLy/F\n", 475 | "DbNe5aU3Pky6JNVh+JckSVKTGnxgV6Z+bQSFBXn85oFyni//IOmSlGH4lyRJUpM7pE9nfnj6SNoW\n", 476 | "FXDzQ6/z13nLky5JGP4lSZKUJQf37silZ46kfdtCbns08pe/v5t0Sa2e4V+SJElZc0DPEi47axSd\n", 477 | "2hdx1xNv8ue/vZ10Sa2a4V+SJElZtX/39lx+1ii6dixm5tNLuP/Zt6itrU26rFbJ8C9JkqSs69m1\n", 478 | "HZefOYrSzm14cM4yZjy9xBOABBj+JUmStE9079yWy886lF5d2/HoC+8w/fFF1HgCsE8Z/iVJkrTP\n", 479 | "dCkp5rKzRvGZ0g48NXc5N//pdaqqa5Iuq9Uw/EuSJGmf6tS+iMvPGkn//Tvxt9dXcv19r1KxrTrp\n", 480 | "sloFw78kSZL2uXZtCrnktBEMPbgrC5Z8xNX3zGPz1qqky2rxDP+SJElKRHFRPt8/pYzDBvVg0Xvr\n", 481 | "+OWdr7B+U2XSZbVohn9JkiQlpiA/j3MnDmHCiN688+FGrrzjFVav25J0WS2W4V+SJEmJystL8Y1j\n", 482 | "AseN6cvKjzdz5fRXWPHRpqTLapEM/5IkSUpcKpXi1An9mDShH2s2VHDl9FdY9sH6pMtqcQz/kiRJ\n", 483 | "ajaOHdOXbx07kE1bt/HLO+fyxttrki6pRTH8S5IkqVkZN7w3550wlG1VNUy7dz6vLFqVdEkthuFf\n", 484 | "kiRJzc7ogT24aFIZ+Xkpbpj1Kk/NXZ50SS2C4V+SJEnN0tCDunHpmSPp0LaQ2x+L3P/sW9TW1iZd\n", 485 | "Vk4z/EuSJKnZOmi/jlzx9UPp3qkND85Zxm2PvkF1TU3SZeUsw78kSZKatZ5d2/HjbxzKAT078Mz8\n", 486 | "FdxwXzkV26qTLisnGf4lSZLU7HXqUMxlZ45i8IFdmLd4Nb++ey4bt2xLuqycY/iXJElSTmhbXMDF\n", 487 | "k4YzZnBPlixfz5XTX3Y24D1k+JckSVLOKMjPY/LEwRxzWB9WfLSZX9z+Mu99uDHpsnKG4V+SJEk5\n", 488 | "JS+V4rR/GcDXvtiftRsrufKOl1noZGC7xfAvSZKknPTlww/g3ImDqdxWw7R75vFc+YqkS2r2DP+S\n", 489 | "JEnKWWOG9GLqaSMoKszn5ocW8uDspc4FsAuGf0mSJOW0QX278ONvpOcCuH/2Um7580Kqqp0LoD6G\n", 490 | "f0mSJOW83t3b8+OzR3PQfiXMefUDrr53Ppu3OhTojgz/kiRJahE6tS/i0jNHMXJAdxa+vYZfTH/F\n", 491 | "oUB3YPiXJElSi1FcmM8FJw3jqNF9eH/1Jn7+x5dZumJ90mU1G4Z/SZIktSh5eSnOOHIAZxw5gPWb\n", 492 | "Kvm/d77CvDdXJ11Ws2D4lyRJUot01Og+fO/kYVAL/33fAp74+7tJl5Q4w78kSZJarJGHlHLZWaMo\n", 493 | "aVfEnU+8yfTHI9U1rXckIMO/JEmSWrSD9uvIv519KJ8pbc//vrKcPz//dtIlJcbwL0mSpBave6e2\n", 494 | "/Ojrh/Llww9g0IFdky4nMQW7WhhCyANuBMqACmByjHFJneUTgZ8AVcAtMcabd7ZNCKE/cCtQA5QD\n", 495 | "F8QYa0MIU4BzM5/xsxjjwyGETsB0oAQoAqbGGP/WhPstSZKkVqZtcQFf+2L/pMtIVENX/k8EimKM\n", 496 | "Y4HLgau2LwghFALTgKOA8cC5IYQemW2K69lmGnBFjHEckAJOCCH0Ai4ExgLHAFeGEIqAHwB/iTFO\n", 497 | "AL4F3ND4XZUkSZJat4bC/+eARwFijC8Ao+ssGwQsjjGuizFuA2YD4zLbPFLPNqNijM9kfn4EOBL4\n", 498 | "LDAnxrgtxrgeWEz6NwZXA7/LrFsIODuDJEmS1Ei7vO0H6AjUnRWhOoSQF2OsySxbV2fZBqDTTrbJ\n", 499 | "J321v751/+kzYozrADK/GbgduGi390iSJElSvRoK/+tJ33e/3fbgD+nQXndZCbB2J9tUhxDqjqnU\n", 500 | "cSfrlgBrAEIIw4C7gEtijM/uxr6kSktLGl5Le8XeZo+9zR57m132N3vsbfbY2+yxt7mhodt+5gDH\n", 501 | "AYQQxgAL6ix7AxgQQuiSuU9/HPDcLraZG0IYn/n5WOAZ4EXgCyGE4sxDvoOA8hDCYGAGcEaM8bFG\n", 502 | "7qMkSZIkIFVbW7vThSGEFJ+O3ANwDnAo0CHG+PsQwvHAv5M+ifhDjPGm+raJMS4KIQwAfk969J7X\n", 503 | "gSmZ0X4mkx7tJw/4eYxxVgjh/sz22wdhXRtjPKnpdluSJElqfXYZ/iVJkiS1HE7yJUmSJLUShn9J\n", 504 | "kiSplTD8S5IkSa1EQ0N9NnshhDw+fcC4ApgcY1ySbFXNX2aG5luAvkAx8DNgIXArUAOUAxdkHsqe\n", 505 | "Qvqh7CrgZzHGh0MIbYHpQCnp+Rm+GWNcvc93pBnLzHj9MvAl0j29FXvbJEIIPwImkp4E8HrSo4zd\n", 506 | "iv1tlMz36c3AIaR7OQWoxt42SgjhcOC/YoxfDCH0p5H9zIykd01m3cdjjP+57/eqedihtyOA60gf\n", 507 | "sxXA2THGD+3t3qnb2zrvnQl8L8Y4NvPa3u6FHY7bHqQHxOlMek6ss2OMy7LZ25Zw5f9EoChzIF4O\n", 508 | "XJVwPbniLGBVjHEc8GXgBtK9uyLzXgo4ITPR2oXAWOAY4MrM0K7nAfMz6/4R+LcE9qHZypxc/RbY\n", 509 | "RLqX07C3TSKEMAE4IvN3fgJwMB67TeVooH2M8fPAfwK/wN42SgjhUtL/sBdn3mqK74LfkB4K+/PA\n", 510 | "4ZnQ2+rU09trSAfTLwL3AZeFEHpib/dYPb0lhDAS+Had1x63e6Ge3v4SuD3GOJ70CJpDs93blhD+\n", 511 | "Pwc8ChBjfAEYnWw5OWMG6YMM0sfBNmBUjPGZzHuPAEcCnwXmxBi3xRjXA4tJ/5blk75n/jxyXxWe\n", 512 | "I34F3ASsyLy2t03naODVzJDAfwIeBA61v01iC9ApM2RzJ6ASe9tYi4GT+XSW+0Z9F4QQSkhf8Fqa\n", 513 | "ef8xWm+fd+zt6THG7XMLFZI+ng/D3u6Nf+htCKEb8HPgYj7tt73dOzset2OBPiGEv5C+MPu/ZLm3\n", 514 | "LSH8dyQ9U/B21ZlfXWsXYoybYowbMwfNDNJnj3X7toH0P/4dSc/mXN/763d4T0AI4Vukf6vyeOat\n", 515 | "FJ/+JQd721ilpOcbORX4LnAn9repzAHakJ7E8bekb6Gwt40QY7yP9K/it2tsP3f8N6/V9nnH3sYY\n", 516 | "PwAIIYwFLgCuxt7ulbq9zWSqPwBTgY11VrO3e6Ge74QDgY9jjEcB7wCXASVksbctISSvJ92k7fJi\n", 517 | "jDVJFZNLQgh9SJ9h/jHGeBfpe1C36wis5Z/7W1LP+9vfU9o5wFEhhKeAEcBtpAPrdva2cVaTvqex\n", 518 | "Ksa4CNjKP37R2d+9dynpq02B9LH7R9JXULezt43X2O/ZHdfd/hkCQginkf6t63Exxo+wt03hUKA/\n", 519 | "6b7eBQwOIUwjHU7tbeN9RPo32JD+bfZosnzctoTwPwc4DiDzwMOCXa8ugMx9kI8Dl8YYb828PTeE\n", 520 | "MD7z87HAM8CLwBdCCMUhhE7AINIPqX3S9zrrCogxjo8xTsjcdzoPOBt41N42mdmkn1MhhNAbaAc8\n", 521 | "aX+bRHs+vYK0hvSgEH4vNK1G9TPGuAGoDCEcnLk962jsMwAhhK+TvuI/Ica4LPO2vW2kGONLMcah\n", 522 | "mX/TTgdejzFOBV7C3jaF2cBXMj+PJ93DrB63OT/aDzCL9FXWOZnX5yRZTA65gvTV0n8PIWy/9/8i\n", 523 | "4LrMQyWvAzMzo1BcBzxL+mTxihhjRQjhJuC2EMKzpEdVOHPf70LOqAUuAX5vbxsvM+LBuBDCi6T7\n", 524 | "dj6wDPvbFH4F/L9MbwqBH5EescreNl5t5s+m+C74LnAHkA88FmN8aV/uSDNUm7k15VrgbeC+EALA\n", 525 | "0zHGn9rbRqnd4XVq+3sxxg/sbaPU/U64OYRwHukr9mfGGNdls7ep2tod/79KkiRJaolawm0/kiRJ\n", 526 | "knaD4V+SJElqJQz/kiRJUith+JckSZJaCcO/JEmS1EoY/iVJkqRWwvAvSZIktRKGf0mSJKmV+P+8\n", 527 | "TNiCUkOKcAAAAABJRU5ErkJggg==\n" 528 | ], 529 | "text/plain": [ 530 | "" 531 | ] 532 | }, 533 | "metadata": {}, 534 | "output_type": "display_data" 535 | } 536 | ], 537 | "source": [ 538 | "x = np.linspace(0,15000,1000)\n", 539 | "plt.plot(x, a.pdf(x))" 540 | ] 541 | }, 542 | { 543 | "cell_type": "code", 544 | "execution_count": null, 545 | "metadata": { 546 | "collapsed": true 547 | }, 548 | "outputs": [], 549 | "source": [] 550 | } 551 | ], 552 | "metadata": { 553 | "kernelspec": { 554 | "display_name": "Python 3", 555 | "language": "python", 556 | "name": "python3" 557 | }, 558 | "language_info": { 559 | "codemirror_mode": { 560 | "name": "ipython", 561 | "version": 3 562 | }, 563 | "file_extension": ".py", 564 | "mimetype": "text/x-python", 565 | "name": "python", 566 | "nbconvert_exporter": "python", 567 | "pygments_lexer": "ipython3", 568 | "version": "3.4.3" 569 | } 570 | }, 571 | "nbformat": 4, 572 | "nbformat_minor": 0 573 | } 574 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Quentin ANDRE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: sh 2 | ============== 3 | Introduction 4 | ============== 5 | 6 | :Date: April 11, 2015 7 | :Version: 0.9.0 8 | :Authors: Quentin ANDRE, quentin.andre@insead.edu 9 | :Web site: https://github.com/QuentinAndre/John-Rust-1987-Python 10 | :Copyright: This document has been placed in the public domain. 11 | :License: John-Rust-1987-Python is released under the MIT license. 12 | 13 | Purpose 14 | ======= 15 | 16 | John-Rust-1987-Python provides a Python implementation of the single agent dynamic choice model of bus engine replacement described by John Rust in his 1987 article *"Optimal replacement of GMC bus engines: An empirical model of Harold Zurcher"*. 17 | 18 | Content 19 | ======= 20 | 21 | 1. **Data Generation and Likelihood Fit.ipynb**: An IPython notebook describing the different steps used to: 22 | * Generate the bus mileage data 23 | * Compute the forward-looking (dynamic) utility of the agent 24 | * Generate four datasets of bus engine replacement: 25 | * One assuming a linear maintainance cost (Lin_Dataset.csv) 26 | * One assuming a quadratic maintainance cost (Quad_Dataset.csv) 27 | * One assuming an exponential maintainance cost (Exp_Dataset.csv) 28 | * One assuming a logarithmic maintainance cost (Log_Dataset.csv) 29 | * Estimate the parameters of this bus replacement pattern 30 | * Plot the results of this estimation against the true underlying parameters. 31 | 32 | 2. **dynamiclogit.py**: A library containing a DynamicUtility class, which can be used as a statistical workbench to estimate single-agent dynamic choice models. The state transition probabilities of the buses and the form of the maintenance cost are supplied at the class initialization as an external parameters, which allows to test a wide range of specifications. 33 | 34 | Installation 35 | ============ 36 | 37 | Dependencies 38 | ------------ 39 | This code has been tested in Python 3.4, using the Anaconda distribution: 40 | * `The Anaconda distribution for Python 3.4 `_ 41 | 42 | Download 43 | -------- 44 | 45 | * Using git: 46 | * git clone https://github.com/QuentinAndre/John-Rust-1987-Python.git 47 | 48 | * Download the master branch as a zip: 49 | * https://github.com/QuentinAndre/John-Rust-1987-Python/archive/master.zip 50 | 51 | 52 | References 53 | ========== 54 | Rust, J. (1987). Optimal replacement of GMC bus engines: An empirical model of Harold Zurcher. Econometrica: Journal of the Econometric Society, 999-1033. 55 | -------------------------------------------------------------------------------- /dynamiclogit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | This library defines a DynamicLogit class, which is used as a statistical 4 | workbench to evaluate single-agent choice models in which the utility is 5 | dynamic (in the fashion of Rust 1987). 6 | """ 7 | import numpy as np 8 | import scipy.optimize as opt 9 | import pandas as pd 10 | from matplotlib import pyplot as plt 11 | 12 | 13 | class DynamicLogit(object): 14 | def __init__(self, data, Y, X, p, MF, npars): 15 | """ 16 | A statistics workbench used to evaluate the cost parameters underlying 17 | a bus replacement pattern by a forward-looking agent. 18 | 19 | Takes: 20 | * Data: a Pandas dataframe, which contains: 21 | -Y: the name of the column containing the dummy exogenous 22 | variable (here, the choice) 23 | -X: the name of the column containing the endogenous variable 24 | (here, the state of the bus) 25 | 26 | * p: The state-transition vector of endogenous variable. 27 | For instance, p = [0, 0.6, 0.4] means that the bus will 28 | transition to the next mileage state with probability 0.6, 29 | and to the second next mileage state with probability 0.4. 30 | 31 | * MF: A function passed as an argument, which is the functional 32 | form for the maintenance cost. This function must accept as 33 | a first argument a state s, and as a second argument a vector 34 | of parameters. 35 | 36 | * npars: The number of parameters to evalutate (i.e. the number of 37 | parameters of the maintenance cost function, plus 1 for 38 | the replacement cost) 39 | """ 40 | 41 | self.endog = data.loc[:, Y].values 42 | self.exog = data.loc[:, X].values 43 | 44 | self.N = self.endog.shape[0] 45 | self.S = int(self.exog.max()*2) # Assumes that the true maximum number 46 | # states is twice the maximum observed 47 | # state. 48 | 49 | 50 | # Check that p is a correct vector of probabilities (i.e. sums to 1) 51 | p = np.array(p) 52 | if p.sum() == 1: 53 | self.p = p 54 | else: 55 | raise ValueError(("The probability of state transitions should add" 56 | " up to 1!")) 57 | 58 | 59 | # Check that the stated number of parameters correspond to the 60 | # specifications of the maintenance cost function. 61 | try: 62 | MF(1, [0]*(npars-1)) 63 | except ValueError: 64 | raise ValueError(("The number of parameters specified does not " 65 | "match the specification of the maintenance cost" 66 | " function!")) 67 | else: 68 | self.MF = MF 69 | self.npars = npars 70 | 71 | 72 | 73 | # To speed up computations and avoid loops when computing the log 74 | # likelihood, we create a few useful matrices here: 75 | S = self.S 76 | 77 | # A (SxN) matrix indicating the state of each observation 78 | self.state_mat = np.array([[self.exog[i]==s for i in range(self.N)] 79 | for s in range(self.S)]) 80 | 81 | # A (SxS) matrix indicating the probability of a bus transitioning 82 | # from a state s to a state s' (used to compute maintenance utility) 83 | 84 | self.trans_mat = np.zeros((S, S)) 85 | for i in range(S): 86 | for j, _p in enumerate(self.p): 87 | if i + j < S-1: 88 | self.trans_mat[i+j][i] = _p 89 | elif i + j == S-1: 90 | self.trans_mat[S-1][i] = p[j:].sum() 91 | else: 92 | pass 93 | 94 | # A second (SxS) matrix which regenerates the bus' state to 0 with 95 | # certainty (used to compute the replacement utility) 96 | self.regen_mat = np.vstack((np.ones((1, S)),np.zeros((S-1, S)))) 97 | 98 | # A (2xN) matrix indicating with a dummy the decision taken by the agent 99 | # for each time/bus observation (replace or maintain) 100 | self.dec_mat = np.vstack(((1-self.endog), self.endog)) 101 | 102 | def myopic_costs(self, params): 103 | S = self.S 104 | """ 105 | This function computes the myopic expected cost associated with each 106 | decision for each state. 107 | 108 | Takes: 109 | * A vector params, to be supplied to the maintenance cost function 110 | MF. The first element of the vector is the replacement cost rc. 111 | 112 | Returns: 113 | * A (Sx2) array containing the maintenance and replacement costs 114 | for the S possible states of the bus 115 | """ 116 | rc = params[0] 117 | thetas = params[1:] 118 | maint_cost = [self.MF(s, thetas) for s in range(0, S)] 119 | repl_cost = [rc for state in range(0, S)] 120 | return np.vstack((maint_cost, repl_cost)).T 121 | 122 | def fl_costs(self, params, beta=0.75, threshold=1e-6, suppr_output=False): 123 | """ 124 | Compute the non-myopic expected value of the agent for each possible 125 | decision and each possible state of the bus, conditional on a vector of 126 | parameters and on the maintenance cost function specified at the 127 | initialization of the DynamicUtility model. 128 | 129 | Iterates until the difference in the previously obtained expected value 130 | and the new expected value is smaller than a constant. 131 | 132 | Takes: 133 | * A vector params for the cost function 134 | * A discount factor beta (optional) 135 | * A convergence threshold (optional) 136 | * A boolean argument to suppress the output (optional) 137 | 138 | Returns: 139 | * An (Sx2) array of forward-looking costs associated with each 140 | sate and each decision. 141 | """ 142 | achieved = True 143 | # Initialization of the contraction mapping 144 | k = 0 145 | EV = np.zeros((self.S, 2)) 146 | self.EV_myopic = EV_new = self.myopic_costs(params) 147 | 148 | # Contraction mapping Loop 149 | while abs(EV_new-EV).max() > threshold: 150 | EV = EV_new 151 | pchoice = self.choice_prob(EV) 152 | ecost = (pchoice*EV).sum(1) 153 | futil_maint = np.dot(ecost, self.trans_mat) 154 | futil_repl = np.dot(ecost, self.regen_mat) 155 | futil = np.vstack((futil_maint, futil_repl)).T 156 | 157 | EV_new = self.EV_myopic + beta*futil 158 | k += 1 159 | if k == 1000: 160 | achieved = False 161 | break 162 | 163 | # Output: 164 | if not suppr_output: 165 | if achieved: 166 | print("Convergence achieved in {} iterations".format(k)) 167 | else: 168 | print("CM could not converge! Mean difference = {:.6f}".format( 169 | (EV_new-EV).mean()) 170 | ) 171 | 172 | self.EV_FL = EV_new 173 | return EV 174 | 175 | def choice_prob(self, cost_array): 176 | """ 177 | Returns the probability of each choice for each observed state, 178 | conditional on an array of state/decision costs (generated by the 179 | myopic or forward-looking cost functions) 180 | """ 181 | cost = cost_array - cost_array.min(1).reshape(self.S, -1) 182 | util = np.exp(-cost) 183 | pchoice = util/(np.sum(util, 1).reshape(self.S, -1)) 184 | return pchoice 185 | 186 | def plot_gof(self): 187 | """ 188 | Represent the goodness-of-fit of the forward-looking array of costs 189 | obtained in maximum likelihood. 190 | 191 | This function plot the choice probabilities fitted to the data against 192 | the observed choice probabilities, and returns the plot. 193 | """ 194 | obs_choice = pd.DataFrame({"Choice":self.endog, "State":self.exog}) 195 | obs_choice = obs_choice.groupby("State").mean().sort().reset_index() 196 | plt.plot(self.choice_prob(self.EV_FL).T[0]) 197 | plt.plot(obs_choice["State"], 1-obs_choice["Choice"]) 198 | plt.ylabel("Probability of maintenance") 199 | plt.xlabel("State of the bus") 200 | plt.legend(["Fitted", "Observed"]) 201 | plt.xlim(0, self.S-1) 202 | plt.ylim(0, 1.05) 203 | plt.title("Action probabilities of the agent") 204 | plt.show(); 205 | return None 206 | 207 | def loglike(self, params): 208 | """ 209 | The log-likelihood of the Dynamic model is estimated in several steps. 210 | 1°) The currenter parameters are supplied to the contraction mapping 211 | function 212 | 2°) The function returns a matrix of decision probabilities for each 213 | state. 214 | 3°) This matrix is used to compute the loglikelihood of the 215 | observations 216 | 4°) The log-likelihood are then summed accross individuals, and 217 | returned 218 | """ 219 | util = self.fl_costs(params, suppr_output=True) 220 | pchoice = self.choice_prob(util) 221 | logprob = np.log(np.dot(pchoice.T, self.state_mat)) 222 | return -np.sum(self.dec_mat*logprob) 223 | 224 | def fit_likelihood(self, x0=None, bounds=None): 225 | """ 226 | Fit the parameters to the data. 227 | """ 228 | if bounds == None: 229 | bounds = [(1e-6, None) for i in range(self.npars)] 230 | 231 | if x0 == None: 232 | x0 = [0.1 for i in range(self.npars)] 233 | 234 | self.fitted = opt.fmin_l_bfgs_b(self.loglike, x0=x0, approx_grad=True, 235 | bounds=bounds) 236 | 237 | 238 | def get_parameters(self): 239 | """ 240 | Return the parameters obtained after fitting the likelihood function 241 | to the data. 242 | """ 243 | return self.fitted[0] 244 | 245 | def print_parameters(self): 246 | loglike = self.fitted[1] 247 | fit_params = self.get_parameters() 248 | RC, thetas = fit_params[0], fit_params[1:] 249 | logstring = "Log-likelihood = {0:.2f}".format(loglike) 250 | thetas_string = ["theta1_{0} = {1:.4f}".format(i+1, t) \ 251 | for i, t in enumerate(thetas)] 252 | thetas_string = ", ".join(thetas_string) 253 | rc_string = "Parameters: RC = {0:.4f}".format(RC) 254 | print(logstring, rc_string + ", " + thetas_string) 255 | 256 | 257 | 258 | if __name__ == "__main__": 259 | 260 | # Loading data generated by a linear maintenance cost function 261 | print("Fitting a linear function to a linearly-generated dataset") 262 | datalin = pd.read_csv("Datasets\Lin_Dataset.csv") 263 | 264 | # Linear maintenance cost function 265 | def lin_cost(s, params): 266 | theta1_1, = params 267 | return s*theta1_1 268 | 269 | # The state-transition probabilities 270 | p = np.array([0.36, 0.48, 0.16]) 271 | 272 | # Initialization 273 | lin_to_lin = DynamicLogit(datalin, "Choice", "State", p, lin_cost, npars=2) 274 | 275 | # Fitting the likelihood function 276 | lin_to_lin.fit_likelihood() 277 | 278 | # Printing parameters obtained 279 | lin_to_lin.print_parameters() 280 | 281 | # Generating GOF plot. 282 | lin_to_lin.plot_gof() 283 | 284 | 285 | # Loading data generated by an exponential maintenance cost function 286 | print("Fitting an exp. function to an exponentially-generated dataset") 287 | dataexp = pd.read_csv("Datasets\Exp_Dataset.csv") 288 | 289 | # Exponential maintenance cost function 290 | def exp_cost(s, params): 291 | theta1_1, = params 292 | return np.exp(s*theta1_1) 293 | 294 | # Initialization 295 | exp_to_exp = DynamicLogit(dataexp, "Choice", "State", p, exp_cost, npars=2) 296 | 297 | # Fitting the likelihood function 298 | exp_to_exp.fit_likelihood() 299 | 300 | # Printing parameters obtained 301 | exp_to_exp.print_parameters() 302 | 303 | # Generating GOF plot. 304 | exp_to_exp.plot_gof() 305 | -------------------------------------------------------------------------------- /styles/bmh2_matplotlibrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "lines.linewidth": 2.0, 3 | "axes.edgecolor": "#bcbcbc", 4 | "patch.linewidth": 0.5, 5 | "legend.fancybox": true, 6 | "axes.color_cycle": [ 7 | "#1BE61B", 8 | "#FF0000", 9 | "#2606EC", 10 | "#CEFFCE", 11 | "#FFAB81", 12 | "#C8E0FF", 13 | "#E4349B" 14 | ], 15 | "axes.facecolor": "#eeeeee", 16 | "axes.labelsize": "large", 17 | "patch.edgecolor": "#eeeeee", 18 | "axes.titlesize": "x-large", 19 | "legend.fontsize": 15, 20 | "legend.markerscale": 2 21 | } 22 | -------------------------------------------------------------------------------- /styles/bmh_matplotlibrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "lines.linewidth": 2.0, 3 | "axes.edgecolor": "#bcbcbc", 4 | "patch.linewidth": 0.5, 5 | "legend.fancybox": true, 6 | "axes.color_cycle": [ 7 | "#348ABD", 8 | "#A60628", 9 | "#7A68A6", 10 | "#467821", 11 | "#CF4457", 12 | "#188487", 13 | "#E24A33" 14 | ], 15 | "axes.facecolor": "#eeeeee", 16 | "axes.labelsize": "large", 17 | "patch.edgecolor": "#eeeeee", 18 | "axes.titlesize": "x-large" 19 | } 20 | -------------------------------------------------------------------------------- /styles/custom.css: -------------------------------------------------------------------------------- 1 | 65 | 80 | -------------------------------------------------------------------------------- /styles/custom2.css: -------------------------------------------------------------------------------- 1 | #notebook_panel { /* main background */ 2 | background: #f6f6f6; 3 | color: #f6f6f6; 4 | } 5 | 6 | div #notebook { /* centre the content */ 7 | background: #fff; 8 | color: #333; 9 | width: 115ex; 10 | margin: auto; 11 | padding-left: 1em; 12 | padding-right: 1em; 13 | padding-top: 2ex; 14 | } 15 | 16 | /* remove big margins around title */ 17 | div.text_cell_render.border-box-sizing.rendered_html { 18 | margin: 0; 19 | padding: 0; 20 | margin-left: 1ex; 21 | } 22 | div.cell.text_cell.border-box-sizing { 23 | margin: 0; 24 | padding: 0; 25 | } 26 | .rendered_html h1 { 27 | margin: 0; 28 | padding: 0; 29 | } 30 | .rendered_html h2 { 31 | margin: 0; 32 | padding: 0; 33 | } 34 | .rendered_html h3 { 35 | margin: 0; 36 | padding: 0; 37 | } 38 | 39 | div.cell { /* set cell width to about 80 chars */ 40 | width: 200em; 41 | } 42 | 43 | div.cell.code_cell { /* area that contains code + output */ 44 | background: #fff; 45 | border: none; 46 | border-radius: 10px; 47 | padding-top: 1ex; 48 | } 49 | 50 | div.input_area { /* box around box with code */ 51 | border: none; 52 | background: #f5f5f5; 53 | border: 1px solid #ccc; 54 | border-radius: 10px; 55 | padding-top: 0.5ex; 56 | padding-bottom: 0.5ex; 57 | padding-left: 0.5em; 58 | } 59 | 60 | div.input { /* box with code */ 61 | } 62 | 63 | div.CodeMirror { /* code font */ 64 | font-family: "Inconsolata-dz", monospace; 65 | font-size: 10pt; 66 | } 67 | 68 | div.prompt { /* remove In/Out prompt */ 69 | display: none; 70 | } 71 | 72 | div.output_subarea { /* remove margin in front of output */ 73 | border: none; 74 | } 75 | 76 | div.cell.border-box-sizing.code_cell.running { 77 | /* draw border around running cells */ 78 | border: 3px dotted #f33; 79 | } 80 | 81 | /* header colours and fonts */ 82 | h1 { color: #444; } 83 | h2 { color: #444; } 84 | h3 { color: #444; font-style: italic; font-weight: normal} 85 | 86 | 87 | -------------------------------------------------------------------------------- /styles/matplotlibrc: -------------------------------------------------------------------------------- 1 | ### MATPLOTLIBRC FORMAT 2 | 3 | # This is a sample matplotlib configuration file - you can find a copy 4 | # of it on your system in 5 | # site-packages/matplotlib/mpl-data/matplotlibrc. If you edit it 6 | # there, please note that it will be overridden in your next install. 7 | # If you want to keep a permanent local copy that will not be 8 | # over-written, place it in HOME/.matplotlib/matplotlibrc (unix/linux 9 | # like systems) and C:\Documents and Settings\yourname\.matplotlib 10 | # (win32 systems). 11 | # 12 | # This file is best viewed in a editor which supports python mode 13 | # syntax highlighting. Blank lines, or lines starting with a comment 14 | # symbol, are ignored, as are trailing comments. Other lines must 15 | # have the format 16 | # key : val # optional comment 17 | # 18 | # Colors: for the color values below, you can either use - a 19 | # matplotlib color string, such as r, k, or b - an rgb tuple, such as 20 | # (1.0, 0.5, 0.0) - a hex string, such as ff00ff or #ff00ff - a scalar 21 | # grayscale intensity such as 0.75 - a legal html color name, eg red, 22 | # blue, darkslategray 23 | 24 | #### CONFIGURATION BEGINS HERE 25 | 26 | # the default backend; one of GTK GTKAgg GTKCairo CocoaAgg FltkAgg 27 | # MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG Template 28 | # You can also deploy your own backend outside of matplotlib by 29 | # referring to the module name (which must be in the PYTHONPATH) as 30 | # 'module://my_backend' 31 | backend : MacOSX 32 | 33 | # if you are runing pyplot inside a GUI and your backend choice 34 | # conflicts, we will automatically try and find a compatible one for 35 | # you if backend_fallback is True 36 | #backend_fallback: True 37 | interactive : True 38 | toolbar : toolbar2 # None | classic | toolbar2 39 | timezone : UTC # a pytz timezone string, eg US/Central or Europe/Paris 40 | 41 | # Where your matplotlib data lives if you installed to a non-default 42 | # location. This is where the matplotlib fonts, bitmaps, etc reside 43 | #datapath : /home/jdhunter/mpldata 44 | 45 | 46 | ### LINES 47 | # See http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.lines for more 48 | # information on line properties. 49 | lines.linewidth : 1.0 # line width in points 50 | #lines.linestyle : - # solid line 51 | # lines.color : purple 52 | #lines.marker : None # the default marker 53 | #lines.markeredgewidth : 0.5 # the line width around the marker symbol 54 | #lines.markersize : 6 # markersize, in points 55 | #lines.dash_joinstyle : miter # miter|round|bevel 56 | #lines.dash_capstyle : butt # butt|round|projecting 57 | #lines.solid_joinstyle : miter # miter|round|bevel 58 | #lines.solid_capstyle : projecting # butt|round|projecting 59 | lines.antialiased : True # render lines in antialised (no jaggies) 60 | 61 | ### PATCHES 62 | # Patches are graphical objects that fill 2D space, like polygons or 63 | # circles. See 64 | # http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.patches 65 | # information on patch properties 66 | patch.linewidth : 0.5 # edge width in points 67 | patch.facecolor : 348ABD # blue 68 | patch.edgecolor : eeeeee 69 | patch.antialiased : True # render patches in antialised (no jaggies) 70 | 71 | ### FONT 72 | # 73 | # font properties used by text.Text. See 74 | # http://matplotlib.sourceforge.net/api/font_manager_api.html for more 75 | # information on font properties. The 6 font properties used for font 76 | # matching are given below with their default values. 77 | # 78 | # The font.family property has five values: 'serif' (e.g. Times), 79 | # 'sans-serif' (e.g. Helvetica), 'cursive' (e.g. Zapf-Chancery), 80 | # 'fantasy' (e.g. Western), and 'monospace' (e.g. Courier). Each of 81 | # these font families has a default list of font names in decreasing 82 | # order of priority associated with them. 83 | # 84 | # The font.style property has three values: normal (or roman), italic 85 | # or oblique. The oblique style will be used for italic, if it is not 86 | # present. 87 | # 88 | # The font.variant property has two values: normal or small-caps. For 89 | # TrueType fonts, which are scalable fonts, small-caps is equivalent 90 | # to using a font size of 'smaller', or about 83% of the current font 91 | # size. 92 | # 93 | # The font.weight property has effectively 13 values: normal, bold, 94 | # bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as 95 | # 400, and bold is 700. bolder and lighter are relative values with 96 | # respect to the current weight. 97 | # 98 | # The font.stretch property has 11 values: ultra-condensed, 99 | # extra-condensed, condensed, semi-condensed, normal, semi-expanded, 100 | # expanded, extra-expanded, ultra-expanded, wider, and narrower. This 101 | # property is not currently implemented. 102 | # 103 | # The font.size property is the default font size for text, given in pts. 104 | # 12pt is the standard value. 105 | # 106 | font.family : monospace 107 | #font.style : normal 108 | #font.variant : normal 109 | #font.weight : medium 110 | #font.stretch : normal 111 | # note that font.size controls default text sizes. To configure 112 | # special text sizes tick labels, axes, labels, title, etc, see the rc 113 | # settings for axes and ticks. Special text sizes can be defined 114 | # relative to font.size, using the following values: xx-small, x-small, 115 | # small, medium, large, x-large, xx-large, larger, or smaller 116 | font.size : 10.0 117 | # font.serif : Bitstream Vera Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif 118 | #font.sans-serif : Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif 119 | #font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, cursive 120 | #font.fantasy : Comic Sans MS, Chicago, Charcoal, Impact, Western, fantasy 121 | font.monospace : Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace 122 | 123 | ### TEXT 124 | # text properties used by text.Text. See 125 | # http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.text for more 126 | # information on text properties 127 | 128 | #text.color : black 129 | 130 | ### LaTeX customizations. See http://www.scipy.org/Wiki/Cookbook/Matplotlib/UsingTex 131 | #text.usetex : False # use latex for all text handling. The following fonts 132 | # are supported through the usual rc parameter settings: 133 | # new century schoolbook, bookman, times, palatino, 134 | # zapf chancery, charter, serif, sans-serif, helvetica, 135 | # avant garde, courier, monospace, computer modern roman, 136 | # computer modern sans serif, computer modern typewriter 137 | # If another font is desired which can loaded using the 138 | # LaTeX \usepackage command, please inquire at the 139 | # matplotlib mailing list 140 | #text.latex.unicode : False # use "ucs" and "inputenc" LaTeX packages for handling 141 | # unicode strings. 142 | #text.latex.preamble : # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES 143 | # AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP 144 | # IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO. 145 | # preamble is a comma separated list of LaTeX statements 146 | # that are included in the LaTeX document preamble. 147 | # An example: 148 | # text.latex.preamble : \usepackage{bm},\usepackage{euler} 149 | # The following packages are always loaded with usetex, so 150 | # beware of package collisions: color, geometry, graphicx, 151 | # type1cm, textcomp. Adobe Postscript (PSSNFS) font packages 152 | # may also be loaded, depending on your font settings 153 | 154 | #text.dvipnghack : None # some versions of dvipng don't handle alpha 155 | # channel properly. Use True to correct 156 | # and flush ~/.matplotlib/tex.cache 157 | # before testing and False to force 158 | # correction off. None will try and 159 | # guess based on your dvipng version 160 | 161 | #text.markup : 'plain' # Affects how text, such as titles and labels, are 162 | # interpreted by default. 163 | # 'plain': As plain, unformatted text 164 | # 'tex': As TeX-like text. Text between $'s will be 165 | # formatted as a TeX math expression. 166 | # This setting has no effect when text.usetex is True. 167 | # In that case, all text will be sent to TeX for 168 | # processing. 169 | 170 | #text.hinting : True # If True, text will be hinted, otherwise not. This only 171 | # affects the Agg backend. 172 | 173 | # The following settings allow you to select the fonts in math mode. 174 | # They map from a TeX font name to a fontconfig font pattern. 175 | # These settings are only used if mathtext.fontset is 'custom'. 176 | # Note that this "custom" mode is unsupported and may go away in the 177 | # future. 178 | #mathtext.cal : cursive 179 | #mathtext.rm : serif 180 | #mathtext.tt : monospace 181 | #mathtext.it : serif:italic 182 | #mathtext.bf : serif:bold 183 | #mathtext.sf : sans 184 | #mathtext.fontset : cm # Should be 'cm' (Computer Modern), 'stix', 185 | # 'stixsans' or 'custom' 186 | #mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern 187 | # fonts when a symbol can not be found in one of 188 | # the custom math fonts. 189 | 190 | #mathtext.default : it # The default font to use for math. 191 | # Can be any of the LaTeX font names, including 192 | # the special name "regular" for the same font 193 | # used in regular text. 194 | 195 | ### AXES 196 | # default face and edge color, default tick sizes, 197 | # default fontsizes for ticklabels, and so on. See 198 | # http://matplotlib.sourceforge.net/api/axes_api.html#module-matplotlib.axes 199 | #axes.hold : True # whether to clear the axes by default on 200 | axes.facecolor : eeeeee # axes background color 201 | axes.edgecolor : bcbcbc # axes edge color 202 | axes.linewidth : 1 # edge linewidth 203 | axes.grid : True # display grid or not 204 | axes.titlesize : x-large # fontsize of the axes title 205 | axes.labelsize : large # fontsize of the x any y labels 206 | axes.labelcolor : 555555 207 | axes.axisbelow : True # whether axis gridlines and ticks are below 208 | # the axes elements (lines, text, etc) 209 | #axes.formatter.limits : -7, 7 # use scientific notation if log10 210 | # of the axis range is smaller than the 211 | # first or larger than the second 212 | #axes.unicode_minus : True # use unicode for the minus symbol 213 | # rather than hypen. See http://en.wikipedia.org/wiki/Plus_sign#Plus_sign 214 | axes.color_cycle : 348ABD, 7A68A6, A60628, 467821, CF4457, 188487, E24A33 215 | # E24A33 : orange 216 | # 7A68A6 : purple 217 | # 348ABD : blue 218 | # 188487 : turquoise 219 | # A60628 : red 220 | # CF4457 : pink 221 | # 467821 : green 222 | 223 | 224 | 225 | 226 | # color cycle for plot lines 227 | # as list of string colorspecs: 228 | # single letter, long name, or 229 | # web-style hex 230 | 231 | #polaraxes.grid : True # display grid on polar axes 232 | #axes3d.grid : True # display grid on 3d axes 233 | 234 | ### TICKS 235 | # see http://matplotlib.sourceforge.net/api/axis_api.html#matplotlib.axis.Tick 236 | xtick.major.size : 0 # major tick size in points 237 | xtick.minor.size : 0 # minor tick size in points 238 | xtick.major.pad : 6 # distance to major tick label in points 239 | xtick.minor.pad : 6 # distance to the minor tick label in points 240 | xtick.color : 555555 # color of the tick labels 241 | #xtick.labelsize : medium # fontsize of the tick labels 242 | xtick.direction : in # direction: in or out 243 | 244 | ytick.major.size : 0 # major tick size in points 245 | ytick.minor.size : 0 # minor tick size in points 246 | ytick.major.pad : 6 # distance to major tick label in points 247 | ytick.minor.pad : 6 # distance to the minor tick label in points 248 | ytick.color : 555555 # color of the tick labels 249 | #ytick.labelsize : medium # fontsize of the tick labels 250 | ytick.direction : in # direction: in or out 251 | 252 | 253 | ### GRIDS 254 | #grid.color : black # grid color 255 | #grid.linestyle : : # dotted 256 | #grid.linewidth : 0.5 # in points 257 | 258 | ### Legend 259 | legend.fancybox : True # if True, use a rounded box for the 260 | # legend, else a rectangle 261 | #legend.isaxes : True 262 | #legend.numpoints : 2 # the number of points in the legend line 263 | #legend.fontsize : large 264 | #legend.pad : 0.0 # deprecated; the fractional whitespace inside the legend border 265 | #legend.borderpad : 0.5 # border whitspace in fontsize units 266 | #legend.markerscale : 1.0 # the relative size of legend markers vs. original 267 | # the following dimensions are in axes coords 268 | #legend.labelsep : 0.010 # the vertical space between the legend entries 269 | #legend.handlelen : 0.05 # the length of the legend lines 270 | #legend.handletextsep : 0.02 # the space between the legend line and legend text 271 | #legend.axespad : 0.02 # the border between the axes and legend edge 272 | #legend.shadow : False 273 | 274 | ### FIGURE 275 | # See http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.Figure 276 | figure.figsize : 11, 8 # figure size in inches 277 | #figure.dpi : 80 # figure dots per inch 278 | figure.facecolor : 0.85 # figure facecolor; 0.75 is scalar gray 279 | figure.edgecolor : 0.50 # figure edgecolor 280 | 281 | # The figure subplot parameters. All dimensions are fraction of the 282 | # figure width or height 283 | #figure.subplot.left : 0.125 # the left side of the subplots of the figure 284 | #figure.subplot.right : 0.9 # the right side of the subplots of the figure 285 | #figure.subplot.bottom : 0.1 # the bottom of the subplots of the figure 286 | #figure.subplot.top : 0.9 # the top of the subplots of the figure 287 | #figure.subplot.wspace : 0.2 # the amount of width reserved for blank space between subplots 288 | figure.subplot.hspace : 0.5 # the amount of height reserved for white space between subplots 289 | 290 | ### IMAGES 291 | #image.aspect : equal # equal | auto | a number 292 | #image.interpolation : bilinear # see help(imshow) for options 293 | #image.cmap : jet # gray | jet etc... 294 | #image.lut : 256 # the size of the colormap lookup table 295 | #image.origin : upper # lower | upper 296 | #image.resample : False 297 | 298 | ### CONTOUR PLOTS 299 | #contour.negative_linestyle : dashed # dashed | solid 300 | 301 | ### Agg rendering 302 | ### Warning: experimental, 2008/10/10 303 | #agg.path.chunksize : 0 # 0 to disable; values in the range 304 | # 10000 to 100000 can improve speed slightly 305 | # and prevent an Agg rendering failure 306 | # when plotting very large data sets, 307 | # especially if they are very gappy. 308 | # It may cause minor artifacts, though. 309 | # A value of 20000 is probably a good 310 | # starting point. 311 | ### SAVING FIGURES 312 | #path.simplify : True # When True, simplify paths by removing "invisible" 313 | # points to reduce file size and increase rendering 314 | # speed 315 | #path.simplify_threshold : 0.1 # The threshold of similarity below which 316 | # vertices will be removed in the simplification 317 | # process 318 | #path.snap : True # When True, rectilinear axis-aligned paths will be snapped to 319 | # the nearest pixel when certain criteria are met. When False, 320 | # paths will never be snapped. 321 | 322 | # the default savefig params can be different from the display params 323 | # Eg, you may want a higher resolution, or to make the figure 324 | # background white 325 | #savefig.dpi : 100 # figure dots per inch 326 | #savefig.facecolor : white # figure facecolor when saving 327 | #savefig.edgecolor : white # figure edgecolor when saving 328 | #savefig.extension : auto # what extension to use for savefig('foo'), or 'auto' 329 | 330 | #cairo.format : png # png, ps, pdf, svg 331 | 332 | # tk backend params 333 | #tk.window_focus : False # Maintain shell focus for TkAgg 334 | 335 | # ps backend params 336 | #ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10 337 | #ps.useafm : False # use of afm fonts, results in small files 338 | #ps.usedistiller : False # can be: None, ghostscript or xpdf 339 | # Experimental: may produce smaller files. 340 | # xpdf intended for production of publication quality files, 341 | # but requires ghostscript, xpdf and ps2eps 342 | #ps.distiller.res : 6000 # dpi 343 | #ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType) 344 | 345 | # pdf backend params 346 | #pdf.compression : 6 # integer from 0 to 9 347 | # 0 disables compression (good for debugging) 348 | #pdf.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType) 349 | 350 | # svg backend params 351 | #svg.image_inline : True # write raster image data directly into the svg file 352 | #svg.image_noscale : False # suppress scaling of raster data embedded in SVG 353 | #svg.embed_char_paths : True # embed character outlines in the SVG file 354 | 355 | # docstring params 356 | #docstring.hardcopy = False # set this when you want to generate hardcopy docstring 357 | 358 | # Set the verbose flags. This controls how much information 359 | # matplotlib gives you at runtime and where it goes. The verbosity 360 | # levels are: silent, helpful, debug, debug-annoying. Any level is 361 | # inclusive of all the levels below it. If your setting is "debug", 362 | # you'll get all the debug and helpful messages. When submitting 363 | # problems to the mailing-list, please set verbose to "helpful" or "debug" 364 | # and paste the output into your report. 365 | # 366 | # The "fileo" gives the destination for any calls to verbose.report. 367 | # These objects can a filename, or a filehandle like sys.stdout. 368 | # 369 | # You can override the rc default verbosity from the command line by 370 | # giving the flags --verbose-LEVEL where LEVEL is one of the legal 371 | # levels, eg --verbose-helpful. 372 | # 373 | # You can access the verbose instance in your code 374 | # from matplotlib import verbose. 375 | #verbose.level : silent # one of silent, helpful, debug, debug-annoying 376 | #verbose.fileo : sys.stdout # a log filename, sys.stdout or sys.stderr 377 | 378 | # Event keys to interact with figures/plots via keyboard. 379 | # Customize these settings according to your needs. 380 | # Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '') 381 | 382 | keymap.fullscreen : f # toggling 383 | keymap.home : h, r, home # home or reset mnemonic 384 | keymap.back : left, c, backspace # forward / backward keys to enable 385 | keymap.forward : right, v # left handed quick navigation 386 | keymap.pan : p # pan mnemonic 387 | keymap.zoom : o # zoom mnemonic 388 | keymap.save : s # saving current figure 389 | keymap.grid : g # switching on/off a grid in current axes 390 | keymap.yscale : l # toggle scaling of y-axes ('log'/'linear') 391 | keymap.xscale : L, k # toggle scaling of x-axes ('log'/'linear') 392 | keymap.all_axes : a # enable all axes 393 | -------------------------------------------------------------------------------- /styles/outputonly.css: -------------------------------------------------------------------------------- 1 | 68 | 83 | --------------------------------------------------------------------------------