You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

1-Least_squares.ipynb 252 kB

4 years ago
4 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "markdown",
  5. "metadata": {},
  6. "source": [
  7. "# 最小二乘(Generalized Least Squares)\n",
  8. "\n",
  9. "## 1. 最小二乘的基本原理\n",
  10. "\n",
  11. "最小二乘法(generalized least squares)是一种数学优化技术,它通过最小化误差的平方和找到一组数据的最佳函数匹配。 最小二乘法通常用于曲线拟合、求解模型。很多其他的优化问题也可通过最小化能量或最大化熵用最小二乘形式表达。\n",
  12. "\n",
  13. "最小二乘原理的一般形式为:\n",
  14. "$$\n",
  15. "L = \\sum (V_{obv} - V_{target}(\\theta))^2\n",
  16. "$$\n",
  17. "其中$V_{obv}$是我们观测的多组样本值,$V_{target}$是我们假设拟合函数的输出值,$\\theta$为构造模型的参数。$L$是目标函数,如果通过调整模型参数$\\theta$,使得$L$下降到最小则表明,拟合函数与观测最为接近,也就是找到了最优的模型。\n"
  18. ]
  19. },
  20. {
  21. "cell_type": "markdown",
  22. "metadata": {},
  23. "source": [
  24. "### 1.1 示例\n",
  25. "\n",
  26. "假设我们有下面的一些观测数据,我们希望找到他们内在的规律。"
  27. ]
  28. },
  29. {
  30. "cell_type": "code",
  31. "execution_count": 1,
  32. "metadata": {},
  33. "outputs": [
  34. {
  35. "data": {
  36. "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEGCAYAAACKB4k+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAA9qklEQVR4nO2df5hcVZnnv29Xbkg3unQiGTY0CUGXCWtkSEsr7LIzKzhjFAboESXysKMz4zPsrs7zDJHtNazOEFxcsoOK7jM7urjMjK6IicC0ARyRkbi78hiwYyfEKNkJQhLKKNGko6SbpLr73T/q3sqtW+ece879Xd3v53n66e5bt26dc6vqfc95fxIzQxAEQRAAoKfsAQiCIAjVQZSCIAiC0EKUgiAIgtBClIIgCILQQpSCIAiC0GJB2QNIw5lnnskrV64sexiCIAhdxY4dO37OzEtVj3W1Uli5ciXGxsbKHoYgCEJXQUT7dY+J+UgQBEFoIUpBEARBaCFKQRAEQWiRm1IgokVE9DQR7SKiPUR0u3/8b4noeSLa6f+s8Y8TEf03ItpHRM8Q0RvzGpsgCIKgJk9H8wkAVzDzy0TkAfgOEf29/9gIMz8QOf8dAM73fy4B8Fn/tyAIglAQuSkFblbae9n/1/N/TNX3rgXwRf9524mon4iWMfOhvMYoCIJQNqPjddz12F78ZGIKZ/f3YmTtKgwPDpQ2nlx9CkRUI6KdAF4C8DgzP+U/9HHfRHQ3EZ3mHxsAcDD09Bf9Y9Fr3kREY0Q0dvjw4TyHLwiCkCuj43Xc+tBu1CemwADqE1O49aHdGB2vlzamXJUCM88w8xoA5wB4MxG9AcCtAC4A8CYASwB82PGa9zDzEDMPLV2qzL0QBEHoCu56bC+mGjNtx6YaM7jrsb0ljaig5DVmniCibQDezsyf8A+fIKK/AfAf/P/rAJaHnnaOf0wQBCERVTPNRPnJxJTT8SLIM/poKRH1+3/3AvgdAM8S0TL/GAEYBvAD/ylbAbzXj0K6FMAx8ScIgpCUKppmopzd3+t0vAjyNB8tA7CNiJ4B8D00fQqPALiPiHYD2A3gTAB3+Od/HcCPAewD8HkAH8hxbIIgzHGqaJqJMrJ2FXq9WtuxXq+GkbWrShpRvtFHzwAYVBy/QnM+A/hgXuMRBKH7SGP+qaJpJkowlyqZuLq6IJ4gCHOXwPwTrPYD8w8AK6F5dn8v6goFUKZpRsXw4ECl/BxS5kIQhEqS1vxTRdNMNyA7BUGYp8z1yJwqmma6AVEKgjAPSWuaKYIszD9VM810A2I+EoR5iETmCDpkpyAI8xCJzBF0iFIQhHmIROYIOsR8JAjzEDHNCDpkpyAI8xAxzQg6RCkIwjylCqaZqofFzkdEKQiCUArdEBY7HxGlIAgFI6vjJqaw2Pl4P6qCKAVBKBBZHZ+iG8Ji5yMSfSQIBdINSWNFUcVeAoIoBUEoFFkdn0LCYquJmI+ErqLK9nibsbkkjVV1rlmNS8Jiq4koBaFrqLI93nZsI2tXtZ0HqFfHVZ1r1uOqQlis0I6Yj4Suocr2eNuxDQ8O4M53XoiB/l4QgIH+Xtz5zgs7BGNV51rVccUxOl7HZZuewHkbHsVlm56oVJ/mqiE7BaFrqLI93mVsNqvjKs01bC5izTlVeA90VHXXVVVkpyB0DVWOVsl6bFWZayBQ6waFAFTjPdDRrbubshClIHQNRUeruJgcsh7byNpV8GrUdsyrUeGROSqBGqXqEUNV2nV1A7kpBSJaRERPE9EuItpDRLf7x88joqeIaB8RbSaihf7x0/z/9/mPr8xrbEJ3YmuPz4LoCjkwOegUQy5jiy7NTUv1nDAJzrzfg6yoyq6rWyDmfD5pREQATmfml4nIA/AdAH8K4EMAHmLmrxDR5wDsYubPEtEHAPwGM/87InoPgN9j5nWm1xgaGuKxsbFcxi/Mby7b9IQydHSgvxdPbrhizr9+1caRhqhPAWjubqquzPKEiHYw85Dqsdx2CtzkZf9fz/9hAFcAeMA//gUAw/7f1/r/w3/8rb5iEQRn0kablG1yKPv1A+ZCglmRO8y5QK7RR0RUA7ADwD8D8N8BPAdggpmn/VNeBBC8MwMADgIAM08T0TEArwHw8zzHKMw9sog20SWZ9RDhvA2P5p5oVZXOaHMlwUzyIezJVSkw8wyANUTUD+DvAFyQ9ppEdBOAmwBgxYoVaS8nzEGyqL6pSjIDgBnf3Jp3WKNtkpsNaTOQRaDOLwrJU2DmCSLaBuBfAOgnogX+buEcAMG+vg5gOYAXiWgBgDMA/EJxrXsA3AM0fQpFjF9IRlJhlFaIZWF6ia6Qe4haCiEgrzLPwfynGjOo+a87kHCFLjH6git5Rh8t9XcIIKJeAL8D4EcAtgF4l3/a+wB8zf97q/8//Mef4Ly84ELuuEbvpH1emKyiTYYHB/Dkhivw/KarMKv5KGZt4w/PH2juTIIdQhIhLjH6git55iksA7CNiJ4B8D0AjzPzIwA+DOBDRLQPTZ/Bvf759wJ4jX/8QwA25Dg2IWeSCqMshFgeztGiwhqzFuJVcVgL3UNu5iNmfgbAoOL4jwG8WXH8FQDvzms8QrEkFUZ5mH6ycI5maeM3kbUQ7+/zcHSy0XFcYvQFHVL7SMiFpNEzWUXdZO0cLSoKJ8uoo9HxOl5+ZbrjeBmZ0UL3IGUuhFxIasKpclx82Mfw5IYrcos6ymr+dz22F43ZTl/I6QsXiJNZ0CI7BSEXbFbWpiijsuLiy25sk+X8dSanY1Od5iRBCBClIDhjKzhNJpy4UMm8BbFqDgAqEb5pM/+su7zNJcpW7N2OmI8EJ7IIGQXKDZXUzWHj1j2FjylJOQ7b96DKpri8yOrzOZ8RpSA4kZUwLzNUUjeHCY1ZJa8xJRVgWXd5SzLuqnYxk7yM9Ij5SHAiK2Ge1rShM//YmA2SjDUPkpbjsH0P8jCjVD1DWvIy0iNKQXAiKzt1mrh/lWAaeWAXwGhF25iElW4Oi/s8vNKYzT0XIcBFgIUFvKrkBtD+HuiE99j+I3j0mUOt3IX+Xg8br1ltLdBdFFkZtv356kfJEjEfCU5kZadOY9pQCabGDHeEX0bNBoHZoz4xhWhN9l6vhtuuXl1oiWXbLOmomUmlEKLvgU54f2n7gbZktompBka+usvaBGSryD46uhvrN+8s3LY/H/0oWSM7BcGJLEMmk0YZuZgCgnOjK2dGs3MYAx3F5vJSAtGV8+UXLMWDO+ranUlwvmrlCwA1IswyK98Dl3vUmGXrwn42K/HR8Tru236go1FcXgUEw5Qd0jwXEKUgOFN2KWWdYNKdC6hXzoFCcO0glsQsojLnPLijjusuHsC2Zw93XEvVLSzKLDOe33SV8jGXewTYKxEbs99dj+3Vdg4twu9R9uez2xGlIHQdKsHk1ajNpwCcElaj43WtgHR1QCZ1tOrMOduePaxUSqrzo5zR62kfU92jYGekwtbmbrMSN91TG79H+HWE4hGlIHQdOsGkOxYIGhWuDsi8I4bijoc5fnIao+N1beJgMN6wuWrz9w6iMdOuGrwet1pIcStx3S6FACu/R94mJsGMKAWhK9EJpuixyzY9oV1xezXC5RcsbTmfbRraJBXirlExNuafxozZF6C6R0PnLsHtD+9JHH1kg26XcuOlK6x2FBI+Wi6iFIQ5jUnAzMwyNj99sGVysmm1mTTk0TUEV9cONIqrAM3C3q7zA4SP9/d5OG1BD45NNaQMR5chSkEojSLi2E0r7lmGtqOazoyRNL/CNSomej6g9geY/Ap5YMp/CEdSHZ1soNer4e51a7RzLKpHheAGdXPHy6GhIR4bGyt7GEICVNE1vV4t87wAmygeHQQoo3vKSMoa/Ng3lc1yFvd5GP/zt+X62jaJczXN8bjoLileVw5EtIOZh1SPyU5BKIU4J+PoeB0bt+5p1SNa3Ofhtqvdbd/B+bds2aUUWiZ0Zoy0JpgkgnBCoRB0x7MUtFGlqruHuuNx5i3dvcxLWYgSikeUglAY4S+kKY59dLyOka/uagsvPTrZaJaygHu4YnC+y44hLzNG0jBMW/t7mjBPlcC0CY0F9DuFpB3j8ghVlRBYO6TMhVAI0VINOs7u79V2DAuibZIQlNWoUbTAxSmCx/Isb5G0iqdt+Yak19dVbLVJgOv1arjhkuWZdozLo9KpVFC1Q3YKQiHYrDgDIbJ+807tOWnCFXU7hjx8GTqShmHaOqqTXl8nMHU7AFWJjaFzl+TaMS5tqKqEwNohSqEi5GnrTHPtrMZl+uIR0HZtU72ftOGKZdfGSROGaePL0F2/hwjnbXjUWZnMMKPXq1kp0azKS+QVqiohsHbkZj4iouVEtI2IfkhEe4joT/3jG4moTkQ7/Z8rQ8+5lYj2EdFeIlqb19iqRp7dotJcO8tx6b54A/29eH7TVXhywxUtgTKydhW8nk4zj1dzy7zVMTw4gCc3XNHxukWQdxVP1fWBpnA3vYem96fIyrFAfvdIKqjakVtIKhEtA7CMmb9PRK8GsAPAMIDrAbzMzJ+InP96APcDeDOAswH8A4BfZ2atzWGuhKQGGbVRkhRry/LaWY7LNQRVF30EdH8FzLwjYGxCSKPvYVEhwrZI9FG+lBKSysyHABzy//4VEf0IgOnuXwvgK8x8AsDzRLQPTQXx3bzGWBXytHWmuXaW4wqbbYKSEmEnn40pIm30SF6dyFyvmXcVz/D1z9vwqPKc6HtYtlktSl73SCqoxlOIT4GIVgIYBPAUgMsA/AkRvRfAGIBbmPkomgpje+hpL0KhRIjoJgA3AcCKFSvyHXhB5GnrTHPtrMelcvTaCHZTXwHbAmoqhbJ+807cvHmnsdZR0de0eU0Xwe3yHorAFIACQlKJ6FUAHgRwMzP/EsBnAbwOwBo0dxKfdLkeM9/DzEPMPLR06dKsh1sKedo601w7j3G5hgWG/Ro6bHYuun4KQLyvRNeoPs01k5DExyN2dMGVXHcKROShqRDuY+aHAICZfxZ6/PMAHvH/rQNYHnr6Of6xOU+eW/c0185jXK4mKZtQVtPOJa57WYCpz7BuZxOnjLIuA61TqLds0Sf1VcEsJHb8bMn7fuamFIiIANwL4EfM/KnQ8WW+vwEAfg/AD/y/twL4MhF9Ck1H8/kAns5rfFUjz617mmtnXYbA1SQVJ3hNq17Xukeq1zLtbGzKW2cZA697rRlmowmuTLOQZBFnSxH3M0/z0WUAfh/AFZHw078got1E9AyAywGsBwBm3gNgC4AfAvgGgA+aIo+E8kgTqupqzjDtAuLCI21LNJhey7Sz0YV/xl0zKaZs7Kpm5koWcbYUcT/zjD76Dpp5SVG+bnjOxwF8PK8xCdmQpmOWqzlDV17ZJlTSZZWuU0ymnU00oira7jJr231cQb8qZuZmGcEmZqhisrIlo1lwJu0H08WckcYmbmoLyZH/r7tYPSadUgo6tgVj+vS6NYnHactAjLmqipm5WUWwiRmqSRFZ2aIUBGeKLhcQp0SiHb+YgWNTDZzR68GrUVtPYlXzegaw7dnD2tcGOnsdhxvKBALqzndemDrZ0ISpG1tVI4qyaqQj/ZybFNGYSJSC4MzI2lUdpa1dm79nRXQFGW5EMzHVgNdDWNznYWKyYXQM1yemcNmmJ5Sr+6hSUvV9thFQac0fqgTAuJ7SNuRplskq+qnoYnZVNVUVEU0mSkFIRtRbpPeB5kqcM7kxy+hbuKDVnUxXugOwN0kkEVBZmT+yjiQqwiyTxZiL3J1W3VSVdzSZ9FMQnLnrsb1tJhkgea8DXWJY3GMBruU64iKGbCI5dILIJKDiokZs5poH3RIdVGQSXrfck7yQnYLgTFZbedOKDLArh2GTKxAW1lETTJJ5JLHrmu5ZmSvTbukxUGQSXrfck7wQpSA4k9VWPm5FZmO3NzlfAbWwDrbfOlNS3DySCCjTPSvTidpNPQaKSsLrpnuSB2I+EpzJaitvWpHZrtaGBwfa6v0v7vPQ3+u11f4HoDTNmOYRZ85x7clgeq0yV6ZSG6mT+X5PZKcgOJPVVj5uRZZFdU8b00x0HoB7Jdc4TPdMZ8oqYmVahdpIVWO+35PcmuwUwVxpsjNfMTV2AbLppZykUZApQinrktij43Xc/vCetlBaoNwGN8Lcp5QmO8LcJ4tY7kVeT0vw9/d62HjN6rZrpO0tncSZbHrMtGtwvR+6gn2q+5CE8D3IKqdBmPuIUhASkUUXtKhAPDE923ZOUseiTXVUk2kmLqJJ5QROcj90ORann7YgE4UQHk9QN6lqMfdC9RBHs5CItHH3uuffvHln6jj9uIS2OKehTfXT6G4iSWx7Fg5mlwZAtuMS5jeyUxASkTbuPqmJJs3YADufgE0uQ3SnkUTAJwl9jNZ5evmV6Va5EZcGQPMl5l5wR3YKBVBWtmocacZlyuq1WTXHRdakWc3qrh04l227zj254Qp8et0aq/DEJFnOrqGP0T4WRycbbfWngPYGQCbmS8y94I4ohZxJ05CmyuO6/AJ1f+zLL1hqtWpOYqKxRXVtwqmidy73PpoHoWvskyS23fbaAbZNg+IaAM2nmHvBHTEf5UxVS/6mHZeu1PS2Zw9bmUWSmGh0qKJ+7nznhcrmN0lMUzYO76Sx7S7OdFslqWoAJNFHgi2iFHKmqnVU4nwCccLN9Py7162xqg0UCERdvoLNalbnvwh6G6hyDtIoZdO9ybsMg02dp/B9K7M3s9C9iPkoZ5LYmrNG5TvQvf4ZvZ6VWck0r7BZBGj2Fg4Escp042pGCRPnv8i6HWSZpkCVScirUUdZD1EEQhpkp5AzRXRKMqFbSV938UBb97BgXETJC9FFV6mAfbmIpKvaOKGfZXGzsk2B8738glAMslPImTSr4CzQCbJtzx5WjmsiUm4hIK4QnWpeRdSlj9uJZVncrAqmQNdCfILgiuwUCqBM265JkKnG5VKcLW5etiUm0pTLsN2xpFldB+PTVQlL4xAXoS5UjdyUAhEtB/BFAGehGfxxDzN/hoiWANgMYCWAFwBcz8xHiYgAfAbAlQAmAfwBM38/r/HNBWyEjM580kOE0fG6MrQyKmS9GuH4iWmct+FRa2E2Ol5vi/qJjil8nq2JyTRf3fG0gjiuZEZah7hqnt2IKLy5Q547hWkAtzDz94no1QB2ENHjAP4AwLeYeRMRbQCwAcCHAbwDwPn+zyUAPuv/FhTYChldE5oZZuX5USHbt7CG4ydnMDHVML5OFNPKOpzjYGunj5uvaixZCOK43IBFntoCGxWSkyenKxmanAVzXeHNN3LzKTDzoWClz8y/AvAjAAMArgXwBf+0LwAY9v++FsAXucl2AP1EtCyv8XU7tvb6wPZfI+q4hs6+H9it7163BpMnOwWijV/AZGf/0vYDrSgonYkpejyJf8L0HNts7jh/wdHJRkcEkipKKVoa2/b63cB872k81yjEp0BEKwEMAngKwFnMfMh/6KdompeApsI4GHrai/6xQ6FjIKKbANwEACtWrMhv0BXHxek5PDiA9Zt3Ol0HMK/244RZXEx9sJokAlQtPWq+eStYbScZh+6x4LV1vaHDK/z+Pk8r0AOiK37bzGNgbpSbqIIDXsiO3KOPiOhVAB4EcDMz/zL8GDc7/Dh1+WHme5h5iJmHli5Vl1qYD7jmPyTJl4gr5mZiZO0qdO5N2plqzCgVAnDKvFU3KIS4cegeC/ImomPZuHVPxwr/5Vem4dXiZtJ+r2yF4VwpN1GFXBwhO3JVCkTkoakQ7mPmh/zDPwvMQv7vl/zjdQDLQ08/xz8mKHANtUwSmqn7UpN/PRPDgwO48dIVsYpBh0pwR0lSArvXq7V6C0SZmGp0vGZjlnH6wgWt0FuVGQ5ov1c2wtAUmlzVAoo65ntP47lGbkrBjya6F8CPmPlToYe2Anif//f7AHwtdPy91ORSAMdCZiYhgmv+Q/T8/l4Pi7werDf0L9AVlrvx0hVWDsQ7hi/EjZeu0ApS+ONwEdwBNSJcd7G5N3NgxgleP7hHA44r2GNTjVZuwCevvyhWAMYV+yNAm2NQdtZ0EsrOxRGyJU+fwmUAfh/AbiLa6R/7TwA2AdhCRO8HsB/A9f5jX0czHHUfmiGpf5jj2LoSVdifrs+wCl2tIV20SNoY/9HxOh7cUdcK+F6vho3XrFa+hqlQHtA0Lz24o46hc5coQ1ejXccCwa3KtA7GssjrUfoPdIX8dPck+PuWLbuUczftJMrOmk6K1FmaO+SmFJj5O4DWevBWxfkM4IN5jafbyTLsz0XwpPmymxyu0WqdqteIa6mpG3Pc/HSCXfWapkJ+JkzKx2RWEaetUDaS0dwluAjyuESiJM3sk6C7XmA+UREe+xm+iWtisuEUfWQjWE2CPaskrCQ7LV20U3+fB0CSxIT80SoFIvo6gA8w8wvFDUfQYbuCjNtR2GYaZ4FrMbro2CemGuj1arh73Rqn8htpiuC57ozihLTr9XSuFGZJEhOKweRo/hsA3ySij/hRRELOmKJObMP+4hKJdLkHNhFFruiiUi6/YKl1s/lg7C7d1JJGw7hG/eThFD42pc6JODbVkCQxoRC0OwVm/ioR/T2APwMwRkT/C8Bs6PFP6Z4ruKNbBY7tP4Jtzx7u6CAGqAVd3I5C9zgj+9Xm8OAAxvYfwf1PHcQMM2pEeOOKM9pKdts0mw+K9wGnCvaZuqklMdskWYXrhPTGrXsSm3hMu5wi/A1inhLiQlJPAjgO4DQAr478CBmiEzD3bT/QEhKMU557Xdhf3I7C1NQeyDZGPhp9NMOMJ587ol3txo09KL8x0N/bsduJrphdS0wnWYXrhPHEVCPx7sG0y8k7Sawbw2GF7DH5FN4O4FNo5g+8kZknCxvVPMS0go/+P9Df23LURld2l1+wFJu/dxCNmVPP9GrU2lGYSk1nbbN2Kffg0sYz7Yo5uGfh3sWmcemwaY8JuIWUmnY5Y/uP4L7tB2J3i0np1nBYIVtM0UcfAfBuZt5T1GDmM7YCBjglqFRCfPPTBzuFXOhfk9C5bNMTmQoFF7NGtNl8knLgNitmVQ5D3Lh06CrQqnC5FyrndLDrCo+WAGMCnysSDisAZp/CbxY5kPmOSsDERQmpVnaN2c5nNGa5TbDrImKyFgq2ii7s5LaJ1tEJ48mT08oeEWFcdi9xq3CVEps8Oa1NgBsdr+P2h/e0Hu/v9bDxmtVWQl01bgaw7dnDVnOxIcvWpUL3InkKFUElYC6/YKmyj3IgqFyEddy5o+N19GhMKUmFwsjaVVi/eWdsxUNXJ3dw7sate1p9HoBTZazD5wSETUZxENC2SzE5X6NKTNWUJ4i4GnlgV5tZb2KqgZGv7jKON3jNInJLyu4nLlQDUQoVQrVKHjp3iVYguZicTII9EGQqhWAbyqkao84OHsW1FhHQvFd3Pba3TSkAdg16TIT9NarnxvlZdCawux7b26YQAqK7ON1rFpFbkrasiTA3EKVQIEnC/UzmFGXrzB4CCG0CKE6w60wqQdG5ux7bi/WbdyrHHCc07xi+sKXYbMNqbbE1d9majKJjGR2vK+sXxflZVO+Zrp+F7XiDyLO8nMwBUsNIEKVQEHlko5pq+NgonziTSlB0zjRml4gVQrNcA3MzGSvtStTWBm4ysQTRR9FaTKbdk+qacQrftKuzHW8QeSareCFPRCkURF7hfrqVXdw1bUwqumY04THHtdOMvs7RyVOlK9IKNFsbuE4gR01FYeJ2F2FBHpd4GNRxqvUQZiKBAF4PZTJeQcgKUQoFUbVwvzih1+vVtI+Hx6yL8w96GNiU3Ui68rW1gSdxoJrel+hzTYmHwZ2ZmGrA6yEsWljDcb/vdTj6KFoI0KuRkwlQELJClEJBVC3czyT0BvrNPQ3O6D1VCktnXgmOJ+mT7KoYbMtYuygg3ftVI+rIJLdNPGzMMn6tbyH2fKx9ta8qBAgAPQTMcmeZcUHIk9x7NAtN4oq0Fd2C0VTuIigLMbJ2VdNxHeG4nw8QnK+7jul1ABRa3M217IXu/frk9RdZlxZRoVIgul3bLJ/6jIhCEIpClEJBDA/qWxaWUXNGJfS8GuH4iemWYgKAVy3q3Ew2ZrglvE3KbnS8juMnpp3GVZXsWdP7FUVXwVWFSoGY5ixVUIWiEfNRxrgkOgWUUXMmalLp7/Pw8ivTLdNF1LwTJRBkLl3MbKhS9qxteGaSxMMwcfkmVVGUwvxAlEKGJA07jYvgyYuw0Lts0xMd5RmCpvcqvwH7zwknqoVR1VGKo5udqa6Jh2HiaihVSVEKcx9RChmSdMUfF8FTBKZcBV0kkknpua5u55IzNbpbjAu/1ZXtALpbUQrdifgUMsQUaWNyIsdF8ORN0KJTRWBL1zmUdTZvl9VtEKs/VxRCEv/Q8OAAdt72Nnx63RorP4Yg5IXsFDJEZxsO2kYC6tX1gCFZKSkuJTV0LTqBZuXRoMSFjnAp77hYe4Ax1Zhte76q/o8LVeoWltY/ZOvHqNKchblFbjsFIvprInqJiH4QOraRiOpEtNP/uTL02K1EtI+I9hLR2rzGlSe6KJS4LmFJewrrcF2tmkw9RycbrWvo6O/zsOb2b+LmzTtbrzkx1QAYWNznta16X4koBJsxmBgdr2PkgV1tcx15YFeukVum8OGiWmZKhzQhL/I0H/0tgLcrjt/NzGv8n68DABG9HsB7AKz2n/NXRFRTPLfSqMIYdSvwsJBwCX+0wbW1ZFpH5tHJRoctHGjuAPoWLmjLDci6peTtD+/pqD7amGHc/nA+vaHiBHLeLTOBZK1DBcGW3MxHzPx/iGil5enXAvgKM58A8DwR7QPwZgDfzWt8eRHd/l+26QmrTOYsq1PG+TaiJgeXDmJpx5J1zX5VQxvT8bTEmYdG1q7CyFd3tTU7UtU3SkPVSqYIc4syfAp/QkTvBTAG4BZmPgpgAMD20Dkv+sc6IKKbANwEACtWrMh5qOkpo3FJUt9G2EZ9/MS0cvWfZCxhuqlmv8pubyWQo177jIPIqlYyRZhbEOcY4eLvFB5h5jf4/58F4Odomtn/M4BlzPxHRPSXALYz85f88+4F8PfM/IDp+kNDQzw2Npbb+LMiiVMwjSNRVQFV16RFV3nTpTGNjl6vlmn0jOqeqMI4A2pEuOGS5bhj+MJEr6VS5qct6FG+XnAfdTtD031O8tlQjU0ilQRbiGgHMw+pHit0p8DMPwv+JqLPA3jE/7cOYHno1HP8Y11B3Bfb1TSUtveCajXu2s4xfI0kSXSL+zzcdrVd/2FAfQ/DcwgyrgOzTHBPrrt4AJufPqjsTT3DjC9tP4CHdryI//LO33B6D3RmokVeT0fehk2LVJXpDoDyfQ6X3NZ9nsL3Jk6ZSKSS4ELRO4VlzHzI/3s9gEuY+T1EtBrAl9H0I5wN4FsAzmdm4zK1CjuFPFZtrqvNNNcMrmsSFKbnBgQ7kSRJaKp7qOogZxp7nPJyfU/O2/CocmdFAO5et0YrZHX3StU1bZHXo/R9qM5N+nkqalchiqe7KGWnQET3A3gLgDOJ6EUAtwF4CxGtQfMz/wKAfwsAzLyHiLYA+CGAaQAfjFMIVSGPukW2jkSXL6LJmRy3EzE5MKNN7pOguoeqlb+K+sRUaye2csOj2vOmGjO4ZcsubVvRKCa7vWuLVF1Yss40pwthTnJ/i6irlUdXQaE88ow+ukFx+F7D+R8H8PG8xpMVUUHsapaxwcaRmKahvOraJkGRdyewNDWeCM17MTw4oC0XEhA8ZiO0kgYIRO9z3JhsSfp5KiJSqYyCjkJ+SJkLB1Qx6i4lkm25/IKlHde17faVJlZdJyiyTq6LkqbGEwOtOd9wyXLzySHi7lWa3JEgNLXXqxkVQn+vZ11y+4xeL1G/jSLyJiREdm4hZS4cUAli1Vc+bTbygzvqbdclANdd3G6ycP0i2kQT6QRFXmGkwa4r7Uo6mHMQZXTfUwdgc8k4oZUmd8Sm3enGa1a3zjWV3PZ6CMdPdpY1D8ZoooiQaAmRnVuIUnDAJET6ez0cm2rkYl9nANuePdx2zPWLaCOkTILCRkC6+DhslNTiPg99CxfE5k6E53zH8IW4Y/jCtrH0aEw4eQotm3an4T4bYaIltydPTivLmt+yZZfy+WGKyAspIxdHyA9RCg6YfAinn7YAO297W+rXsN0BuH4RXYRUHLrwURsfR/DcOD9Cr1frCGnVKZJJvz2oLgxYF4FTRgKhjR8mqoDP0zjQZ5itdgxRxRCYzbJSDN2UkCjEIz4FB0xCJCv7aZwNOCjGtn7zTizyetDf61nZvBd56rc63JPZBl3tn9sf3hPr4wg/14RqLoEymWrMdNjdj042jAXhhgcHcN3FAy3fRY2owxyXNbriiEG+gkvxurg+13F+JCmgJ7ggSsGB4cEBLO7zlI9lZYqI63kc/nIfnWzgxPQs7l63xijYb/z8dzvKVQPNN991taxzcOtqDYWVZZwJC1ArqagyUbkLAnOKStAFfprAhDTDjAd31HMVimFHNdAeluoqlFWfiTBxC5K8C+iJ0plbiFJw5LarV+caiWOKekny5R4dr+PJ544oH5tFU2C4fHldd0RhZRn3XEIz8iqKjTIBTplTovMpq6ro8OAAntxwhbJarsvrB58JXZRW3IIk7+ggqdo6txCfgiNF2E91Tt0kX+6NW80lpF0TjXS28v5eDyemZzuStsJCPq5BPQN4cEcdQ+cusYq0UqGKjy87ZDKL1w/mk8Q3knd0UNn3V8gW2SkkIFgBhvsEFIFrzPnoeN2q0qnLqk5n3tp4zWpcd/FAm70/EPLByj3ODKIbyxm9apOdjqgwsr1vuuY5pqY6NmSVK5A0dyLvPJMiciGE4hCl0EW4frldtu+2WcUmwbTt2cNGM0n0uTrCQn10vI7jJ6c7zukB0KO5SFQY2dy3j47uxvpQ57hgB/XR0d2p7eVZCmWbBUlUiQHItIlTlLyVjlAsYj7qIlxNVy7b93C5CJtxJDVvhZ9r04Dorsf2KovineFXYbUxp8Tdt9HxOu7bfkCp0O5/6mBHjoNrCYciQzZ15U/ufOeFmZQkUSEhqXMLUQpdhkuWbZwNPwyj2drSVL467svuaru2ybXQKZqJyYZRGKlyKXRC8a7H9mrbpuqyrV3t5Wmyo10oqw5RUfMT8keUgiNZlAguqsywTujqInmOTjZaoaX1iSmMPLALYHT0MADUTmnXhLrhwQGM7T/SWo0H+QMAWr0H4rKRVcLItVigScDrCtpV1V4uTl8hLeJTcCCLeOysY7pNTlCd/X/AUqA1ZrijhLXJKe3qCFXlD2x++iBGHtjVuj8qgRxnr3YNkdQJeEKzyF432cvF6SukJdcmO3lTdJOdLJrfZNlAx6WBSnh3ckavh+Mnp2Mb2OggAM9vuirRc8PYNO8JqBFhltlqZ6VrkAM077PK1KTqgXDjpSs66ihV3V4urToFGyrTjrPbyWJrnsU1TPWDVPbjqKCYmGrA6yEs7vMwMdkwFptTcXZ/byaC0mXOM8x4IUYRBWPSKYSgzASgNinp5tNN9nJx+gppEaXgQBZJQLYNdEyRMnHVRaPCVtfZrG/hAoz/+du01/Vq1OZTAJqCdeVrejPptOXiCI9m80bvkarkdBhd97NAgXaT4AfU8zf1dRYEW8Sn4EAW8dhx14jzOdiUfIgqKdtQ0WjRuHVvWo51b17ekZD25HNHMilrYJPMFjDD3PKfrNzwaEdOwX3bD2jvi6rMREA3OmBVn5EvbT8gtYeETBCl4ECably214hzksYJMZWSsnE+6orGPfrMIa1AjZIkTDN8L0wd2Bb3ecaieCaTUVB/SEU3OmBtFgZSe0hIyrw1HyW1iWdhZjBdI25VbzK56PoimEJF4/wTNoXoTl2zB6+79eut8NIbLlne6oamI3wvdH0DAIAZTmMJCIT+XGoEY6t8u3EXJJTPvFQKrnHsRRLnc1AJN6+H8KpFC1oNVMb2H+mwL9/5zguxceueljN5kdeDsf1HjHZ4VyZD5blnmPGl7QcAIFYxhOeoK7Z3zMIJHvUbhIV+WQ7YPCKXbH0x3bgLEspnXoakmsJCR9auSpXVmxabkELX8NJer4brLh7oUAAq52sUVfVTF2pEeO7OK63ONc09rltbMMcqOVvzCg+1CTaQMFTBhCkkNTelQER/DeB3AbzEzG/wjy0BsBnASgAvALiemY8SEQH4DIArAUwC+ANm/n7cayRVCqY49mjGr9dDAKFN6Gb1xTZFGNkqIdtYf11mrgkCcPe6NQBOKcX+Pg8vvzLdkdRmIhxKGjc33eO6XAKGezvRotC9Ny45Fzok+khIQ1l5Cn8L4C8BfDF0bAOAbzHzJiLa4P//YQDvAHC+/3MJgM/6v3NBt/2uESlDN6OkrSUTZ75y8VvY2o1dFQJwahdh2jnpylAEhJ3HNmY73dy7Mf5e994E9yuN2bLbQmiF7iFX8xERrQTwSGinsBfAW5j5EBEtA/BtZl5FRP/D//v+6Hmm6yfdKei29S4mEpes3rAz17Rit81qDq8S44RyQA8BqsW9yYSkMh0FuyQAsSYdALjsdUvw7qEVxnOTZHPbUmY2su0uLs/5C4KKKmU0nxUS9D8FcJb/9wCAg6HzXvSPdSgFIroJwE0AsGLFCucBhBvABwI67EuwTaaydeJFFZBJgNus+l2u1wY3k9HCZjCvh7BwQQ+On+xUhr1eDUSdET9TjRls3LrH2s/w3R8f0bYDDbC9566UHVCgCgpQkUWUUDeV4hCqTWl5CtzcojhvU5j5HmYeYuahpUs7+/maiDaAn2FuRagMDw4ok6m8Hmpm9oZwCWW07S8M2CmauOvViOAp3tVZNP0igTmnv9cDCG0KIZhlkDsxMamO+JmYaljPycb1EPRyyJqyewfb5mGkjRLKusiiML8pWin8zDcbwf/9kn+8DmB56Lxz/GOZEickVIlld737Itz1rosSJ6zZrgJtFU3c9WaYEYoMVT4e7AKiEUtR+V1USCMDuHnzzkStLk1UoYx0uFPaJ6+/KFVGvK4ibtnKT5hbFG0+2grgfQA2+b+/Fjr+J0T0FTQdzMfi/AlJiBMSpi140q24TUy5S/SMS70gHXFJacFKUxXGmidZmndGx+uxvRiywtZ0k8ZZbjKFVUH5CXOH3JQCEd0P4C0AziSiFwHchqYy2EJE7wewH8D1/ulfRzMcdR+aIal/mMeYTIlhedmfTXblsJN3bP8RK2Fha6dOy1RjBvc9dQA3XrJC2aoyz9fduHVPJnH8SXoxJH0t289N0qgh024gi0KNghCQm/mImW9g5mXM7DHzOcx8LzP/gpnfysznM/NvM/MR/1xm5g8y8+uY+UJmzqVJgqkYXV5b8LBJCjhlVw4rBNuCZlEnuQldU/uA/l4vthgdM3D/0weNCiGuZpGKWszgJqYaqcxIOr9LjSjzhK6iTDem3UAWhRoFIWBeFcQzFaPTfenqE1Opbd2BXfmFTVfhuTuvNFbtDIgKFp2TXMcsQ1sEjgBsvGY1rrt4AHHifMbgKR7o78Xzm67CrENY8+I+D59890Wx3d+ic9d1l1Ohey9nmTOPyDF9brL0j5iKGmZRqFEQAuZd7SPd9t1kq8/KlGQqPqd7XVOv4nBYbZTAT6HrKDY8OIDbH96Tyiw0eXIao+N1az9Hr1fDbVevbr0Ho+N13Lx5p/LcsJ/H1axXhDklrqEPgEzDXy+/YGmrllT0ePAaogSELJhXOwUTcbX905oEoit9G4JOYbpexYB6xxAOs42uIO9et6bVYvKoJuTUlqOTDdz60G5cfsHSWFMUAXjjijOwceserNzwKFZueBS3P7wHfar4WZwS4EnMM3mbU2zfyyzNSNuePex0XBCSMu92CjrCkSG6L3uaaA6XfIUAm1W8rohfXNmIrITVVGMG2549jOsuHsD9Tx3UKq+gOU+Yo5MN1HoIXg+1lRMJC/AkkTV5l8RweS+zigCSCCOhKEQphAgEqK48QRLzg43JKFpqwqZ6KdC+I9AJPF24pI0wWdznWe0m6hNTbQ16XJiZZfyTPg99CxcoBXhSU1Ce5hQXQZyVycr2Pkhms5AWUQoKkjRkUX0ZAWDkq7uMFUV1K32dIolW2ATQ8jvE9XMO2+NNfoBPr1vTuoZN/Z4eRTkMFyYmG61e0VGq2BxHd+9M/RzSYnMfyi7rIcwN5mU/BRtcVly6AnsAY8qQXmwqwW1TKhqA8nWDvgJxHdrWb96p3JGEC7TF1e6P1lPSYdr9xBWEq9rqV/d+593PIe4+mPqESME9IUyVCuJ1DS7mB50z1ERcFnPUxxHNa7j1od1Y5PUoXzcu2ewnE1MYHhyIjfwJOG3Bqdc5fWENXq0Hx6YaOLu/F8dPTLe6uUUJ72ouv2ApNj99sGPX5NUodjUd9RGEy5KUQVllvOM+k+J3ELJAlEIMNqvUJF+68Eo8zkmsWgGaSlXErdsDO/RAjJ1atSKe5WaOg01f5U9ef1HbvRo6d0lbS9DFfV4rRNVEFc0iVQwBlcxmIQtEKRiwFUau9YgW93mt6488sKtlfqlPTGHkgV0d189ypRe2Q8fZqXU7oJs378TY/iO4Y/hCY1/lqNDMo8RDFQRzVcxbVfS/CN2H5CkYsI2Rj8txCOPVCLddvRoAcPvDezrs8Y0Z7qgYmtVKjwhtPoxoHkN/r4dFXg/W+69vUnRf2n4AHx3drc0J2HjNautxxWUsZ2EWcc2KdrluHmWrk4xXMpuFLBBHswFdL2dV17XwatF0R8ORPSsNphegvctZVkXwXtB0i7NpBh+lRoTn7rwy1UrZprl9nIKK88/YvEZS8nDu5jleQQDE0ZwYFxtt2DRiEhTB4zar3GBXEgiXsOCdPDmdKCN5dLzeFrIaXBNw73gU5CWksa/bmIbiKsPG+RjyND/l4dyturlMmNuIUjCQ1Eare97lFyx1Xo0HwiUqeE11g0wEwjP4O83uw7U6qgoboRrM+5Ytu7QJciahmWdUTh7OXYkiEspEfAoGkthoVeWtg+dte/awsxDuIVLak4cHB1oOaxcC4Zmk7EaUS1+7ONXzAb3wZKDNlj48OBBbjVUnNE0VRtOSR52lPMcrCHHITiEGF9NI1BYc7QG9PsHKfoYZ60PRPmFuu3p1otV+VivOF35hd51wqY+gqmvgBxhZu0qb9R01C8VFeemEZp5ROXnkLEgUkVAmohQyRGcL/tCWnYlMPQEM4L7tBzB07pI2YRMVSLY+gUB4xoXRLu7z8Mupaa3Jxka5qBRl8NojD+zCujcth6mpQ9gstPI1eqVgEpp5J5tlnbNQVnKcIAASfZQJrn0SwtgWvwPiI1ps6hTZRjQF543tP6Ks428zHpsx9VAzIc4EAbh73RptWY4aUUeinCAIeiT6KAfCisBFsIcZ8Ms/2PZAjluZq8wOXo1w+sIFrbIU0RVnsBpd5PXgxPQsZrkpZK+7+NTqVzU+m/IUNmOOUwhAc2djamiTR0e1uURVkuuE7kCUQgKiJpEkCoGAtlW2jWKwKRcNuJsdGMArjdnW688w48EddQydu0QrjE9fuMBKsLhme0cJzEImf4w4YPVUsUSIUG3EfJQAGzNNHKoS2IEw71tYw/GT7WadLJOXPjq620oJDfT3an0VcQl84XnFOcOjTXai1WBNPS4C01JWAi6rVXVVVudSOVVQYTIflaIUiOgFAL8CMANgmpmHiGgJgM0AVgJ4AcD1zHzUdJ2ySmfrMp2TohL4eQmVj47u1voIohDMK/2w0DZl4QJoK4QXRWfiCt+D/j4PL78y3aE8brx0RUdUVlKyyiSuUkayS1a+MH+oqk/hcmb+eej/DQC+xcybiGiD//+HyxhY3JbbxiTi4mdQJV7lUYVzdLxurRAAtAS0bqUfLuBnysJ9csMVLSGvSkBrzDBOP20Bdt52qtHO6Hi9LVT16GQDPdSsz6Tzj6Qlq0ziKmUkS+VUwZUqJa9dC+AL/t9fADBc1kDiCuHZFMBTKQTTc5LmDtgWTgsUnS3h/IoggU9FY4bxoS07rfpamxLQovPfuHVPR+7CLAPHNLuNLMgqk7hKGcl5JNcJc5uylAID+CYR7SCim/xjZzHzIf/vnwI4q5yhxX+phwcHcN3FA6bw+g6CrGadcE3a/9m2QqdLBnONqKOaqsn+PMv6VIPovGyzdXWmJvZ/sqpGmmRsRV0nC6RyquBKWUrhXzHzGwG8A8AHiei3wg9y09GhXFIS0U1ENEZEY4cPH85lcDZf6m3PHnbOLxgeHMDI2lXwetpFqNdjF94Zxba0N2C/Su31aoli/hmdikG1Io1buQY7Hxt0c01KVqvqqq3OA6X+/KarWp9DQdBRik+Bmev+75eI6O8AvBnAz4hoGTMfIqJlAF7SPPceAPcATUdzHuOzKTPgYgroODcqPRXL7DQd334yMdXx/P4+T1tV9fRQtNNUYwa3bNmlLKvR3+tpV/DAqYgh05hNYbNJyndnaZLJKpNYMpKFbqbw6CMiOh1ADzP/yv/7cQAfA/BWAL8IOZqXMPN/NF2rrOgjwC0sNRz+ZxMiaBu9orvW4j4PrzRm25PYegggtDX1icta/jeRyJ6o89c0hyQkCfWV0EpBcKdq0UdnAfg7alYQXQDgy8z8DSL6HoAtRPR+APsBXF/C2FrERf+odhO1HsJMRGDa7jDCx29/eI9V9IpuR8OMjucHgjxakG54cAC3bNmlHNP9Tx1sUwrBa6vCS23NIyZla1r1L1aEpIrDVBCyp3ClwMw/BnCR4vgv0NwtdAU6E4HqmE0/58BfMTpe15p5okJTNwZT9m+0cmtwTHeuat7RHAJb80jSUN9gN1CVhDBBmMtImYsU6HYTJkGlqnUUXvGaHKdxHd8C4orzRXcdwe4hiqmJTpI8irj4/ThfTh65G4IgtFOlPIU5z+h4HQ/uqLcpBALais+ZTCi2phKbPIrw69xwyXLlObrjSbEJ9ZXwSUEoF9kpFIhqpcxohrcG6Ewo/b2etXAMm5V0O4bwriPwG9z/1EHMMKNGhBsuWZ5Z+Yjwa8Zl18puQBDKRZRCgdg4mXUmlI3XrHZ6rbDt36aL1x3DF2auBKKouqwlzdEQBCEfRCkUiO1KGcguxr1yMfMWORqCIJSHlM4ukCpVzywDKeMsCNWgankK85bKrdoLpkqF4gRBUCNKoWDmoyM1yC/Q7UmljLMgVAdRCkKuxNUzkqxkQagWohSEXDGV7B6YZ+YzQegGRCkIuaLzFxAgzmVBqCCS0SzkSpUazgiCEI8oBSFXqtZwRhAEM2I+EnJlvofhCkK3IUpByJ35GIYrCN2KmI8EQRCEFqIUBEEQhBaiFARBEIQWohQEQRCEFqIUBEEQhBZdXTqbiA4D2B86dCaAn5c0nCKZL/ME5s9cZZ5zjyrP9VxmXqp6oKuVQhQiGtPVCJ9LzJd5AvNnrjLPuUe3zlXMR4IgCEILUQqCIAhCi7mmFO4pewAFMV/mCcyfuco85x5dOdc55VMQBEEQ0jHXdgqCIAhCCkQpCIIgCC26TikQ0RIiepyI/tH/vVhz3jeIaIKIHokcP4+IniKifUS0mYgWFjNyNxzm+T7/nH8koveFjn+biPYS0U7/59eKG308RPR2f3z7iGiD4vHT/Pdnn/9+rQw9dqt/fC8RrS104AlIOlciWklEU6H38HOFD94Bi3n+FhF9n4imiehdkceUn+MqknKeM6H3c2txo3aAmbvqB8BfANjg/70BwH/VnPdWAFcDeCRyfAuA9/h/fw7Avy97TknnCWAJgB/7vxf7fy/2H/s2gKGy56GZWw3AcwBeC2AhgF0AXh855wMAPuf//R4Am/2/X++ffxqA8/zr1MqeU05zXQngB2XPIcN5rgTwGwC+COBdoePaz3HVftLM03/s5bLnEPfTdTsFANcC+IL/9xcADKtOYuZvAfhV+BgREYArADwQ9/wKYDPPtQAeZ+YjzHwUwOMA3l7M8FLxZgD7mPnHzHwSwFfQnG+Y8PwfAPBW//27FsBXmPkEMz8PYJ9/vaqSZq7dROw8mfkFZn4GwGzkud30OU4zz66gG5XCWcx8yP/7pwDOcnjuawBMMPO0//+LAKra/cVmngMADob+j87nb/xt6p9VTMjEjbvtHP/9Oobm+2fz3CqRZq4AcB4RjRPR/yai38x7sClI875003uadqyLiGiMiLYT0XCmI8uISnZeI6J/APBPFQ99JPwPMzMRdW1Mbc7zvJGZ60T0agAPAvh9NLezQvdwCMAKZv4FEV0MYJSIVjPzL8semJCYc/3v5WsBPEFEu5n5ubIHFaaSSoGZf1v3GBH9jIiWMfMhIloG4CWHS/8CQD8RLfBXZOcAqKccbmIymGcdwFtC/5+Dpi8BzFz3f/+KiL6M5ra3KkqhDmB56H/V+xCc8yIRLQBwBprvn81zq0TiuXLTCH0CAJh5BxE9B+DXAYzlPmp30rwv2s9xBUn1+Qt9L39MRN8GMIimj6IydKP5aCuAIDrhfQC+ZvtE/0u2DUAQEeD0/IKxmedjAN5GRIv96KS3AXiMiBYQ0ZkAQEQegN8F8IMCxmzL9wCc70eCLUTTuRqNxAjP/10AnvDfv60A3uNH7JwH4HwATxc07iQknisRLSWiGgD4K8vz0XTCVhGbeepQfo5zGmdaEs/Tn99p/t9nArgMwA9zG2lSyvZ0u/6gaWv9FoB/BPAPAJb4x4cA/M/Qef8XwGEAU2ja/db6x1+LphDZB+CrAE4re04p5/lH/lz2AfhD/9jpAHYAeAbAHgCfQcUidABcCeD/oblK+oh/7GMArvH/XuS/P/v89+u1oed+xH/eXgDvKHsuec0VwHX++7cTwPcBXF32XFLO803+d/E4mru+PabPcVV/ks4TwL8EsBvNiKXdAN5f9lxUP1LmQhAEQWjRjeYjQRAEISdEKQiCIAgtRCkIgiAILUQpCIIgCC1EKQiCIAgtRCkIQkYQ0XIiep6Ilvj/L/b/X1ny0ATBGlEKgpARzHwQwGcBbPIPbQJwDzO/UNqgBMERyVMQhAzxM8h3APhrAH8MYA0zN8odlSDYU8naR4LQrTBzg4hGAHwDwNtEIQjdhpiPBCF73oFmhdM3lD0QQXBFlIIgZAgRrQHwOwAuBbDer3ArCF2DKAVByAi/kdFnAdzMzAcA3AXgE+WOShDcEKUgCNnxxwAOMPPj/v9/BeCfE9G/LnFMguCERB8JgiAILWSnIAiCILQQpSAIgiC0EKUgCIIgtBClIAiCILQQpSAIgiC0EKUgCIIgtBClIAiCILT4/6Mxet+YPjmWAAAAAElFTkSuQmCC\n",
  37. "text/plain": [
  38. "<Figure size 432x288 with 1 Axes>"
  39. ]
  40. },
  41. "metadata": {
  42. "needs_background": "light"
  43. },
  44. "output_type": "display_data"
  45. }
  46. ],
  47. "source": [
  48. "%matplotlib inline\n",
  49. "\n",
  50. "import matplotlib.pyplot as plt\n",
  51. "import numpy as np\n",
  52. "import sklearn\n",
  53. "from sklearn import datasets\n",
  54. "\n",
  55. "# load data\n",
  56. "d = datasets.load_diabetes()\n",
  57. "\n",
  58. "X = d.data[:, 2]\n",
  59. "Y = d.target\n",
  60. "\n",
  61. "# draw original data\n",
  62. "plt.scatter(X, Y)\n",
  63. "plt.xlabel(\"X\")\n",
  64. "plt.ylabel(\"Y\")\n",
  65. "plt.show()\n"
  66. ]
  67. },
  68. {
  69. "cell_type": "markdown",
  70. "metadata": {},
  71. "source": [
  72. "### 1.2 数学原理\n",
  73. "有$N$个观测数据为:\n",
  74. "$$\n",
  75. "\\mathbf{X} = \\{x_1, x_2, ..., x_N \\} \\\\\n",
  76. "\\mathbf{Y} = \\{y_1, y_2, ..., y_N \\}\n",
  77. "$$\n",
  78. "其中$\\mathbf{X}$为自变量,$\\mathbf{Y}$为因变量。\n",
  79. "\n",
  80. "我们希望找到一个模型能够解释这些数据,假设我们使用最简单的线性模型来拟合数据:\n",
  81. "$$\n",
  82. "y = ax + b\n",
  83. "$$\n",
  84. "那么问题就变成求解参数$a$, $b$能够使得模型输出尽可能和观测数据有比较小的误差。\n",
  85. "\n",
  86. "如何构建函数来评估模型输出与观测数据之间的误差是一个关键问题,这里我们使用观测数据与模型输出的平方和来作为评估函数(也被称为损失函数Loss function):\n",
  87. "$$\n",
  88. "L = \\sum_{i=1}^{N} (y_i - a x_i - b)^2 \\\\\n",
  89. "L = \\sum_{i=1}^{N} \\{y_i - (a x_i + b)\\}^2\n",
  90. "$$\n",
  91. "\n",
  92. "使误差函数最小,那么我们就可以求出模型的参数:\n",
  93. "$$\n",
  94. "\\frac{\\partial L}{\\partial a} = -2 \\sum_{i=1}^{N} (y_i - a x_i - b) x_i \\\\\n",
  95. "\\frac{\\partial L}{\\partial b} = -2 \\sum_{i=1}^{N} (y_i - a x_i - b)\n",
  96. "$$\n",
  97. "既当偏微分为0时,误差函数为最小,因此我们可以得到:\n",
  98. "$$\n",
  99. "-2 \\sum_{i=1}^{N} (y_i - a x_i - b) x_i = 0 \\\\\n",
  100. "-2 \\sum_{i=1}^{N} (y_i - a x_i - b) = 0 \\\\\n",
  101. "$$\n",
  102. "\n",
  103. "将上式调整一下顺序可以得到:\n",
  104. "$$\n",
  105. "a \\sum x_i^2 + b \\sum x_i = \\sum y_i x_i \\\\\n",
  106. "a \\sum x_i + b N = \\sum y_i\n",
  107. "$$\n",
  108. "通过求解二元一次方程组,我们即可求出模型的最优参数。"
  109. ]
  110. },
  111. {
  112. "cell_type": "markdown",
  113. "metadata": {},
  114. "source": [
  115. "### 1.3 求解程序"
  116. ]
  117. },
  118. {
  119. "cell_type": "code",
  120. "execution_count": 2,
  121. "metadata": {},
  122. "outputs": [
  123. {
  124. "name": "stdout",
  125. "output_type": "stream",
  126. "text": [
  127. "a = 949.435260, b = 152.133484\n"
  128. ]
  129. },
  130. {
  131. "data": {
  132. "image/png": "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hz59+nBHPL/N2rVr6dmzJ2eeeSZ9+vRh/fr1CUU2/vznP9OzZ08OP/xwxowZwy233ALA2LFjmT7dqCXevXt3Jk6cSP/+/enbty8rV64EYMGCBfzsZz+jrKyMww47jFWrvC2fmpoaTj31VPbff39OPPFEamp2fZl+//vfM3DgQHr37s3EiRMBuOuuu/jyyy8ZOnQoQ4cOdd1P44+2VneRjbnMNXliuafCilq8eDGPPPII8+fPR0rJoEGDOOqoo2jXrh2ffvopjz32GIceemjCMQsXLmTGjBksW7aM2tpa+vfvz4ABAxzP36FDB95//33uvfdebrnlFv7xj3/Qq1cv3nrrLVq0aMHrr7/O1Vdf3Zhx0on77ruP4uJiPv74Y5YvX07//v0bX7vxxhtp37499fX1HH300SxfvpyLL76Y2267jTlz5tChQwfX/Q488MBQ96w5oa3VXejEXkkgJTQ0QGGh/74ByQvLPRVW1Ntvv82JJ55ImzZt2G233TjppJN46623ANhnn32aCDvAvHnzGDlyJK1bt2b33Xfn+OOPdz3/SSedBMCAAQNYu3YtAFu3buXkk0+mT58+XHrppaxYscKzjXPnzuX0008H4MADD0wQ5WeffZb+/ftTVlbGihUr+OijjxzPobpf1GSzv1qlbUGs1Wzta1Tt0om9QiAlvPwyDBoEDzyQkkvkheWebiuqTZs2SZ/DTB1cWFhIXV0dANdeey1Dhw7lhRdeYO3atQwZMiTUudesWcMtt9zCwoULadeuHWPHjmXHjh2h94uabPZXq7ZN1VrN1r5G3a5sCMfMCaSEV16BSZNg4ULo3h06dkzJpfLCck+Fz++II46goqKC6upqtm/fzgsvvMARRxzheczgwYN58cUX2bFjB99//z0vvfRSoGtu3bqV0lLjC/Loo4/67m9NK/zhhx82lvjbtm0bbdq0oW3btnzzzTe88sorjcfsvvvufPfdd777pZJs9lertk3VWs3WvmZru/zI1lGQL6aoH3oojBgBGzfCP/4Bn3wCJ5+ckkvmheWeCp9f//79GTt2LIcccggAv/3tbykrK2t0oThx8MEHc8IJJ3DggQey995707dvX9q2bat8zSuuuIKzzjqLyZMnM2LECN/9f//733P22Wez//77s//++zf69w866CDKysro1asXXbt2ZfDgwY3HjBs3jmOPPZbO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\n",
  133. "text/plain": [
  134. "<Figure size 432x288 with 1 Axes>"
  135. ]
  136. },
  137. "metadata": {
  138. "needs_background": "light"
  139. },
  140. "output_type": "display_data"
  141. }
  142. ],
  143. "source": [
  144. "N = X.shape[0]\n",
  145. "\n",
  146. "S_X2 = np.sum(X*X)\n",
  147. "S_X = np.sum(X)\n",
  148. "S_XY = np.sum(X*Y)\n",
  149. "S_Y = np.sum(Y)\n",
  150. "\n",
  151. "A1 = np.array([[S_X2, S_X], \n",
  152. " [S_X, N]])\n",
  153. "B1 = np.array([S_XY, S_Y])\n",
  154. "# numpy.linalg模块包含线性代数的函数。使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。\n",
  155. "coeff = np.linalg.inv(A1).dot(B1)\n",
  156. "\n",
  157. "print('a = %f, b = %f' % (coeff[0], coeff[1]))\n",
  158. "\n",
  159. "x_min = np.min(X)\n",
  160. "x_max = np.max(X)\n",
  161. "y_min = coeff[0] * x_min + coeff[1]\n",
  162. "y_max = coeff[0] * x_max + coeff[1]\n",
  163. "\n",
  164. "plt.scatter(X, Y, label='original data')\n",
  165. "plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n",
  166. "plt.legend()\n",
  167. "plt.show()"
  168. ]
  169. },
  170. {
  171. "cell_type": "markdown",
  172. "metadata": {},
  173. "source": [
  174. "## 2. 如何使用迭代的方法求出模型参数\n",
  175. "\n",
  176. "当数据比较多的时候,或者模型比较复杂,无法直接使用解析的方式求出模型参数。因此更为常用的方式是,通过迭代的方式逐步逼近模型的参数。\n",
  177. "\n",
  178. "### 2.1 梯度下降法\n",
  179. "在机器学习算法中,对于很多监督学习模型,需要对原始的模型构建损失函数,接下来便是通过优化算法对损失函数进行优化,以便寻找到最优的参数。在求解机器学习参数的优化算法中,使用较多的是基于梯度下降的优化算法(Gradient Descent, GD)。\n",
  180. "\n",
  181. "梯度下降法有很多优点,其中最主要的优点是,在梯度下降法的求解过程中只需求解损失函数的一阶导数,计算的代价比较小,这使得梯度下降法能在很多大规模数据集上得到应用。\n",
  182. "\n",
  183. "梯度下降法的含义是通过当前点的梯度方向寻找到新的迭代点。梯度下降法的基本思想可以类比为一个下山的过程。假设这样一个场景:\n",
  184. "* 一个人被困在山上,需要从山上下来(i.e. 找到山的最低点,也就是山谷)。\n",
  185. "* 但此时山上的浓雾很大,导致可视度很低。因此,下山的路径就无法确定,他必须利用自己周围的信息去找到下山的路径。\n",
  186. "* 这个时候,他就可以利用梯度下降算法来帮助自己下山。\n",
  187. " - 具体来说就是,以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走\n",
  188. " - 同理,如果我们的目标是上山,也就是爬到山顶,那么此时应该是朝着最陡峭的方向往上走。\n",
  189. " - 然后每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。\n",
  190. "\n",
  191. "\n",
  192. "我们同时可以假设这座山最陡峭的地方是无法通过肉眼立马观察出来的,而是需要一个复杂的工具来测量,同时,这个人此时正好拥有测量出最陡峭方向的能力。所以,此人每走一段距离,都需要一段时间来测量所在位置最陡峭的方向,这是比较耗时的。那么为了在太阳下山之前到达山底,就要尽可能的减少测量方向的次数。这是一个两难的选择,如果测量的频繁,可以保证下山的方向是绝对正确的,但又非常耗时,如果测量的过少,又有偏离轨道的风险。所以需要找到一个合适的测量方向的频率,来确保下山的方向不错误,同时又不至于耗时太多!\n",
  193. "\n",
  194. "\n",
  195. "![gradient_descent](images/gradient_descent.png)\n",
  196. "\n",
  197. "如上图所示,得到了局部最优解。x,y表示的是$\\theta_0$和$\\theta_1$,z方向表示的是花费函数,很明显出发点不同,最后到达的收敛点可能不一样。当然如果是碗状的,那么收敛点就应该是一样的。\n",
  198. "\n",
  199. "对于某一个损失函数\n",
  200. "$$\n",
  201. "L = \\sum_{i=1}^{N} (y_i - a x_i - b)^2\n",
  202. "$$\n",
  203. "\n",
  204. "我们更新的策略是:\n",
  205. "$$\n",
  206. "\\theta^1 = \\theta^0 - \\alpha \\triangledown L(\\theta)\n",
  207. "$$\n",
  208. "其中$\\theta$代表了模型中的参数,例如$a$, $b$\n",
  209. "\n",
  210. "此公式的意义是:$L$是关于$\\theta$的一个函数,我们当前所处的位置为$\\theta_0$点,要从这个点走到L的最小值点,也就是山底。首先我们先确定前进的方向,也就是梯度的反向,然后走一段距离的步长,也就是$\\alpha$,走完这个段步长,就到达了$\\theta_1$这个点!\n",
  211. "\n",
  212. "我们更新的策略是:\n",
  213. "\n",
  214. "FIXME: 和后面的公式表达一样,好对比\n",
  215. "$$\n",
  216. "a^1 = a^0 + 2 \\alpha [ y - (ax+b)]*x \\\\\n",
  217. "b^1 = b^0 + 2 \\alpha [ y - (ax+b)] \n",
  218. "$$\n",
  219. "\n",
  220. "下面就这个公式的几个常见的疑问:\n",
  221. "\n",
  222. "* **$\\alpha$是什么含义?**\n",
  223. "$\\alpha$在梯度下降算法中被称作为学习率或者步长,意味着我们可以通过$\\alpha$来控制每一步走的距离,以保证不要步子跨的太大,错过了最低点。同时也要保证不要走的太慢,导致太阳下山了,还没有走到山下。所以$\\alpha$的选择在梯度下降法中往往是很重要的。\n",
  224. "![gd_stepsize](images/gd_stepsize.png)\n",
  225. "\n",
  226. "* **为什么要梯度要乘以一个负号?**\n",
  227. "梯度前加一个负号,就意味着朝着梯度相反的方向前进!梯度的方向实际就是函数在此点上升最快的方向,而我们需要朝着下降最快的方向走,自然就是负的梯度的方向,所以此处需要加上负号。\n",
  228. "\n"
  229. ]
  230. },
  231. {
  232. "cell_type": "markdown",
  233. "metadata": {},
  234. "source": [
  235. "### 2.2 示例代码"
  236. ]
  237. },
  238. {
  239. "cell_type": "code",
  240. "execution_count": 3,
  241. "metadata": {},
  242. "outputs": [
  243. {
  244. "name": "stdout",
  245. "output_type": "stream",
  246. "text": [
  247. "epoch 0: loss = 2590736.867664, a = 18.689017, b = 148.815329\n",
  248. "epoch 1: loss = 2557255.189453, a = 36.831348, b = 148.828655\n",
  249. "epoch 2: loss = 2525130.800853, a = 54.614824, b = 148.822534\n",
  250. "epoch 3: loss = 2494255.916234, a = 72.046438, b = 148.816532\n",
  251. "epoch 4: loss = 2464581.753419, a = 89.133153, b = 148.810649\n",
  252. "epoch 5: loss = 2436061.445196, a = 105.881792, b = 148.804882\n",
  253. "epoch 6: loss = 2408649.957111, a = 122.299046, b = 148.799229\n",
  254. "epoch 7: loss = 2382304.015732, a = 138.391470, b = 148.793687\n",
  255. "epoch 8: loss = 2356982.039720, a = 154.165492, b = 148.788256\n",
  256. "epoch 9: loss = 2332644.073594, a = 169.627411, b = 148.782932\n",
  257. "epoch 10: loss = 2309251.724102, a = 184.783402, b = 148.777713\n",
  258. "epoch 11: loss = 2286768.099073, a = 199.639520, b = 148.772598\n",
  259. "epoch 12: loss = 2265157.748666, a = 214.201696, b = 148.767584\n",
  260. "epoch 13: loss = 2244386.608923, a = 228.475748, b = 148.762669\n",
  261. "epoch 14: loss = 2224421.947529, a = 242.467375, b = 148.757851\n",
  262. "epoch 15: loss = 2205232.311697, a = 256.182166, b = 148.753129\n",
  263. "epoch 16: loss = 2186787.478095, a = 269.625597, b = 148.748500\n",
  264. "epoch 17: loss = 2169058.404731, a = 282.803039, b = 148.743962\n",
  265. "epoch 18: loss = 2152017.184726, a = 295.719754, b = 148.739515\n",
  266. "epoch 19: loss = 2135637.001889, a = 308.380901, b = 148.735155\n",
  267. "epoch 20: loss = 2119892.088045, a = 320.791536, b = 148.730882\n",
  268. "epoch 21: loss = 2104757.682020, a = 332.956616, b = 148.726693\n",
  269. "epoch 22: loss = 2090209.990240, a = 344.881000, b = 148.722587\n",
  270. "epoch 23: loss = 2076226.148871, a = 356.569449, b = 148.718562\n",
  271. "epoch 24: loss = 2062784.187440, a = 368.026633, b = 148.714617\n",
  272. "epoch 25: loss = 2049862.993883, a = 379.257126, b = 148.710750\n",
  273. "epoch 26: loss = 2037442.280956, a = 390.265414, b = 148.706960\n",
  274. "epoch 27: loss = 2025502.553972, a = 401.055894, b = 148.703244\n",
  275. "epoch 28: loss = 2014025.079785, a = 411.632875, b = 148.699602\n",
  276. "epoch 29: loss = 2002991.857005, a = 422.000581, b = 148.696032\n",
  277. "epoch 30: loss = 1992385.587369, a = 432.163154, b = 148.692533\n",
  278. "epoch 31: loss = 1982189.648231, a = 442.124651, b = 148.689103\n",
  279. "epoch 32: loss = 1972388.066142, a = 451.889051, b = 148.685741\n",
  280. "epoch 33: loss = 1962965.491447, a = 461.460255, b = 148.682445\n",
  281. "epoch 34: loss = 1953907.173892, a = 470.842084, b = 148.679215\n",
  282. "epoch 35: loss = 1945198.939172, a = 480.038285, b = 148.676048\n",
  283. "epoch 36: loss = 1936827.166411, a = 489.052532, b = 148.672944\n",
  284. "epoch 37: loss = 1928778.766513, a = 497.888424, b = 148.669902\n",
  285. "epoch 38: loss = 1921041.161364, a = 506.549490, b = 148.666919\n",
  286. "epoch 39: loss = 1913602.263848, a = 515.039190, b = 148.663996\n",
  287. "epoch 40: loss = 1906450.458648, a = 523.360914, b = 148.661131\n",
  288. "epoch 41: loss = 1899574.583794, a = 531.517985, b = 148.658322\n",
  289. "epoch 42: loss = 1892963.912935, a = 539.513662, b = 148.655569\n",
  290. "epoch 43: loss = 1886608.138306, a = 547.351138, b = 148.652870\n",
  291. "epoch 44: loss = 1880497.354362, a = 555.033542, b = 148.650225\n",
  292. "epoch 45: loss = 1874622.042047, a = 562.563943, b = 148.647632\n",
  293. "epoch 46: loss = 1868973.053689, a = 569.945349, b = 148.645090\n",
  294. "epoch 47: loss = 1863541.598476, a = 577.180708, b = 148.642599\n",
  295. "epoch 48: loss = 1858319.228507, a = 584.272908, b = 148.640157\n",
  296. "epoch 49: loss = 1853297.825385, a = 591.224784, b = 148.637763\n",
  297. "epoch 50: loss = 1848469.587337, a = 598.039110, b = 148.635417\n",
  298. "epoch 51: loss = 1843827.016840, a = 604.718609, b = 148.633117\n",
  299. "epoch 52: loss = 1839362.908723, a = 611.265949, b = 148.630862\n",
  300. "epoch 53: loss = 1835070.338746, a = 617.683744, b = 148.628653\n",
  301. "epoch 54: loss = 1830942.652617, a = 623.974558, b = 148.626486\n",
  302. "epoch 55: loss = 1826973.455442, a = 630.140902, b = 148.624363\n",
  303. "epoch 56: loss = 1823156.601589, a = 636.185240, b = 148.622282\n",
  304. "epoch 57: loss = 1819486.184948, a = 642.109985, b = 148.620242\n",
  305. "epoch 58: loss = 1815956.529568, a = 647.917504, b = 148.618242\n",
  306. "epoch 59: loss = 1812562.180670, a = 653.610117, b = 148.616282\n",
  307. "epoch 60: loss = 1809297.895998, a = 659.190096, b = 148.614361\n",
  308. "epoch 61: loss = 1806158.637522, a = 664.659671, b = 148.612477\n",
  309. "epoch 62: loss = 1803139.563458, a = 670.021025, b = 148.610631\n",
  310. "epoch 63: loss = 1800236.020598, a = 675.276301, b = 148.608822\n",
  311. "epoch 64: loss = 1797443.536950, a = 680.427596, b = 148.607048\n",
  312. "epoch 65: loss = 1794757.814654, a = 685.476969, b = 148.605309\n",
  313. "epoch 66: loss = 1792174.723185, a = 690.426435, b = 148.603605\n",
  314. "epoch 67: loss = 1789690.292815, a = 695.277972, b = 148.601934\n",
  315. "epoch 68: loss = 1787300.708335, a = 700.033517, b = 148.600297\n",
  316. "epoch 69: loss = 1785002.303019, a = 704.694970, b = 148.598692\n",
  317. "epoch 70: loss = 1782791.552830, a = 709.264191, b = 148.597119\n",
  318. "epoch 71: loss = 1780665.070844, a = 713.743007, b = 148.595576\n",
  319. "epoch 72: loss = 1778619.601901, a = 718.133206, b = 148.594065\n",
  320. "epoch 73: loss = 1776652.017457, a = 722.436540, b = 148.592583\n",
  321. "epoch 74: loss = 1774759.310646, a = 726.654730, b = 148.591130\n",
  322. "epoch 75: loss = 1772938.591527, a = 730.789459, b = 148.589707\n",
  323. "epoch 76: loss = 1771187.082519, a = 734.842379, b = 148.588311\n",
  324. "epoch 77: loss = 1769502.114022, a = 738.815108, b = 148.586943\n",
  325. "epoch 78: loss = 1767881.120197, a = 742.709234, b = 148.585602\n",
  326. "epoch 79: loss = 1766321.634920, a = 746.526311, b = 148.584288\n",
  327. "epoch 80: loss = 1764821.287889, a = 750.267864, b = 148.583000\n",
  328. "epoch 81: loss = 1763377.800890, a = 753.935387, b = 148.581737\n",
  329. "epoch 82: loss = 1761988.984199, a = 757.530345, b = 148.580499\n",
  330. "epoch 83: loss = 1760652.733134, a = 761.054173, b = 148.579286\n",
  331. "epoch 84: loss = 1759367.024737, a = 764.508280, b = 148.578096\n",
  332. "epoch 85: loss = 1758129.914584, a = 767.894044, b = 148.576931\n",
  333. "epoch 86: loss = 1756939.533728, a = 771.212818, b = 148.575788\n",
  334. "epoch 87: loss = 1755794.085750, a = 774.465927, b = 148.574668\n",
  335. "epoch 88: loss = 1754691.843935, a = 777.654671, b = 148.573570\n",
  336. "epoch 89: loss = 1753631.148552, a = 780.780322, b = 148.572493\n",
  337. "epoch 90: loss = 1752610.404243, a = 783.844130, b = 148.571438\n",
  338. "epoch 91: loss = 1751628.077518, a = 786.847318, b = 148.570404\n",
  339. "epoch 92: loss = 1750682.694337, a = 789.791085, b = 148.569391\n",
  340. "epoch 93: loss = 1749772.837797, a = 792.676607, b = 148.568397\n",
  341. "epoch 94: loss = 1748897.145906, a = 795.505037, b = 148.567423\n",
  342. "epoch 95: loss = 1748054.309442, a = 798.277504, b = 148.566469\n",
  343. "epoch 96: loss = 1747243.069899, a = 800.995115, b = 148.565533\n",
  344. "epoch 97: loss = 1746462.217508, a = 803.658956, b = 148.564616\n",
  345. "epoch 98: loss = 1745710.589343, a = 806.270090, b = 148.563716\n",
  346. "epoch 99: loss = 1744987.067493, a = 808.829561, b = 148.562835\n",
  347. "epoch 100: loss = 1744290.577312, a = 811.338391, b = 148.561971\n",
  348. "epoch 101: loss = 1743620.085732, a = 813.797581, b = 148.561125\n",
  349. "epoch 102: loss = 1742974.599648, a = 816.208114, b = 148.560295\n",
  350. "epoch 103: loss = 1742353.164357, a = 818.570953, b = 148.559481\n",
  351. "epoch 104: loss = 1741754.862068, a = 820.887041, b = 148.558683\n",
  352. "epoch 105: loss = 1741178.810465, a = 823.157303, b = 148.557902\n",
  353. "epoch 106: loss = 1740624.161324, a = 825.382646, b = 148.557135\n",
  354. "epoch 107: loss = 1740090.099189, a = 827.563959, b = 148.556384\n",
  355. "epoch 108: loss = 1739575.840097, a = 829.702112, b = 148.555648\n",
  356. "epoch 109: loss = 1739080.630352, a = 831.797961, b = 148.554926\n",
  357. "epoch 110: loss = 1738603.745351, a = 833.852341, b = 148.554219\n",
  358. "epoch 111: loss = 1738144.488447, a = 835.866073, b = 148.553526\n",
  359. "epoch 112: loss = 1737702.189871, a = 837.839962, b = 148.552846\n",
  360. "epoch 113: loss = 1737276.205677, a = 839.774796, b = 148.552180\n",
  361. "epoch 114: loss = 1736865.916748, a = 841.671348, b = 148.551527\n",
  362. "epoch 115: loss = 1736470.727823, a = 843.530375, b = 148.550887\n",
  363. "epoch 116: loss = 1736090.066576, a = 845.352619, b = 148.550259\n",
  364. "epoch 117: loss = 1735723.382723, a = 847.138809, b = 148.549644\n",
  365. "epoch 118: loss = 1735370.147167, a = 848.889657, b = 148.549041\n",
  366. "epoch 119: loss = 1735029.851171, a = 850.605863, b = 148.548450\n",
  367. "epoch 120: loss = 1734702.005574, a = 852.288113, b = 148.547871\n",
  368. "epoch 121: loss = 1734386.140028, a = 853.937078, b = 148.547303\n",
  369. "epoch 122: loss = 1734081.802266, a = 855.553417, b = 148.546747\n",
  370. "epoch 123: loss = 1733788.557403, a = 857.137775, b = 148.546201\n",
  371. "epoch 124: loss = 1733505.987262, a = 858.690785, b = 148.545666\n",
  372. "epoch 125: loss = 1733233.689723, a = 860.213068, b = 148.545142\n",
  373. "epoch 126: loss = 1732971.278103, a = 861.705231, b = 148.544628\n",
  374. "epoch 127: loss = 1732718.380559, a = 863.167870, b = 148.544125\n",
  375. "epoch 128: loss = 1732474.639507, a = 864.601570, b = 148.543631\n",
  376. "epoch 129: loss = 1732239.711074, a = 866.006902, b = 148.543147\n",
  377. "epoch 130: loss = 1732013.264567, a = 867.384429, b = 148.542673\n",
  378. "epoch 131: loss = 1731794.981959, a = 868.734701, b = 148.542208\n",
  379. "epoch 132: loss = 1731584.557401, a = 870.058256, b = 148.541752\n",
  380. "epoch 133: loss = 1731381.696752, a = 871.355623, b = 148.541306\n",
  381. "epoch 134: loss = 1731186.117121, a = 872.627321, b = 148.540868\n",
  382. "epoch 135: loss = 1730997.546436, a = 873.873858, b = 148.540438\n",
  383. "epoch 136: loss = 1730815.723022, a = 875.095730, b = 148.540018\n",
  384. "epoch 137: loss = 1730640.395202, a = 876.293427, b = 148.539605\n",
  385. "epoch 138: loss = 1730471.320908, a = 877.467426, b = 148.539201\n",
  386. "epoch 139: loss = 1730308.267311, a = 878.618197, b = 148.538805\n",
  387. "epoch 140: loss = 1730151.010464, a = 879.746199, b = 148.538416\n",
  388. "epoch 141: loss = 1729999.334955, a = 880.851882, b = 148.538036\n",
  389. "epoch 142: loss = 1729853.033583, a = 881.935688, b = 148.537663\n",
  390. "epoch 143: loss = 1729711.907037, a = 882.998050, b = 148.537297\n",
  391. "epoch 144: loss = 1729575.763593, a = 884.039393, b = 148.536938\n",
  392. "epoch 145: loss = 1729444.418820, a = 885.060132, b = 148.536587\n",
  393. "epoch 146: loss = 1729317.695300, a = 886.060674, b = 148.536242\n",
  394. "epoch 147: loss = 1729195.422355, a = 887.041420, b = 148.535904\n",
  395. "epoch 148: loss = 1729077.435792, a = 888.002761, b = 148.535573\n",
  396. "epoch 149: loss = 1728963.577645, a = 888.945081, b = 148.535249\n",
  397. "epoch 150: loss = 1728853.695944, a = 889.868757, b = 148.534931\n",
  398. "epoch 151: loss = 1728747.644477, a = 890.774156, b = 148.534619\n",
  399. "epoch 152: loss = 1728645.282573, a = 891.661642, b = 148.534314\n",
  400. "epoch 153: loss = 1728546.474885, a = 892.531568, b = 148.534014\n",
  401. "epoch 154: loss = 1728451.091187, a = 893.384282, b = 148.533720\n",
  402. "epoch 155: loss = 1728359.006178, a = 894.220124, b = 148.533433\n",
  403. "epoch 156: loss = 1728270.099288, a = 895.039428, b = 148.533150\n",
  404. "epoch 157: loss = 1728184.254503, a = 895.842521, b = 148.532874\n",
  405. "epoch 158: loss = 1728101.360185, a = 896.629725, b = 148.532603\n",
  406. "epoch 159: loss = 1728021.308903, a = 897.401353, b = 148.532337\n",
  407. "epoch 160: loss = 1727943.997275, a = 898.157714, b = 148.532077\n",
  408. "epoch 161: loss = 1727869.325813, a = 898.899110, b = 148.531821\n",
  409. "epoch 162: loss = 1727797.198769, a = 899.625836, b = 148.531571\n",
  410. "epoch 163: loss = 1727727.523995, a = 900.338184, b = 148.531326\n",
  411. "epoch 164: loss = 1727660.212803, a = 901.036437, b = 148.531086\n",
  412. "epoch 165: loss = 1727595.179837, a = 901.720875, b = 148.530850\n",
  413. "epoch 166: loss = 1727532.342938, a = 902.391770, b = 148.530619\n",
  414. "epoch 167: loss = 1727471.623027, a = 903.049391, b = 148.530392\n",
  415. "epoch 168: loss = 1727412.943986, a = 903.694001, b = 148.530170\n",
  416. "epoch 169: loss = 1727356.232544, a = 904.325856, b = 148.529953\n",
  417. "epoch 170: loss = 1727301.418168, a = 904.945210, b = 148.529740\n",
  418. "epoch 171: loss = 1727248.432959, a = 905.552309, b = 148.529531\n",
  419. "epoch 172: loss = 1727197.211551, a = 906.147396, b = 148.529326\n",
  420. "epoch 173: loss = 1727147.691014, a = 906.730709, b = 148.529125\n",
  421. "epoch 174: loss = 1727099.810763, a = 907.302481, b = 148.528928\n",
  422. "epoch 175: loss = 1727053.512464, a = 907.862939, b = 148.528735\n",
  423. "epoch 176: loss = 1727008.739955, a = 908.412309, b = 148.528546\n",
  424. "epoch 177: loss = 1726965.439156, a = 908.950808, b = 148.528360\n",
  425. "epoch 178: loss = 1726923.557995, a = 909.478653, b = 148.528179\n",
  426. "epoch 179: loss = 1726883.046328, a = 909.996055, b = 148.528000\n",
  427. "epoch 180: loss = 1726843.855869, a = 910.503219, b = 148.527826\n",
  428. "epoch 181: loss = 1726805.940116, a = 911.000348, b = 148.527655\n",
  429. "epoch 182: loss = 1726769.254286, a = 911.487641, b = 148.527487\n",
  430. "epoch 183: loss = 1726733.755249, a = 911.965292, b = 148.527322\n",
  431. "epoch 184: loss = 1726699.401462, a = 912.433493, b = 148.527161\n",
  432. "epoch 185: loss = 1726666.152915, a = 912.892430, b = 148.527003\n",
  433. "epoch 186: loss = 1726633.971067, a = 913.342287, b = 148.526848\n"
  434. ]
  435. },
  436. {
  437. "name": "stdout",
  438. "output_type": "stream",
  439. "text": [
  440. "epoch 187: loss = 1726602.818794, a = 913.783243, b = 148.526696\n",
  441. "epoch 188: loss = 1726572.660334, a = 914.215474, b = 148.526548\n",
  442. "epoch 189: loss = 1726543.461235, a = 914.639153, b = 148.526402\n",
  443. "epoch 190: loss = 1726515.188306, a = 915.054449, b = 148.526259\n",
  444. "epoch 191: loss = 1726487.809572, a = 915.461529, b = 148.526119\n",
  445. "epoch 192: loss = 1726461.294221, a = 915.860553, b = 148.525981\n",
  446. "epoch 193: loss = 1726435.612569, a = 916.251683, b = 148.525846\n",
  447. "epoch 194: loss = 1726410.736010, a = 916.635074, b = 148.525714\n",
  448. "epoch 195: loss = 1726386.636980, a = 917.010879, b = 148.525585\n",
  449. "epoch 196: loss = 1726363.288915, a = 917.379249, b = 148.525458\n",
  450. "epoch 197: loss = 1726340.666217, a = 917.740330, b = 148.525334\n",
  451. "epoch 198: loss = 1726318.744212, a = 918.094267, b = 148.525212\n",
  452. "epoch 199: loss = 1726297.499121, a = 918.441201, b = 148.525093\n",
  453. "epoch 200: loss = 1726276.908024, a = 918.781270, b = 148.524975\n",
  454. "epoch 201: loss = 1726256.948827, a = 919.114611, b = 148.524861\n",
  455. "epoch 202: loss = 1726237.600231, a = 919.441356, b = 148.524748\n",
  456. "epoch 203: loss = 1726218.841703, a = 919.761637, b = 148.524638\n",
  457. "epoch 204: loss = 1726200.653451, a = 920.075580, b = 148.524530\n",
  458. "epoch 205: loss = 1726183.016388, a = 920.383312, b = 148.524424\n",
  459. "epoch 206: loss = 1726165.912113, a = 920.684955, b = 148.524320\n",
  460. "epoch 207: loss = 1726149.322881, a = 920.980630, b = 148.524218\n",
  461. "epoch 208: loss = 1726133.231583, a = 921.270455, b = 148.524118\n",
  462. "epoch 209: loss = 1726117.621717, a = 921.554545, b = 148.524021\n",
  463. "epoch 210: loss = 1726102.477370, a = 921.833014, b = 148.523925\n",
  464. "epoch 211: loss = 1726087.783192, a = 922.105974, b = 148.523831\n",
  465. "epoch 212: loss = 1726073.524378, a = 922.373533, b = 148.523739\n",
  466. "epoch 213: loss = 1726059.686650, a = 922.635798, b = 148.523648\n",
  467. "epoch 214: loss = 1726046.256229, a = 922.892873, b = 148.523560\n",
  468. "epoch 215: loss = 1726033.219826, a = 923.144863, b = 148.523473\n",
  469. "epoch 216: loss = 1726020.564620, a = 923.391866, b = 148.523388\n",
  470. "epoch 217: loss = 1726008.278237, a = 923.633982, b = 148.523305\n",
  471. "epoch 218: loss = 1725996.348741, a = 923.871308, b = 148.523223\n",
  472. "epoch 219: loss = 1725984.764612, a = 924.103938, b = 148.523143\n",
  473. "epoch 220: loss = 1725973.514733, a = 924.331966, b = 148.523064\n",
  474. "epoch 221: loss = 1725962.588374, a = 924.555481, b = 148.522987\n",
  475. "epoch 222: loss = 1725951.975181, a = 924.774575, b = 148.522912\n",
  476. "epoch 223: loss = 1725941.665156, a = 924.989333, b = 148.522838\n",
  477. "epoch 224: loss = 1725931.648652, a = 925.199842, b = 148.522765\n",
  478. "epoch 225: loss = 1725921.916352, a = 925.406186, b = 148.522694\n",
  479. "epoch 226: loss = 1725912.459264, a = 925.608447, b = 148.522625\n",
  480. "epoch 227: loss = 1725903.268703, a = 925.806706, b = 148.522556\n",
  481. "epoch 228: loss = 1725894.336285, a = 926.001043, b = 148.522489\n",
  482. "epoch 229: loss = 1725885.653913, a = 926.191534, b = 148.522424\n",
  483. "epoch 230: loss = 1725877.213768, a = 926.378257, b = 148.522360\n",
  484. "epoch 231: loss = 1725869.008296, a = 926.561285, b = 148.522297\n",
  485. "epoch 232: loss = 1725861.030202, a = 926.740692, b = 148.522235\n",
  486. "epoch 233: loss = 1725853.272442, a = 926.916548, b = 148.522174\n",
  487. "epoch 234: loss = 1725845.728205, a = 927.088926, b = 148.522115\n",
  488. "epoch 235: loss = 1725838.390917, a = 927.257893, b = 148.522057\n",
  489. "epoch 236: loss = 1725831.254223, a = 927.423516, b = 148.522000\n",
  490. "epoch 237: loss = 1725824.311982, a = 927.585863, b = 148.521944\n",
  491. "epoch 238: loss = 1725817.558260, a = 927.744997, b = 148.521889\n",
  492. "epoch 239: loss = 1725810.987324, a = 927.900983, b = 148.521835\n",
  493. "epoch 240: loss = 1725804.593630, a = 928.053883, b = 148.521783\n",
  494. "epoch 241: loss = 1725798.371821, a = 928.203757, b = 148.521731\n",
  495. "epoch 242: loss = 1725792.316718, a = 928.350666, b = 148.521680\n",
  496. "epoch 243: loss = 1725786.423315, a = 928.494668, b = 148.521631\n",
  497. "epoch 244: loss = 1725780.686770, a = 928.635821, b = 148.521582\n",
  498. "epoch 245: loss = 1725775.102403, a = 928.774181, b = 148.521535\n",
  499. "epoch 246: loss = 1725769.665688, a = 928.909804, b = 148.521488\n",
  500. "epoch 247: loss = 1725764.372248, a = 929.042743, b = 148.521442\n",
  501. "epoch 248: loss = 1725759.217848, a = 929.173052, b = 148.521397\n",
  502. "epoch 249: loss = 1725754.198393, a = 929.300783, b = 148.521353\n",
  503. "epoch 250: loss = 1725749.309922, a = 929.425986, b = 148.521310\n",
  504. "epoch 251: loss = 1725744.548603, a = 929.548712, b = 148.521268\n",
  505. "epoch 252: loss = 1725739.910728, a = 929.669010, b = 148.521226\n",
  506. "epoch 253: loss = 1725735.392708, a = 929.786928, b = 148.521186\n",
  507. "epoch 254: loss = 1725730.991072, a = 929.902512, b = 148.521146\n",
  508. "epoch 255: loss = 1725726.702459, a = 930.015810, b = 148.521107\n",
  509. "epoch 256: loss = 1725722.523617, a = 930.126866, b = 148.521069\n",
  510. "epoch 257: loss = 1725718.451397, a = 930.235724, b = 148.521031\n",
  511. "epoch 258: loss = 1725714.482753, a = 930.342429, b = 148.520995\n",
  512. "epoch 259: loss = 1725710.614734, a = 930.447022, b = 148.520959\n",
  513. "epoch 260: loss = 1725706.844482, a = 930.549546, b = 148.520923\n",
  514. "epoch 261: loss = 1725703.169232, a = 930.650042, b = 148.520889\n",
  515. "epoch 262: loss = 1725699.586303, a = 930.748549, b = 148.520855\n",
  516. "epoch 263: loss = 1725696.093102, a = 930.845107, b = 148.520822\n",
  517. "epoch 264: loss = 1725692.687115, a = 930.939754, b = 148.520789\n",
  518. "epoch 265: loss = 1725689.365908, a = 931.032529, b = 148.520757\n",
  519. "epoch 266: loss = 1725686.127121, a = 931.123468, b = 148.520726\n",
  520. "epoch 267: loss = 1725682.968469, a = 931.212608, b = 148.520695\n",
  521. "epoch 268: loss = 1725679.887739, a = 931.299985, b = 148.520665\n",
  522. "epoch 269: loss = 1725676.882782, a = 931.385632, b = 148.520635\n",
  523. "epoch 270: loss = 1725673.951521, a = 931.469585, b = 148.520606\n",
  524. "epoch 271: loss = 1725671.091938, a = 931.551877, b = 148.520578\n",
  525. "epoch 272: loss = 1725668.302080, a = 931.632540, b = 148.520550\n",
  526. "epoch 273: loss = 1725665.580052, a = 931.711608, b = 148.520523\n",
  527. "epoch 274: loss = 1725662.924017, a = 931.789111, b = 148.520496\n",
  528. "epoch 275: loss = 1725660.332194, a = 931.865080, b = 148.520470\n",
  529. "epoch 276: loss = 1725657.802855, a = 931.939547, b = 148.520445\n",
  530. "epoch 277: loss = 1725655.334325, a = 932.012540, b = 148.520420\n",
  531. "epoch 278: loss = 1725652.924980, a = 932.084089, b = 148.520395\n",
  532. "epoch 279: loss = 1725650.573243, a = 932.154222, b = 148.520371\n",
  533. "epoch 280: loss = 1725648.277584, a = 932.222968, b = 148.520347\n",
  534. "epoch 281: loss = 1725646.036521, a = 932.290353, b = 148.520324\n",
  535. "epoch 282: loss = 1725643.848614, a = 932.356405, b = 148.520301\n",
  536. "epoch 283: loss = 1725641.712465, a = 932.421150, b = 148.520279\n",
  537. "epoch 284: loss = 1725639.626719, a = 932.484614, b = 148.520257\n",
  538. "epoch 285: loss = 1725637.590060, a = 932.546823, b = 148.520236\n",
  539. "epoch 286: loss = 1725635.601209, a = 932.607801, b = 148.520215\n",
  540. "epoch 287: loss = 1725633.658927, a = 932.667572, b = 148.520194\n",
  541. "epoch 288: loss = 1725631.762010, a = 932.726160, b = 148.520174\n",
  542. "epoch 289: loss = 1725629.909289, a = 932.783590, b = 148.520154\n",
  543. "epoch 290: loss = 1725628.099627, a = 932.839883, b = 148.520135\n",
  544. "epoch 291: loss = 1725626.331922, a = 932.895062, b = 148.520116\n",
  545. "epoch 292: loss = 1725624.605102, a = 932.949149, b = 148.520097\n",
  546. "epoch 293: loss = 1725622.918128, a = 933.002166, b = 148.520079\n",
  547. "epoch 294: loss = 1725621.269989, a = 933.054135, b = 148.520061\n",
  548. "epoch 295: loss = 1725619.659702, a = 933.105075, b = 148.520043\n",
  549. "epoch 296: loss = 1725618.086312, a = 933.155007, b = 148.520026\n",
  550. "epoch 297: loss = 1725616.548894, a = 933.203951, b = 148.520009\n",
  551. "epoch 298: loss = 1725615.046544, a = 933.251927, b = 148.519993\n",
  552. "epoch 299: loss = 1725613.578388, a = 933.298953, b = 148.519977\n",
  553. "epoch 300: loss = 1725612.143573, a = 933.345050, b = 148.519961\n",
  554. "epoch 301: loss = 1725610.741272, a = 933.390234, b = 148.519945\n",
  555. "epoch 302: loss = 1725609.370679, a = 933.434524, b = 148.519930\n",
  556. "epoch 303: loss = 1725608.031013, a = 933.477937, b = 148.519915\n",
  557. "epoch 304: loss = 1725606.721512, a = 933.520492, b = 148.519900\n",
  558. "epoch 305: loss = 1725605.441435, a = 933.562205, b = 148.519886\n",
  559. "epoch 306: loss = 1725604.190064, a = 933.603092, b = 148.519872\n",
  560. "epoch 307: loss = 1725602.966697, a = 933.643171, b = 148.519858\n",
  561. "epoch 308: loss = 1725601.770653, a = 933.682456, b = 148.519845\n",
  562. "epoch 309: loss = 1725600.601270, a = 933.720964, b = 148.519831\n",
  563. "epoch 310: loss = 1725599.457903, a = 933.758711, b = 148.519818\n",
  564. "epoch 311: loss = 1725598.339923, a = 933.795710, b = 148.519806\n",
  565. "epoch 312: loss = 1725597.246722, a = 933.831977, b = 148.519793\n",
  566. "epoch 313: loss = 1725596.177703, a = 933.867527, b = 148.519781\n",
  567. "epoch 314: loss = 1725595.132289, a = 933.902373, b = 148.519769\n",
  568. "epoch 315: loss = 1725594.109917, a = 933.936530, b = 148.519757\n",
  569. "epoch 316: loss = 1725593.110038, a = 933.970011, b = 148.519746\n",
  570. "epoch 317: loss = 1725592.132118, a = 934.002830, b = 148.519734\n",
  571. "epoch 318: loss = 1725591.175638, a = 934.034999, b = 148.519723\n",
  572. "epoch 319: loss = 1725590.240092, a = 934.066532, b = 148.519712\n",
  573. "epoch 320: loss = 1725589.324986, a = 934.097441, b = 148.519702\n",
  574. "epoch 321: loss = 1725588.429841, a = 934.127738, b = 148.519691\n",
  575. "epoch 322: loss = 1725587.554189, a = 934.157436, b = 148.519681\n",
  576. "epoch 323: loss = 1725586.697574, a = 934.186546, b = 148.519671\n",
  577. "epoch 324: loss = 1725585.859554, a = 934.215081, b = 148.519661\n",
  578. "epoch 325: loss = 1725585.039694, a = 934.243051, b = 148.519651\n",
  579. "epoch 326: loss = 1725584.237575, a = 934.270467, b = 148.519642\n",
  580. "epoch 327: loss = 1725583.452786, a = 934.297341, b = 148.519633\n",
  581. "epoch 328: loss = 1725582.684926, a = 934.323683, b = 148.519624\n",
  582. "epoch 329: loss = 1725581.933606, a = 934.349504, b = 148.519615\n",
  583. "epoch 330: loss = 1725581.198445, a = 934.374814, b = 148.519606\n",
  584. "epoch 331: loss = 1725580.479074, a = 934.399623, b = 148.519598\n",
  585. "epoch 332: loss = 1725579.775131, a = 934.423941, b = 148.519589\n",
  586. "epoch 333: loss = 1725579.086264, a = 934.447779, b = 148.519581\n",
  587. "epoch 334: loss = 1725578.412130, a = 934.471144, b = 148.519573\n",
  588. "epoch 335: loss = 1725577.752394, a = 934.494048, b = 148.519565\n",
  589. "epoch 336: loss = 1725577.106730, a = 934.516498, b = 148.519557\n",
  590. "epoch 337: loss = 1725576.474819, a = 934.538504, b = 148.519550\n",
  591. "epoch 338: loss = 1725575.856351, a = 934.560074, b = 148.519542\n",
  592. "epoch 339: loss = 1725575.251023, a = 934.581218, b = 148.519535\n",
  593. "epoch 340: loss = 1725574.658540, a = 934.601943, b = 148.519528\n",
  594. "epoch 341: loss = 1725574.078613, a = 934.622259, b = 148.519521\n",
  595. "epoch 342: loss = 1725573.510962, a = 934.642172, b = 148.519514\n",
  596. "epoch 343: loss = 1725572.955312, a = 934.661691, b = 148.519507\n",
  597. "epoch 344: loss = 1725572.411396, a = 934.680825, b = 148.519501\n",
  598. "epoch 345: loss = 1725571.878952, a = 934.699579, b = 148.519494\n",
  599. "epoch 346: loss = 1725571.357726, a = 934.717963, b = 148.519488\n",
  600. "epoch 347: loss = 1725570.847468, a = 934.735982, b = 148.519482\n",
  601. "epoch 348: loss = 1725570.347937, a = 934.753646, b = 148.519476\n",
  602. "epoch 349: loss = 1725569.858895, a = 934.770959, b = 148.519470\n",
  603. "epoch 350: loss = 1725569.380112, a = 934.787931, b = 148.519464\n",
  604. "epoch 351: loss = 1725568.911360, a = 934.804566, b = 148.519458\n",
  605. "epoch 352: loss = 1725568.452420, a = 934.820872, b = 148.519453\n",
  606. "epoch 353: loss = 1725568.003077, a = 934.836856, b = 148.519447\n",
  607. "epoch 354: loss = 1725567.563120, a = 934.852523, b = 148.519442\n",
  608. "epoch 355: loss = 1725567.132345, a = 934.867881, b = 148.519436\n",
  609. "epoch 356: loss = 1725566.710551, a = 934.882934, b = 148.519431\n",
  610. "epoch 357: loss = 1725566.297542, a = 934.897690, b = 148.519426\n",
  611. "epoch 358: loss = 1725565.893128, a = 934.912154, b = 148.519421\n",
  612. "epoch 359: loss = 1725565.497121, a = 934.926331, b = 148.519416\n",
  613. "epoch 360: loss = 1725565.109340, a = 934.940228, b = 148.519411\n",
  614. "epoch 361: loss = 1725564.729607, a = 934.953850, b = 148.519407\n",
  615. "epoch 362: loss = 1725564.357747, a = 934.967203, b = 148.519402\n",
  616. "epoch 363: loss = 1725563.993590, a = 934.980291, b = 148.519398\n",
  617. "epoch 364: loss = 1725563.636972, a = 934.993120, b = 148.519393\n",
  618. "epoch 365: loss = 1725563.287729, a = 935.005696, b = 148.519389\n",
  619. "epoch 366: loss = 1725562.945702, a = 935.018023, b = 148.519385\n",
  620. "epoch 367: loss = 1725562.610739, a = 935.030106, b = 148.519380\n",
  621. "epoch 368: loss = 1725562.282686, a = 935.041949, b = 148.519376\n",
  622. "epoch 369: loss = 1725561.961396, a = 935.053559, b = 148.519372\n",
  623. "epoch 370: loss = 1725561.646724, a = 935.064938, b = 148.519368\n",
  624. "epoch 371: loss = 1725561.338531, a = 935.076093, b = 148.519365\n",
  625. "epoch 372: loss = 1725561.036676, a = 935.087027, b = 148.519361\n",
  626. "epoch 373: loss = 1725560.741026, a = 935.097744, b = 148.519357\n",
  627. "epoch 374: loss = 1725560.451449, a = 935.108250, b = 148.519354\n",
  628. "epoch 375: loss = 1725560.167816, a = 935.118547, b = 148.519350\n",
  629. "epoch 376: loss = 1725559.890000, a = 935.128641, b = 148.519347\n",
  630. "epoch 377: loss = 1725559.617879, a = 935.138535, b = 148.519343\n",
  631. "epoch 378: loss = 1725559.351332, a = 935.148234, b = 148.519340\n",
  632. "epoch 379: loss = 1725559.090241, a = 935.157740, b = 148.519337\n",
  633. "epoch 380: loss = 1725558.834492, a = 935.167059, b = 148.519333\n",
  634. "epoch 381: loss = 1725558.583972, a = 935.176193, b = 148.519330\n",
  635. "epoch 382: loss = 1725558.338570, a = 935.185146, b = 148.519327\n",
  636. "epoch 383: loss = 1725558.098179, a = 935.193922, b = 148.519324\n",
  637. "epoch 384: loss = 1725557.862695, a = 935.202525, b = 148.519321\n",
  638. "epoch 385: loss = 1725557.632013, a = 935.210957, b = 148.519318\n",
  639. "epoch 386: loss = 1725557.406033, a = 935.219223, b = 148.519315\n",
  640. "epoch 387: loss = 1725557.184657, a = 935.227324, b = 148.519313\n",
  641. "epoch 388: loss = 1725556.967789, a = 935.235266, b = 148.519310\n",
  642. "epoch 389: loss = 1725556.755334, a = 935.243051, b = 148.519307\n",
  643. "epoch 390: loss = 1725556.547200, a = 935.250681, b = 148.519305\n",
  644. "epoch 391: loss = 1725556.343298, a = 935.258160, b = 148.519302\n",
  645. "epoch 392: loss = 1725556.143538, a = 935.265492, b = 148.519299\n",
  646. "epoch 393: loss = 1725555.947836, a = 935.272678, b = 148.519297\n",
  647. "epoch 394: loss = 1725555.756105, a = 935.279723, b = 148.519295\n",
  648. "epoch 395: loss = 1725555.568265, a = 935.286628, b = 148.519292\n",
  649. "epoch 396: loss = 1725555.384233, a = 935.293396, b = 148.519290\n",
  650. "epoch 397: loss = 1725555.203932, a = 935.300030, b = 148.519288\n",
  651. "epoch 398: loss = 1725555.027283, a = 935.306533, b = 148.519285\n",
  652. "epoch 399: loss = 1725554.854212, a = 935.312908, b = 148.519283\n",
  653. "epoch 400: loss = 1725554.684644, a = 935.319156, b = 148.519281\n",
  654. "epoch 401: loss = 1725554.518507, a = 935.325281, b = 148.519279\n",
  655. "epoch 402: loss = 1725554.355730, a = 935.331284, b = 148.519277\n",
  656. "epoch 403: loss = 1725554.196244, a = 935.337169, b = 148.519275\n",
  657. "epoch 404: loss = 1725554.039980, a = 935.342937, b = 148.519273\n",
  658. "epoch 405: loss = 1725553.886873, a = 935.348591, b = 148.519271\n",
  659. "epoch 406: loss = 1725553.736857, a = 935.354133, b = 148.519269\n",
  660. "epoch 407: loss = 1725553.589869, a = 935.359566, b = 148.519267\n",
  661. "epoch 408: loss = 1725553.445846, a = 935.364891, b = 148.519265\n",
  662. "epoch 409: loss = 1725553.304728, a = 935.370111, b = 148.519263\n",
  663. "epoch 410: loss = 1725553.166456, a = 935.375227, b = 148.519262\n",
  664. "epoch 411: loss = 1725553.030969, a = 935.380242, b = 148.519260\n",
  665. "epoch 412: loss = 1725552.898213, a = 935.385158, b = 148.519258\n",
  666. "epoch 413: loss = 1725552.768130, a = 935.389977, b = 148.519257\n",
  667. "epoch 414: loss = 1725552.640666, a = 935.394701, b = 148.519255\n",
  668. "epoch 415: loss = 1725552.515767, a = 935.399331, b = 148.519253\n",
  669. "epoch 416: loss = 1725552.393381, a = 935.403869, b = 148.519252\n",
  670. "epoch 417: loss = 1725552.273456, a = 935.408317, b = 148.519250\n",
  671. "epoch 418: loss = 1725552.155943, a = 935.412678, b = 148.519249\n",
  672. "epoch 419: loss = 1725552.040792, a = 935.416952, b = 148.519247\n",
  673. "epoch 420: loss = 1725551.927954, a = 935.421142, b = 148.519246\n",
  674. "epoch 421: loss = 1725551.817384, a = 935.425249, b = 148.519244\n",
  675. "epoch 422: loss = 1725551.709033, a = 935.429274, b = 148.519243\n",
  676. "epoch 423: loss = 1725551.602858, a = 935.433220, b = 148.519242\n",
  677. "epoch 424: loss = 1725551.498814, a = 935.437088, b = 148.519240\n",
  678. "epoch 425: loss = 1725551.396858, a = 935.440879, b = 148.519239\n",
  679. "epoch 426: loss = 1725551.296947, a = 935.444595, b = 148.519238\n",
  680. "epoch 427: loss = 1725551.199039, a = 935.448238, b = 148.519237\n",
  681. "epoch 428: loss = 1725551.103094, a = 935.451809, b = 148.519235\n",
  682. "epoch 429: loss = 1725551.009073, a = 935.455309, b = 148.519234\n",
  683. "epoch 430: loss = 1725550.916935, a = 935.458739, b = 148.519233\n",
  684. "epoch 431: loss = 1725550.826644, a = 935.462102, b = 148.519232\n",
  685. "epoch 432: loss = 1725550.738161, a = 935.465399, b = 148.519231\n",
  686. "epoch 433: loss = 1725550.651449, a = 935.468630, b = 148.519229\n",
  687. "epoch 434: loss = 1725550.566474, a = 935.471797, b = 148.519228\n",
  688. "epoch 435: loss = 1725550.483199, a = 935.474901, b = 148.519227\n",
  689. "epoch 436: loss = 1725550.401591, a = 935.477945, b = 148.519226\n",
  690. "epoch 437: loss = 1725550.321615, a = 935.480927, b = 148.519225\n",
  691. "epoch 438: loss = 1725550.243239, a = 935.483851, b = 148.519224\n",
  692. "epoch 439: loss = 1725550.166431, a = 935.486717, b = 148.519223\n",
  693. "epoch 440: loss = 1725550.091158, a = 935.489527, b = 148.519222\n",
  694. "epoch 441: loss = 1725550.017389, a = 935.492280, b = 148.519221\n",
  695. "epoch 442: loss = 1725549.945095, a = 935.494980, b = 148.519220\n",
  696. "epoch 443: loss = 1725549.874246, a = 935.497625, b = 148.519219\n",
  697. "epoch 444: loss = 1725549.804812, a = 935.500219, b = 148.519219\n",
  698. "epoch 445: loss = 1725549.736765, a = 935.502761, b = 148.519218\n",
  699. "epoch 446: loss = 1725549.670077, a = 935.505253, b = 148.519217\n",
  700. "epoch 447: loss = 1725549.604720, a = 935.507696, b = 148.519216\n",
  701. "epoch 448: loss = 1725549.540668, a = 935.510090, b = 148.519215\n",
  702. "epoch 449: loss = 1725549.477894, a = 935.512437, b = 148.519214\n",
  703. "epoch 450: loss = 1725549.416373, a = 935.514737, b = 148.519214\n",
  704. "epoch 451: loss = 1725549.356080, a = 935.516992, b = 148.519213\n",
  705. "epoch 452: loss = 1725549.296990, a = 935.519202, b = 148.519212\n",
  706. "epoch 453: loss = 1725549.239078, a = 935.521369, b = 148.519211\n",
  707. "epoch 454: loss = 1725549.182321, a = 935.523493, b = 148.519211\n",
  708. "epoch 455: loss = 1725549.126696, a = 935.525574, b = 148.519210\n",
  709. "epoch 456: loss = 1725549.072179, a = 935.527615, b = 148.519209\n",
  710. "epoch 457: loss = 1725549.018750, a = 935.529615, b = 148.519208\n",
  711. "epoch 458: loss = 1725548.966385, a = 935.531575, b = 148.519208\n",
  712. "epoch 459: loss = 1725548.915064, a = 935.533497, b = 148.519207\n",
  713. "epoch 460: loss = 1725548.864766, a = 935.535381, b = 148.519206\n",
  714. "epoch 461: loss = 1725548.815470, a = 935.537227, b = 148.519206\n",
  715. "epoch 462: loss = 1725548.767155, a = 935.539037, b = 148.519205\n",
  716. "epoch 463: loss = 1725548.719803, a = 935.540811, b = 148.519205\n",
  717. "epoch 464: loss = 1725548.673394, a = 935.542550, b = 148.519204\n",
  718. "epoch 465: loss = 1725548.627910, a = 935.544255, b = 148.519203\n",
  719. "epoch 466: loss = 1725548.583330, a = 935.545926, b = 148.519203\n",
  720. "epoch 467: loss = 1725548.539638, a = 935.547564, b = 148.519202\n",
  721. "epoch 468: loss = 1725548.496816, a = 935.549169, b = 148.519202\n",
  722. "epoch 469: loss = 1725548.454846, a = 935.550743, b = 148.519201\n",
  723. "epoch 470: loss = 1725548.413712, a = 935.552285, b = 148.519201\n",
  724. "epoch 471: loss = 1725548.373396, a = 935.553797, b = 148.519200\n",
  725. "epoch 472: loss = 1725548.333882, a = 935.555279, b = 148.519200\n",
  726. "epoch 473: loss = 1725548.295154, a = 935.556732, b = 148.519199\n",
  727. "epoch 474: loss = 1725548.257196, a = 935.558156, b = 148.519199\n",
  728. "epoch 475: loss = 1725548.219993, a = 935.559552, b = 148.519198\n",
  729. "epoch 476: loss = 1725548.183531, a = 935.560920, b = 148.519198\n",
  730. "epoch 477: loss = 1725548.147793, a = 935.562261, b = 148.519197\n",
  731. "epoch 478: loss = 1725548.112766, a = 935.563576, b = 148.519197\n",
  732. "epoch 479: loss = 1725548.078435, a = 935.564864, b = 148.519196\n",
  733. "epoch 480: loss = 1725548.044787, a = 935.566128, b = 148.519196\n",
  734. "epoch 481: loss = 1725548.011808, a = 935.567366, b = 148.519195\n",
  735. "epoch 482: loss = 1725547.979484, a = 935.568579, b = 148.519195\n",
  736. "epoch 483: loss = 1725547.947802, a = 935.569769, b = 148.519195\n",
  737. "epoch 484: loss = 1725547.916751, a = 935.570935, b = 148.519194\n",
  738. "epoch 485: loss = 1725547.886316, a = 935.572078, b = 148.519194\n",
  739. "epoch 486: loss = 1725547.856486, a = 935.573198, b = 148.519193\n",
  740. "epoch 487: loss = 1725547.827248, a = 935.574296, b = 148.519193\n",
  741. "epoch 488: loss = 1725547.798592, a = 935.575373, b = 148.519193\n"
  742. ]
  743. },
  744. {
  745. "name": "stdout",
  746. "output_type": "stream",
  747. "text": [
  748. "epoch 489: loss = 1725547.770504, a = 935.576428, b = 148.519192\n",
  749. "epoch 490: loss = 1725547.742975, a = 935.577462, b = 148.519192\n",
  750. "epoch 491: loss = 1725547.715992, a = 935.578476, b = 148.519192\n",
  751. "epoch 492: loss = 1725547.689545, a = 935.579470, b = 148.519191\n",
  752. "epoch 493: loss = 1725547.663624, a = 935.580444, b = 148.519191\n",
  753. "epoch 494: loss = 1725547.638217, a = 935.581399, b = 148.519191\n",
  754. "epoch 495: loss = 1725547.613314, a = 935.582335, b = 148.519190\n",
  755. "epoch 496: loss = 1725547.588906, a = 935.583252, b = 148.519190\n",
  756. "epoch 497: loss = 1725547.564983, a = 935.584152, b = 148.519190\n",
  757. "epoch 498: loss = 1725547.541534, a = 935.585033, b = 148.519189\n",
  758. "epoch 499: loss = 1725547.518551, a = 935.585897, b = 148.519189\n"
  759. ]
  760. },
  761. {
  762. "data": {
  763. "image/png": "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hkmx/Dbr1q2jU6dOXHrppRxzzDFs2LAhrsjGXXfdRadOnfjNb37D0KFDue+++wAYPnw406drtcQ7dOjA6NGjOe644+jatSurVq0CYMGCBfz617+moKCAE088kdWrnS2f8vJyLrzwQo466ijOPvtsysv3/5iuvvpqCgsL6dKlC6NHjwbgoYce4vvvv6dv37707dvXdj+FO8pa3U8m5jJX1BPLPRlW1KJFi3jmmWeYP38+Ukp69erFb3/7W5o3b86aNWt47rnnOOGEE+KO+fzzz5kxYwZLly6loqKC4447jh49eliev2XLlnzxxRc88sgj3HfffTz55JN07tyZTz75hEaNGvHee+9x66231mSctOLRRx8lNzeXlStXsmzZMo477ria9+6++25atGhBVVUVp5xyCsuWLeO6667jgQceYM6cObRs2dJ2v27dugW6Zw0JZa3uRyX2ykzqhbgnmnXOik8//ZSzzz6bpk2bAnDOOefwySefMGjQINq3b19L2AHmzp3L4MGDyc7OJjs7m4EDB9qe/5xzzgGgR48eNamBd+zYwbBhw1izZg1CCCoqKhzb+PHHH3PdddcB0K1btzhRnjZtGpMnT6ayspJNmzbx1VdfWYq21/3CJpOjK7y0zc/ioUzta1jtUuGYmUm9EPdUW1G64CeCnjo4EolQWVkJwO23307fvn157bXXWLduHX369Al07m+//Zb77ruPzz//nObNmzN8+HD27NkTeL+wyWR/tde2ebVWM7WvYbcrE8IxFfHUC597Mnx+J510EsXFxZSVlbF7925ee+01TjrpJMdjevfuzeuvv86ePXvYtWsXb7zxhq9r7tixg/x87Qfy7LPPuu5vTCv85Zdf1pT427lzJ02bNqVZs2Zs3ryZt956q+aYAw88kJ9//tl1v2SSyf5qr23zmoY2U/uaqe1yQ0UoeadeWO7J8Pkdd9xxDB8+nOOPPx6AK6+8koKCAtatW2d7TM+ePRk0aBDdunXj0EMPpWvXrjRr1szzNW+++WaGDRvGuHHjOPPMM133v/rqq7nssss46qijOOqoo2r8+8ceeywFBQV07tyZtm3b0rt375pjRowYwRlnnEHr1q2ZM2eO7X7JJJP91X7a5sVazaS+Gt0wdrlgM+EzsCNTR0EJ8e23kJsLhx4a+qnrTcrfTPFr7tq1iwMOOICysjJOPvlkJk+e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\n",
  764. "text/plain": [
  765. "<Figure size 432x288 with 1 Axes>"
  766. ]
  767. },
  768. "metadata": {
  769. "needs_background": "light"
  770. },
  771. "output_type": "display_data"
  772. }
  773. ],
  774. "source": [
  775. "n_epoch = 500 # epoch size\n",
  776. "a, b = 1, 1 # initial parameters\n",
  777. "epsilon = 0.01 # learning rate\n",
  778. "\n",
  779. "for i in range(n_epoch):\n",
  780. " for j in range(N):\n",
  781. " a = a + epsilon*2*(Y[j] - a*X[j] - b)*X[j]\n",
  782. " b = b + epsilon*2*(Y[j] - a*X[j] - b)\n",
  783. "\n",
  784. " L = 0\n",
  785. " for j in range(N):\n",
  786. " L = L + (Y[j]-a*X[j]-b)**2\n",
  787. " print(\"epoch %4d: loss = %f, a = %f, b = %f\" % (i, L, a, b))\n",
  788. " \n",
  789. "x_min = np.min(X)\n",
  790. "x_max = np.max(X)\n",
  791. "y_min = a * x_min + b\n",
  792. "y_max = a * x_max + b\n",
  793. "\n",
  794. "plt.scatter(X, Y, label='original data')\n",
  795. "plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n",
  796. "plt.legend()\n",
  797. "plt.show()"
  798. ]
  799. },
  800. {
  801. "cell_type": "markdown",
  802. "metadata": {},
  803. "source": [
  804. "## 3. 如何可视化迭代过程"
  805. ]
  806. },
  807. {
  808. "cell_type": "code",
  809. "execution_count": 5,
  810. "metadata": {},
  811. "outputs": [
  812. {
  813. "data": {
  814. "application/javascript": [
  815. "/* Put everything inside the global mpl namespace */\n",
  816. "/* global mpl */\n",
  817. "window.mpl = {};\n",
  818. "\n",
  819. "mpl.get_websocket_type = function () {\n",
  820. " if (typeof WebSocket !== 'undefined') {\n",
  821. " return WebSocket;\n",
  822. " } else if (typeof MozWebSocket !== 'undefined') {\n",
  823. " return MozWebSocket;\n",
  824. " } else {\n",
  825. " alert(\n",
  826. " 'Your browser does not have WebSocket support. ' +\n",
  827. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  828. " 'Firefox 4 and 5 are also supported but you ' +\n",
  829. " 'have to enable WebSockets in about:config.'\n",
  830. " );\n",
  831. " }\n",
  832. "};\n",
  833. "\n",
  834. "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
  835. " this.id = figure_id;\n",
  836. "\n",
  837. " this.ws = websocket;\n",
  838. "\n",
  839. " this.supports_binary = this.ws.binaryType !== undefined;\n",
  840. "\n",
  841. " if (!this.supports_binary) {\n",
  842. " var warnings = document.getElementById('mpl-warnings');\n",
  843. " if (warnings) {\n",
  844. " warnings.style.display = 'block';\n",
  845. " warnings.textContent =\n",
  846. " 'This browser does not support binary websocket messages. ' +\n",
  847. " 'Performance may be slow.';\n",
  848. " }\n",
  849. " }\n",
  850. "\n",
  851. " this.imageObj = new Image();\n",
  852. "\n",
  853. " this.context = undefined;\n",
  854. " this.message = undefined;\n",
  855. " this.canvas = undefined;\n",
  856. " this.rubberband_canvas = undefined;\n",
  857. " this.rubberband_context = undefined;\n",
  858. " this.format_dropdown = undefined;\n",
  859. "\n",
  860. " this.image_mode = 'full';\n",
  861. "\n",
  862. " this.root = document.createElement('div');\n",
  863. " this.root.setAttribute('style', 'display: inline-block');\n",
  864. " this._root_extra_style(this.root);\n",
  865. "\n",
  866. " parent_element.appendChild(this.root);\n",
  867. "\n",
  868. " this._init_header(this);\n",
  869. " this._init_canvas(this);\n",
  870. " this._init_toolbar(this);\n",
  871. "\n",
  872. " var fig = this;\n",
  873. "\n",
  874. " this.waiting = false;\n",
  875. "\n",
  876. " this.ws.onopen = function () {\n",
  877. " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
  878. " fig.send_message('send_image_mode', {});\n",
  879. " if (mpl.ratio !== 1) {\n",
  880. " fig.send_message('set_dpi_ratio', { dpi_ratio: mpl.ratio });\n",
  881. " }\n",
  882. " fig.send_message('refresh', {});\n",
  883. " };\n",
  884. "\n",
  885. " this.imageObj.onload = function () {\n",
  886. " if (fig.image_mode === 'full') {\n",
  887. " // Full images could contain transparency (where diff images\n",
  888. " // almost always do), so we need to clear the canvas so that\n",
  889. " // there is no ghosting.\n",
  890. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  891. " }\n",
  892. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  893. " };\n",
  894. "\n",
  895. " this.imageObj.onunload = function () {\n",
  896. " fig.ws.close();\n",
  897. " };\n",
  898. "\n",
  899. " this.ws.onmessage = this._make_on_message_function(this);\n",
  900. "\n",
  901. " this.ondownload = ondownload;\n",
  902. "};\n",
  903. "\n",
  904. "mpl.figure.prototype._init_header = function () {\n",
  905. " var titlebar = document.createElement('div');\n",
  906. " titlebar.classList =\n",
  907. " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
  908. " var titletext = document.createElement('div');\n",
  909. " titletext.classList = 'ui-dialog-title';\n",
  910. " titletext.setAttribute(\n",
  911. " 'style',\n",
  912. " 'width: 100%; text-align: center; padding: 3px;'\n",
  913. " );\n",
  914. " titlebar.appendChild(titletext);\n",
  915. " this.root.appendChild(titlebar);\n",
  916. " this.header = titletext;\n",
  917. "};\n",
  918. "\n",
  919. "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
  920. "\n",
  921. "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
  922. "\n",
  923. "mpl.figure.prototype._init_canvas = function () {\n",
  924. " var fig = this;\n",
  925. "\n",
  926. " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
  927. " canvas_div.setAttribute(\n",
  928. " 'style',\n",
  929. " 'border: 1px solid #ddd;' +\n",
  930. " 'box-sizing: content-box;' +\n",
  931. " 'clear: both;' +\n",
  932. " 'min-height: 1px;' +\n",
  933. " 'min-width: 1px;' +\n",
  934. " 'outline: 0;' +\n",
  935. " 'overflow: hidden;' +\n",
  936. " 'position: relative;' +\n",
  937. " 'resize: both;'\n",
  938. " );\n",
  939. "\n",
  940. " function on_keyboard_event_closure(name) {\n",
  941. " return function (event) {\n",
  942. " return fig.key_event(event, name);\n",
  943. " };\n",
  944. " }\n",
  945. "\n",
  946. " canvas_div.addEventListener(\n",
  947. " 'keydown',\n",
  948. " on_keyboard_event_closure('key_press')\n",
  949. " );\n",
  950. " canvas_div.addEventListener(\n",
  951. " 'keyup',\n",
  952. " on_keyboard_event_closure('key_release')\n",
  953. " );\n",
  954. "\n",
  955. " this._canvas_extra_style(canvas_div);\n",
  956. " this.root.appendChild(canvas_div);\n",
  957. "\n",
  958. " var canvas = (this.canvas = document.createElement('canvas'));\n",
  959. " canvas.classList.add('mpl-canvas');\n",
  960. " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
  961. "\n",
  962. " this.context = canvas.getContext('2d');\n",
  963. "\n",
  964. " var backingStore =\n",
  965. " this.context.backingStorePixelRatio ||\n",
  966. " this.context.webkitBackingStorePixelRatio ||\n",
  967. " this.context.mozBackingStorePixelRatio ||\n",
  968. " this.context.msBackingStorePixelRatio ||\n",
  969. " this.context.oBackingStorePixelRatio ||\n",
  970. " this.context.backingStorePixelRatio ||\n",
  971. " 1;\n",
  972. "\n",
  973. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  974. "\n",
  975. " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
  976. " 'canvas'\n",
  977. " ));\n",
  978. " rubberband_canvas.setAttribute(\n",
  979. " 'style',\n",
  980. " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
  981. " );\n",
  982. "\n",
  983. " var resizeObserver = new ResizeObserver(function (entries) {\n",
  984. " var nentries = entries.length;\n",
  985. " for (var i = 0; i < nentries; i++) {\n",
  986. " var entry = entries[i];\n",
  987. " var width, height;\n",
  988. " if (entry.contentBoxSize) {\n",
  989. " width = entry.contentBoxSize.inlineSize;\n",
  990. " height = entry.contentBoxSize.blockSize;\n",
  991. " } else {\n",
  992. " width = entry.contentRect.width;\n",
  993. " height = entry.contentRect.height;\n",
  994. " }\n",
  995. "\n",
  996. " // Keep the size of the canvas and rubber band canvas in sync with\n",
  997. " // the canvas container.\n",
  998. " canvas.setAttribute('width', width * mpl.ratio);\n",
  999. " canvas.setAttribute('height', height * mpl.ratio);\n",
  1000. " canvas.setAttribute(\n",
  1001. " 'style',\n",
  1002. " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
  1003. " );\n",
  1004. "\n",
  1005. " rubberband_canvas.setAttribute('width', width);\n",
  1006. " rubberband_canvas.setAttribute('height', height);\n",
  1007. "\n",
  1008. " // And update the size in Python. We ignore the initial 0/0 size\n",
  1009. " // that occurs as the element is placed into the DOM, which should\n",
  1010. " // otherwise not happen due to the minimum size styling.\n",
  1011. " if (width != 0 && height != 0) {\n",
  1012. " fig.request_resize(width, height);\n",
  1013. " }\n",
  1014. " }\n",
  1015. " });\n",
  1016. " resizeObserver.observe(canvas_div);\n",
  1017. "\n",
  1018. " function on_mouse_event_closure(name) {\n",
  1019. " return function (event) {\n",
  1020. " return fig.mouse_event(event, name);\n",
  1021. " };\n",
  1022. " }\n",
  1023. "\n",
  1024. " rubberband_canvas.addEventListener(\n",
  1025. " 'mousedown',\n",
  1026. " on_mouse_event_closure('button_press')\n",
  1027. " );\n",
  1028. " rubberband_canvas.addEventListener(\n",
  1029. " 'mouseup',\n",
  1030. " on_mouse_event_closure('button_release')\n",
  1031. " );\n",
  1032. " // Throttle sequential mouse events to 1 every 20ms.\n",
  1033. " rubberband_canvas.addEventListener(\n",
  1034. " 'mousemove',\n",
  1035. " on_mouse_event_closure('motion_notify')\n",
  1036. " );\n",
  1037. "\n",
  1038. " rubberband_canvas.addEventListener(\n",
  1039. " 'mouseenter',\n",
  1040. " on_mouse_event_closure('figure_enter')\n",
  1041. " );\n",
  1042. " rubberband_canvas.addEventListener(\n",
  1043. " 'mouseleave',\n",
  1044. " on_mouse_event_closure('figure_leave')\n",
  1045. " );\n",
  1046. "\n",
  1047. " canvas_div.addEventListener('wheel', function (event) {\n",
  1048. " if (event.deltaY < 0) {\n",
  1049. " event.step = 1;\n",
  1050. " } else {\n",
  1051. " event.step = -1;\n",
  1052. " }\n",
  1053. " on_mouse_event_closure('scroll')(event);\n",
  1054. " });\n",
  1055. "\n",
  1056. " canvas_div.appendChild(canvas);\n",
  1057. " canvas_div.appendChild(rubberband_canvas);\n",
  1058. "\n",
  1059. " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
  1060. " this.rubberband_context.strokeStyle = '#000000';\n",
  1061. "\n",
  1062. " this._resize_canvas = function (width, height, forward) {\n",
  1063. " if (forward) {\n",
  1064. " canvas_div.style.width = width + 'px';\n",
  1065. " canvas_div.style.height = height + 'px';\n",
  1066. " }\n",
  1067. " };\n",
  1068. "\n",
  1069. " // Disable right mouse context menu.\n",
  1070. " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
  1071. " return false;\n",
  1072. " });\n",
  1073. "\n",
  1074. " function set_focus() {\n",
  1075. " canvas.focus();\n",
  1076. " canvas_div.focus();\n",
  1077. " }\n",
  1078. "\n",
  1079. " window.setTimeout(set_focus, 100);\n",
  1080. "};\n",
  1081. "\n",
  1082. "mpl.figure.prototype._init_toolbar = function () {\n",
  1083. " var fig = this;\n",
  1084. "\n",
  1085. " var toolbar = document.createElement('div');\n",
  1086. " toolbar.classList = 'mpl-toolbar';\n",
  1087. " this.root.appendChild(toolbar);\n",
  1088. "\n",
  1089. " function on_click_closure(name) {\n",
  1090. " return function (_event) {\n",
  1091. " return fig.toolbar_button_onclick(name);\n",
  1092. " };\n",
  1093. " }\n",
  1094. "\n",
  1095. " function on_mouseover_closure(tooltip) {\n",
  1096. " return function (event) {\n",
  1097. " if (!event.currentTarget.disabled) {\n",
  1098. " return fig.toolbar_button_onmouseover(tooltip);\n",
  1099. " }\n",
  1100. " };\n",
  1101. " }\n",
  1102. "\n",
  1103. " fig.buttons = {};\n",
  1104. " var buttonGroup = document.createElement('div');\n",
  1105. " buttonGroup.classList = 'mpl-button-group';\n",
  1106. " for (var toolbar_ind in mpl.toolbar_items) {\n",
  1107. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  1108. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  1109. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  1110. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  1111. "\n",
  1112. " if (!name) {\n",
  1113. " /* Instead of a spacer, we start a new button group. */\n",
  1114. " if (buttonGroup.hasChildNodes()) {\n",
  1115. " toolbar.appendChild(buttonGroup);\n",
  1116. " }\n",
  1117. " buttonGroup = document.createElement('div');\n",
  1118. " buttonGroup.classList = 'mpl-button-group';\n",
  1119. " continue;\n",
  1120. " }\n",
  1121. "\n",
  1122. " var button = (fig.buttons[name] = document.createElement('button'));\n",
  1123. " button.classList = 'mpl-widget';\n",
  1124. " button.setAttribute('role', 'button');\n",
  1125. " button.setAttribute('aria-disabled', 'false');\n",
  1126. " button.addEventListener('click', on_click_closure(method_name));\n",
  1127. " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
  1128. "\n",
  1129. " var icon_img = document.createElement('img');\n",
  1130. " icon_img.src = '_images/' + image + '.png';\n",
  1131. " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
  1132. " icon_img.alt = tooltip;\n",
  1133. " button.appendChild(icon_img);\n",
  1134. "\n",
  1135. " buttonGroup.appendChild(button);\n",
  1136. " }\n",
  1137. "\n",
  1138. " if (buttonGroup.hasChildNodes()) {\n",
  1139. " toolbar.appendChild(buttonGroup);\n",
  1140. " }\n",
  1141. "\n",
  1142. " var fmt_picker = document.createElement('select');\n",
  1143. " fmt_picker.classList = 'mpl-widget';\n",
  1144. " toolbar.appendChild(fmt_picker);\n",
  1145. " this.format_dropdown = fmt_picker;\n",
  1146. "\n",
  1147. " for (var ind in mpl.extensions) {\n",
  1148. " var fmt = mpl.extensions[ind];\n",
  1149. " var option = document.createElement('option');\n",
  1150. " option.selected = fmt === mpl.default_extension;\n",
  1151. " option.innerHTML = fmt;\n",
  1152. " fmt_picker.appendChild(option);\n",
  1153. " }\n",
  1154. "\n",
  1155. " var status_bar = document.createElement('span');\n",
  1156. " status_bar.classList = 'mpl-message';\n",
  1157. " toolbar.appendChild(status_bar);\n",
  1158. " this.message = status_bar;\n",
  1159. "};\n",
  1160. "\n",
  1161. "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
  1162. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  1163. " // which will in turn request a refresh of the image.\n",
  1164. " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
  1165. "};\n",
  1166. "\n",
  1167. "mpl.figure.prototype.send_message = function (type, properties) {\n",
  1168. " properties['type'] = type;\n",
  1169. " properties['figure_id'] = this.id;\n",
  1170. " this.ws.send(JSON.stringify(properties));\n",
  1171. "};\n",
  1172. "\n",
  1173. "mpl.figure.prototype.send_draw_message = function () {\n",
  1174. " if (!this.waiting) {\n",
  1175. " this.waiting = true;\n",
  1176. " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
  1177. " }\n",
  1178. "};\n",
  1179. "\n",
  1180. "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
  1181. " var format_dropdown = fig.format_dropdown;\n",
  1182. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  1183. " fig.ondownload(fig, format);\n",
  1184. "};\n",
  1185. "\n",
  1186. "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
  1187. " var size = msg['size'];\n",
  1188. " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
  1189. " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
  1190. " fig.send_message('refresh', {});\n",
  1191. " }\n",
  1192. "};\n",
  1193. "\n",
  1194. "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
  1195. " var x0 = msg['x0'] / mpl.ratio;\n",
  1196. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  1197. " var x1 = msg['x1'] / mpl.ratio;\n",
  1198. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  1199. " x0 = Math.floor(x0) + 0.5;\n",
  1200. " y0 = Math.floor(y0) + 0.5;\n",
  1201. " x1 = Math.floor(x1) + 0.5;\n",
  1202. " y1 = Math.floor(y1) + 0.5;\n",
  1203. " var min_x = Math.min(x0, x1);\n",
  1204. " var min_y = Math.min(y0, y1);\n",
  1205. " var width = Math.abs(x1 - x0);\n",
  1206. " var height = Math.abs(y1 - y0);\n",
  1207. "\n",
  1208. " fig.rubberband_context.clearRect(\n",
  1209. " 0,\n",
  1210. " 0,\n",
  1211. " fig.canvas.width / mpl.ratio,\n",
  1212. " fig.canvas.height / mpl.ratio\n",
  1213. " );\n",
  1214. "\n",
  1215. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  1216. "};\n",
  1217. "\n",
  1218. "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
  1219. " // Updates the figure title.\n",
  1220. " fig.header.textContent = msg['label'];\n",
  1221. "};\n",
  1222. "\n",
  1223. "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
  1224. " var cursor = msg['cursor'];\n",
  1225. " switch (cursor) {\n",
  1226. " case 0:\n",
  1227. " cursor = 'pointer';\n",
  1228. " break;\n",
  1229. " case 1:\n",
  1230. " cursor = 'default';\n",
  1231. " break;\n",
  1232. " case 2:\n",
  1233. " cursor = 'crosshair';\n",
  1234. " break;\n",
  1235. " case 3:\n",
  1236. " cursor = 'move';\n",
  1237. " break;\n",
  1238. " }\n",
  1239. " fig.rubberband_canvas.style.cursor = cursor;\n",
  1240. "};\n",
  1241. "\n",
  1242. "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
  1243. " fig.message.textContent = msg['message'];\n",
  1244. "};\n",
  1245. "\n",
  1246. "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
  1247. " // Request the server to send over a new figure.\n",
  1248. " fig.send_draw_message();\n",
  1249. "};\n",
  1250. "\n",
  1251. "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
  1252. " fig.image_mode = msg['mode'];\n",
  1253. "};\n",
  1254. "\n",
  1255. "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
  1256. " for (var key in msg) {\n",
  1257. " if (!(key in fig.buttons)) {\n",
  1258. " continue;\n",
  1259. " }\n",
  1260. " fig.buttons[key].disabled = !msg[key];\n",
  1261. " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
  1262. " }\n",
  1263. "};\n",
  1264. "\n",
  1265. "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
  1266. " if (msg['mode'] === 'PAN') {\n",
  1267. " fig.buttons['Pan'].classList.add('active');\n",
  1268. " fig.buttons['Zoom'].classList.remove('active');\n",
  1269. " } else if (msg['mode'] === 'ZOOM') {\n",
  1270. " fig.buttons['Pan'].classList.remove('active');\n",
  1271. " fig.buttons['Zoom'].classList.add('active');\n",
  1272. " } else {\n",
  1273. " fig.buttons['Pan'].classList.remove('active');\n",
  1274. " fig.buttons['Zoom'].classList.remove('active');\n",
  1275. " }\n",
  1276. "};\n",
  1277. "\n",
  1278. "mpl.figure.prototype.updated_canvas_event = function () {\n",
  1279. " // Called whenever the canvas gets updated.\n",
  1280. " this.send_message('ack', {});\n",
  1281. "};\n",
  1282. "\n",
  1283. "// A function to construct a web socket function for onmessage handling.\n",
  1284. "// Called in the figure constructor.\n",
  1285. "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
  1286. " return function socket_on_message(evt) {\n",
  1287. " if (evt.data instanceof Blob) {\n",
  1288. " /* FIXME: We get \"Resource interpreted as Image but\n",
  1289. " * transferred with MIME type text/plain:\" errors on\n",
  1290. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  1291. " * to be part of the websocket stream */\n",
  1292. " evt.data.type = 'image/png';\n",
  1293. "\n",
  1294. " /* Free the memory for the previous frames */\n",
  1295. " if (fig.imageObj.src) {\n",
  1296. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  1297. " fig.imageObj.src\n",
  1298. " );\n",
  1299. " }\n",
  1300. "\n",
  1301. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  1302. " evt.data\n",
  1303. " );\n",
  1304. " fig.updated_canvas_event();\n",
  1305. " fig.waiting = false;\n",
  1306. " return;\n",
  1307. " } else if (\n",
  1308. " typeof evt.data === 'string' &&\n",
  1309. " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
  1310. " ) {\n",
  1311. " fig.imageObj.src = evt.data;\n",
  1312. " fig.updated_canvas_event();\n",
  1313. " fig.waiting = false;\n",
  1314. " return;\n",
  1315. " }\n",
  1316. "\n",
  1317. " var msg = JSON.parse(evt.data);\n",
  1318. " var msg_type = msg['type'];\n",
  1319. "\n",
  1320. " // Call the \"handle_{type}\" callback, which takes\n",
  1321. " // the figure and JSON message as its only arguments.\n",
  1322. " try {\n",
  1323. " var callback = fig['handle_' + msg_type];\n",
  1324. " } catch (e) {\n",
  1325. " console.log(\n",
  1326. " \"No handler for the '\" + msg_type + \"' message type: \",\n",
  1327. " msg\n",
  1328. " );\n",
  1329. " return;\n",
  1330. " }\n",
  1331. "\n",
  1332. " if (callback) {\n",
  1333. " try {\n",
  1334. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  1335. " callback(fig, msg);\n",
  1336. " } catch (e) {\n",
  1337. " console.log(\n",
  1338. " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
  1339. " e,\n",
  1340. " e.stack,\n",
  1341. " msg\n",
  1342. " );\n",
  1343. " }\n",
  1344. " }\n",
  1345. " };\n",
  1346. "};\n",
  1347. "\n",
  1348. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  1349. "mpl.findpos = function (e) {\n",
  1350. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  1351. " var targ;\n",
  1352. " if (!e) {\n",
  1353. " e = window.event;\n",
  1354. " }\n",
  1355. " if (e.target) {\n",
  1356. " targ = e.target;\n",
  1357. " } else if (e.srcElement) {\n",
  1358. " targ = e.srcElement;\n",
  1359. " }\n",
  1360. " if (targ.nodeType === 3) {\n",
  1361. " // defeat Safari bug\n",
  1362. " targ = targ.parentNode;\n",
  1363. " }\n",
  1364. "\n",
  1365. " // pageX,Y are the mouse positions relative to the document\n",
  1366. " var boundingRect = targ.getBoundingClientRect();\n",
  1367. " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
  1368. " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
  1369. "\n",
  1370. " return { x: x, y: y };\n",
  1371. "};\n",
  1372. "\n",
  1373. "/*\n",
  1374. " * return a copy of an object with only non-object keys\n",
  1375. " * we need this to avoid circular references\n",
  1376. " * http://stackoverflow.com/a/24161582/3208463\n",
  1377. " */\n",
  1378. "function simpleKeys(original) {\n",
  1379. " return Object.keys(original).reduce(function (obj, key) {\n",
  1380. " if (typeof original[key] !== 'object') {\n",
  1381. " obj[key] = original[key];\n",
  1382. " }\n",
  1383. " return obj;\n",
  1384. " }, {});\n",
  1385. "}\n",
  1386. "\n",
  1387. "mpl.figure.prototype.mouse_event = function (event, name) {\n",
  1388. " var canvas_pos = mpl.findpos(event);\n",
  1389. "\n",
  1390. " if (name === 'button_press') {\n",
  1391. " this.canvas.focus();\n",
  1392. " this.canvas_div.focus();\n",
  1393. " }\n",
  1394. "\n",
  1395. " var x = canvas_pos.x * mpl.ratio;\n",
  1396. " var y = canvas_pos.y * mpl.ratio;\n",
  1397. "\n",
  1398. " this.send_message(name, {\n",
  1399. " x: x,\n",
  1400. " y: y,\n",
  1401. " button: event.button,\n",
  1402. " step: event.step,\n",
  1403. " guiEvent: simpleKeys(event),\n",
  1404. " });\n",
  1405. "\n",
  1406. " /* This prevents the web browser from automatically changing to\n",
  1407. " * the text insertion cursor when the button is pressed. We want\n",
  1408. " * to control all of the cursor setting manually through the\n",
  1409. " * 'cursor' event from matplotlib */\n",
  1410. " event.preventDefault();\n",
  1411. " return false;\n",
  1412. "};\n",
  1413. "\n",
  1414. "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
  1415. " // Handle any extra behaviour associated with a key event\n",
  1416. "};\n",
  1417. "\n",
  1418. "mpl.figure.prototype.key_event = function (event, name) {\n",
  1419. " // Prevent repeat events\n",
  1420. " if (name === 'key_press') {\n",
  1421. " if (event.which === this._key) {\n",
  1422. " return;\n",
  1423. " } else {\n",
  1424. " this._key = event.which;\n",
  1425. " }\n",
  1426. " }\n",
  1427. " if (name === 'key_release') {\n",
  1428. " this._key = null;\n",
  1429. " }\n",
  1430. "\n",
  1431. " var value = '';\n",
  1432. " if (event.ctrlKey && event.which !== 17) {\n",
  1433. " value += 'ctrl+';\n",
  1434. " }\n",
  1435. " if (event.altKey && event.which !== 18) {\n",
  1436. " value += 'alt+';\n",
  1437. " }\n",
  1438. " if (event.shiftKey && event.which !== 16) {\n",
  1439. " value += 'shift+';\n",
  1440. " }\n",
  1441. "\n",
  1442. " value += 'k';\n",
  1443. " value += event.which.toString();\n",
  1444. "\n",
  1445. " this._key_event_extra(event, name);\n",
  1446. "\n",
  1447. " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
  1448. " return false;\n",
  1449. "};\n",
  1450. "\n",
  1451. "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
  1452. " if (name === 'download') {\n",
  1453. " this.handle_save(this, null);\n",
  1454. " } else {\n",
  1455. " this.send_message('toolbar_button', { name: name });\n",
  1456. " }\n",
  1457. "};\n",
  1458. "\n",
  1459. "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
  1460. " this.message.textContent = tooltip;\n",
  1461. "};\n",
  1462. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  1463. "\n",
  1464. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  1465. "\n",
  1466. "mpl.default_extension = \"png\";/* global mpl */\n",
  1467. "\n",
  1468. "var comm_websocket_adapter = function (comm) {\n",
  1469. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  1470. " // object with the appropriate methods. Currently this is a non binary\n",
  1471. " // socket, so there is still some room for performance tuning.\n",
  1472. " var ws = {};\n",
  1473. "\n",
  1474. " ws.close = function () {\n",
  1475. " comm.close();\n",
  1476. " };\n",
  1477. " ws.send = function (m) {\n",
  1478. " //console.log('sending', m);\n",
  1479. " comm.send(m);\n",
  1480. " };\n",
  1481. " // Register the callback with on_msg.\n",
  1482. " comm.on_msg(function (msg) {\n",
  1483. " //console.log('receiving', msg['content']['data'], msg);\n",
  1484. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  1485. " ws.onmessage(msg['content']['data']);\n",
  1486. " });\n",
  1487. " return ws;\n",
  1488. "};\n",
  1489. "\n",
  1490. "mpl.mpl_figure_comm = function (comm, msg) {\n",
  1491. " // This is the function which gets called when the mpl process\n",
  1492. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  1493. "\n",
  1494. " var id = msg.content.data.id;\n",
  1495. " // Get hold of the div created by the display call when the Comm\n",
  1496. " // socket was opened in Python.\n",
  1497. " var element = document.getElementById(id);\n",
  1498. " var ws_proxy = comm_websocket_adapter(comm);\n",
  1499. "\n",
  1500. " function ondownload(figure, _format) {\n",
  1501. " window.open(figure.canvas.toDataURL());\n",
  1502. " }\n",
  1503. "\n",
  1504. " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
  1505. "\n",
  1506. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  1507. " // web socket which is closed, not our websocket->open comm proxy.\n",
  1508. " ws_proxy.onopen();\n",
  1509. "\n",
  1510. " fig.parent_element = element;\n",
  1511. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  1512. " if (!fig.cell_info) {\n",
  1513. " console.error('Failed to find cell for figure', id, fig);\n",
  1514. " return;\n",
  1515. " }\n",
  1516. "};\n",
  1517. "\n",
  1518. "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
  1519. " var width = fig.canvas.width / mpl.ratio;\n",
  1520. " fig.root.removeEventListener('remove', this._remove_fig_handler);\n",
  1521. "\n",
  1522. " // Update the output cell to use the data from the current canvas.\n",
  1523. " fig.push_to_output();\n",
  1524. " var dataURL = fig.canvas.toDataURL();\n",
  1525. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  1526. " // the notebook keyboard shortcuts fail.\n",
  1527. " IPython.keyboard_manager.enable();\n",
  1528. " fig.parent_element.innerHTML =\n",
  1529. " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  1530. " fig.close_ws(fig, msg);\n",
  1531. "};\n",
  1532. "\n",
  1533. "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
  1534. " fig.send_message('closing', msg);\n",
  1535. " // fig.ws.close()\n",
  1536. "};\n",
  1537. "\n",
  1538. "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
  1539. " // Turn the data on the canvas into data in the output cell.\n",
  1540. " var width = this.canvas.width / mpl.ratio;\n",
  1541. " var dataURL = this.canvas.toDataURL();\n",
  1542. " this.cell_info[1]['text/html'] =\n",
  1543. " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  1544. "};\n",
  1545. "\n",
  1546. "mpl.figure.prototype.updated_canvas_event = function () {\n",
  1547. " // Tell IPython that the notebook contents must change.\n",
  1548. " IPython.notebook.set_dirty(true);\n",
  1549. " this.send_message('ack', {});\n",
  1550. " var fig = this;\n",
  1551. " // Wait a second, then push the new image to the DOM so\n",
  1552. " // that it is saved nicely (might be nice to debounce this).\n",
  1553. " setTimeout(function () {\n",
  1554. " fig.push_to_output();\n",
  1555. " }, 1000);\n",
  1556. "};\n",
  1557. "\n",
  1558. "mpl.figure.prototype._init_toolbar = function () {\n",
  1559. " var fig = this;\n",
  1560. "\n",
  1561. " var toolbar = document.createElement('div');\n",
  1562. " toolbar.classList = 'btn-toolbar';\n",
  1563. " this.root.appendChild(toolbar);\n",
  1564. "\n",
  1565. " function on_click_closure(name) {\n",
  1566. " return function (_event) {\n",
  1567. " return fig.toolbar_button_onclick(name);\n",
  1568. " };\n",
  1569. " }\n",
  1570. "\n",
  1571. " function on_mouseover_closure(tooltip) {\n",
  1572. " return function (event) {\n",
  1573. " if (!event.currentTarget.disabled) {\n",
  1574. " return fig.toolbar_button_onmouseover(tooltip);\n",
  1575. " }\n",
  1576. " };\n",
  1577. " }\n",
  1578. "\n",
  1579. " fig.buttons = {};\n",
  1580. " var buttonGroup = document.createElement('div');\n",
  1581. " buttonGroup.classList = 'btn-group';\n",
  1582. " var button;\n",
  1583. " for (var toolbar_ind in mpl.toolbar_items) {\n",
  1584. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  1585. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  1586. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  1587. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  1588. "\n",
  1589. " if (!name) {\n",
  1590. " /* Instead of a spacer, we start a new button group. */\n",
  1591. " if (buttonGroup.hasChildNodes()) {\n",
  1592. " toolbar.appendChild(buttonGroup);\n",
  1593. " }\n",
  1594. " buttonGroup = document.createElement('div');\n",
  1595. " buttonGroup.classList = 'btn-group';\n",
  1596. " continue;\n",
  1597. " }\n",
  1598. "\n",
  1599. " button = fig.buttons[name] = document.createElement('button');\n",
  1600. " button.classList = 'btn btn-default';\n",
  1601. " button.href = '#';\n",
  1602. " button.title = name;\n",
  1603. " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
  1604. " button.addEventListener('click', on_click_closure(method_name));\n",
  1605. " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
  1606. " buttonGroup.appendChild(button);\n",
  1607. " }\n",
  1608. "\n",
  1609. " if (buttonGroup.hasChildNodes()) {\n",
  1610. " toolbar.appendChild(buttonGroup);\n",
  1611. " }\n",
  1612. "\n",
  1613. " // Add the status bar.\n",
  1614. " var status_bar = document.createElement('span');\n",
  1615. " status_bar.classList = 'mpl-message pull-right';\n",
  1616. " toolbar.appendChild(status_bar);\n",
  1617. " this.message = status_bar;\n",
  1618. "\n",
  1619. " // Add the close button to the window.\n",
  1620. " var buttongrp = document.createElement('div');\n",
  1621. " buttongrp.classList = 'btn-group inline pull-right';\n",
  1622. " button = document.createElement('button');\n",
  1623. " button.classList = 'btn btn-mini btn-primary';\n",
  1624. " button.href = '#';\n",
  1625. " button.title = 'Stop Interaction';\n",
  1626. " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
  1627. " button.addEventListener('click', function (_evt) {\n",
  1628. " fig.handle_close(fig, {});\n",
  1629. " });\n",
  1630. " button.addEventListener(\n",
  1631. " 'mouseover',\n",
  1632. " on_mouseover_closure('Stop Interaction')\n",
  1633. " );\n",
  1634. " buttongrp.appendChild(button);\n",
  1635. " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
  1636. " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
  1637. "};\n",
  1638. "\n",
  1639. "mpl.figure.prototype._remove_fig_handler = function () {\n",
  1640. " this.close_ws(this, {});\n",
  1641. "};\n",
  1642. "\n",
  1643. "mpl.figure.prototype._root_extra_style = function (el) {\n",
  1644. " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
  1645. " el.addEventListener('remove', this._remove_fig_handler);\n",
  1646. "};\n",
  1647. "\n",
  1648. "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
  1649. " // this is important to make the div 'focusable\n",
  1650. " el.setAttribute('tabindex', 0);\n",
  1651. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  1652. " // off when our div gets focus\n",
  1653. "\n",
  1654. " // location in version 3\n",
  1655. " if (IPython.notebook.keyboard_manager) {\n",
  1656. " IPython.notebook.keyboard_manager.register_events(el);\n",
  1657. " } else {\n",
  1658. " // location in version 2\n",
  1659. " IPython.keyboard_manager.register_events(el);\n",
  1660. " }\n",
  1661. "};\n",
  1662. "\n",
  1663. "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
  1664. " var manager = IPython.notebook.keyboard_manager;\n",
  1665. " if (!manager) {\n",
  1666. " manager = IPython.keyboard_manager;\n",
  1667. " }\n",
  1668. "\n",
  1669. " // Check for shift+enter\n",
  1670. " if (event.shiftKey && event.which === 13) {\n",
  1671. " this.canvas_div.blur();\n",
  1672. " // select the cell after this one\n",
  1673. " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
  1674. " IPython.notebook.select(index + 1);\n",
  1675. " }\n",
  1676. "};\n",
  1677. "\n",
  1678. "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
  1679. " fig.ondownload(fig, null);\n",
  1680. "};\n",
  1681. "\n",
  1682. "mpl.find_output_cell = function (html_output) {\n",
  1683. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  1684. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  1685. " // IPython event is triggered only after the cells have been serialised, which for\n",
  1686. " // our purposes (turning an active figure into a static one), is too late.\n",
  1687. " var cells = IPython.notebook.get_cells();\n",
  1688. " var ncells = cells.length;\n",
  1689. " for (var i = 0; i < ncells; i++) {\n",
  1690. " var cell = cells[i];\n",
  1691. " if (cell.cell_type === 'code') {\n",
  1692. " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
  1693. " var data = cell.output_area.outputs[j];\n",
  1694. " if (data.data) {\n",
  1695. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  1696. " data = data.data;\n",
  1697. " }\n",
  1698. " if (data['text/html'] === html_output) {\n",
  1699. " return [cell, data, j];\n",
  1700. " }\n",
  1701. " }\n",
  1702. " }\n",
  1703. " }\n",
  1704. "};\n",
  1705. "\n",
  1706. "// Register the function which deals with the matplotlib target/channel.\n",
  1707. "// The kernel may be null if the page has been refreshed.\n",
  1708. "if (IPython.notebook.kernel !== null) {\n",
  1709. " IPython.notebook.kernel.comm_manager.register_target(\n",
  1710. " 'matplotlib',\n",
  1711. " mpl.mpl_figure_comm\n",
  1712. " );\n",
  1713. "}\n"
  1714. ],
  1715. "text/plain": [
  1716. "<IPython.core.display.Javascript object>"
  1717. ]
  1718. },
  1719. "metadata": {},
  1720. "output_type": "display_data"
  1721. },
  1722. {
  1723. "data": {
  1724. "text/html": [
  1725. "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8AAAAKACAYAAABT+RFDAAAgAElEQVR4nOzdf4xc13nf/6dM48ayhSKJC8qklypsOTXSBDaNFlEpOEgasWKs2IhsCWYsJ+gXICOVRrJJJYBktVwuTVLc0CGphhEhk4W0XDaiI9GSqB9rs/QwjVOIslnSaeUWtvtHG9uyC1tO3EZuYkXR+f4xd7TDy7kz955znvPj3vcLuBA8w9m9c+fO+n7u85xzRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvn1fRF4WkW+wsbGxsbGxsbGxsUXfXpb+NToABS+vWLHCrF69mo2NjY2NjY2NjY0t8rZixQoj/RAMQME3Vq9ebQAAAADEt3r1aiP9SjAABQRgAAAAIBEEYEAXARgAAABIBAEY0EUABgAAABJBAAZ0EYABAACARBCAAV0EYAAAACARBGBAFwEYAAAASAQBGKm4XUQWReS/iMi3ReRvROT/iMgXRGS7iLxxxGvmRMRM2N4x5ndeJyIL0v8C/KD474KIvNXtrVyGAAwAAAAkggCMVPwnEXlVRP6biHxGRB4WkZ6I/D/pB9n/ISKrSq+ZK577U+kH11Hbmyt+3w0i8v3i9V8SkU8W/zUi8pKIXO/4fgYIwAAAAEAiCMBIxc+IyI+NePzHReRPpB9MT5aemysen2v4u64SkReK195beu7e4vGvicjrG/7cUQjAAAAAQCIIwMjBe6QfSr9benxO7ALwluJ1XxGRFaXnVhSPGxG5o+HPHYUADAAAACSCAIwc/DPpB9Jvlh6fE7sAfLZ43a6K5z9WPH+m4c8dhQAMAAAAJIIAjNRdLf0gakTkgdJzc8XjT4rIvIgcFZGPi8iHi9dVebF43fsqnn9/8fy3bXd6CAEYAAAASAQBGKn5F9KfvGpR+sH3/0o/jH5aRP5+6d/OSfXsz98TkV8b8fOvHvo376zYh7VD/+YNtm+kQAAGAABAsuZnp83cgXvMzOGdZu7APWZ+djr2LqkiACM1vyVXhtk/EJGVI/7tr0p/iaR3iciPFtsNIvLU0GtvL71m1dBz11Xsw9uH/k3VLNLDvjFme4UADAAAgNTs3rfN3Hr6AXNt71mz8twXX9uu7T1rbj39gNm9b1vsXVRBAEaqflhE3iYi/1pE/lz6E2D9bIPX/54stzG/buhxAjAAAAA67c6HD5hrehcvC77l7ZreRXPnwwdi76p3BGDk4Gekv0Zwk6WJfkxEXpF+iH3P0OO0QAMAAKCz7nz4wNjgW97aFoIJwMjFl+TKMDvJN4vX/Erp8e9KvUmwvtNwH0chAAMAACAJu/dtm1j5HVUJblM7NAEYufi89EPpB2v++x8Ske8Xr/ml0nMsgwQAAIDOufX0A43C72C77fQDsXfdGwIwcvAmEflr6YfSn675mluKf/+qiFxTem5L8dxXRGRF6bkVxeNGRO6w3N9hBGAAAABENz87fcWEV3W3a3vPtmZ2aAIwUvCT0p+t+UdGPPcTIvJH0g+k54ceXyMiH6l4zS/LcpvziRHPXyUiLxTP7y09t7d4/OtSf7zxOARgAACABrq2LE8ocwfusQq/g23XgXtivwUvCMBIwc9JP3S+JCJ/IiInReRTInJBRP62eO6/Sz/0DryrePwvReRzxWueEJGvyvIEVudE5I0Vv/MGWW6Rfr54/fND+3G9p/dGAAYAAKihq8vyhDJzeKdTAN5xeGfst+AFARgp+Aci8m9E5NMi8j+lH0B/ICLfEpH/ICJ3isjfK73mx0VkXkR6IvJnxWtelv7EV09Jf+Krcntz2XUiclz61eCXi/8el/7yS74QgAEAACbo8rI8oVAB7iMAA7oIwAAAAGN0fVmeUBgD3EcABnQRgAEAACqwLE9YzAJNAAa0EYABAAAqEMjC4oYDARjQRgAGAADJijnjMi25cXS95ZwADOgiAAMAgOSkMOMykzLF0+VJxwjAgC4CMAAASEoq4YdleeLavW+bua3iJshtLV52igAM6CIAAwCAZKTU/koFOA3zs9Nm14F7zI7DO82uwG3wMRCAAV0EYAAAkITUJkBiDDBiIAADugjAAAAgCSnOuJziPqHdCMCALgIwAACWYs5Q3DapVltTq0qj/QjAgC4CMAAADaUwQ3HbpDzeNqVxyWg/AjCgiwAMAEADqcxQ3Dapz7jM545QCMCALgIwAAA1UQnUk3IFeKCry/IgLAIwoIsADABADYwF1ZXqGOCqfe3SsjwIiwAM6CIAAwBQA7MB6+MYAwRgQBsBGACACXKqTuaMKjtAAAa0EYABAJggh/GpbcE4a3QdARjQRQAGAGCC1GcobhtmXEaXEYABXQRgAAAmoAIcHjMuo6sIwIAuAjAAABMwBjgeZlxG1xCAAV0EYAAAamCGYgAhEIABXQRgAABqYIZiACEQgAFdBGAAAGpihmIA2gjAgC4CMAAADTBDMQBNBGBAFwEYAICGmKG4vvnZaTN34B4zc3inmWMSK2AiAjCgiwAMAIAlZiiutnvfNnNrxU2CW7lJAFQiAAO6CMAAAMAr2sQBewRgQBcBGAAAeMNEYYAbAjCgiwAMAAC8YKkowB0BGNBFAAYAXIZJi2Dr1tMPNAq/g+220w/E3nUgGQRgQBcBGABgjGHSIriZn52+4typu13be5YbLUCBAAzoIgADAJi0CM7mDtxjFX4H264D98R+C0ASCMCALgIwAHQckxbBh5nDO50C8I7DO2O/BSAJBGBAFwEYADqMSYvgCxVgwA8CMKCLAAwAHcakRfCFMcCAHwRgQBcBGAA6isAC37ihArgjAAO6CMAA0FG0rMI3WuoBdwRgQBcBGAA6ikmLoIFJ1QA3BGBAFwEYgKr52Wkzd+AeM3N4p5k7cA9tswmhAgwtLKsF2CMAA7oIwABU7N63zdx6+oErxphe23vW3Hr6AVoeHfm4sRB6DDA3Q/xK/Xju3rfN3FbxN+A2/gYAlQjAgC4CMADvqP7o8X1jIcSkRdwM8Su34zk/O212HbjH7Di80+xKMKgDqSEAA7oIwAC8YvyfHo0bC9qTFnEzxC+OJ9B+BGBAFwEYgDfMAKtH88aC1s/mZohfHM+0pd6SjnwQgAFdBGAA3rAGqI4QNxZ8Vxa5GeIXxzNdubWkI30EYEAXARiAF6EnVOqSUDcWfE5axM0QvzieaaIlHRoIwIAuAjAAL1hSR0eMGwuukxZxM8TdcDvtzH0zZg3HMzm0pEMLARjQRQAG4MXM4Z1OAXjH4Z2x30KScryxkOM+p6KqnZbjmRZa0qGJAAzoIgAD8ILQoyPHGws57nMK6rTTcjzTQEs6NBGAAV0EYABe0PaqI8cbCznuc2xN22k5nvHwtw7aCMCALgIwAG+oiviX48V2jvsck007LcczHm7wQBsBGNBFAAbgTZfHxWmuAZrjjYUc9zkW22PF8YyDFn9oIwADugjAALzq2syoIdYAzfHGQo77HINLtZzjGQcVYGgjAAO6CMAAvOvK2pgh32eONxbWLy022uf1S4uxdzk41zCV+jnQRrT4QxsBGKm4XUQWReS/iMi3ReRvROT/iMgXRGS7iLxxzGtvFJElEXlRRP5KRL4sInsnvEZE5DoRWZD+F+AHxX8XROStdm9hJAIwABW7920zt1VURm/zVBmNKUYgzenGAhXgelzbaVM+B9qMFn9oIgAjFf9JRF4Vkf8mIp8RkYdFpCci/09EjIj8DxFZNeJ1v108/6qI/LGIPCIi3yoe+7KIvKni990gIt8v/t2XROSTxX+NiLwkItd7eE8iBGAAyuZnp82uA/eYHYd3ml2ex8bGEjPc5XJjgYBQj88KcGrnQJtxgweaCMBIxc+IyI+NePzHReRPpB9MT5aeWyv94PuKiPzi0ONXichni9ecGvEzrxKRF4rn7y09d2/x+NdE5PWN3sFoBGAAaCiFcJfyjQVaROtzOVZres+aHYdmkjwHuiDHYQnIAwEYOXiP9EPpd0uPP1I8fmzEa64Vkb8tnn9H6bktxeNfEZEVpedWFI8bEbnDaa/7CMAA0ADhbjImCWomhRsqsJPTsATkgwCMHPwz6QfSbw499jpZbmH++YrXfa54fnvp8bPF47sqXvex4vkzlvs7jAAMIEuayw6NQ7ibjGVimqGdNm+5DEtAPgjASN3V0g+iRkQeGHr8p4rHTPFvRjlYPP9I6fEXi8ffV/G69xfPf9tuly9DAAaQlRDLDo3jGu62nPid4KE9NG4SNEc7bf5SHpaAvBCAkZp/If2ZmBelH3z/r/TD6KdF5O8P/bv3FY//xZifNZgg68LQY1fLcnB+Z8Xr1g79mzc0fQMlBGAA2Uih3dD3pEUhQntotInbSeH8BhAfARip+S1ZDp+D7Q9EZGXp3324eG7cybtZlsf6Dqwa+rnXVbzu7UP/5s019vkbY7ZXCMAAcpBKhcwl3HUp1OQ2rjVWS30Z7bQACMBI1Q+LyNtE5F+LyJ9LfwKsnx16ngAMAJ6kNkbSNtx1qa01tc9s3H7GbKmvQjst0F0EYOTgZ6S/3NHw0kS0QAOAJ6lVE23CXaoBUMOgmvrBJ5p9bqFvANByDCBFBGDk4kvSD6TvKf73T0v9SbAeLT3+Xak3CdZ3HPZ3gAAMIGmpjidt2pIdO7SHUFVNXdm7lFzITKWlHgDKCMDIxeelH0o/WPxvlkEC4EXMsYkpjItMeUbhOhXElEK7plrHohSEY41rzaU9G0A3EYCRgzeJyF9LP5T+9NDjjxSPHRvxmmtF5JXi+XeUntsiy2ODV5SeW1E8bkTkDtcdFwIwkKyYYxNTGheZ+pqyVZMWpRraNTStpt56+oGo41pTa6kHgGEEYKTgJ0XkdhH5kRHP/YSI/JH0A+n50nPvlv7Y4FdEZMPQ41eJyGeL15wa8TOvEpEXiuf3lp7bWzz+dVkeb+yCAAwkKObYxNTGRaZcAR42PGnRlsX9SYd2n3KrpqbaUg8AAwRgpODnpB86XxKRPxGRkyLyKelPXvW3xXP/XUTWjHjtYKKrV6UflP9QRL5ZPPZl6VePR7lBlluony9+5/ND+3G987vqIwADiYk5NjHFcZE5BpZcQrsPuVVTu/TZAMgTARgp+Aci8m9E5NMi8j+lH0B/ICLfEpH/ICJ3isjfG/P6G4vXflf6rdJfFZF7pXpyrIHrROS49KvBLxf/PS795Zd8IQADCYlZTUu5kpdbyMoxtNvI8X2m3lIPAARgQBcBGEhIzKCXcshMOZxXSfl4+pJjNTXHfQbQLQRgQBcBGEhEzGpaDpW8FNuzx8kxtDeVYzV1fnbaTPXOJ32uA+g2AjCgiwAMJCJmZSqXqlhqE3RNkltobyqX82bYnQ8fmLgucdWWU3UeQL4IwIAuAjCQiJjVtJwqeVXLDsVaU3aS3EJ7Ezl0DgxrekOi/Bmldm4BaCcCMKCLAAwkggpwM8PLDsVcU7aO3EJ7E7mMdbZpSR/ecrxBASBPBGBAFwEYSARjgNsvp9BeVy5jnW2D+sreJcIvgKAIwIAuAjCQEGaBRo5SH+vscoNnqne+FTcqAOSDAAzoIgADCdGqps3PTpu5A/eYmcM7zVxF5TGXSl4K6hzPrkl5rHOOLf4AuosADOgiAAOJ8VlN271vm7m1YuzprSPGnqZeyYut6fHsmlTHOuc0yRsAEIABXQRgIEE+qmm2PyPlSl5MHJf6UhvrTAUYQE4IwIAuAjDgie+2WJdqmmslN9VKnm91PzMq43G5freY5A22GO6AGAjAgC4CMOBIuy22aTXN51je1Cp5vjT5zBgb3RcjCPj8bjHJG5pguANiIgADugjAgIMU22K50B+v6WfW9eMZKwj4/m618UYG1UkdKf5dR7cQgAFdBGDAUoptsbR6jtf0M9t88mCnj2esIKD13UrxO2uD6qSetpwjyBsBGNBFAAYspFpNYrKfajaf2cqm/75FxzNWEND+buVe3ct9/1OW6t91dA8BGNBFAAYspNoWm/JyL7HbNW0/s1SPp6aYQUD7uzU/O23uOrbXrF9aNFO985f9jNQneaM6qSvVv+voHgIwoIsADDSUcptxihXgFNo1XT6z1I5nCLGCgOZ3q+o8nOo9Z9YvnTB3HduTdMs61UldKf9dR/cQgAFdBGCgoRRD5kBqF3Eu7Zo+K8aun1kqxzOEmOeQ1nerDW3DVCd1pfx3Hd1DAAZ0EYCBhlJuMzYmnQtl23ZNjYqx62eWwvEMJUYQGNzs2NzwnKnz3XJtGx7s27b7d5nffGif2Xb/XPAW/tA3JWIPV4gh9b/r6BYCMKCLAAw0lHqlIIVWSdt9+MipwyqVOucKcIdaT0MGgaqbHb6+Wy7fhcG+lccJD7ap3vlgLfwh/ubMz06bu4/tMeuXTpip3nOXvb4Ls0un/ncd3UIABnQRgIGGUmszHiX2ZDkhJpxqss+un9mmkwejHs+QQgWBOm3Jrt8t2/Nw3ZlHa+9biNZpzZsSg6C/uvf5JN5rLDn8XUd3EIABXQRgwEIqbcbjxBr3GGrCqSZV1vnZaXPT0oLTZ9aGcaR1hAgCTW/Q2Hy3Qk98pvm5xxwbHfq9xpTD33V0AwEY0EUABiyk0GZcdz9vqxhPq7XcS8gJpyZdeLq22JY/sxjHU1PVWE+tIDBYgsh1feU6363QE59pfr81bkq43ITIucV/nFz+rqP9CMCALgIwYCl2m3ET87PTZteBe8yOwzvNLuVJbUJOODWu4uijxbbqMwt5PDVMmmhs65E5r0HA91jfOp9T2yY+83lTwibohXyvMeX0dx3tRQAGdBGAAQddaYttInTlbVR7p2uLbZs/s7rn7PqlRS9BwPdY37qfU9uWvvJZnfQxRr/N4175u47YCMCALgIw4KhtbbGuQo+9LE/w41LdivGZhVxypumNgfVLi05BQGOsb93PKfR5ONg0ZwP2UZ30eVzqvtccl1Xi7zpiIgADugjAgCe5t8X6FGIW6KqLcNvfvWFpIehnprHe8aTfZ1NB3HpkzioI+GizLW+//gcHGn23Qp6Hg017PVjX6qTPyvik9xr6HNfA33XEQAAGdBGAAXinEX5GbeU2zFyWMonRYuk6hrRpENAIn02rq6HOQ5d9tOFSnfQ5Nnrce6WNGLBHAAZ0EYABqNBqfx0VzgZCrWEb8rj4CAihbwxotB/b3qAIcR667qMtm+qkrwrwpAnoQp/jQJsQgAFdBGAAaupWgW7/1GHnCX5279tmbmw4cVN5025fjbXMSugbAxoTULnMOlz3PFx35lS0fQzF182JqvfKUkKAOwIwoIsADEBV3XZNl6qRr5mGtSvAWuvrTuLa9tr0xoD3JYh6l8ztnzrsdAzqnIcuLdM5hTjX9vRx7zXWOQ60CQEY0EUABhBEnXZNm3GDvlpctdtXY45PbkMFeOU5f+3g485D2/MppzZe17HR49bHzmEMPpA6AjCgiwAMIClNJvjxOcnR8GRPgyVbZu6bMTOHdnhZviXm+OQ2jAFeeS5clbVJR0GuEznZBP1J7zWHMfhADgjAgC4CMIAk1akY+5ppeLDcz6glW8ph0Hb5ltBtyL6OlW1rqtYSRKFaZQc3YqZ650fux1TvfPT1YF3X160b9Ff3vlDrvcY+x4G2IAADugjAALLks8q4fmmxUSXZpuoXuzoWenIirSWIYs20vO3358xvPbjPbL9/Lvp6sK7r6w4H57uO7TUfOP2JK37WVO+8Wb+0aO4+uqf2e419jgNtQQAGdBGAAWRJa5xpk61JCE5hfGTo5Wm0liDqclByWV93XHC+5cmj5q5jexotqVSWwjkOtAEBGNBFAAY6wLVVMkXeZxq22JpWSFOYIdclQGn9vqZbV1tltWdK9/G5p3COA7kjAAO6CMBAi7m2SqYshQpw0wv3VNZIbTLRmObvs926UAEu37TasX+79bkTsvKfyjkO5IwADOgiAAMtFbrSF5rWTMNNt6atm6HbkCcdw0kTjWn8vu33z5nVvc9bHe+p3vlWdDBUqbpptap3wep43fz0Q8EDaUrnOJAjAjCgiwAMtFBXLkC1ZhpuujWtSLb95kQda88+bXWs3332qdi7rkajXdw2OLu2JHOOA/YIwIAuAjDQMlotiCmOI9aaabjpZjMmNXQbckrmZ6crlxeatNlWgFM8f4dpTRhmu/mYlKrr53jK5xvSRgAGdBGAgZbxPQlNVUvmW3rPmZuWFsyO/dsDv8PLpRAcXMakhm5DrrtPmhfvIZfLyWEcfCo3cnye18Nsz/EcQ2QO5xvSRwAGdBGAgRbxvQxJrZbM3iWz7sypqBd2Gq2jLsctV6Eu3l1n8K5bcc+lDTeVVn7b4+xbriEyl/MN6SMAA7oIwEDmhqskv/nQPqcL3uGKT+PKau9S1Au7Qbul7ZhH260ty7eEvHgPUQFOZRz8pCpmKpO52R5n33INkamcb2gHAjCgiwAMZKqqSuKyDSo+Li2ZsS/sZvdvNysDVYPbsnxL6It3350KZSksxVO3iqm9nJftDaEYnQ25hsgUzje0CwEY0EUABjKk1fI7qPi4tGSmcGEXalxwKhfgLmJdvPseqx7qZ9fRpIrp2g4+6Xe89+kHox6LunIOkbHPN7QPARjQRQAGMqMV7gYVHx8tmSlc2G0+edCs7F1SCxZtCL/GxLt415ytXLO6PEnT7+eHHjuico6uPNe/QZNLsMw1RMY+39BOBGBAFwEYyIjmbLGDC0kfLZmpXNjZVr/Gva82Ld8S++Jdo+U15AzTZbZh03ZJqHE/c/hYpd5aHPs8dBHzfEN7EYABXQRgJCnH5S9C0Jotdrji46slM4ULO9tActexPWbH4Z1m5tCM2XFoJqklinxK4eLd96RHoWaYHsX2+7n27FNWryuP7x13gyblyaVSOA9txTzf0F4EYEAXAbhlcg+OqS1/kdLx1Jwtdvii19ekPKlc2KVe/YoplYv3wQzeo773TSvurufvR0/st/quu3w/p3rnG0/cdk3vopndv73R+ro+j7NPqZyHNnIO70gXARjQRQBuidSCo42UKhQpHk+N2WJHHU9fQTulC7uUzq2UpHbxPj873SjQVf0MH+dv0++667Hc+HizscAu56qP4+xTaudhEzm3byNdBGBAFwG4BdpwcZ9SlS7V4+lztthJFR/XVusUL+xSrX7F1NaLd59DBep+131UMVP926Mt9/Mw1wm8kC4CMGL7YRH5BRH5uIhcEJHvicjfiMj/FpEnReTmitfNiYiZsL1jzO+9TkQWpH/y/6D474KIvNX+rYxEAM5cSsHRVkqzlKZ8PF2rJL/14L5GrZIuk22lfGGXWvUrtjZevGtMFjfpu+6ritnVGzU5n4cp/X8Y2oEAjNhulOXA+i0ReVpE/lBEnh96/BMi8ndKr5srnvtT6QfXUdubK37nDSLy/eL1XxKRTxb/NSLykohc7/aWLkMAzlhb/k83lQuf1I9n6CqJ7XJLKZ5jqJb6eW/L93Jhk96z7+9n127U5H4epnzzFPkhACO2fy4ip0TkPSOe+5CIvCL9YPprpefmisfnGv6+q0TkheK195aeu7d4/Gsi8vqGP7cKAThjqQRHFym1vuVwPEPv450PH2g8Oc+oMcWpTCSG0dp68V6npdjn9yiHvyEpy/087GoLO/wjACN1/076ofSzpcfnxC4Abyle9xURWVF6bkXxuBGROxr+3CoE4EylFBxdpDL5SS7H06q1s3fR3HVsr/U+7t63zaw786hZ2bvU6MIupYnEcgzhofe5rRfvVS3FGt/13KuYKcj9POxqCzv8IgAjdR+V5cA6bE7sAvDZ4nW7Kp7/WPH8mYY/twoBOFOpBEdXqSx/kdPxtG3tdA2es/u3mw1LC2aq99zEC7tULmJTCuF1xdznNl+8D1qKtyx+XPW7nnsVMwVtOA+71sIOvwjASN190g+k/7H0+Fzx+JMiMi8iR6U/kdaHReTqMT/vxeJ176t4/v3F89+23eESAnCmUgmOrlIJnrkdT5fWTtfgOenCLpUAkEoIbyKVfW7zxXuI73oqn2Pu2nweAuMQgJGya6Q/K7QRkd8oPTcn1bM/f0+uHDMs0g/Gg3/zzorfuXbo37zBae/7CMCZSiU4ukql9TjH4+na2qlx8Z1KC2jTEH7r6Qeit0Y33edNJw9m19adglDf9TZUMQHEQQBGqv6u9Mf9GhH5ryLyutLzvyoi20XkXSLyo8V2g4g8JcsB9vbSa1YNPXddxe99+9C/qZpFuuwbY7ZXCMB5SiU4+pDCxDE5H8/52Wlz17E9E8foagTP8jjVW04fjf5ZuiyBE6s12m5s96Uk9l2L1hjo0N91qpgAmiIAI1WDya9eFJGfaPja35PlNubh4EwARiMpBEcfUqka5nw8Q+971TjVpiHcJVj4Phbl88tXhbxOkPOxzxr7HkOIMdA5f9cBtB8BGCn6t9IPoH8u/Zbkpn5MlpdPGl5eiRZoNJJKcPQhhXGjuR7PGOsD+1xaZrD5aCN3ObSpduIAACAASURBVBa+z7O6Qc73Pmt+R7SFGjub63cdQDcQgJGaA9IPn38hIv/E4ed8s/g5v1J6/LtSbxKs7zj87mEE4MylEBx9SWHimByPZ8jxy7YzUNfZfEwk5nosfIWeJuey733ONbCF/u7l+F2PIcclxIDcEYCRkv2yPInVP3X4OT8kIt8vftYvlZ5jGSQ0lkJw9CWFiWNyO56hZrB2GVtbZ3OpAA8u0jcrBPSmba82E3BpHdNcWnZjVWRz+66HlOMSYoCLlG72EICRinnxE35FRG4pftar0p9JetgWWV5XeEXpuRXF40ZE7nDchwECcEukEBx9ij1xjMvxDP1/oqEqwJpBzXYMcOVY5Ej7ZjeZld5NhdgTtNVle2699+kHnX932/52+sCNAXRJijd7CMBIwR5ZbnuuE37XiMhHRORHRjz3y7Lc5nxixPNXicgLxfN7S8/tLR7/uoi8vs6O10AAbpnYwbFtmhzPWP8nGmIMsNY41cFmU6nUGos8atO+SbCqdyH6vsfidG71LpnNJw962w/+dtIajm5J9WYPARixDcbcGhG5ICILFdvvDr3mXcW//0sR+ZyInBSRJ0Tkq0M/65yIvLHid94gyy3Szxevf7743y+JyPXub+s1BGDAg9j/J6o9q63WONXBcWl6c0BzLPKorU6buEuQ0wzAPsZWa/JxbhHC/GByMHRJyjd7CMCI7V/Kcmgdt/2vodf8uPRbpnsi8mfSD60vS3/iq6ekP/FVub257DoROS79avDLxX+Pi8jbnN/R5QjAgKMU/k9U+8LVdZyxz+OhPRZ51Faniuoc5JTeU+oVYB/nFiHMD5aHQlekfrOHAAzoIgADDlL6P1HNIK5RAbatiGuORR611W0Tdw1ytz7h/33lMAZ45r4ZL++VEOYm9HJqQEyp3+whAAO6CMCAg9T+T1SrFdt1nGb5Ytl2ciHtscgun5WPych8j2vOIRTOHNrh5b0SwtyEXE4NiCmHmz0EYEAXARiwlOr/iWrNamsb9j9w+qi3yYU0xyKP2ppU632dD1WfX/lGgs99j8lnez0hzF6o5dS0pLSEDdKWw80eAjCgiwAMWEr9/0R9z2qbQru360X6T5490+jfN62Uu3YEDF/EzxzaYWYOzbz2+W0+eVB132PxeVMjdgjLWep/z6qkuIQN0pbDzR4CMKCLAAxYyuH/RH2LPeFXqAqw7fhk25sEW4/M1bqIjz3buAafbe1UgO2l2tEyThu/D9CXw80eAjCgiwAMWMrh/0Q1aF50jmpjvKwqet+MWaM8BnjdmUedqkZNbxKsX1psdDy1Wtxj8jGxGWOA3aU2p8E4sW/GIV853OwhAAO6CMCApRz+T1SL7xBW1ca4qnfhijVyNdfMHYRN1xBZ9ybB+qVF64t43y3uMflY2iqHCb9Sl8IwhzbtJ9KV+s0eAjCgiwAMOEj9/0S1+Qhhvmc+9rH5+Hwm3STYemSOi/ghTSt6KR6XNkzElENllb+7+Z9nsaV+E4UADOgiAAMOUv8/0dS5hB7NzWeFvuomQdcv4kexvRkSu721bRMxpTy2tuudN206z2JL+WYPARjQRQAGHKX8f6Ip89H2qrltWdyvVl1J5SI+xUrSoHK+uveFiccihQmOUg6LLlIda87cC+06z2JL9bgSgAFdBGDAEQHYjo+JjwZbeVzwtb1nzfqlE15+tkZ1JfZFfA6VpPnZaXP30T1m/dKimeqdTyqEDXThu5/aWHNm32/neRZTijd7CMCALgIw4IAWaDs+l75Zee6LZk3vWbNjaM3cQWXT188ffG6+LixjXsSnWvEYJ7UQZgzf/Vhi3zwKjfMsnJT+zhCAAV0EYMBBjuM4U2h71VjPt3xh6ztkDzYfwTDWRbxGJSmF8ymGHL/7bZDK8IFQOM+6iQAM6CIAA5ZyuxDz1fbqI/C4VkBHbaOqoj7brAebj+pKjHPHdyUphzZqLbl999umK6GQ86y7CMCALgIwYCmnVjwfba8+A0+ICvBgnzUm2vJxIR36It7n78uxjdqnnL77bdSVtmDOs+4iAAO6CMCApVwmY/HR9uo78PhuTx5X7dBYaslHdSXkRbzPShIT8uTz3W+zLpyHnGfdRQAGdBGAAUs53J33EbK0LjR9tidPqorari+r/fmFuoj3da52pfI2SQ7f/S5oeycC51l3EYABXQRgwFIO47Nc2141A4+v9uQmv2/UUhe2m6/qSoiLeF+VpK6MvZwkh+9+V6S4hI0vnGfdRQAGdBGAAQcpBwIfF0/a789He3I5GE6apGuw1MWWE7/j9HuHl1tynQFZ+yLeRyWJi/HLpfzd76KUlrDxifOsmwjAgC4CMOAg5ZZQ19Cz49BMkMBj255croo2naTLJdBN9c6bW04f9T4DstZFvI/wSjvm5VL+7qM9OM+6iQAM6CIAA45SnYzFte11y+LHgwWeqgroqt4Fs6p34YpAVq6K2rYRW49D7l1q/Ltic60kMSHPlVL97qNdOM+6hwAM6CIAAx6kOBmLa8Xuoyf2Bw88oyqgk6qiLheHWsskpXgh6lpJogI8WorffbQP51m3EIABXQRgwJPUJmNxbXuduW8m+cATY5brpr9rx/7tXsYJ++Bys4AxwNVS++6jnTjPuoMADOgiAAOepTQZi0vbaw6Bx9cEMbXGIU9oe67aRrVwu4wTduVSSWJCnvFS+u6jvTjP2o8ADOgiAAMt5lohTTnw+A7o46orHzh91Ez1zlv9rqYhMwSbStL87LS569hes5IJeQBAFQEY0EUABlou9BjZUIFHq0V7VHXFdfxr3ePdhI8lmOpUkqpm19Z+f1qqjpuvJa0AwBUBGNBFAAY6wKXtNbUZSAeB7C2955yCZ5NJulxnQPZ5w6Dpck8ubJeoGnc+xVJ13KZ6583as09fUeGP3aoOoLsIwIAuAjCgKJWq0qB9df3S4sgL/UkTqKQyA6lLICtvTSbp0qwArzxXv2U85OdgOzlYihPytCnIA2g/AjCgiwAMKAhZpbPZj6nec2b90glz17E9tUN57BlIfc7W3HSSLpfxxr72J2Ql3mp5qN6lRudTKL7OG0IwgFAIwIAuAjDgWU7V0sF+NKlUx5iB1Pd6vTaTdNlOCFZ3G1eRDj0WO+XJzwbqnLM+zxsm8wIQCgEY0EUABjxKZbxs0/1Y3fvCZf87tfGPPsOnbZDxHcLL27gxySEDaerLXzXprvB906IryzkBiIsADOgiAAOe+KzSuYwd9l31it366bv92OX9+GzDLm/jZqUOGUhdxzs3GVvdVNOuBt9t66HWtwbQbQRgQBcBGPDER5XOx9hhjVbdmCHY1wRUPieH8l0JHhesQgdS1xmvm8yuPU75JtCmkwcb7cfGx+/3/j2wOZ4A0BQBGNBFAI4slVmC2yLW8fRRpfMxdlhrsqaY4x9dA9lbes95n6SrakKwVb0LVvs4rrU2dCCNXQGuXHe4d6nZvii1q/sK+ABQhQAM6CIAR5LKLMFtEft4uoaGjY8fafTvq0Kw5nI9scY/ur6nHYdm1PatPCHY7P7t3ierCh1IY44B1qiu+96oAAPQRgAGdBGAI0hlluC2SOF4ulbpmlarqkKT834ohhtbqU/KVOZ7IrQY7z/GLNAq46ubVo0TPJ8AdA8BGNBFAA4slVmC2yKV46lZeW0SNrT3I1b1yzaQbXhmIUpg8X1TJnQgDb3skvYM25rfOQDwjQAM6CIABxT6orLtUjqe87PTZqp33u7C2rJKNaoapTUGeLDFGv/oEpBiDSuoGid8be/ZxmOSY5zrIW8uqa6x7KkKzN9iAKEQgAFdBOCAYrQVtllqx3Pt2af1LuIrtlEVWc0wEXP8o2uLbKxhBeVxwrYV6RjdDiGGF2jftNn4WLPx9ZrHEwDqIAADugjAgeQ2jjF1qR1PpwqwwzaqIqvVThriPJw0i7ePSZJyDjIxxrv7rGSPotm232SG9VDHEwAmIQADugjAgcReWqRtfB9P1+WTYowBHndeaEwopNmJ0GQW76pA1iTQ5NzKqh1Iq/iqZJdpTtxWXmN71HGb6p037z771BU3sLSPJwBUIQADugjAgYRey7PtfB1PX8snaV7EV22TKrI+l5TRDI22Vc352WmzYem4czDKlVYgDU3r5lHVOVt13NpyPAHkjwAM6CIAB0IF2C8fx9NnO2kqs0CXVVW9Vvc+3+h3abWAuoxrTa0NvgnXjoM20RoDTNsygFwRgAFdBOBAcr5YT5Hr8dx88qDXi2mX/ZnqnVef4XdUdSv2+smuMxvneFPJV8dB2/icuI0xuwByRwAGdBGAA0pt1uKU1amQ2R7P9z79oErgdPl8m1ZCbz39gJfKYazxpMa4fx9yG1YQ+4ZDyqwmbistb8SYXQBtQQAGdBGAA0pp3dpUNZ0MyeZ43vzMQ07Ba9y+u3y+tcbsjrjo91E5DD3+0UdHRE4V4BhLGOWm6THafPIgY3YBtBIBGNBFAA6MC+FqNhWypsdz08mDqq3orp9v5QzHpeA76bikzkd4zWVYATe+6qNKDgAEYEAbATgCLvKu5BIcmxzPEFVDH5/voCJ76xPN2oRzOWd8tS/nMKwgh31MScy2fABIAQEY0EUAjoSLvGU+KmR1j2eocaM+Pt82Vw593YhI/RjlUqVOEcsSAegqAjCgiwAcGRd5fitkk45n6HGjLp9vmyuHPoNhysMKchqnDABIAwEY0EUARlShK2S5VORC7GfstWh9BvxUhxWkPlN17HMAAHAlAjCgiwCMqGJUyHKorGoel1TWovXZvjw/O23uPrbHrF86YaZ6z13xvmIMK9i9b5vZsHQ8+Pldd99SOAcAAFciAAO6CMCIKkaFLPVxo8bYh/RJxyW1SqmPWbNHBbmp3nlz49KiufvonihVzVpLWk3YtDoOUjsHAACXIwAjth8WkV8QkY+LyAUR+Z6I/I2I/G8ReVJEbp7w+htFZElEXhSRvxKRL4vIXhF544TXXSciC9I/+X9Q/HdBRN7a/C2MRQCGE9cWStdK545DM1b7bbPmaKhW0ab7NmobVTkMOVa2yXlhG8hSDXI+Pr+V53Q6DlIeLw1dtLsD+SAAI7YbRcQU27dE5GkR+UMReX7o8U+IyN8Z8drfLp5/VUT+WEQeKX6GkX4QflPF77xBRL5f/Lsvicgni/8aEXlJRK53f1uvIQDDiq8WSpexrivPfdGscWjZrFWl61007z77pHnLiLZajVZRm+p0eRtVOQxV9bY9L5rOmp1qkPPx+dkee419y2VWcVSj3R3IDwEYsf1zETklIu8Z8dyHROQV6QfTXys9t1b6wfcVEfnFocevEpHPFq85NeJnXiUiLxTP31t67t7i8a+JyOubvIkxCMBozHflzbXdt+nvG1YVvKZ6581PfPacWdm7pPJ7NY/FqMphiHHPPtc/HjdrdspBzsfn5xrYqyp9OYx9h1+pdkkAGI8AjNT9O+mH0s+WHn+kePzYiNdcKyJ/Wzz/jtJzW4rHvyIiK0rPrSgeNyJyh9NeLyMAoxGNypuvqplLcBgOXhsfPzIx+PoMLMP74FINX3nui2bliKAXYkbpkBXZVIOcl8/v3BfN6t4XrCpz4yp9t5w+aqZ651XPAaQl1S4JAJMRgJG6j8pyYB14nSy3MP98xes+Vzy/vfT42eLxXRWv+1jx/BnL/S0jAKM2zcqbr3GTrpU+2/3wUWF0HQ+98twXzcreJbNj/3avP3fSTMQhK7K+w7zPcZFePr/SMaobSnxMuuVyDiAtKXdJAJiMAIzU3Sf9QPofhx77KVkeH3x1xesOFs8/Unr8xeLx91W87v3F89+2290rEIBRm3blzddFvG2lz7US7VphdJ0Re7Ct6l24rILoe6btcmi85fTRYMfLV5h3HRc5Kjj7+vzK26QQ7OvmUZNzAGlLtUsCQD0EYKTsGunPCm1E5DeGHn9f8dhfjHntYIKsC0OPXS3LwfmdFa9bO/Rv3mC115cjAKOWEG20xiyPyV3j0Epq27LpOn7TtVVUq4KoHRqbtou7HC8fYd5lXOS44HzT0oLXz294X8ZNHqZZ+S2fA0hfqL/VAPQQgJGqvyvLk1n9V+m3PQ98uHh83Im7Wa5snV4ly+H2uorXvX3o37y55r5+Y8z2CgEYdWi30ZbN3DcT9Pf5Gr/pEhR87UN523zyoFnVu2D12lW9C2Z+dlqtxbbp8XI9Dzc+fqTRvx8OwfVmDbe7GTBpq6rM+Zp0a9xGKMpL6L/VAPwjACNVg8mvXhSRnyg9RwBG6/huo03t9/mqvrq2iqoEmt5F82aHALzp5EG1cNX0eLncJJjqnTcrLcdFhmgzHrdVjV/WuGFS3miLzUvov50A/CMAI0X/VvoB9M+l35JcRgs0Wid0VSF4xdnT+E3X6kmoltZGW2KTK9neJFh79imr17336QeT+EzKx8p3y/yojYmR8kMFGMgfARipOSDL4fafVPybn5b6k2A9Wnr8u1JvEqzv1N/lsQjAqCX0uLLQv89HmPDVKhq72hhqsz1etjPc2i4DZNs+7nsrV+a0Jt0a3lgaJz+MAQbyRwBGSvZLP3x+T0T+6Zh/xzJIaKXQM4uG/H0+2kl9tore+fABtfGkqWwux6vpTYIPPdZs7K+XzfPnF7IC3GQJplF8Li+F5pgFGsgbARipmJd64XfgkeLfHxvx3LUi8krx/DtKz22R5bHBK0rPrSgeNyJyR90dn4AAjNpCry0Z+ve5jL/VaBXdemSutSHYx/HafPLgxPbsQZALUS0dtW1YWvAyTjfUGOA1vWfNbTWWgariurwU/GAdYCBvBGCkYI8stz3XCb8iIu8WkVelH3Q3DD1+lSzPHn1qxOuuEpEXiuf3lp7bWzz+dRF5fc39mIQAjEaaVt5cWyib/r6Nj99vXW1yGX+r1Sra1nZol+NVuRxTKXANB7kQ42VHbTsO7zTzs9Nm14F7zI7DO82GpeNWPyfULNAzh2asPxeX5aXgX+i/1QD8IQAjtsGY28GEVQsV2++OeO1goqtXReSPROQPReSbxWNfFpE3VfzOG2S5hfp5ETlZ/NeIyEsicr3LGyohAKOx0Be6TZfgcak2NQ6cAS7ofSxBNNU73/xnaEz81Ltk1i8t6h6L3kWz6eTBy14Xasbk8lZuW/ZdmfM9aZrtDMCErTRxUwLIEwEYsf1LWQ7A47b/VfH6G0Xk09Kf3OqvReSrInKvVE+ONXCdiByXfjX45eK/x0XkbbZvpAIBGJXGjePbvW+bua2i1dGlhbJK1e/TuLCru97rujOPBmkZ7I8Hdgs5t51+oHFI2XzyoFpotP1cXH6HbbXUdhKsqgmFfIdFn10CNjMA026bttB/qwG4IwADugjAuEKTcXzD7Z27Akx2Mz87bTY2nNDIJmxVXTRO9Z4zG5YWzOz+7Qrv7ko+ws1w2GhaEVJZl9giAPkIWbY/4+ZnHrJ6j+MmFPJdmfPRJWA7AzATLuUh9N9qAPYIwIAuAjAuk3rLXOhqU8yLRl/treXPqklFSHNd4iYByFfIsqm+ap1zvitzg59nW7EOPXs6S+4AwGgEYEAXARivyWEcX5eqTa7V10k3KuqGe62JuOoGIN8hy+Ymj+Z3w/dNltn92xu3zNveJHKdXMym5RoA2o4ADOgiAMMYk8c4vi5Vm5wmbepdMh84fdTrZ+OjxdY2AGmELJvqa+rdEeV91Qrsw1yXlxo36RZrCQPoKgIwoIsADGNM+MqqzcVtl6pNMd9r1WdjMxGZSwAa0A5ZTaqvOU0oFCKwa92cYC1hAF1GAAZ0EYARtLLqcnGrGYRSE+O91v1shkPj9EP71IN6ijc+QowN91EB1Q7s87PTZqp33upzmeqd99KeDgBtQwAGdBGAESxguF7cbnz8/uSCkJbQoc/2swlx86RLre/G6FRANQP72rNPW3027z771GU/J4c5CAAgBAIwoIsA3FJNqkchqo2uF7euEzHlFoRChr5Y6+vGmAU6dblVQH1VgHOYgwAAQiEAA7oIwC1jUz3Srja6Xtz6WIontyBkjHvoq3MTJNb6uit7FxutpZxCQNKelCnHCqivvx1ducEBAHUQgAFdBOAWSbWN1fXi1sdyQDlWimxD39Yjc7VvgsRaX7dqf8aJFRBDTMqUQsC34aN7pGst7gAwCQEY0EUAbgnXcHDLk0e9BKEy14vbXdu3OM86nEKlzFbTz3X90mLtmyAx1tcdtz91j0fIFuFQvy/XCqiPCnCKk5wBQEwEYEAXAbgFXKpHg+qWzTi+OhUo14vb6QfnnV6/8bEjgT4FPXc+fMCsnPT59i6a9UuLjY7Nhx474j14uCyVVDdEhlqKKFTF2ceNiFhr5vrY9y7N7s7axgDqIAADugjALWBbPVp35lGnsbV1LvhdL243O05+NWkN2BwuRmtVVnuXJofkUa9ROrY79m9vvD9NW3o1ZzYO2ZLsepNow9LxqGvmulavu1ABZm1jAE0QgAFdBODMuVRgbLcmLZ+xK8BVVcpcLkZdZ7/W3MYFj1xbegdC7r/rTSJf31VbrjcL2j4GOLeZvQHERwAGdBGAM+caMJtsU73zlS2mVdXUmGOAbceppnIx6mP264mbZRV4XPBIPdCMOleHH5s5tMOsCbj/Ib7D2udzDktpxZDjzN4A4iMAA7oIwJnTrB6Vtw+c/sQVv79ONTXWLNCuMxXHvhh1nf1acxsXPFJtaa06V1f1LphVvQvejk3T/Q/RxRFixmiXm0tbj8w1vhmTwizY4+Q6szeA+AjAgC4CcOZCVoDL1a26F7wfOXU4+DrAPtaqjXkxGrS13fNxSXFSI9sZqkPtf4ibHSGqpTYTlNl+NrFvUE3S1qo2AH0EYEAXAThzoccAD6pbTaupa88+1ejfr19avOx9dq3FMuSNjY2PN5sNelLwSK0CHHoctc3+h2h3Dzletu4EZTafTSpDFMZJfRgAgLQRgAFdBOAWCNkqu+PwTruLdQ/tjbYtljlejIZqbR+8P59jo1M63kHGUXva/xBBvRzOY86Ebvt3ZOuRuWD7aCu1m0AA8kIABnQRgFsg5EX+rgP3BAvco6qvNi2WOV6MhqoADx9jn+vr2p4jG55Z8BrCQo+jdu0Y0G7VHrRnV42Hnuo9Z9YvnTB3H9ujHoZz68poIsVhAADyQQAGdBGAWyJE9ch1Vmab3zdupuG6a8DmeDEac2IkH+vrutyU8bUcVejhAb7GjI+7EbHhmQWnfdx14J7aIXt17/Nqy4Kl1CWgIcebbgDSQQAGdBGAW6RuG+u6M6esLspuO/1A0LGpvi4Ec70Y1a5eprY0zqhz1WUfZw7tCHqu+j6eo25EuAbHzScPBv8cRrVZ5/qdrKvtAR+ALgIwoIsA3DJ12lhdZkQOuezSynN+qq/zs9NB13X1RbO1feNjR4K8Bx8tvU3D16C99y2954Kco5MCou9xtrY3Rt779INOn4Xt5zDqb9H6pRPR/y5oa3OLNwBdBGBAFwG4pSa1sdrOqpxbBXhwEW67zqvPi1GbIKTV2h4yQFTdlKm7NWktDrnc0aSx0XXWyLY9njY3sG5+5iGn95vS55B6BdiY/JZeA5AOAjCgiwDcYTYz/4YcV+lafXW9CPc5ptMlCGmEiRgBYn522mxYOm61v3VuRGiPg1/Te9bMHJqpNTba56zaPt7rppMHvXxvU/gccmoRdl2+DUA3EYABXQTghMRYksRm5t+Ys0DX5eMi/M6HDzh/Jr6C0O5928y6M49mHSA0x0WGmAl90vk4OFeafj9cQnDdc8tX50YOn0NqtG+GAGgfAjCgiwCcAK1WySaazPwbax3gulwvwq/pXTQfOXXY+TPRqP5sOnnQrHQMGLEChObER9o3Zcadj1Xf31Dnep0bWD7H7qf6OaTM5xJjANqPAAzoIgBHlmt1oGm4W7+02Ojf277f+dlpc9OS3VIxq3oXzG2nHzC3f+qw82eiOf5vcDH9lt75rAKE1nJUIdryqz5rX+3prjclJt3A8jl2P8XPIRc+lhgD0H4EYEAXATii3MeHNQ3vmmF/UIWzne155bn+GM9NDZeJqdpXzRlgXd5rzHNIqwKsOTHbuPPR51hX7bZ0n+E0tc8BANqGAAzoIgBH0pYZQpu29mm0AnqdJMrDZ6I51tX2vaYQILSOi2tl+c29/3zFLOF1ZniOMTGZy5h0H+3Jmp/D+qVFWoQBwBCAAW0E4EjatkZk09Y+X62A2jPO2nwmWpVOm/eaWoDQOO9dj/fMoZnG56PGWNdxS1PZzhMwHJjvPrbHObRrfg6D406LMICuIwADugjAEWhWCLskxIyzNp+JxlhXu4nHLprZ/dsDfiKTaXQ+hP4+aY11HXfjo+nQgarAvLr3eev9S+1zAIC2IgADugjAEWjOhtsloZZjavqZaHy+beoY0Bj7HvL4aIx1rQqANseqVpt8w1nZU/wcAKCtCMCALgJwBFqz4XZJiBlnbT+TXdu3WAWMQTDZtX2Lt/c6CFYx1pgex/eEaCHH1PtcUmhcAAyx3Nibe/+51nEa9zm4tlmnOLcBAMREAAZ0EYAjoALsznsVzrGVWrMC7Przblo6HnWN6Sq+J0QLNau673OvKgAG6XDoXTSb/+B3zfqlRTNVWlarzkRgo9qsV/W+EORzAIC2IgADugjAETBWzp3vKtzmkwe9fSa+K/waFcfh8BU7gPic+CjEutq+uw9G7UvIDodB9bnJ5+Bj5vUUzj0ASBEBGNBFAI5Ea6xcaq2uWnxV4YYvwm0/k3VnHvW6b74rwLYhLFcaS22V+ajOjguAIT7z4ePS5O+E68zrqc1MDgCpIQADugjAkfges2i7TEquXCtka0ZchLvMKj0cZHxX+ENUA9s4DlNzSR2Xc6VOANSs+o/a6g6rcJ15fePjR1p7Uw4AfCEAA7oIwBH5GrMYou0zRbZVuJ/9zCfNtvvnRlbIbatb5QDps8I/PzttNiwdVw9BzMTbTNNz5dYnFdng7gAAIABJREFUHqgdxENWgFeeqz+xnmvlu403WgDANwIwoIsAHJlreA018U+KfMySO6pCvu7MKecA6aPCX1XV19oYX96c1s2n0LOc16kA+9onbrQAwHgEYEAXATgBtmMWQy79kirX8YjlkOKzfdnl5oSPSYa0ghAupzXmONQ613VvfPiqSnOjBQDGIwADugjACmwnomo6ZlFrIq3c+AyLH3rsiNcAaVMh9BXqbTbWmLbne8yx63hb338PfI5L5kYLAFQjAAO6CMAehZyIiqWULldVhSu3PE/cmv77GgGySYUwVOghmOSh8c0QxY4Qn+OSudECANUIwIAuArAnoSei8r3UTlsMV+FuCjBxVJPjWqdCGKrtddTWxhsjbdDkb4vmnAA+xyW39e8PAPhAAAZ0EYA9iDERlWs7YtsrME4X65ZV4KneebNr+5Y4++xha1trfJs06SLQvBnn4wYNN1oAYDwCMKCLAOwo1kRUVIDHC72MzPDFvW27e6x99nVOQl9VF0F53oEd+7erTMzlo0WfGy0AMB4BGNBFAHYUayKq+dlps6p3wep3r+pdaH0FxnnCHseLfJsKm89JhppubVoeq0smzTswu3+714m5jHGbpI0bLQAwGQEY0EUAdhBzIioC8Hiu1dSNj7vNBm0TLGNUgH2OS0dYoecdaPq7udECAHYIwIAuArADH23Itksm0QI9no+bEz6WV2pS8Qo9BnjdmUepxmUqxrwDZYNxyat7n+dGCwB4RAAGdBGAHbi2rK5fOmG9ZFJbJsGyvQFQx7ozp6yOzQdOf+K1fbrr2F7zgdOfcAqmTdrdQ84CTTtqnmLNO1Blfnba3HVsj1m/dMJM9Z674u+Zy5hjAOgiAjCgiwDsQLNldVLFJPcKsPaaydbjFHuXzFTv/BX79P4nj5m31Kh0jdqatLuHXgeYCYnyE2vegTrqLPUFABiPAAzoIgA7CNGyWhWCY44/dqU9djF0iKyzTVofeLgKvvnkwUY/+xc+/e+tl26KfS6UaXYEtEHO33sXnBcAuoQAjBT8IxH5DRFZEJHnReQVETEiMjPmNXPFvxm3vWPM668rft83ROQHxX8XROStlu+hCgHYkXbL6rjWxZQrQVVCjF0M2UZcd9txeOcVF/Gz+7dXVsHXnTlV+yZB7t0Axix3BKwpHYs1njoCUtYk3LXhs25Cu1MEAFJEAEYK7pPRAbZOAP5T6QfXUdubK157g4h8v3j9l0Tkk8V/jYi8JCLX272NkQjAjkJUG6sCa2pjAScJsb+hJ5Kqu920dPzK/ZpUte1dNOvOPDpxLdfcx4PHnM04Jptwl/tn3URXzwsAIAAjBZtE5OMi8mHpV20XpX4Anmv4u64SkReK195beu7e4vGvicjrG/7cKgRgD1zWxayzjWtdTGE22LpCVKxjLCU0cbNsTx5sm04eHDuuMueqYE7nr0+24S7nz7qJrp4XAGAMARhpWhC9ALyleN1XRGRF6bkVxeNGRO5o+HOrEIA98bFkju2Faw6VklBjF10rZCluk6rguY4L3b1vW/ObA71L2be9uoS7XD/rJnLrbAEA3wjASNGC6AXgs8XrdlU8/7Hi+TMNf24VArBHg3UxR7U0rl9adApBk1oXx/3uFJYhCVW5SrIC7GGbVAXPcTz4zc88ZLXPNz/9ULR9duUj3OX4WTfR9vcHAJMQgJGiBakfgJ8UkXkROSrLbdRXj3ndi8Xr3lfx/PuL57/dZIfHIAArGLUUSKgAmOoyJL7GLk6aMCjVMcCu26TqXW5Vs/nZabOqd8HqWKzqXUjmvG7KR7jL7bNuogsVbgCYhACMFC2I2yzQ3xORXxvxmquH/s07K37u2qF/84bGe34lAnAgXb+wc70BcPfRPbUnDEpxFmgf26SbIDmNm5w5tMPpWOw4NBNt3235/BuQ02fdRFfGOAPAOARgpGhBJgfgXxWR7SLyLhH50WK7QUSekuUAe3vpNauGnruu4ue+fejfVM0iXfaNMdsrBOBwutza53Lxv7r3BbOywRjnFNcB9rHVmcE3h/Hgxhjzrxb3Ox2Ljy7uj7r/o0zqTvAZ7toagLs0yzUAVCEAI0ULMjkAj/N7stzG/LqhxwnALdfm1sU6QlRmBxf62jNzx9jqVrdSGA8+KQxuOeEYgE/8jvp7qKvucka+wl2svyNN1iu2RQUYAAjASNOCuAXgHxORV4qf8Z6hx2mB7oC2Vm7qsKrMNpwlePhCv241dFJ1OYXNpg0+xnjw2mHwvhmn43Hj0mISN4aaVNx9hbvQnSQ26xXb6vpQEQAwhgCMNC2IWwAWEflm8TN+pfT4d6XeJFjfcfjdwwjAEcRsUw1RxRknRGW2PGHQpGpoDtXiHNrgm5zXLpNgaX9HmrzfJvu7+eRB53AXOiDG+FvV5aEiAGAMARhpWhC3APxDIvL94mf8Uuk5lkHKgI8QGbpNNWQVZ5K6F9Wre5/3dqE/qRqqvY6za9BLodo5MOr8t+lseO/TD3o5Ph984oHgN3Ns25Bt3/Mg3IVsEXZdr9j2b2TXh4oAAAEYKVoQtwB8S/H6V0XkmtJzW4rnviIiK0rPrSgeNyJyh+XvLiMAN6ARIkO0qaY4MdKkGwB3H9sT7EJ/0j41bcP2vYX4XOoElqrzf6p33qpVfeuROa/t5yFv5thWKW9++iGncOdjHHHdz9pmP7cemfPyNzLGUJHY3TEAMEAARooWZHwAXiMiHxGRHxnx3C/LcpvziRHPXyUiLxTP7y09t7d4/Osi8vqmO12BAFxTiiGyjtTHHFfdAIg5G+zwPm1YOu4toDXdQpxPdW/qaFTIbzv9gEr7ufZxc21D3nTyoPV30rUCfNPScd2lxCbcCGny2YT6m5tSdwwAGEMARhreLSLPDW3fkeUgOvz4YFbmdxXP/6WIfE5ETorIEyLyVVmewOqciLyx4vfdIMst0s8Xr3+++N8vicj1Ht8bAbiG1ENklZxbCVOYDdYl6LiEhlCzNdcNGOuXFlXe96BV/c6HD6hMRKb1PfRxbtqGO6dzsmY4DXHe1/1stIeK5Hpj0wYVbiAfBGCk4OdkObiO2/5h8e9/XETmRaQnIn8m/dD6svQnvnpK+hNflduby64TkePSrwa/XPz3uIi8zcs7WkYAniDnEJnzZDKuF/q3nD7q/Bm4Bp1J2+Aifsf+7cFna05l4q/BjYrd+7b5r7b3Lpq7ju31fsHvczkjm3CnvZzYxsfvV//cm/6N1BgqkuuNzaaocAP5IQADugjAE+QaIkPNFqtZVXC90Het3LgGnart1tMPBAu6o1gtR6W0Dbeqb7t/TvV3+brg992d0DTcqX9+gc6NmH8jc76x2USXKtxAmxCAAV0E4DFyXpNSu4U4RFXB14W+7cWd7wpwKhea2hVE2/PsNx/aF+R3un4OKfxdSKWC77LF/BuZ643NJrpS4QbaiAAM6CIAm+oqZgrjUG1pTiIVsqrg40LftnLjayxkqDG9Id+Tl613yWw+efC1fdt2/66gv9/l/EwhQNWamMx2BvNAM5/H+BuZwg0MbV2pcANtRQAGdHU6AE+qYrpWpFxmInalFd5jVBV8zEBsGzxsg86GZxaCjumtS3tcs802OEdC75vLBX8qAaNqHPFU77z5x5/9TPTPdtI2+BsZcoKmnG9s1pXCDRoA9gjAgK7OBuB61RO30BXzQkmjyhHzon/3vm3mA6ePWlembCs3qQQdX7TGNbtsg+M1PzvdX1M44O92ueBPqcV0eBzxxseP+BnHG6AKfNexPcEnaIq5xFoIXahwA21HAAZ0dTIAhxg/l8KFhO8qQOyqQqzKTUpBx9XMfTPq577LORJ6fLLr9zS1SYZ8/m3b+NgR1WO/uvf5KMeu7RXgtr8/oAsIwICuzgXgUDPgptBKtvXIXOMqTlX1MnZVYfe+beZGx/VoXSo3qQWdpgYtpr/+739X/dx3OUdizFDtesGvvVZtk/3wdeyG12hWG2fcYPP5vYr9t0xb2yvcQBcQgAFdnQvAISpMKbTA2o6brbrQjFlV8DEG2HUfjEkn6DRRNc49xW3w+YSe4djXBb/GWrVN+PzbNnwDb9J5v/XIXPPvp6cbc6GPVQo3NiehAgzkjwAM6OpUAA41A27sKqBNgJhUvYxVVfAVhnxWbmIHnbp83TgItQ2fIyH3vQ0X/D7/to3rAqk670PctPAZPts2tn9Y2yvcQBcQgAFdnQrA2rPMptACa9UG2btkth6ZG/tzY1QVfLZ0ply50ZgBVyWQTKraeZ40rqry6LPlti0X/D7/ttn+Das7seDq3hes9muN58+qTWP7y9pc4Qa6gAAM6OpUAPYyA27v0hUz1abUAqt14ROjquCrpTNU5aZpkJ20DJft2sV3HdvrZxbg0nbz0w+NbYWd3b9d5RwpVx537N8+Ohh3+ILfx982HzfwJrVL33Vsr9M+3rR03Ot3uW5o3zS0XnUO2lzhBrqAAAzo6lQA9lUl+cDpo0m2wGqH1JBVBZ8tndqVG5sg63tSLe2xvsMXx+NaYUOfI4P9uOvYnk5f8Lv+bdvwzILXY1F1jqQS1IdVdhrU/C6nqs0VbqDtCMCArk4FYF+hKtW2Se025ZBVBR83K0K0pNsEWd8XpiHGyzYJ4jYt+Ld/6rDT56BxXHPi8rfNd2vxOCm0alfZfPLgxM6JFIa5NJH77PVAVxGAAV2dCsDG+GurTXHinBATVYUKGa7vZf3SCfVqjc2x8H0TQXvyoSYXx4MW8A8+Yfcd83ER3uULftu/bR84fTTYPoaYrMtGm2+e5Dh7PdB1BGBAV+cCsK+JlVJcK1GzAjw8vnXj4/erV0pSX8rDNsje/MxDVu9nVIuw5pq5TS6OK9uvIy11M7jgX1PanzUtv+C3PR+meueDtvdqLddkqyvjZXdt32KmH5w3mx8+YKYfnDe7tm+JvUsAKhCAAV2dC8DG+KmapVgB1hgDXBVupnrnzdqzT6lNCPb/ffKQ9Wy/IVrUbS/iV/UueHtPGmtaf3Rxf6Nx7b7brzcsHXf+7Abn7KgAnNs4zqZc/raFqoz7vHHj47ve9hmTNSbbA6CLAAzo6mQANsaYTScPJh2wbPm8mKvbTrrxsSPeJgTbvW+bWXfmlNNFsfaFaaj1pMvb8E0XjX1oel5rtV+7BNUut0APuN6UCHFsfJ47Ljcj275mLt8HIE8EYEBXZwOwMcZrO2oqfLXzxRgTd+fDB5yX7wnRmqi9nnTVNtx2r7EPTc5rzfZr2wvzNo/jbGrQBl7u0EjlO2SMv+4Bl+EoqQ+1cMH3AcgXARjQ1ekA3NaxX64XPjGOi6+KUIiLOC/rSTtebHvfh94ls/XIXO1joNF+7fKZtvW77OqW00etjnmom3y7920zG5aOe/teNBVi4sAY+D4AeSMAA7o6HYCNae9dcpfWt9Bj4rxUE3uXzPVnTgW5gItRAS63W2rsQ92Ka+gW8DoX5m0fx2kjl/be+dnpK8Zrh9rPtlaA+T4AeSMAA7o6H4CNae84KZvlL2JcNPusJob4nFyOke0kWOULU80QOun4xbgBMO7CPJegF1pO4S5WYGvjudPG9wR0DQEY0EUALrR5rcT52Wmz68A9tSaqCn3RPD87bTVOcdKmHYJtL9jf+/SD3loTtdqQJ1VcY7SAj7swzynohZRTe2/Mlt22VUv5PgD5IwADugjAJU3CYhuFvmj+0GNHVAKT9ng2lwv2xuOdK6ramhNRjbu4jzUJWNWFeahzdngt7LkGfxtsX+cqtyAUazhK28bL5nTjA8BoBGBAFwEYlwl50ay1jM5g067QuFyw92e8brYM16gLfq1jOK7iutlhCTGNC3Ptc9Z2HdXY66/m2AobazhKm+aCyO3GB4ArEYABXQRgXCbURXOIZXRCXMTbXrDv3ret8ZJPVVUnX8vJ1LkQ1r5pYXNhrnnO9sN+8883lXkFcmzv1RqOMqkSn8pn5irHGx8ALkcABnQRgHGFEBfNoZbRCVHNsLlg932Mq/bBZStXXJ1vWjhUjSddmGscz3VnTjX6WYNglFI1Mef2Xl/DUZpU4tsyF0SONz4ALCMAA7oIwLiC9kVzyGV0Qo5nq3vBrlmhGd6H6QfnnY5d+eaB602LTScPmpss13yddGHu85ztt6c3D/rX9C6arUfmkgucKQXy0GyrurnPBZHzjQ8ABGBAGwEYI2leNIecRGnjY0cUj5KdUGP0fAZtp5sWvUtm08mDxhjdC3Mf56xri/fas09ZvS7EePU2tPc20eXgbwzvH8gZARjQRQBGJa2L5tDL6AzvX9MZeTVm8A05S6uvVkifod3Xhfmoz8blnPUyLt2yzTvE2Mu2tPfWQQW0r4s3PoA2IAADugjAGEvjojn0MjqD1tQmM/JqzuAbcpZWX0HAd2h3DarjPputR+asztlQ49J9fK4ucm/vrYMxsMu6dOMDaAsCMKCLAIxafF40hxwD/No2oTI3HLa0qyahZ2n1UXHVCO02F+ZNPpsm52yUc7K0sf6qH8yCPFoXbnwAbUEABnQRgI1OmyvGi11tq9rWLy06h0XN929boXIN9aEm7hp3Yd6WcelVG+uv+sE6uAByRwAGdHU6AGu2ufrS1nBuNd7SYRkdrd9hO24wxhjFrUfm+pM0ld9j75JZe/Yps/XI3BWvGT7/NijN4FyH9vHyNi494THAXRFyjD0AaCAAA7o6G4BTnxwkh3A+zCaoN63offCJNKvGLlXZJr/H5Vxser5XnX+hbhCUaVfMfVWAU50FukuoAAPIHQEY0NXJAJz68hCph/NhrkG9yXtNoU111OZSvQvxWTc939cvLbrPhuzxuxNiTKePMcCprgPcNYwBBpA7AjCgq3MBOPXlMVIP5+V99RHeJk2GNLt/u5k7cI/Zdv+cmeo95yWY+d5cqkaas7R6WdrHMgz6Ojd9VPTqdCi4jksfnkQtl+9wWzELNICcEYABXZ0LwClfGKUezodpXOSXJ0PasX/76DbcBDcf4wY1ZmlVn2ys1BKtsbSK65jO9UsnanUo2N4sGBX2c+riaKOc/pYCQBkBGNDVqQCcemtcyuF82Oz+7Wal8sVlnQCR0jZcAU5l4rJQS/tseGZBZWmVwXH8V4v71fa9HEKb3thZd+bRyvOa9VfjohIPIFcEYEBXpwJwypOjpB7OjVke77uqd8FqP+sG9aYXrrG3wfFPbeKyUGOmfZ9/lRNwKW7lEDzx5kvvotl08mCt98P6q/FQiQeQIwIwoKtTATjl5TFSDufG+KnI1glKXseshlg26Vw/2Kd4oe1taZ+A51+syn+5Q4HqbVpcuir4LAHkhgAM6OpUAE45ZGqGc9eWXJ8V2UnH0MeY1cGFrc2MvI1Dc++iuf1Thxu9JlQIDjlrdp2bQ5POw9iV/1EdClRv46rbVVHnbxyfJYBcEIABXZ0KwCm3GWuEcx8tub5nEZ4U1G0/n6neebPt9+euuLC1WQKo0e/uXVIfD20r1Bjglee+aGYOzVTuR53zMNZs1eX9IRSlo24r+rozp5IZdgAAPhCAAV2dCsDGpDvRlO9w7qsl1/cswuMqwFoV+qbH4s6HDzQOtamdTwPqs0AX246KAFz32K87cyrIfrqcnwjHVzcA43sB5IgADOjqXABOeXkMX+Hc1+ynviuIkypsWm3gtQLt0IVyiGpkyInLQlRWy8d+fnbafOixI+q/t3xMG1fwa55DCEfjnCUEA8gJARjQ1bkAbEy6y2P4COc+A77vMaSTqp4aFWCbzzpU1TRUtTHE2NrBexm0O0/1zgc5hivPfdF89MTvvNb6nvI4f9Sj8f1jjV8AOSEAA7o6GYCNSXd5DNdw7rPF2+cswnUuQH23gVtVknoXg4W3kNVGzdmVB8c+1gzOw8cx5XH+mExz3Hro9dIBwBYBGNDV2QBsTLrLY9iGc98X/z4rwHVvJPgM8KEqubZb6Gpj1fnuI1jEnMG5fBxTHeePyTRnLucGB4BcEIABXUkFYNflelx+b2rLY9iEc9/tnz6qMU2r6L5auOdnp82aQDMgu16M79q+xfzmQ/vM5ocPmN98aJ/ZtX2LxRlT3+B837L4cef3cU3vot1yU4qhJuVx/hhPe+1qWtwB5IAADOhKIgD7WK6nrZqEc41JpGyraat6F8ZW0cfd7HBtA9+9b5u5aWkhSiCruw3WKV579ukr1x7uXTJrzz5tth6ZsztpavIRNkKOma46jqOkOs4/llg3F5vSXruaSc4A5IAADOiKHoBTHYubI621hG3G0e7Yv33kPta92WF7XsQah9r0+PzsZz55ZfC94t9dMuuXFv2fKAXX82XjY0eCrjU86vMfd3OMvy353VzUPp+oAAPIAQEY0BU1AFOl8UtrAqCmn9OmkwdHVpuaBpKqNvCp3nmzfmnR3HVsr1PlONb2j89+ptG/1wrBLufLVO+8l1mXXbY6fw9SHecfQq43ALQ6ChgDDCAXBGBAV7QA7HOcXpP2vlxaAW1pTQBUq7Lau2jWnTk1MmysO3PKOtzMz06bu47tMeuXTpip3nNX/Oxbi3ZiX5Xfqd553SrypMrviH+v1Q7ter74HrO57syjKqEtxXH+mnK+uai1djWTnAHIBQEYKfhHIvIbIrIgIs+LyCsiYkRkpsZrbxSRJRF5UUT+SkS+LCJ7ReSNE153XfH7viEiPyj+uyAib22475NEC8A+glqT9r7cWgFtaU4ANK6aVie42O5TvfDdMFROOMdSqya/++xTtT7/pjd4XM8XnxXgwc/tctXWhzZMAub7+5fa+wOAcQjASMF90g+85W1SAP7t4t+9KiJ/LCKPiMi3ise+LCJvqnjdDSLy/eLffUlEPln814jISyJyvf1buUKUAOyjVbdJe1+urYC2tKs/5Wra5pMHVUJfjCDaOHiH2nqXxs4O7XKDx+V88Tlmc9SyXl2q2vrSlmWgfH7/2vK3HUA3EICRgk0i8nER+bCIvENEFmVyAF4r/eD7ioj84tDjV4nIZ4vXnxrxuqtE5IXi+XtLz91bPP41EXl90zdRIUoAdp585/EjakEj5QulJtW9UKFfq11x5bkArcg1Pv+qauSq3oWg+7Xy3BfNbz24T+2zdvkZrmM223TzKTaXGxJres+amUM7khoe4tp1wrkFIEcEYKRoQSYH4EeKf3NsxHPXisjfFs+/o/TcluLxr4jIitJzK4rHjYjc0XSnK0QJwM7jBhVDUYqtcrbVvRCtpDGXwPG9rTvz6BXvb3DTYdv9c2b6wXmz7ffn+lXJ/duDh/Nf/4MrL+R9VvttzxfbmyBTvfO0NHvmsyU9peEhVd0AtMsDaCMCMFK0IOMD8OtkuYX55yv+zeeK57eXHj9bPL6r4nUfK54/U393x8qyAqy9pdQK6KO6p9VKGnMJHI1teJbYOjcdQrdnlyvAWmM9bc6Xpsdi4+NHkqgwto3vScnq/H1JAe3yANqEAIwULcj4APxTsjxO+OqKf3OweP6R0uMvFo+/r+J17y+e/3b93R0ruzHAPic7qhOEYkp9JtfUb2TYbLsO3ON9fLmXbcQY4FuePGr1s7Ru8HRtrH2KNL+TfG4AEAYBGClakPEB+H3F838x5mcMJsi6MPTY1bIcnN9Z8bq1Q//mDbX3uFp2s0CHDEIhDI/rnTm0w8zcN2NmDu80dx/bk+xMroN93pzYTMk+tqbn5Z0PH3itDXOqd15tv4Zngd69b5u55fRR65tBmjd4YrWktn15s7o0uzJSHB4CAG1EAEaKFmR8AP5w8fy4E3ezLI/1HVgly+H2uorXvX3o37y55v5+Y8z2Sk7rAIeo/g62HYd3qr//US22rptm+7bWPie1Wd50UK0E9y6ZX37yE8YYfzPjat/gCdWS2pXlzZrQvLmY0vCQYdwAAdAmBGCkaEEIwF40bfH90GN6sz+HDAiaYUmrupfUkkBKm+3MzuvOPBpk/9YvLXr7Wdo3eEKg5Xo0zZnZUxkeMsANEABtRABGihaEFmhvNp88OLHqNriIDTXpkuZFXoiJk3yH99CTPTlvlp0C1ksbhepM8Ph7Nj52xOs5Elrq4+Nj0/zOhhoeMgk3QAC0FQEYKVqQ8QH4p6X+JFiPlh7/rtSbBOs79Xd3rGgBuE477ahxgyHGDmu1+WlWZoY3n9W9UPvsbbMNiTm9R09brsFAa/brttHq2kihe4AbIADajACMFC0IyyA5qXVh1rtoNp08eMVrtQOZ5oVyqIm/fFZoUp+szNf2wSe68T4v23qXzN3H9iTV0lqH7TmZ6vhVTVWTkrlssSvA3AAB0HYEYKRoQcYHYJH+8kZGRI6NeO5aEXmleP4dpee2yPLY4BWl51YUjxsRuaPpTlcIHoB93LnXbO/TqhTk2L7dtnV+qy6M73z4QCuXdGpyzuQyXtLlnExt/GpIw5OSzRyaMWsyPobcAAHQdgRgpGhBJgfgd4vIq9IPuhuGHr9KRD5bvP7UiNddJSIvFM/vLT23t3j86yLyeov9HiVoAPZ55973Wq3aY8VCBSyfF3lZhELLluc1pfb6LoT9SVsO4yVdz8nY1ctUpBoiJ83mzA0QAF1AAEYK3i0izw1t35HlIDr8eHlW5sFEV6+KyB+JyB+KyDeLx74sIm+q+H03yHIL9fMicrL4rxGRl0Tkej9vS0QCB2CfF13zs9PmrmN7zfqlxSvWXx01djjW+qQDM4d3BgkwPt9HiH223noXzc995mHr168ZUfXsSrv3pC3lEOx6TqYwftWG72V+UmsjrjubMzdAAHQBARgp+DlZntRq3PYPR7z2RhH5tPQnt/prEfmqiNwr1ZNjDVwnIselXw1+ufjvcRF5m8sbGSFYAPZ1577qQmmq95xZv3TC3DVhTGOo9UnLQlRTfQeX1CvA1rM2ly7qB8ct6IRfAde0tjkmqbZDdy0AaS7zk8pEUk06dLp6AwRAtxCAAV3BArCPC9cUWpltqbbYKr3nLrUFD45fdks+KW2pjpfcdPIEdMJCAAAgAElEQVSg9c2D3FpgQ/y9i/03NfRa8LndAAHQTQRgQFewAOx6575pe2qKIVirxXb4AtV3q2Rn2oJ7F82O/duNMXrLx+S0pRgWXW9OpBrqRwlZnY01PMS2Dbs85CXncxoARiEAA7qyqQA3Xac1xTZO7RbbdWdOeW2VnJ+dNncf25N0u67PbVXvwmvH6vZPHY6+P7G3lKplrt+dFP8eVIk1Pjf08BDbm2trzz5l9bqcboAA6DYCMKArizHAtmM9U7zgidVi26SNsWrcYVe2a3oXG99waeOW0nhJ106EFDtCqqQ6Q7NPLv9/MNU734obogBQhQAM6MpiFmjbAJxqy1vMFttJQSCn9l8fk2AF2TKtoG987Eigb8R4TmPRe5fM5pMHY7+F2rqyzI9rR9DGx5uNBc7pBggAEIABXcmvA+xaifvoif1exsL6VjXuTnsbVwnJbQKo9z79YLJhfap33mz7/Tkz/eB82N/du+jtmNSpmvkecz5Kl2Z+7sp79TGbc+wJvABACwEY0BU0ABvTPGR98Ak/kzD5WDZEw/C4ux2HZszMoRmz5cTvqIakUa2SMW5OuGyDcJZqaB8c49BrKd/58AGvN1eq2mo1l+cp69LSN9vu3+X0XtcvnUjub9wovoJ+7PXdAUADARjQFTwAG9Ns6Q3fa9HmUBHQDk2jWiVzm+15+DO88+EDabUZ9y6ZrUfmjDEB11LuXTKbSq2+87PT5u6je5xuVIw6V0JX3rpQFR3cULCd4Vjr2Gvx3eoda313ANBAAAZ0RQnAxtS/c6+1Fm2KF4iDdtItJ/arB6bBReLcgXvMtvt32V94WwZP6/G7vUtXfHYua8NqbYMQEmot5ZuffqjyvNr4+P3O58pAyOV5hr8XbR4XqzXuPsW/ccO6MNkXANggAAO6ogXggTp37jWqkynNChpj1uUblxajzvJsNX53qLI6kGoL9GC78+ED6tX1SeeyrxbiWMvzGNPesKR5/qb0N26UrUfmmt+4GvE3AADahgAM6IoegOvQWj83hYvjnGZdHndRanNh7lpN1F5X2cd2Te+i2XpkTnU/N588+NpEVDP3zZiZQzsum5TKVwtxzBAaM3xrCXH+pvA3rkpbb2oAgCsCMKAriwBsjE6lJHZ7ZOrVy7rbxsfslyRxGU+ay7jl204/oPJZX9O7aNadOTW2kn9t71lzy5NHrVvcB9+RFNqQY7Rfawpx/sb+G1clhfMJAFJFAAZ0ZROAjdGplsaaICeH6mWTi1GXIGszk2uosbWhj1HtrXep2eRWlmOkB9W2VCaiasvSNyHP3xQnAUvlfAKAFBGAAV1ZBWBj/K+fG2OJlPnZaXPT0kKQi1/tbbgd0XVJkiYzuQabXdlzCNl6ZM6sPftUcpN2jdqGW4hTWoqoDUvfhDx/U1wGKqXzCQBSQwAGdGUXgAcGYWnL4se9BJP/v727D7qjKuw4/iNIVUQdq8NbSICW1laL8uJ0NL4MtU2hQS0gUWxt59GSEIMaHKgk5Ul4UsDEaBItJA3BhhAkAYOQSEjNhGtjtSQE82ilM1YtI1pARC1QRRGQ7R+727u5z+7e3T3n7J7dfD8zZyB399679z7n3ru/PW91iCe7mtqSlssyASntb+NySZK619e1EULaNt472YrqY4tdm5e+qbP++tha6mN9AgBfEIABt1obgGNtGUvWtvBTNiDZEE/YlJzAKUvbWoDPu73cOGmnZUjrc1oX4rZ8ztqirvrr63tfV30q850CAL4gAANutT4AB0Fzs4kWPbmyPgFShaVDbD5/VkCqeqKZtQzUsb27g3NrHAN8bO/u4Jyt11ZfEzmjTOntLjde13GZ0tsdnLP12tJdiJm11566xgD7/N67rE9VvlMAwBcEYMCtTgTgupdIKXNy5WKyq7KzLr+75P5ZJS0gmZ5oNjILdG88OHfLmmB05WiwcOXohC60tmfnPXHnF60+no0Sv94yXYi7uBRRk5peH7pprupTVyZKA3DgIgADbnUiAAdBfUuklD25sn2SW2XWZZPWpim9PcGCVWOpAcn0RLPpdYCzjsvqRYveuJcTXlWdRKhrSxE1yfVM8G14723XJ+ongC4gAANudSYAB4H7K/9lT65mbVphvZtj1VmXqwbxc7autfJeDL7ni5YtKN0tOK31x6R7eV5rUlfWaM4qJpMI0cJmT9l6Nn37hs6997bqEz0UAHQFARhwq1MBOAjcLZFSqbXGcuuOyazLVVubpvR2W+nWHR973GX66N69ld6DtPF/czYuN17nNo3JxGVH9vZ5Ne43WWxMjNSFpYh8UTYAdvG9t/GaGKMOoCsIwIBbnQvAMdtLpLger1ekmLbqmLaWmnbrnrZjs3GXz7TwtnTRvMoTV2WFwTioZz3uMb09wSk775iwPT5hn7FtXeP1JavYPOFPfs5GV44GoysXMuNuBVUCYJuXgcpS9TUxSzmALiEAA251NgDbVNeMrVnFZpdG0+WYznfQrbtsGey+a3tN0ULvUWJ89eAJu8v6Ytqy7KLLJzPu2tPFUFsH1hUG0CUEYMCtAyIAm64F2dSas8f0due2/pgsOzQzp3VzWPBr4r1IlsEJnEavvtza49mYRMdFfUm2BJq05NseG8p4YPjA5ncAADSNAAy41ekAbKtlyvTkqmqZf82Ys9cUBEFw9ta1jbwu0+KqBbjqOO/LBo7HSn3p7QsuWXtlZktg2ZZ8FyGUGXfhC1qAAXQJARhwq7MB2GbLVFMtwFW65hZ9TU13665assYA2xj/Z7Ku8Mk7twWXrh6zVl+K/A2zxo0Ovj4XEyMx4269THuxdB1jgAF0CQEYcKuTAdh2y1QTYXHwpMz2a2oq1JuWrAmcTGeAtfI37o0H07dvMHus3ngwa9OKUvV9cCKqhStHnY8hZcbdejC+ujjqJICuIAADbnUuALtqmap7FujB9X5tv6amunWblLzXVLX78sJlC4IgsHtBYPr2DZXry4xt6yrU+nq1pbWt7a2mjK8uh14JALqCAAy41bkA7KoVoOo6ujaCXtXXdMb2GzJP/tvYAjzsRL/K5FBxS9q89UvtHWtvPPjADR/3/mS8akD0fbxlF1pNuzS+us4LEV163wAcuAjAgFudCsCuW6ZMZt+telJmssZt3sl/q8YA98aD8wt2C668zJPlixun7LzD25Nx04Do84y7XWg17UpLZlMXIrpQBwAc2AjAgFudCsB1tEyZrqNb9qTMdktt8jnq7tZtFJpWjhauB0Umh3JeeuPB4gVzvTsZt3E8pnVy9k2fcNIS6OsFh7K6MJa16Xqf9R3galI4ALCJAAy41akAXFfLlIuANX37htSTsvmrFjsJaHM2Lq+1W7dpuXDDstL1YdGyBY2uW3zRuiW59aXuk3FbAdFW74Epvd3WWgK70mralvHVeXy6EJGcIM7lpHAAYBMBGHCrUwG47rGJyZOreevMxpAOPnc8bu49n7/GSTiLT/7r6tZtWi688eOF/ybxeMMztt/Q6DHPvmn5hGNr6mTcdkC02XvARktgF1pNg8D/8dXDdOVCBAA0iQAMuNWpANxk64mt584aN+eixCf/hbp19/YFk3t7nR9TVhkd0gW6zvetaIlbgH1gOyC66D1QNQR3odU05vP46iK6ciECAJpEAAbc6lQADoJmT8BMn9vl+OJhJ/9Fuuk2NmZ4yCRYdb9vRY958YK5xnXKBlcB0XbvgaotgW1vNU1q82vp0oUIAGgSARhwq3MBuMkueCbP3VRX5LSu11nddK9YMr/RMbVpLYS+duE+ZecdxvXJFtNQlTcBme2LD1UuRLW91TSpzSGyzeEdAHxCAAbc6lwADoLmJmG5Ysn8YNqOW0s/d5OTUZU9+T/v9lWNHOcRX5p4ocLbSbx648Glq8es1CkbTAPiMb09uZNVxb0Hplrofl4lxHUteLW1G3GXLkQAQJMIwIBbnQzAQVD/MhxlW8J8WY7ovNtWl3qdSxfNa3QscPIk39dlnE72qPU3COwtpTXs8zK6cqGV56kyGV1bW03TtHUiqa5diACAphCAAbc6G4CDoL7lZ8q2OE/bsfn/n9vWkjImpexFgCaDZxxYfHjfmg4jyRmv89bVtf1eZdUX0xbAuFRpCWxrq2kWn5YSKqprFyIAoCkEYMCtTgfgmMvlZ0xba2y1ztUZ2Jruerx4+WXu3rfeuJXHcRmssma8Pqa3Jzh9+/pg4bIFE+5je9mitPpi629SpSWwra2meeruxWJD1y5EAEATCMCAWwdEAHbJ9ITPVquZaZmxbV2p193k5FMLr77c2fv25i/eYuVxXLVoFVuyajyYtuNWp+Ol0wKLjZZmk/etja2mw9TVi8WWLl6IAIC6EYABtwjABkxO+Kf09gTzV40Fc9d/3EmQK11648GsnKWG0jS1/JCrFuDJvb3B/E8vsnqcNpW+6NAb3y/kTd++wdprywqqpi3Npi2BbWw1LcJlLxbbunghAgDqRAAG3CIAG/Ch+7LtUvZkNKuFylVxOQZ45tY1wdJF84Kje/daeTybs9qatOC6mmk8LeBfunqscjdym8uRtanVtIu6eiECAOpAAAbcIgBXEE8+NMvTNWhNStUQkmyhmrduqbPjczULdPJ1n3nn9VYe02YLsMlrPbK3L5ixbZ31v8VgwJ+zcbnROtG2w1CbWk27iAsRAFANARhwiwBcQtbkQ10rpt1QXc3Q7HId4GT4umLJfOPJsGyOAbbxftpq1U6WZMA3HRM+bcdmK+8V/MOFCAAohwAMuEUALqip8a5NFBvhzcVSSWkthKbBK6sbpul4WZuz2vrY1T5ZR2xciGAZHAAAQgRgwC0CcI64q3OT695OKL191pbqySum3Xdtts4OGytYdGbk5L+n5nTDND1227Pa+jJTeLK46Ipue9IwoIyi62oDgGsEYMAtAnAKH7s6JwNbHUsQ2ZjAqexxTu7ds9+/y4wVjMcbTp2wNu7u4OSddwTH9HZPeD/PzXhs00Bneyyrby3AyYBvs7u7zUnDgKKyvu+PzfmOAACXCMCAWwTgAb52dR5dOVrrcdpqjSszG6zJWMH4JHYwAA9rLR9sXTYKdBWWkirC1ZjqqiX5ftkM57QAo27MVg3ARwRgwC0CcEIdLatVy+yNyyd0y4tbPQdbTk2L7fGYLmaDTXZXfPdtq40vBsQnuKaBrkqIK9L10odu+GlBwFb3bMYAo26sVwzAVwRgwC0CcMTFOqkuSlq3vKWL5gUXX3dlMH37jcGU3h7j57A5gVOSjdlgM1t6LYS7K5bMNw50Zbrxlul6Gc5MbVg/K94/70KFrRZgV3XOFZ/Hi/p8bL6o8n1ve2w/AGQhAANudTYAlz0J9KGFrezJWFqLRDJkXrL2ytKhx+eTPNN1ZouEMNNAt3Cgq3reaynb9fL8TSuMjm1yb2+p/c/duib1QkXyszW6cqHxxQif69wgn8eL+nxsvqn6fd+2CzUA2okADLjVuQBc5STQtzGWZcqwbnld6eZXR/f0Y3t3B4sXzDWqC3mTa1V9Lcm/ybQdt5q/1pLjomNZny3TNYZ9rXODfB4v6vOx+cbk+56u+gDqQABG262XFAwpL8i476mSNkv6kaSnJH1P0tWSDrd4fJ0KwFVPAn2bZbdMKdJ61vaTYyvdfwuWxZaWvcoLkSZdL2121S8z67aLSdd8rnODfL6Q5POx+aiJcf4AUAYBGG23XmHI/Wr0/2nlkJT7nSvpmei+eyXdIun+6N+PSDrB0vF1JgCbnAT6uM5qmVKkW56LiajqMmPbutrey4VXX241ZA6GDRtdL221hh/Z2xdcfN2VQ8dku2h9n7Zjs9d1Lsnn8aI+H5uv6hznDwBVEIDRdusVhtaREvc5WtKT0f1mJ24/WNKN6ofigywcXycCsOlJYJtbgI/4UrlueTYmoqrT0kXzgiN7X6vtvYxbd2yGTBtr5g7+jW21yA67eGJ9crjevuB8B0tFueTzeFGfj81XtAAD8B0BGG23XuUD8LLoPjtTth0m6fFo++mGxyZ1JACbngS2eQxw10/Kzt3yj7W9h65Dpu0T77hV32QSqmEXT6p+to4aGBc8tQU9DdL4PF7U52PzGe8bAN8RgNF261U+AH83us/7MrZviLZfa3JgkdYHYFsnM22bBXqwNN0tz8XSK+HY3/wJm2yWtFYxGyFzalTPXHW9HF250Ohxsy6eGF0YGvi7FZkczEc+txb6fGy+o+UcgM8IwGi79QrD6g2SlktaK2mJpLMlPT9l/xerPznWiRmP+WH1u0Gban0AtnUS2JZ1gH07mXW59EqdFyWGjYsc/dSo0eOfsf2G4OLrrnLyN3YVrF0MDWjTxFdB4Pd4UZ+PzXeMnQbgMwIw2m69smd/fljSGQP7n5jY/tKMxzw72v5jC8fX+gBs8ySwjqV28krZdVrj0lS3PJezS9fdLX3YMVqZKK23z8nf2FVLoMvJ4doSgn1uZfX52NqA2bMB+IoAjLb7iMIW21crbN09XNJ0Sf+mMMQ+Lem0xP7T1A/Az8t4zOnR9l8VPIYHc8qzbQ/Atk8C52xcXtuSO3GJQ2KbuuW5PnmsbWKy3nihYzPtZmxa8v7GrsY0mrZ6D6vzbWhN83m8qM/H1hZtXyIOQDcRgNFVB0naojDIfiNxOwG4JBcngWfeeX0toWZwCaK2dMur4zhrWZqqNx5cunqs2PHYDIMlxzUXee9sXjyJx3PP/uwnnb7/bRlP6fOFKZ+PrS3avEQcgG4iAKPLXqt+2J0S3UYX6Apsn/zX0fV2Sm9PsHjB3AnP34ZueXWcdNfRAlzmvWtyregix2njokTWeG5XpS2tkD5fmPL52NqmbUvEAeguAjC67DfUD7tviG57iYpPgnWvhWPoRAC2eRJY55rAaWPwfA/AdXW7dH0hYnJvb6lJumzXi8m9e6x3vTSpO7aWfLLxGfCRz59Ln48NAFAeARhddpT6YfcPErezDFIFtk4C62zpG5yFtY7WHNPlimyPuc47nqotza/buSWYuXVNMLl3T6H3r0ggcBHIL77uSutdL6uMaWxy8rc2zUTs83hRn48NAFAOARhd9hGFQfYJSYckbl8W3b4z5T6HSXos2n66hWPoTAAOAjsngU22ALvsWmxruSJbs24XOR6TCwIuWsVsL8sUvxe2u16WGdPY9PJfbWkBjvk8XtTnYwMAFEcARpudJOkdmjiZ1SRJfyPplwqD7BUD24+W9GS0bVbi9oPVb/3dq3AiLVOdCsBBYH4SWNcY4MHuwC67FttsHbLRAlzmeKoEWVct6bbDouvwVyRY17nWctl66zOfx4v6fGwAgOEIwGizsxSG1f+RdJekmyTdKen76nd93qj02Z5nSno22mePpJsl3R/9+xFJJ1g6xs4F4JjJSWAdoWCw1dbVmp62W0JNg/r5m1aUus87t6wJzrt91dClqZIB3mVLuq3uwj6Ev7rXWq7yfgMAcKAhAKPNjpe0UtJXFFbiX0p6SmEA3ixpxpD7nyrp85IeVbjk0QOSrpF0hMVj7GwANuG6W2haa6OtrsWmr8Plkjtnbru+8vs6pbc7OHnnHcGU3u4JQTLZsr900bwJ+5R5jiKh1MaEUa7CX5kx3nV2969SzwAAOBARgAG3CMAZXE4MlNbK6qIFuOp6xsPCWdVgPWPbOivB6bzbVme27LtqSU97D2ZuXVMpbLsIf1XGeNua8O3Y3t3BtB2bjT8DAACAAAy4RgDOUWas6vmbVpTqpjvI9hjg8HjGrT1e2ntT5jFnbVphtbtt1vs4f9Vio8edf81YqTqydNG84LzbVjca/qqO8Ta9WHDhhmX7XYRgJmIAAMwRgAG3CMBDlJ1R12QCLltjV220XhdpCS0TeGx3t81qRf3w9UuMHveidUsK1ozq74VNJmO8XUy8xkzEAACYIQADbhGACyozqVbVCbhsjNm1NX656PqsRQOPi/WV07pqz181ZvSYC1aVawGu8l7YYqO+uJowjJmIAQCohgAMuEUA9sicjcuHdqPOa9ELAnszWJddomdY4HEx4VJaK2RdY4BN3gtbbIRXVxOlAQCAagjAgFsEYE+U7rbcG58Qfm0ta+NiiR5XS+4MBtY6ZoH2gc3uy7aXygIAANURgAG3CMAeqNRtOaUVzlYrq6slelysr5zWVdvlOsC+sN3SzQRWAAD4gQAMuEUA9oCtwGZjnK3L7q0u1ldO67J8IHTrdbVuNBNYAQDQLAIw4BYBuGE2u7LaaAF23cJnc33lvK7aXe/W63KsMxNYAQDQHAIw4BYBuGE2g4zRONveeDBr04paXnOR7rZFyrAuy13u1utiCSMAANA8AjDgFgG4Yba7slbtTj1j27paX3dWd9uipWiX5S536z0QxjoDAHCgIQADbhGAG2a7K2vbxr/G3W3LhrmyrbZd7Nbbtr81AAAYjgAMuEUAbpiLrqxtHf/a5S7LrrT1bw0AANIRgAG3CMAecNGVta1hsstdll0gAAMA0C0EYMAtArAHXHVlbXOY7GKXZdvoAg0AQPcQgAG3CMCecNmSR5jsJibBAgCgewjAgFsEYI+0tdsy6scySAAAdBMBGHCLAOyZNndbRn1szx4OAAD8QAAG3CIAe4puy8hje/1oAADgBwIw4BYBGGiZK5bMD07fvp4WYAAAOogADLhFAAZapMg4ccYAAwDQXgRgwC0CMNASZWcKZxZoAADahwAMuEUABlqgypq/WbOIM5EaAAD+IgADbhGAgRaouubvYGEJLQAA/EYABtwiAAOeM1nzN9nyS/gFAMB/BGDALQIw4DnTNX/P2L6ebs8AALQEARhwiwAMeI41fwEAOHAQgAG3CMCA50xbgFnzFwCA9iAAA24RgAHPmYwBZs1fAADahQAMuEUABlqg6izQrPkLAEC7EIABtwjAQAtUWQeYNX8BAGgfAjDgFgEYaIk5G5ez5i8AAB1HAAbcIgADLTJn4/KhLcGs+QsAQHsRgAG3CMBAy1yxZH4wc+uaCRNjHdu7O5i5dQ3dngEAaDECMOAWARhoqaWL5gWLl18WLLz68mDx8suY7RkAgA4gAANuEYABAAAATxCAAbcIwAAAAIAnCMCAWwRgAAAAwBMEYMAtAjAAAADgCQIw4BYBGAAAAPAEARhwiwAMAAAAeIIADLhFAAYAAAA8QQAG3CIAAwAAAJ4gAANuEYABAAAATxCAAbcIwAAAAIAnCMCAWwRgAAAAwBMEYMAtAjAAAADgCQIw4NbTkyZNCiZPnkyhUCgUCoVCoVAaLpMmTQokPd10SAC66kmFH7AHc8qzUcnbh9LtQh2gUA8o1AMKdYBCPainPK3wHB1AQ+IPIw5c1AFI1AOEqAegDkCiHgDoML7gQB2ARD1AiHoA6gAk6gGADuMLDtQBSNQDhKgHoA5Aoh4A6DC+4EAdgEQ9QIh6AOoAJOoBgA7jCw7UAUjUA4SoB6AOQKIeAOgwvuBAHYBEPUCIegDqACTqAYAO4wsO1AFI1AOEqAegDkCiHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACd8GJJH5P0bUm/lPQTSXdKemvFxztF0iWSNkn6jqTnJAWS3lvw/jMl7ZL0mKQnJf27pI9KOqTi8WA423VAkiZJukDSPZJ+FpV7JM2WdFDGfcYU1pW88nsGxwT7n69TJW2W9CNJT0n6nqSrJR0+5H5HSLom2v9X0f03K/z+gFtN14HjNPxzvrTisaA4W/Xg5ZJGFP7N75b0C4V/w7sK3v8ESeslPajwu+DB6N+/VfI4UE3T9eA0Df8+mFPyWAAg1+EKQ08g6WFJn5P0ZYWh9TlJH6rwmFuU/gVWJAB/Ktr3GUk7JH1e4ZdyIOkrkl5Y4XiQz0UdOFjh3y5Q+IP6hajEP4ifUxiQB41F27+h8AQorRxV4XgQsv35Ojd6rEDSXkm3SLo/+vcjCk9s0/yuwrAURPvfEt0/PrazSx4HivOhDhwXbf+5sj/nM0seB8qxWQ/OUvpvfpEA/EaFvxGBpP+QdHP037h+vL7EcaA8H+rBaep/X6zPKH9U4jgAYKg4rN4l6dDE7TMkPSvp15JeU/Ix50u6StI7FV7B3aViATj+8vyZ9m8FeoWkb0bbPlnyWDCcizpwUfSYD0o6PnH78ZIeirZ9MOV+Y9G2sZLPh+Fsf76OVv/EdXbi9oMl3ah+IBps7T9I0ni0fUO0f2x24hiPLHEsKMaXOnBctO2BEs8Fe2zXgzdIWqOwDrxOYc+fIsHnUPV/Dz42sO1j0e0/EBe+XfGlHpwW7berxHMBQGWvUvil86ykY1O2fybavsnweXapWACOW4AuS9n2pmjbU5Jeang86HNRByZJ+mF0v79M2f7eaNtDmtgKPCYCsCu2P1/LovvsTNl2mKTHo+2nD2ybEd3+WLTfoLui7UsKHgeK86UOHCcCcJNc/9aOqFjwmRvt921N/C2YpH7PpAsqHgfy+VIPThMBGECNLlP4pfPljO1vVb8bksn4210aHoAnq99d5viMfX4QbX+PwbFgfy7qwBvV/+F8Qcr2Fyoc5xUovGKcNCYCsAsuPl/fjfZ/X8b2DdH2awduvy66/YaM+71f/ZNi2ONTHThOBOCm1PFbO6JiwWdntN/ijO1/H23fUfE4kM2nenCaCMAAanSrwi+d5RnbX6L+F+SrDJ5nl4YH4LdF+/w0Z5/bon2WGRwL9ueiDnww2n9fzj5xF9i5A7ePRbd/QeEkOGslfULSXyicqAvV2P58vVj9enFixj4fVr8LbNLXotuzxpa/Jtr+nKQXFTgWFONTHTguuv3HCofMrFE4cc5Fkl5Z4LlRXR2/tSMqFnx+Eu339ozt74i2P1rxOJDNp3pwWrTftyQtUnjB7NOSPiBpasXnBoBM+xR+6czL2eeJaJ8zDZ5nl4YH4A9F+3w9Z59PR/tsNjgW7M9FHVge7X97zj5bo30+MXD7mPon1ZhpjNAAAAZ5SURBVIPlcUl/XfAYsD/bn68T1f+7ZHWPO1v9kJP00+j2P8+438sSj/3qAseCYnyqA8cp+3P+nMLxw2nd42Gujt/aEQ0PPskLKK/N2OfkxD5cDLPLl3og5c8C/YykFZKeV/EYAGCC7yj8gjk/Z594ggqTbse7NDwA/120z1dz9rlKdIeyzUUdWBvt/9mcfW5SetfIv5K0QNJJCoPQyxR2qb5D/R/EtHHFyGf78zVN/b9H1onJ9Gj7rwZufzq6/U8y7ndI4rEHu8ijOp/qwFEKvyf+VNIxCodFvErSqMLhFvExZC2Xhurq+K0d0fDgc7T69SdrtvjfSezD7P92+VIPpPBCx0pJb1E4+eGhCi+wrVD/92JtxWMA0DHLJP1nhfKmxGMQgNvN1zpgEoDz/IP63eF+o8T94Ff4IQA3w6c6kOcPFU7KFyicpRZ2+RJ8CMDN8qUeDHOO+nXgJIPHAdARn1V2l5G8ckbiMegC3W6+1gGTLtB5flP9E+M3l7gf/Or+ShfoZvhUB4a5PbrfP5W8H4bzpesrXaCb5Us9KOLr0eMsNHwcAJAULngeqNgESCYnors0PAC/PdrnJzn7xBMylAlNyOeiDsQ/rEUmwbqw4GPGHpZ5j4QDke3PV7JeDJsA6d6B2+OLLkUmwWIcqD0+1YFh4jVg6e1jXx2/tSMqFnzii2HDJsEqewEFw/lUD4bZqPI9xgAgk0/LIB2j/skUyyDVx7dlkPIcLOnJ6H5vK3E/uPl8sQxSu/hUB4a5NrrfrSXvh+Hq+K0dUbHgwzJIzfGpHgyzI3qcTxo+DgBIClv0AoXdStOmmv9MtH2T4fPs0vAALLlflB0TuagDkyT9MLpf2oRV7422PRTtW1TcnfI5hRNloBzbn69l0X12pmw7TNJj0fbTB7bNiG5/TOndGu+Kti8peBwozpc6kOdF6vf0+GiJ+6E417+1IyoWfOaqf7Fr8LdgUnR7IOmCiseBfL7UgzyTJf0iepx3GTwOAOxni/onMC9M3P5nCkPRrxV2SRy0QeGESh8s8By7VCwAnxXt9zNJpyRuf7mkb4orgK64qAMXRY/5oPa/unx8dFuQcr+pCutIWqvxWep3l7sx99UgS5XP19kK/8a9lMc7Wv0W+VmJ2w9Wv+VvrybO5HuQ+l3gb4j2j81OHCMXOezzpQ7MljQl5fGOV/8CyGOSXjHsBaES2/Vg0IiKBZ9D1Z9k8aqBbfEETP+t/X+XYI8v9WCe0j/rr1H/t+K/JD2/wHMCQCGHqz8T8MOSbpH0Lwpb2QKFY7jS7Iq2j6VsO1PSnkT5X/W/wJK3p4knXXha0j8r7AIXtyJ8VfwQuuCiDhys/vihJxVOerVV/ZPlzZp4xf8k9X+M/1Vhq/OWxLEFkr4kxoWaKPv5Gom2PZDxeDPVn5hsj6SbJd0f/fsRZc/u+kqFs3kH0f43S7on+vczCk+y4IYPdeAbCr9f7lM4D8Gm6L5PqT8u8S3lXxpKsF0Pkr/t8d//iYHb0yZSfKP6vwv3KawL96k/9Ob15V8aSvChHjyu8DvkawrPDW6J/v/X0f2/L+n3K706AMjxEoXdDb+j8ATkpwq/CP845z67lB1+RtQPLHkly7sUjkl9QmHXl/skXSqWvnHJdh2QwoB7gcIJcH4elb3RbWnre75c0lKFV5a/H+3/tMJQfofCcUhlukwjXZnP14jyT3Yk6VSFIeZRhWO7H5B0jaQjhhzHkdF+D0T3ezR6nFNy7gM7mq4D71d4kvsthd81zyg86d6r8Pvk8MKvBCZs1oMiv/kjGfc9QWFvkIcUfuc/FP37t0u9GlTVdD34W4UXu7+rMAw/o/B74SuSLlE4YzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMf/AcU+btj8rF7FAAAAAElFTkSuQmCC\" width=\"432\">"
  1726. ],
  1727. "text/plain": [
  1728. "<IPython.core.display.HTML object>"
  1729. ]
  1730. },
  1731. "metadata": {},
  1732. "output_type": "display_data"
  1733. }
  1734. ],
  1735. "source": [
  1736. "%matplotlib nbagg\n",
  1737. "\n",
  1738. "import matplotlib.pyplot as plt\n",
  1739. "import matplotlib.animation as animation\n",
  1740. "\n",
  1741. "n_epoch = 3000 # epoch size\n",
  1742. "a, b = 1, 1 # initial parameters\n",
  1743. "epsilon = 0.001 # learning rate\n",
  1744. "\n",
  1745. "fig = plt.figure()\n",
  1746. "imgs = []\n",
  1747. "\n",
  1748. "for i in range(n_epoch):\n",
  1749. " for j in range(N):\n",
  1750. " a = a + epsilon*2*(Y[j] - a*X[j] - b)*X[j]\n",
  1751. " b = b + epsilon*2*(Y[j] - a*X[j] - b)\n",
  1752. "\n",
  1753. " L = 0\n",
  1754. " for j in range(N):\n",
  1755. " L = L + (Y[j]-a*X[j]-b)**2\n",
  1756. " #print(\"epoch %4d: loss = %f, a = %f, b = %f\" % (i, L, a, b))\n",
  1757. " \n",
  1758. " if i % 50 == 0:\n",
  1759. " x_min = np.min(X)\n",
  1760. " x_max = np.max(X)\n",
  1761. " y_min = a * x_min + b\n",
  1762. " y_max = a * x_max + b\n",
  1763. "\n",
  1764. " img = plt.scatter(X, Y, label='original data')\n",
  1765. " img = plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n",
  1766. " imgs.append(img)\n",
  1767. " \n",
  1768. "ani = animation.ArtistAnimation(fig, imgs)\n",
  1769. "plt.show()"
  1770. ]
  1771. },
  1772. {
  1773. "cell_type": "markdown",
  1774. "metadata": {},
  1775. "source": [
  1776. "## 4. 如何使用批次更新的方法?\n",
  1777. "\n",
  1778. "如果有一些数据包含比较大的错误(异常数据),因此每次更新仅仅使用一个数据会导致不精确,同时每次仅仅使用一个数据来计算更新也导致计算效率比较低。\n",
  1779. "\n",
  1780. "\n",
  1781. "* [梯度下降方法的几种形式](https://blog.csdn.net/u010402786/article/details/51188876)"
  1782. ]
  1783. },
  1784. {
  1785. "cell_type": "markdown",
  1786. "metadata": {},
  1787. "source": [
  1788. "## 5. 如何拟合多项式函数?\n",
  1789. "\n",
  1790. "需要设计一个弹道导弹防御系统,通过观测导弹的飞行路径,预测未来导弹的飞行轨迹,从而完成摧毁的任务。按照物理学,可以得知模型为:\n",
  1791. "$$\n",
  1792. "y = at^2 + bt + c\n",
  1793. "$$\n",
  1794. "我们需要求解三个模型参数$a, b, c$。\n",
  1795. "\n",
  1796. "损失函数的定义为:\n",
  1797. "$$\n",
  1798. "L = \\sum_{i=1}^N (y_i - at_i^2 - bt_i - c)^2\n",
  1799. "$$\n"
  1800. ]
  1801. },
  1802. {
  1803. "cell_type": "code",
  1804. "execution_count": 6,
  1805. "metadata": {},
  1806. "outputs": [
  1807. {
  1808. "data": {
  1809. "image/png": "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\n",
  1810. "text/plain": [
  1811. "<Figure size 432x288 with 1 Axes>"
  1812. ]
  1813. },
  1814. "metadata": {
  1815. "needs_background": "light"
  1816. },
  1817. "output_type": "display_data"
  1818. }
  1819. ],
  1820. "source": [
  1821. "%matplotlib inline\n",
  1822. "import matplotlib.pyplot as plt\n",
  1823. "import numpy as np\n",
  1824. "\n",
  1825. "#t = np.array([2, 4, 6, 8])\n",
  1826. "t = np.linspace(0, 10) # Add random noise\n",
  1827. "\n",
  1828. "pa = -20\n",
  1829. "pb = 90\n",
  1830. "pc = 800\n",
  1831. "\n",
  1832. "y = pa*t**2 + pb*t + pc\n",
  1833. "\n",
  1834. "\n",
  1835. "plt.scatter(t, y)\n",
  1836. "plt.show()"
  1837. ]
  1838. },
  1839. {
  1840. "cell_type": "markdown",
  1841. "metadata": {},
  1842. "source": [
  1843. "### 5.1 如何得到更新项?\n",
  1844. "\n",
  1845. "$$\n",
  1846. "L = \\sum_{i=1}^N (y_i - at_i^2 - bt_i - c)^2\n",
  1847. "$$\n",
  1848. "\n",
  1849. "\\begin{eqnarray}\n",
  1850. "\\frac{\\partial L}{\\partial a} & = & - 2\\sum_{i=1}^N (y_i - at_i^2 - bt_i -c) t_i^2 \\\\\n",
  1851. "\\frac{\\partial L}{\\partial b} & = & - 2\\sum_{i=1}^N (y_i - at_i^2 - bt_i -c) t_i \\\\\n",
  1852. "\\frac{\\partial L}{\\partial c} & = & - 2\\sum_{i=1}^N (y_i - at_i^2 - bt_i -c)\n",
  1853. "\\end{eqnarray}"
  1854. ]
  1855. },
  1856. {
  1857. "cell_type": "markdown",
  1858. "metadata": {},
  1859. "source": [
  1860. "## 6. 如何使用sklearn求解线性问题?\n"
  1861. ]
  1862. },
  1863. {
  1864. "cell_type": "code",
  1865. "execution_count": 7,
  1866. "metadata": {},
  1867. "outputs": [
  1868. {
  1869. "name": "stdout",
  1870. "output_type": "stream",
  1871. "text": [
  1872. "X: (442, 1)\n",
  1873. "Y: (442,)\n",
  1874. "a = 949.435260, b = 152.133484\n"
  1875. ]
  1876. },
  1877. {
  1878. "data": {
  1879. "image/png": "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\n",
  1880. "text/plain": [
  1881. "<Figure size 432x288 with 1 Axes>"
  1882. ]
  1883. },
  1884. "metadata": {
  1885. "needs_background": "light"
  1886. },
  1887. "output_type": "display_data"
  1888. }
  1889. ],
  1890. "source": [
  1891. "from sklearn import linear_model\n",
  1892. "from sklearn import datasets\n",
  1893. "import numpy as np\n",
  1894. "\n",
  1895. "# load data\n",
  1896. "d = datasets.load_diabetes()\n",
  1897. "\n",
  1898. "X = d.data[:, np.newaxis, 2]\n",
  1899. "Y = d.target\n",
  1900. "print(\"X: \", X.shape)\n",
  1901. "print(\"Y: \", Y.shape)\n",
  1902. "\n",
  1903. "# create regression model\n",
  1904. "regr = linear_model.LinearRegression()\n",
  1905. "regr.fit(X, Y)\n",
  1906. "\n",
  1907. "a, b = regr.coef_, regr.intercept_\n",
  1908. "print(\"a = %f, b = %f\" % (a, b))\n",
  1909. "\n",
  1910. "x_min = np.min(X)\n",
  1911. "x_max = np.max(X)\n",
  1912. "y_min = a * x_min + b\n",
  1913. "y_max = a * x_max + b\n",
  1914. "\n",
  1915. "plt.scatter(X, Y)\n",
  1916. "plt.plot([x_min, x_max], [y_min, y_max], 'r')\n",
  1917. "plt.show()"
  1918. ]
  1919. },
  1920. {
  1921. "cell_type": "markdown",
  1922. "metadata": {},
  1923. "source": [
  1924. "## 7. 如何使用sklearn拟合多项式函数?"
  1925. ]
  1926. },
  1927. {
  1928. "cell_type": "code",
  1929. "execution_count": 8,
  1930. "metadata": {},
  1931. "outputs": [
  1932. {
  1933. "data": {
  1934. "text/plain": [
  1935. "array([800., 90., -20.])"
  1936. ]
  1937. },
  1938. "execution_count": 8,
  1939. "metadata": {},
  1940. "output_type": "execute_result"
  1941. }
  1942. ],
  1943. "source": [
  1944. "# Fitting polynomial functions\n",
  1945. "\n",
  1946. "from sklearn.preprocessing import PolynomialFeatures\n",
  1947. "from sklearn.linear_model import LinearRegression\n",
  1948. "from sklearn.pipeline import Pipeline\n",
  1949. "\n",
  1950. "t = np.array([2, 4, 6, 8])\n",
  1951. "\n",
  1952. "pa = -20\n",
  1953. "pb = 90\n",
  1954. "pc = 800\n",
  1955. "\n",
  1956. "y = pa*t**2 + pb*t + pc\n",
  1957. "\n",
  1958. "model = Pipeline([('poly', PolynomialFeatures(degree=2)),\n",
  1959. " ('linear', LinearRegression(fit_intercept=False))])\n",
  1960. "model = model.fit(t[:, np.newaxis], y)\n",
  1961. "model.named_steps['linear'].coef_\n"
  1962. ]
  1963. }
  1964. ],
  1965. "metadata": {
  1966. "kernelspec": {
  1967. "display_name": "Python 3",
  1968. "language": "python",
  1969. "name": "python3"
  1970. },
  1971. "language_info": {
  1972. "codemirror_mode": {
  1973. "name": "ipython",
  1974. "version": 3
  1975. },
  1976. "file_extension": ".py",
  1977. "mimetype": "text/x-python",
  1978. "name": "python",
  1979. "nbconvert_exporter": "python",
  1980. "pygments_lexer": "ipython3",
  1981. "version": "3.6.9"
  1982. }
  1983. },
  1984. "nbformat": 4,
  1985. "nbformat_minor": 2
  1986. }

机器学习越来越多应用到飞行器、机器人等领域,其目的是利用计算机实现类似人类的智能,从而实现装备的智能化与无人化。本课程旨在引导学生掌握机器学习的基本知识、典型方法与技术,通过具体的应用案例激发学生对该学科的兴趣,鼓励学生能够从人工智能的角度来分析、解决飞行器、机器人所面临的问题和挑战。本课程主要内容包括Python编程基础,机器学习模型,无监督学习、监督学习、深度学习基础知识与实现,并学习如何利用机器学习解决实际问题,从而全面提升自我的《综合能力》。