{ "cells": [ { "cell_type": "code", "execution_count": 590, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T18:34:59.163168Z", "start_time": "2018-12-24T18:34:58.509697Z" } }, "outputs": [ { "data": { "text/plain": [ "(0, 100)" ] }, "execution_count": 590, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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U4CIiIgrChAREXFFASIiIq4oQERExBUFiIiIuKIAERERVxQgIiLiigJERERcUYCIiIgrChAREXFFASIiIq4oQERExBUFiIiIuKIAERERVxQgIiLiigJERERcUYCIiIgrChAREXFFASIiIq4oQERExBUFiIiIuKIAERERVxQgIiLiigJERERcUYCIiIgrChAREXFFASIiIq4oQERExBUFiIiIuKIAERERVxQgIiLiigJERERcUYCIiIgrChAREXFFASIiIq4oQERExBUFiIiIuKIAERERVxQgIiLiigJERERcUYCIiIgrChAREXFFASIiIq4oQERExBUFiIiIuKIAERERVxQgIiLiigJERERcUYCIiIgrChAREXHF398F+Hw+HnrkC0yafAcFBYV0tLexc/sHbP/ofQAM02TlQ48xs3o+hmFw5NA+1v56Ndlstt/Fi4jI4Ol3gJimSWdHOz/7pxdpbr7M6LJynv7at+hob+fwwb0sXrqCCZOm8OLzP8DKZnnq6W+yfOUjbFj7Zi7qFxGRQdLvAEmn07z3ztqevxsb6jhx/DDjJkzi8MG9VM9byIa1b9LR3gbA5k3reOKpr7Jh3a/Atq+7XMM0McybH2HrnsfNvPng9fpANeaC1+sD79fo9frg9qixt/n6HSDXamzchEo+2rKJUDhMSclwGurreqZfqK8lEolSXFxCW2vLdZdTUTmtX8NcFZXTXc+bD16vD1RjLni9PvB+jV6vD4Z2jT6f77rTch4gDz38eZKJBPv37qSgoBCAZDLeMz2RcG6HQqFel1N7+jCZdOqm2zdMk4rK6dSePoRtWTc9/0Dzen2gGnPB6/WB92v0en1we9ToDwSZt2DJtaf1t7grfeahxxg/oZJXX3kBK5sllUoCEApFiMdiAITDEQCSyWSvy7Itq19PSH/nH2herw9UYy54vT7wfo1erw+Gdo29zZOzgbuVn32cyilT+ckrf9cTFslEgtbWZsrGjO15XFl5BfF4jLa21lw1LSIigyAnAfLgw5+ncvKd/OSVvyMW67xq2t5d21i8bAWFRcVEowUsXf4g+/bs6HUHuoiIeF+/h7CKS4Zx96IlZDJpnv2D/9pz//mzp3nt1ZfYsnkjkWgBzzz7XM95IJs2rOlvsyIiMsj6HSBtrS38+Z/8p+tOty2L9WveYP2aN/rblIiIeIh3D14WERFP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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import mxnet as mx\n", "\n", "# Step1: Load the model in MXNet\n", "\n", "# Use the same prefix and epoch parameters we used in save_mxnet_model API.\n", "sym, arg_params, aux_params = mx.model.load_checkpoint(prefix='siti_fully', epoch=0)\n", "\n", "\n", "# We use the data_names and data_shapes returned by save_mxnet_model API.\n", "mod = mx.mod.Module(symbol=sym, \n", " data_names=['/first_input9'], \n", " context=mx.gpu(), \n", " label_names=None)\n", "mod.bind(for_training=False, \n", " data_shapes=[('/first_input9', (3,16))], \n", " label_shapes=mod._label_shapes)\n", "mod.set_params(arg_params, aux_params, allow_missing=True)\n", "\n", "pt = np.array([ 0.79899497, 1. , -0.79899497, -0.95979899, 0.42713568,\n", " -1. , 1. , 1. , 0.63819095, -1. ,\n", " 1. , -0.59798995, -0.86934673, 0.68844221, -0.34673367,\n", " -0.77889447])\n", "\n", "ttt = np.tile(pt, (1,1))\n", "\n", "\n", "# data_iter = mx.io.NDArrayIter(ttt, None, 1)\n", "# res2 = mod.predict(data_iter).asnumpy()\n", "# lams = np.linspace(400, 800, endpoint=True, num=128)\n", "# plt.plot(lams, 100*res2[0])\n", "# plt.xlim([400, 800])\n", "# plt.ylim ( [0,100])\n", "# plt.xlabel('wavelength (nm)')\n", "\n", "\n", "num_layers = 16\n", "d_min = 0.5\n", "d_max = 100 \n", "\n", "#geom = np.random.uniform(0,1, 16)\n", "\n", "indexx = np.random.randint(0,20)\n", "geom = (bests_g[indexx]-0.5)/99.5\n", "# geom = np.array([0.99740673, 0.16047267, 0.27205694, 0.28930667, 0.39390871,\n", "# 0.12006336, 0.8 , 0. , 0.50488817, 0.10512654,\n", "# 0.31236766, 0.8 , 0.07536845, 0.15084873, 0.33889699,\n", "# 0.14410015])\n", "# geom[3] = 1.0\n", "# geom[12] = 1.0\n", "geom_ac = rndtop5(0.5 + 99.5*(geom))\n", "#print(geom_ac)\n", "geom_nor = geom*2 - 1 \n", "geom_nor_t = np.tile(geom_nor, (3,1))\n", "\n", "# #best_ac = rndtop5(bests_g)\n", "\n", "# indexx = 1\n", "# bests_ac = -1.0 + 2.0*(bests_g - 0.5)/99.5 \n", "# R_gp = 100*mod.predict(bests_ac).asnumpy()\n", "\n", "\n", "# # # #Rs_b = oqx.tmm_eval_wsweep( best_ac ,0, lam_pts=128)\n", "\n", "Rsmod = 100*mod.predict(geom_nor_t)\n", "Rs2 = Rsmod[0].asnumpy()\n", " \n", "Rs = oqx.tmm_eval_wsweep( geom_ac ,0, lam_pts=128)\n", "#Rs = oqx.tmm_eval_wsweep( bests_g[indexx] ,0, lam_pts=128)\n", "\n", "lams = np.linspace(400, 800, endpoint=True, num=128)\n", "plt.plot(lams, Rs)\n", "plt.plot(lams, Rs2)\n", "#plt.plot(lams, R_gp[indexx])\n", "plt.ylim([0,100])\n", "\n", "#bests_g" ] }, { "cell_type": "code", "execution_count": 286, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T18:01:56.495275Z", "start_time": "2018-12-24T18:01:56.104325Z" } }, "outputs": [ { "data": { "text/plain": [ "37" ] }, "execution_count": 286, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.randint(0,100)" ] }, { "cell_type": "code", "execution_count": 545, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T18:27:22.520554Z", "start_time": "2018-12-24T18:27:19.009552Z" }, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "----------------- I-1---------------------\n", "19 2.5254126\n", "----------------- I-2---------------------\n", "19 1.0218053\n", "----------------- I-3---------------------\n", "19 2.3306732\n", "----------------- I-4---------------------\n", "19 6.1065593\n", "----------------- I-5---------------------\n", "19 1.26777\n", "----------------- I-6---------------------\n", "19 0.12779659\n", "----------------- I-7---------------------\n", "19 5.573145\n", "----------------- I-8---------------------\n", "19 1.0077518\n", "----------------- I-9---------------------\n", "19 4.2593427\n", "----------------- I-10---------------------\n", "19 1.1253717\n", "----------------- I-11---------------------\n", "19 4.2575607\n", "----------------- I-12---------------------\n", "19 3.3356645\n", "----------------- I-13---------------------\n", "19 1.7500688\n", "----------------- I-14---------------------\n", "19 1.8015399\n", "----------------- I-15---------------------\n", "19 5.98615\n", "----------------- I-16---------------------\n", "19 2.3099566\n", "----------------- I-17---------------------\n", "19 3.7223969\n", "----------------- I-18---------------------\n", "19 1.5900933\n", "----------------- I-19---------------------\n", "19 3.7400239\n", "----------------- I-20---------------------\n", "19 6.3340344\n" ] } ], "source": [ "%reload_ext autoreload\n", "%autoreload 2\n", "import warnings\n", "warnings.filterwarnings(\"ignore\",category =RuntimeWarning)\n", "import numpy as np\n", "import de2 as de\n", "import multiprocessing as mp\n", "import makeqx as mkq\n", "import oldqx as oqx\n", "import mxnet.ndarray as nd\n", "\n", "\n", "def arc_metric(R_arr):\n", " pop_size = R_arr.shape[0]\n", " lam_size = R_arr.shape[1]\n", " R_ref = np.linspace(0.0, 0.0, endpoint=True, num=lam_size)\n", " R_ref_tiled = np.tile(R_ref, (pop_size, 1))\n", " return np.mean(np.abs(R_arr - R_ref_tiled), axis=1) \n", "\n", "def bpass_metric(R_arr):\n", " b_low = 550\n", " b_high = 600\n", " pop_size = R_arr.shape[0]\n", " lam_size = R_arr.shape[1]\n", " \n", " lams = np.linspace(400.0, 800.0, endpoint=True, num=lam_size)\n", " \n", " left_r = lams[lams < b_low].size\n", " right_r = lams[lams <= b_high].size\n", " R_ref = np.linspace(100.0, 100.0, endpoint=True, num=lam_size)\n", " R_ref[left_r:right_r] = 0.0\n", " \n", " R_ref_tiled = np.tile(R_ref, (pop_size, 1))\n", " return np.mean(np.abs(R_arr - R_ref_tiled), axis=1) \n", " \n", " diffarr = np.abs(R_arr - R_ref_tiled)\n", " passb = np.mean(diffarr[:, left_r:right_r], axis=1)\n", " stopb = np.mean( diffarr[:, 0:left_r -1], axis=1) + np.mean( diffarr[:, right_r + 1:], axis=1)\n", " return stopb + passb\n", "\n", "# anti-reflection coating\n", "R_ref = np.linspace(100.0, 100.0, endpoint=True, num=50)\n", "# narrow band transmission filter\n", "R_ref[17] = 0.0\n", "\n", "\n", "def rndtop5(x):\n", " return np.round(x*2.0)/2\n", "\n", "def tmm_wrapper2(arg):\n", " args, kwargs = arg\n", " return oqx.tmm_eval_wsweep(*args, **kwargs)\n", "\n", "\n", "def arc_par_gp(pop, **kwargs):\n", " x_in = 2.0*(pop - 0.5)/(99.5) - 1.0\n", " y_in = 100.0*mod.predict(x_in)\n", " means = nd.mean(y_in, axis=1)\n", " return means.asnumpy()\n", "\n", "\n", "\n", "\n", "def arc_par(pop, **kwargs):\n", " jobs = []\n", " pool=mp.Pool(90)\n", " for indiv in pop:\n", " #indiv = indiv.reshape((int(indiv.size/2), 2))\n", " #indiv[:,1] = mkq.digitize_qx(indiv[:,1], dlevels=2)\n", " indiv = rndtop5(indiv)\n", " #indiv = indiv.flatten()\n", " jobs.append((indiv, 0))\n", " arg = [(j, kwargs) for j in jobs]\n", " answ = np.array(pool.map(tmm_wrapper2, arg))\n", " pool.close()\n", "\n", "# c2 = np.zeros(pop.shape[0])\n", "# for idx, indiv in enumerate(pop):\n", "# c2[idx] = np.sum(indiv)\n", "# if c2[idx] <= 385:\n", "# c2[idx] = 385/c2[idx]\n", "# else:\n", "# c2[idx] = 0.0\n", " return arc_metric(answ) \n", " #return bpass_metric(answ)\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "bnds = [(d_min, d_max)]*num_layers\n", "its_first = 0\n", "psnew = 5*num_layers\n", "islands_g = 20\n", "its_second = 25\n", "numgens = 3\n", "\n", "isl_g = np.ones((psnew*islands_g, num_layers))\n", "for indiv in range(int(psnew*islands_g)):\n", " isl_g[indiv] = np.random.uniform(0,1, num_layers)\n", "\n", "poplist_g = np.split(isl_g, islands_g)\n", "\n", "bids_g = np.zeros(islands_g, dtype=int)\n", "bfits_g = np.zeros(islands_g)\n", "bests_g = isl_g[0:islands_g]\n", "\n", "for isln in range(islands_g):\n", " print(\"----------------- I-\" + str(isln + 1)+ \"---------------------\")\n", " poplist_g[isln], bids_g[isln], bfits_g[isln], bests_g[isln] = de.de_cp(\n", " fobj=arc_par_gp, bounds=bnds, \n", " pop=poplist_g[isln], \n", " history=[], \n", " it_start=its_first, \n", " popsize=psnew, \n", " its=its_second, \n", " lam_low=400, \n", " lam_high=800, \n", " lam_pts=128)\n", "\n", "\n", "\n", "# for gen in range(numgens):\n", "# print(\"==============================\")\n", "# print(\"Epoch #:\" + str(gen + 1))\n", "# print(\"==============================\")\n", " \n", "# for isln in range(islands):\n", "# print(\"----------------- I-\" + str(isln + 1)+ \"---------------------\")\n", " \n", "# if gen == 0:\n", "# poplist[isln], bids[isln], bfits[isln], bests[isln] = de.de_cp(\n", "# fobj=arc_par_gp, bounds=bnds, \n", "# pop=poplist[isln], \n", "# history=[], \n", "# it_start=its_first, \n", "# popsize=psnew, \n", "# its=its_second, \n", "# lam_low=400, \n", "# lam_high=800, \n", "# lam_pts=256)\n", "# else:\n", "# poplist[isln], bids[isln], bfits[isln], bests[isln] = de.de_cp(\n", "# fobj=arc_par, bounds=bnds, \n", "# pop=poplist[isln], \n", "# history=[], \n", "# it_start=its_first, \n", "# popsize=psnew, \n", "# its=its_second, \n", "# lam_low=400, \n", "# lam_high=800, \n", "# lam_pts=256)\n", "\n", " \n", "# print(np.sum(bests[isln]))\n", " \n", "# if its_second > 64:\n", "# its_second = int(its_second/2)\n", " \n", "# if gen < (numgens - 1):\n", "# print(\"Round robin best migration\")\n", "# stmp = np.copy(poplist[islands-1][bids[islands-1]])\n", "# for isln in range(1, islands):\n", "# poplist[isln][bids[isln]] = poplist[isln-1][bids[isln-1]]\n", "# poplist[0][bids[0]] = stmp \n", " \n", "# print(bfits) \n", "# print(bests[np.argmin(bfits)])\n", "\n", "# print(np.sum(bests[np.argmin(bfits)]))" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T16:20:54.808585Z", "start_time": "2018-12-24T16:20:54.719378Z" } }, "outputs": [ { "data": { "text/plain": [ "array([6.95943609e-02, 2.73140855e-02, 2.38148496e-03, 0.00000000e+00,\n", " 1.18641138e-01, 4.37494963e-01, 2.25770753e-02, 6.82759564e-03,\n", " 3.18860188e-02, 1.62156439e+00, 2.58233175e-02, 3.02884996e-01,\n", " 1.61414035e-02, 1.01335580e-02, 1.51378568e-02, 1.28030205e+00,\n", " 6.01995029e-02, 1.09164156e-01, 1.44417863e-03, 2.95243934e-02])" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(bfits_g)\n" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T16:21:51.788816Z", "start_time": "2018-12-24T16:21:49.517039Z" } }, "outputs": [ { "data": { "text/plain": [ "array([1.25103446, 1.78700328, 2.3109896 , 1.11588667, 1.45650532,\n", " 2.74298038, 0.94518088, 1.82786372, 1.93577577, 9.17519445,\n", " 2.25408966, 2.21879332, 1.94204131, 1.86506282, 1.54120511,\n", " 4.07923547, 2.2086548 , 2.32715269, 1.80240239, 1.64751775])" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arc_par(bests_g)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T16:20:21.048595Z", "start_time": "2018-12-24T16:20:20.712691Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaYAAAFoCAYAAAAck1/HAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xd0lPed9/33b0ZdAiSEEEhCjWZjUwzYxJhqmsG4lySPHcfJJrspm81uNved3dx5cnb3PPdma5JNslk7jmM7iVsc23HDgE0xmN47GCEkoS4k1JE00vyePwQystpgNLouaT6vc/YszGhmPv5mrI+v9rvMnAV3WkRERFzC43QAERGRK6mYRETEVVRMIiLiKiomERFxFRWTiIi4iopJRERcRcUkIiKuEjaQHzbr5rlMnTGL0cljKSos4Plnn+h4LjwigpWrH2Di5Cm0tbZy8MBuNr//7kDGExERFxjQYqqvr2XHh5sYmzKO1HEZnZ5bvvIeYmJi+e+f/DORUVF8/rE/p76ulr27tg1kRBERcdiA7so7deIop04cpaGhrtPjYeHh3DD1JjZvXEtT00Vqqi+wa9sHTL/ploGMJyIiLjCgW0w9GZmYhNfrpay0uOOx0pJCkkYnY4zB2u5XTYqKiaPV1zJQMUVEpBdh4RE0NdZf+/v0Q5ZrFhkRic/nw/r9HY81NTXh8XgJCw/H19K1fKJi4lh1/5cGMqaIiPRhzWvPXHM5uaKYmluaCQ8Px3g8HeUUFRWF399Gq8/X7WsubymtfeO3+FqaByzrYGA8HlIyJlOcf6pT2Uu7gZiPxeCf+HnMxXI8he8H5TOCQd+dnmk2vQuPiOSOex7rl71YriimqsoK2traSE4eS2lJEQDJY1M5X1He4268y3wtzfiamwYi5qBhPB7a2trwNTfpX6BuDMR8bPIcrHcYJu8FTNvg+X7qu9MzzWbgDOjJD8bjwRsWhsfjxRjT/mevl1afj2NHDrDw9juIjIpiRHwCc+Yu5OD+XQMZT6Rf2IgR2JSFmIJ1g6qURNxiQLeY5i1YwvxFyzv+/r0f/Ij8vDM8/+wTvPfum9yx+n7+8m/+D21tbRzcv0unisugZNOWQH0+XDjpdBSRQWlAi2nr5vfYuvm9bp9raWnmzddeHMg4Iv3OxqVBwmTMsV9hnA4jMkhpSSKRfmIBm7YUKg5gmiqdjiMyaKmYRPpLwhSIHoUp3uJ0EpFBTcUk0g+s8WLTFmNKtmFaG52OIzKoqZhE+kPyLYCBst1OJxEZ9FRMItfIhsVgx8zFFG3C2Dan44gMeiomkWtkU+ZDcxVUHXM6isiQoGISuQY2KhFG3YQ5955ODxfpJyomkWtg05ZAzWlMfaHTUUSGDBWTyKdkh2XA8GxM4Uano4gMKSomkU/BYrDjlkLFXkzzBafjiAwpKiaRTyNxKkSMwBR/6HQSkSFHxSRylawnHJu6CFPyoVYPFwkCFZPI1UqeA34flO91OonIkKRiErkKNjwOO+ZWTOFGjNXN4kSCQcUkchVsykJoLIXqU05HERmyVEwiAbLRo2HUNMy593UxrUgQqZhEAmABO24JVB3HNJY4HUdkSFMxiQRixHiIS8cUbXI6iciQp2IS6YPFtC89VLYL01LrdByRIU/FJNKXpJsgLAZTst3pJCIhQcUk0gvricCmLMAUb8H4W5yOIxISVEwivbBj50JrI1QccDqKSMhQMYn0wEYMh+Rb2i+mxTodRyRkqJhEemBTF0F9IdTkOB1FJKSomES6YWPGwsgbdDGtiANUTCKf0H4x7VKoPIK5WO50HJGQo2IS+aT4yRAzBlO02ekkIiFJxSRyBWs82LTboWwnxlfvdByRkKRiErlS0izwhGNKdzqdRCRkqZhELrHeKGzKfEzRBxi/z+k4IiFLxSRyiR07D1pqofKw01FEQpqKSQSwkQkweval08N1Ma2Ik1RMIoBNXQy1uZi6PKejiIQ8FZOEPBuXBgmTMYUbnI4iIqiYJMRZwKYthYoDmKZKp+OICComCXUjp0D0KEzxFqeTiMglKiYJWdaEYVNvx5Rsw7Q2Oh1HRC5RMUnIsqNnt/+hbLezQUSkExWThKQ2E4EdMxdTtAlj25yOIyJXUDFJSKqOnAxNlVB1zOkoIvIJKiYJOTYqkfqIdDyFG3SvJREXUjFJyPGn3k5MaxmmodDpKCLSDRWThBQ7LBOGZRHfdNzpKCLSAxWThAyLwY5biqnYR7hfp4eLuJWKSUJH4lSIGI4p3eZ0EhHphYpJQoL1hGNTF2FKPsS0NTkdR0R6oWKS0JD8GfD7oHyv00lEpA8qJhnybHgcdsxnMIUbMdbvdBwR6YOKSYY8m7IQGkuh+pTTUUQkAComGdJs9GgYNe3SnWlFZDBQMcmQZQE7bhlUHcc0ljgdR0QCFOZ0gCvFDRvO8pX3kp6ZDUBhQR7r1rxOXW2Nw8lkUIqfDLEpmKNPOJ1ERK6Cq7aYVtx5Hx6vh1/+9Ef84if/F5+vhVV3Peh0LBmErPG2X0xbugPjq3M6johcBVcVU0JCIieOHqKlpZlWn4+jh/eTlDzG6VgyGCXPAQyU7nQ6iYhcJVftytu1YwvX3zCdnNMnsH7L1OmzOPPRyV5fYzwejMdV/eq4y/MI1bnY8Djs2Nsw+e/gMX4wnecQ6vPpjWbTM82md/05F1cVU2FBHjNuupnvfO8fsRbKy4p54blf9fqalIzJtLXpRm/dSc2a4nQER5yPnkGrrSM5MQyTeGOPPxeq8wmEZtMzzaZ7Xq+3397LPcVkDJ9/7KucOHaYF3//awDmL1rOZx/9M5779S96fFlx/il8zVpi5krG4yE1awpFZ49j/aF1QamNScE/ORXPyWcpuljW7c+E8nz6otn0TLPpXXhkFDNnz+uX93JNMUVHRxMfP5K9uz6k1ecDYO+uD7n1tkVEx8RwsbH71aCt368vSQ9CbTYWsGlL4fwhaCjB9vXzITafq6HZ9Eyz6V5/zsQ1O0svNjZSVVnBrJvn4g0LwxsWxuw586itqe6xlEQ6GXkjRCViijY7nUREroFrtpgA/vjSsyxdcTff+s4PMMZQVlrMKy8+43QsGQSsJxybdnv76uGt+g8ZkcHMVcV0vqKcly4dXxK5GnbMXPC3QPkep6OIyDVyza48kU/LRoyAMZ9pXw9Pq4eLDHoqJhn0bNoSqMuHmhyno4hIP1AxyaBmh6VD/CTMufe0erjIEKFikkHLYrDjlkPFPkxTpdNxRKSfqJhk8Bo1A8KHYYq3Op1ERPqRikkGJeuNxKYuxBR/gGnTyh8iQ4mKSQYlO3Y++Oqh4oDTUUSkn6mYZNCxUYkwevalEx76WnhIRAYbFZMMOnbcUqg5janLdzqKiASBikkGFTtiPAzLxJzb4HQUEQkSFZMMGtZ42lcPL9uFaal2Oo6IBImKSQaP0bPBG4kp2e50EhEJIhWTDAo2LAY7dj6maBPG3+J0HBEJIhWTDAo2ZSE0VULlEaejiEiQqZjE9Wx0MiTN0Hp4IiFCxSSuZgGbvgyqjmEaipyOIyIDQMUk7pZwHcSMxRRucjqJiAwQFZO4ljVh2LQlmNLtGF+d03FEZIComMS9xsxp//+lu5zNISIDSsUkrmTDh2HHzMUUbsDYVqfjiMgAUjGJK9m0xdBYAhdOOh1FRAaYiklcx8amwMgbMAU6PVwkFKmYxFUstN8u/fxBzMUyp+OIiANUTOIuiVMhKhFT9IHTSUTEISomcQ3rCcemLsaUbMW0NjodR0QcomIS17Bjb4O2Zijf63QUEXGQiklcwUbEQ/IcTOH7GOt3Oo6IOEjFJK5gxy2BujxMzRmno4iIw1RM4jg7LANGTMSce9/pKCLiAiomcZTFYMctg/K9mKZKp+OIiAuEXc0Pj0xMIj5hJOHh4TQ2NFBaWoSvRXcTlWuQdBOEx2FKtjqdRERcos9iGhGfwMyb53LjtJuIjR2GueJSfL/fz7mCPA7s3cGJY4eDmVOGIOuNwqYsxBRtxrQ1Ox1HRFyi12K6fdmdzLz5VvJyc9i8YS3FhQXU1dbQ2uojOjqGpOSxZGRms2jpKubOX8Lbb/yBshLdzE0CY1Pmg68Ozh90OoqIuEivxRQRGckTP/836utquzzX0FBPQ+5p8nJP88HGdVw3ZRqjRo1WMUlAbFQiJM3CnH4Bg3U6joi4SK/FtPbt1wJ+o5PHtStPAtO+Ht4yqP4IU1fgdBwRcZlPdVae8XgYlZRM0ugxeLze/s4kQ92ICTAsA1O4wekkIuJCV3VWHsDY1HHc//AXCA8Lx3g8tLb6eOOPL1CQnxuMfDLEWOPBjlsKpTsxLTVOxxERF7rqYlq+8h7Wvv0aZ06338Dt5jnzWHnXAzz5i3/v93AyBI2eDZ4ITOl2p5OIiEv1uSvv4f/ny8QNG97x96ioaM7ln+34e0HBWaJjYoOTToYUGxaDHTsfU7gR4/c5HUdEXKrPLabcnFM8/pVvsXXzeg4d2MORQ/t4/Kvf4vSp43i8Xq6fMo3DB/YMRFYZxNpPeFgKTZVQddTpOCLiYn0W097d2zj90XFW3vUgU26cwTtvvkJpSRFZ2RMxwPp33+Cjk/pFI30YNQPiJ2NOPKPbpYtIrwI6xlRTfYGXfvcUM2bewmNf/ibbP9zIhvVvBzubDBE2OhmbvgKT9w6m6bzTcUTE5a7qdPGD+3fz7K9/zvgJ1/Ho418jPiExWLlkiLDeSOz4+6HyMEa78EQkAH1uMSWNHsOd9zxE4qjRlJUW8/af/sArLz7DjdNm8ujjX2PXji3s2akFOKUrC9iMO8HfgilY73QcERkk+txiuvOehygqLODZp37GRyePccfq+wE4eng/z/zqv0gbl8Fjf/aXQQ8qg9Do2TA8C3PmNYxtczqNiAwSfRZT4qjR7Nm5lcrzFezesYXExKSO5xoa6nn9ld+za/vmIEaUwcjGpmDTlmLy3sY0X3A6jogMIn3uyispLmTRkpUcOrCH7AmTKS3tukjrqRM6diAfs95obPb9ULEXU33K6TgiMsj0ucX09p9exhjD0hV3ERsbd1ULu0rosYDNuht8dZjCjU7HEZFBqM8tptqaal5/5fcDkUWGgjFzIS4Fc/xpjPU7nUZEBqFet5jCwq5uKb2r/XkZWmxcOjZlASb3TUxL13t4iYgEotdi+vq3/47Zc24jMiqq1zdJSUvngc8+xi23LujXcDJ42LBYbPZ9ULYTU3vG6TgiMoj1uonzyovPsnTFXSxeuoqC/LOUFBVQV1tLa6uPqOgYkkYnMy4jm9jYOHZu28yu7R9cc6AJk65nweLljExMoqW5mV07tvTL+0rwWAw2+15oOo8p0v9WInJtei2m0uJCfv/M/zAmJY0bp97EhEnXMyJ+JOHh4TQ2NFBaUsTu7Vs4emQ/vpaWaw6TPWEyK1c/wFuvv0R+fi7h4eGMGBF/ze8rwWVTFkD0qPbjSrpNuohco4AOCpUWF1JaXBjsLCxYvIJtWzaQdzYHgJbmZirKy4L+ufLp2eHZMOZWzOkXMb56p+OIyBDgmrMVwsPDGZuSyvGjB/nzb36X6OgYCs/l897aN6itqe7xdcbjwXg+1R3ih6zL8wj2XGz4MGz2PZjSD/E0nINB8r/DQM1nMNJseqbZ9K4/5+KaYoqKjsEYD9NmzObl55+moaGeZSvu5v6HH+PZp37W4+tSMibT1qblbrqTmjUlaO9tMZTFzsXYekbH1mLG3xi0zwqWYM5nsNNseqbZdM/r9fbbe7mmmFqamwHYs+tDaqrbl7DZvPFd/uZ//yNxw4ZTX9f96cfF+afwNTcNWM7BwHg8pGZNoejscaw/ONcS+VNvx0aH4TnxW4raLgblM4JlIOYzWGk2PdNsehceGcXM2fP65b1cU0zNzU1UV1eBveLgeQDH0a3fry9JD4I1Gxs/GZs0G3Pqd+BrGLSnO+i70zPNpmeaTff6cyau2ll6YO9Obv7MfIYNH4E3LIwFt6+guOhcj1tLMvBsZDw2czWmaCOmoeu6iSIi1+qqt5iSkscycuQozuScpNXnw+v10ub3d97S+ZR2bNtMVFQ0f/YXfw3GUFiQx2t/+O01v6/0D2u82OwHoC4PynY7HUdEhqiAiykqOpoHPvtF0jOysBae+Pm/Un2hihV33kdzczMb1r117WmsZdP7a9j0/pprfy/pd3bcMvBGtt/KwukwIjJkBbwrb8ny1Vi/n//+6Y/w+T6+mPbk8SNkj58UlHDiHnbkDTBqOubMq5i2ZqfjiMgQFnAxZY2fxMb33ulyTVFVZQXDtTrDkGajErEZqzAF6zEXdcGziARXwMUUHR1DU1PX04IjIiKx/XB86dMarGeEDRbWE44d/wBUn4LzB5yOIyIhIOBiKi0pInvC5C6PT50xm+Kic/0a6mrY5Fsd++yhzgI2/Q4ATP67Oq4kIgMi4JMftm5+jwc/9zjDho/A4/Fw47RZJI1OZuLkG3jhuSeDmbFXNmkW1ufDlHzoWIYha9QMSLgOc+IZjN/ndBoRCREBbzHl5Z7mlRd/Q1paBtZabp23iNi4Ybz0+6coPJcXxIi985z9E3bMXOzY2xzLMBTZ6GRs+or2LaWm807HEZEQclXXMeWfPUP+WXfdBM40FGJyXsZO/CxYP6Z0h9ORBj3rjcSOvx8qj2CqjjodR0RCTMBbTGNT0khJHdfl8ZTUcYxJSevXUFfL1OVjcl7BpszHJs9xNMtgZwGbcSf4WzAF65yOIyIhKOBiWr7qXkbEj+zy+PAR8SxfeW+/hvo0TO1ZTM4fsamLsMm3OB1n8Bo9G4ZnYc68hrFatV1EBl7AxTQqKZmSbm4WWFpSxKik0f0a6tMytbmYM3/Epi7Gjp7tdJxBx8amYNOWtq/s0HzB6TgiEqICLiZrLZGRkV0ej4qKxhj3nEhsas5gzryKTVuCTZrldJxBw3qjsdn3Q8VeTPUpp+OISAgLuJiKzuUzZ+7CLo/PmbuQosKCfg11rUxNDib3dey4ZdikmU7HcT0L2Ky7wVeHKdzodBwRCXEBn5X3wca1PPqlr/Plv/hr8s7mgLVkZk9kZOIofv/sE8HM+KmY6o8g93Vs9n3tZ+udP+h0JPcaMxfiUjDHn8ZY3WdGRJwVcDGVlhTx7FM/59Z5ixl/aQWI0pIi3nr9RSrK3bl+mqk+BWf/hM26F6zFVB5yOpLr2Lh0bMoCTM4rmBbd90pEnHdV1zGdryjjrddfClaWoDAXTgJvYLPuAfyYyiNOR3INGxbbvkVZthNT667r00QkdF31jQI9Xi+xsXFdTnj45KrjbmIunADjwWbe1b7lpItGsRhs9r3QXIkp+sDpOCIiHQIupviEkdx590OMy8iCK5bzNKb95rX/8k/fC0a+fmOqjgEGm7ka8GOqjjsdyTHWeLFpSyB6VPtxJa3RLiIuEnAxrbr7ISKjonjj1Repq6sZlPebMFVHL2053d2+5XThhNORBpQFSLiuvZQw7Tf989U7nEpEpLOAiykldRzP/foXVJSXBjNP0JnKw2BM+zEn6w+Za3baF2VdBjFjMaXboXQXxrY6HUtEpIuAi6m2phrjCfiyJ1cz5w8BnvYD/7mvD+lysmGx2NRFMGoaVB7F5L6B8dU5HUtEpEcBN82m99ewaMkdREVHBzPPgDHnD2DOrcdm34cdMdHpOP3O4sGf/Bns1K+3H0s6+RyevLdUSiLiegFvMS1Zvpq4YcP59nd/SF1dLW1tnRf4fPLn/9bv4YLNVOwHPO23eDjzKqYmx+lI18wCxE+meNgibHQrJm8NXDiuu8+KyKARcDEdPXwgmDkcYyr2th9zGv8A5LyCqc11OtKndvk4ko0Zy7CWXOpOvAVtLU7HEhG5KgEX04cfvBfMHI4y5Xvay2nCQ5DzB0ztWacjXZVPHkfy5L1JfHom9bZ1MJ48KSIh7qovsB2qTNnu9lPJJzyMrclpX2uvOgfTdtHpaD2yxgvJt7TfVv5iBebkc5iG4iFzkoqIhKaAi8nj9TJ33u3cMHUGI+IT8Hi8nZ53+wW2gTClO6GhBJtwXfsWSOZqbF3BpZL6CNNS43RE4OPjSHbcEsCDyV8DVTqOJCJDQ8DFNH/hMqbNmM3O7ZtZtGQVH2xcS3zCSCZfdyNbNq8PYsSBZeryMXX52IJ1EDMWGz8JO2oGpC/HNpa1F1T1R9BY6kgRdL4eaUf7Ond+XY8kIkNHwMU05cYZvPv2q+R8dIIFi1dw4thhqi9Ucr68jLRxmezfsyOYOQecAWgswTSWQPEH2Ih4SJjUXlRjb4OWOuzlkqovCPrtInQ9koiEioCLKW7YMMrLSgDw+Xwdd7M9/dFx5i9eHpx0LmJaqqFsN6ZsNzYsGkZMwMZPxk54GGzbx8elas5g/P13JlxPx5FERIaqgIuprq6WmNg4amuqqamuIj0jm7LSYpJGj8HvD62by5nWi1B5BFN5BGvCYHhW+5ZU+grwRmLr8j8+LvUp16LTcSQRCVUBF1P+2RwmTZ5CaXEhh/bvZvmq+7j+xhmMTh7D0UP7g5nR1YxthZrTmJrT2HwDcantJZV8C2SsxNYXdZQUTecDKhYdRxKRUBZwMb371qsdfz64fzdNTU2My8ji2OH97N+3MyjhBhuDhfpCTH0htnAjRCW2b/XET4K0xdBUdcVxqcIut5toP460EEZN13EkEQlZARfT8BHxnW4GePL4YU4eP9ztc3Lp5ImmSijdjindjg2PgxETsQmTsKNnQ1vzx8el6gogaQZ27DwdRxKRkBfwlZjf+PbfExMb2+Xx6OgYvvHtv+/XUEOR8dVjzh/Ac/plzMGfYArWXro31GrsTX+LHX0zJn+NSklEQl7AW0ymh4MjYeHhtLXp+MfVMP4WuHASc+Ek1nggZgxcLNdxJBERAiimeQuXAu23T58zdxG+luaO54zxkJaeSUV5WfASDnHG+kFbSCIiHfosphunzQTat5iumzIVe8Wp4W1tbVRXV7HpvXeCl1BEREJKn8X0xKX7LD3yxb/g1Zd/S1OTexc1FRGRwS/gY0zPP/dkMHOIiIgAV3FW3n0PPcrc+bd3efzWeYu598FH+jWUiIiEroCLKT0jm5zTJ7s8fub0SdIzsvs1lIiIhK6AiykyKqrTGXmX+Xw+oqKj+zWUiIiEroCL6UJVJVnZk7o8njV+ItUXqvo1lIiIhK6AT37Yv2cHi5etwhsWRl7uR1gL2RMmM3/RMj7YsDaYGUVEJIQEXEz79mwnJjaORUvuwLt8NQBtba3s2r6Fvbu3BS2giIiEloCLCWDr5vXs2LaJpKRkAM5XlOHz+YISTEREQtNVFROA1+PFWkt5eSn+trZgZBIRkRAWcDGFhYdzx533M3X6TKy1PPHzf6P6QhV3rL6futoatm3ZEMycIiISIgI+K2/h4hUkj0nh9888QWvrx6tg5+acYvL1NwYlnIiIhJ6Ai2ny9VNZt+Z1zhWcxdqP77x6vqKM+ITEoIQTEZHQE3AxxcYN6/YutR6PF48n4LcRERHpVcCNUnm+nLT0zC6PT7ruBspKS/ozE2FhYXztr77Hd/7un/r1fUVExP0CPvlh57ZNLF91HxERkRhjSM8cz02zb+XmObfx+iu/79dQCxavoK62hpiYrrdyFxGRoS3gYjp+9BDesHDmL1xGeHg4d979ILU1Nbzz5h85fep4vwVKHpvK+InX8f66t7jvoUf7/Hnj8WC0K7GTy/PQXLqn+fRMs+mZZtO7/pzLVV3HdOTgXo4c3Et0TAzGGBobGvotCLT/g62660HWrXk94NekZEymTddTdSs1a4rTEVxN8+mZZtMzzaZ7Xq+3397rqi+wBbjY2NhvAa4059YFlJeVUJCXS3pmYLfSKM4/ha+5KSh5Bivj8ZCaNYWis8exfr/TcVxH8+mZZtMzzaZ34ZFRzJw9r1/eq9di+twXvhrwG730u6euKUh8QiKzbpnLb5746VW9zvr9+pL0QLPpnebTM82mZ5pN9/pzJr0WU11tTb99UF/GZWQRExPHV7/5XaB9szAyMpK/+u4PefXl5yg6lz9gWURExDm9FtPhg3soOpePfwD+6+DE0YPk5pzq+HvauAzuvOdhnn7iJ1y8GJxdhyIi4j69nkbxyBe/RlRU+91pv/7tvyM6OiZoQVpbW2mor+v4v8tl1FBfp8ViRURCSK/F1NR0kfiEkQDExydgjBmQUAAFebn8+F9+OGCfJyIi7tDrrrzTp47xyONfo662Bmvhi1/5Fn7b/W69J3/+b0EJKCIioaXXYlrz5h/JzTnFyMQkFixezqkTR2hpaRmobCIiEoJ6LSZrLSeOHQYgM2sC27ZuoLlJ1wyJiEjwBLyGxPPPPdlRSsE8CUJEREJb4Cs/GMP8hcuYPec2IiMjO+5gu2jpSmouXODAvp1BjCkiIqEi4C2mufMWM3XGLN57941Oa9OVlRQzdcbsoIQTEZHQE3AxTZ0+i7Vvv8bRw/s7XXBbUV7CyMRRQQknIiKhJ+BiGj4igfMVZV0e9/v9hIeH92soEREJXQEXU011FcljUro8npU9icrz5f0aSkREQlfAJz/s37ODZXfcQ2trKwAJI0eRPWEyC5fcwftr3wxaQBERCS0BF9Pe3duIjonhgc9+kfDwMD736J/R2trK9q0bOXxwbzAziohICLmqGwVu3fweOz7cxKjRYzDGcL68FJ/PF6xsIiISgq76Ju2tra2UFhdSUnSuo5QyMsf3ezAREQlNARdTeEQEYWGdN7CSx6byuS98lc8/9uf9HkxEREJTn7vy4oYN576HHiU1LQNr/ezesZUtm9ax4s77mTZjFqc/OsHvnvnlQGQVEZEQ0GcxLVqyksjIKN5b+wbXT5nGnLkLSUvPorbmAr/67/+kqrJiIHKKiEiI6HNXXmbWBNa+8xr7dm/nT6++gDGQl/sRb7z6gkpJRET6XZ/FFDdsGBeqKgGor6vF52vlxLFDQQ8mIiKhqc9iMsZgr1gbz1q/ThEXEZGgCeg6pvse/kLHiuJhYeHcfd/n8F1aAeKyl373VP+nExGRkNNnMR0+uK/T348e3h+0MCIiIn0W0ztv/GEgcoiIiACfYuUHERGRYFIxiYiIq6iYRETEVVRMIiLiKiomERFxFRWTiIilDFeNAAASqUlEQVS4iopJRERcRcUkIiKuomISERFXUTGJiIirqJhERMRVVEwiIuIqKiYREXEVFZOIiLiKiklERFxFxSQiIq6iYhIREVdRMYmIiKuomERExFVUTCIi4ioqJhERcRUVk4iIuIqKSUREXEXFJCIirqJiEhERV1ExiYiIq6iYRETEVVRMIiLiKiomERFxlTCnA1zm9XpZvuo+MrMnEBsbR31dLfv2bGfPzg+djiYiIgPINcXk8XhoqK/jpd89xYULVYxOHsvnH/0K9XV1nDh2yOl4IiIyQFxTTD6fjy2b1nX8vby0mJzTJ0hLz+y1mIzHg/Foj+SVLs9Dc+me5tMzzaZnmk3v+nMurimmTzIeD2npWezctrnXn0vJmExbW9vAhBpkUrOmOB3B1TSfnmk2PdNsuuf1evvtvVxbTMtX3kNzUxNHDu3r9eeK80/ha24aoFSDg/F4SM2aQtHZ41i/3+k4rqP59Eyz6Zlm07vwyChmzp7XL+/lymJasnw149KzeP65J/D3sTVk/X59SXqg2fRO8+mZZtMzzaZ7/TkT1xXT0jvuJjNrAi889yQXGxudjiMiIgPMVUfxlq28h6zsibzw3JM0NjY4HUdERBzgmi2m4SPiuXnOPFpbfXzjr/++4/Fz+Wd5+fmnHUwmIiIDyTXFVFtTzT//w/9yOoaIiDjMVbvyREREVEwiIuIqKiYREXEVFZOIiLiKiklERFxFxSQiIq6iYhIREVdRMYmIiKuomERExFVUTCIi4ioqJhERcRUVk4iIuIqKSUREXEXFJCIirqJiEhERV1ExiYiIq6iYRETEVVRMIiLiKiomERFxFRWTiIi4iopJRERcRcUkIiKuomISERFXUTGJiIirqJhERMRVVEwiIuIqKiYREXEVFZOIiLiKiklERFxFxSQiIq6iYhIREVdRMYmIiKuomERExFVUTCIi4ioqJhERcRUVk4iIuIqKSUREXEXFJCIirqJiEhERV1ExiYiIq6iYRETEVVRMIiLiKiomERFxFRWTiIi4iopJRERcRcUkIiKuomISERFXUTGJiIirqJhERMRVVEwiIuIqKiYREXGVMKcDXMl4PCxdvpobp8/CGMPJ44dZ987rtLW1OR1NREQGiKu2mG6bfzvpmeN56pf/yRM/+1dGJY1h0dJVTscSEZEB5Kotpukzb2HDureor6sFYOvm9dz74CNsWP82WNvta8IjIgcy4qBgPB68Xi/hkVFYv9/pOK6j+fRMs+mZZtO7/vxd7JpiioyKYsSIBEpLijseKyspIjo6huHDR1BbU93p58PCIwC4457HBjTnYDJz9jynI7ia5tMzzaZnmk3vwsIjaPW1XNt79FOWaxZxqW2bmy92PNbU1P7nyMiuTdzUWM+a15655gGIiEj/CAuPoKmx/trfpx+y9IuWlmYAIiOjudjYCEBUVDQAzc3N3b6mPwYgIiL9o782FFxz8kNzUxM1NRdIHpPS8Vjy2FQuXmyktrbGwWQiIjKQXFNMAIf27+a2BbcTN2w4MTGxzF+0jMMH9/Z44oOIiAw9rtmVB7Bt60aiY2L56jf+tuM6ps0b3nU6loiIDCAzZ8Gd2hwRERHXcNUWE8Dqez/LDVNndFrt4flnn6CkuBDoe3WIobx6RG+z8Xq9LF91H5nZE4iNjaO+rpZ9e7azZ+eHHT87lGcDfX93LgsLC+Mr3/hbYmJi+fG//LDj8aE8n0BmM2HS9SxYvJyRiUm0NDeza8cWdm3/AAjt2cQNG87ylfeSnpkNQGFBHuvWvE7dpWPfQ3k2V+rp+xGM38muKyaAfXt28P7aN7t97srVIfxtbTz4+S+xaOkqNqx7K6DnB7ueZuPxeGior+Ol3z3FhQtVjE4ey+cf/Qr1dXWcOHYIGPqzgd6/O5ctWLyCutoaYmJiOz0+1OfT22yyJ0xm5eoHeOv1l8jPzyU8PJwRI+I7ng/l2ay48z6MMfzypz/Cb/3cefdDrLrrQV5+/mlg6M8Gev9+BON3sqtOfgjE9Jm3sG3L+9TX1dLY2MDWzeuZNmM2GBPQ80OVz+djy6Z1XKiqBGspLy0m5/QJ0tIzO34mVGdzpeSxqYyfeB3bt27s8lwoz2fB4hVs27KBvLM5WL+fluZmKsrLOp4P5dkkJCRy4ughWlqaafX5OHp4P0nJYzqeD4XZ9Pb9CMbvZFduMU2dPoup02dRX1fLoQN72L1zK1jb5+oQzc1NV7V6xGDU02w+yXg8pKVnsXPbZuDqV9YYrHqbj/F4WHXXg6xb83qX14XCfHqaTXh4OGNTUjl+9CB//s3vEh0dQ+G5fN5b+wa1NdUhPRuAXTu2cP0N08k5fQLrt0ydPoszH50EQuN709v3o6/fuZ/2d7LrimnPrg/ZuP5tLl5sJCU1nXsfegRrLXt2bu1zdQh76YsU6OoRg01vs/mk5SvvobmpiSOH9gFXv7LGYNTXfObcuoDyshIK8nI7jhdcNtTn09tsoqJjMMbDtBmzefn5p2loqGfZiru5/+HHePapn4X0bKD9mNKMm27mO9/7R6yF8rJiXnjuV8DQ/94AvX4/Xn35OaD/fye7bldeWUkRjY0NWGspKsxnx4ebmHLjdKDz6hCXXbk6RF/PD3a9zeZKS5avZlx6Fi8//2v8lw4wDvXZQO/ziU9IZNYtc9m4/u1uXzvU59Prv1eX/vn27PqQmuoLtPp8bN74Limp44gbNjykZ4MxfP6xr1JYWMC///MP+I8f/YCzuTl89tE/A4b+9wZ6/35cLp7+/p3sumL6JHvFbqq+VocItdUjbDe78JbecTdZ4yfxwnNPdiztBKG5ssaV8xmXkUVMTBxf/eZ3+avv/pAHPvtFIiMj+avv/pDUcRkhN59O/141N1FdXdV5l/AVfwzl2URHRxMfP5K9uz6k1eej1edj764PSU3LIDomJiRm09f3Ixi/k11XTNffMI2IS5t4Y1LSuHXeYk4eP9LxfF+rQwzl1SP6ms2ylfeQlT2RF557ksbGhi6vH8qzgd7nc+LoQX75Xz/i6Sd+wtNP/IQ1b75Cc3MzTz/xk47TgofyfPr67hzYu5ObPzOfYcNH4A0LY8HtKyguOtdxC5pQnc3FxkaqKiuYdfNcvGFheMPCmD1nHrU11R3/4TeUZ3NZb9+PYPxOdt0Fto9+6euMTh6Lx+OhrraGQwf2sHP7B50OYC9dcRc3Tpv58Tnxa/5EW2trQM8PZr3NZviIeP7yb/4Pra0+/FfcK+Zc/tmO01qH8myg7+/OldIzs3nwc493vY5piM6nz9kYw+IlK5l+081gDIUFeax/908dB6dDeTajkkazdMXdjElJwxhDWWkxG9a9RVlp+wH9oTybDr18P4LxO9l1xSQiIqHNdbvyREQktKmYRETEVVRMIiLiKiomERFxFRWTiIi4iopJRERcRcUkchXSM7P5/j/8O8OGj3A6Sof5i5bxtb/63qd6bXhEBN/6zg8Ym5LWz6m6iohoX2ljdPLYoH+WDG4qJnGN6TfdzPf+33/pWBjzsq98/Ts9Pr763s8OZERHDRs+gu//w793WYD2Wtx622JKigu73EwxGFpamtm9YwtLVtwV9M+SwU3FJK5xNvc0Xq+30y/e6JgYRiUlU19f2+XxpNHJ5J3NcSLqkOANC2PmzbdyYN/OAfvMwwf3kJ6RTdLo5AH7TBl8XHfbCwldtTXVVFWdJzNrAjkfnQAgM2sCFeWlnMvP7fK4MR7yck8DMCI+gaUr7iIlLZ2oqGguVFWyc9tmjh7eD8CMmbdw+/LV/Ow//onWK5ZC+cxti7h5zjx+/pP/C9aSMDKRxUvvJDN7AtZaSooL2bDuLSrKS3vM3ddrps6YzZ13P8jvn3mC5avuIXHUaCrKy1j79quUlhR1vE9m9kSWrriLkYmjqKo8z/o1f+LRL32dN157kWOH9/Ot7/wAgEcf/zoA1dVV/PKnP+p4/cTJN3D7slUMGx5PSVEB77z5R6ovVPaYe/yEyYSFhZN75qOOx0bEJ/DNv/4+r7/yO26cNovM7AnU19exddP6jlkCfP8f/p31a/5EWnomEyZN4eLFBjase4uzZ06z4s77mDh5Co2NDWxc/w6nTny8Jl9jQwNF5/K4YdpMNr//bo/ZJLRpi0lcJT83h8zsiR1/z8iaQP7ZHPLOnuny+PmKso5FRiMiIsnLzeGl3z/NU7/8MQf37WL1vQ+TkTkegBPHDuP1hjHpuhs7fd7U6bPaf+FaS2xsHF/48jdpbKjnd7/5Jc/9+hdUnS/nkce/1uU27JcF+hpjDIuWruS9d9/kN0/+lKami9z30BcwnvZ/BeOGDeehzz9OcVEBv3nyp7y/9s0uu7yefuInALz68nP813/8E8/+6mcdz8XFDWfmzbfyxqsv8Nunf0FkVDSr73mo11mnZ2RTVlqEvWJtxcsWLV3F0cP7+PX//JgTxw6x+t6HSRg5qtPPzF2whDOnT/L0Ez8m56MT3HXf57j3wUc4m3ua3zz5U85ceiw6OqbT64qKzpGROaHXbBLaVEziKnlnT5M0OpmY2PZf6hlZE8jPO0NB/hlGJY3u9PjlrSWAivJS9u3ZTkVZCdUXKtm7exs5H51kytSbgPal+0+fOsbU6bM6XpM8NpWk0WM6bqY48+ZbqamuYu07r1FRXkpVZQXr332D5qYmbph2U7d5A32NMR7eW/sm5wrOUnm+gi2b1pEwMpGEhEQAZt08l4aGet5961XOV5STdzaHDzau7fRZl1eMv3ixkYb6uk4ryIeFeXnrtRcpLSmivKyEnds2MS4jC29YzztFRiSMpK6HWw/s272dE8cOc6Gqkg82rqO1tZXMrM5lcvzoQY4c2seFqkq2blpPeHgEF6rOc+TgXi5UVbJl03oiIiJIHZfR6XV1tdUkJIzsMZeIduWJq1w+ZpSZNZFzBWdJSBhJQV4uzc1NlJeVdDyemJjExvXvdLwuLDyceQuXMnHSFOKGDcfr9eL1hpGfd6bjZ44c2sdDn3+c2LhhNNTXMXXaTEqKz3G+ogyAsSnjGDM2je9+///rlCksLJyRI5O6zRvoa6z1U1768e2lLxdCbFwcVZUVjEpKpqToXKd7ARWdyw94bnV1tZ2Kqq62FmM8xMbG9Xj76vCwcJqbmrp9rqz0412M1u+nob6e2Li4Tj9z5T9PY2MDfn8b5WUlHY81NV2ktbWVmNjOr2ttbSUsPDzgfzYJPSomcZWLjY2UlZaQmT0Br9dLaUkRzc3tvzzzz57peNzvb6PgitJZsmw1E6+bwoZ1b1N5vhyfr4Uly+8iMiqq42dyc07R2NDADVNvYs+uD5ky9Sa2b93Q8bwxhryzOaxf83qXXD39Ag/0Ndbabm/saIzpcRaWwBf+b7t0p+JPvra3929sbOiym6239/vke7V1swuw62NdXxcdHUNjQ9f7hYlcpmIS18k7m8N110/F4/F2OusuP+8My1fei8fjpaS4sKOwoP0OtccOH+DEsUPtDxjDyMRRNDTUd/yMtZZjRw4wdfosKs+XEx0dzfEjBzueLykuZNqM2dTV1nQ6QaI3n+Y13TlfUcYNU2/CGNNRYKlpnXeBtbW1v7/H9M8e+NKSImbdMrdf3utqJI0eQ0nxuQH/XBk8dIxJXCcv9zTxCSOZfP2N5J/9eKuoID+X4SNGMPn6G8nL7XyaeFVlBZOuu4GxqeMYlTSaVXc9QNyw4V3e+/ChfSSPSWHh7Xdw5vSpTru/9u3ehvEYHvzc44xLz2JEfAJp6ZksvP2OLsdJruU13b7Pnu3ExsVxx+r7SRw1mozM8Sxackf7k5eKqrGxkebmJrLGTyI2bhhRUdEBv393zpw+SUJC4oBfLJyekU3O6ZMD+pkyuGiLSVznXH4ubW2thIWFca7gbMfjLc3NlBQXkZqW3unEB4D31r7JnXc/xCNf/BotzU0c2LeLk8ePkDAysdPPVZSVUFpSxJixqWzbsqHTcw0N9Tz361+waMlKHvjsY0RERtFQX8e5grMdZ/990qd5TXfq62p55cVnWXbH3UydPpuqygo2vvcOn3v0Kx9viVnLujV/YsGi5dxy6wLq6mo6nS5+tSrPl5N/Noep02exfevGT/0+VyMjczzhEREfb9mKdEN3sBVxqXEZWXzhS9/gqV/+Z6/XUV3TZ6Rnce+Dj/A/P/9XWn2+oHzGlR5+5MsU5OWyc9vmoH+WDF7etIxJ/+B0CBGBmbNvxeP14vF4SBuXyYpV93Gh6nxQt2Zqa6ppaWmmpbm5027NYIiIiGTY8Hh27/ig2xNBRC7TFpOISyxaupIbpt5EbGz76exncz9i03truHix0eloIgNKxSQiIq6is/JERMRVVEwiIuIqKiYREXEVFZOIiLiKiklERFxFxSQiIq7y/wPSN/d99O68gAAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from jupyterthemes import jtplot\n", "# currently installed theme will be used to\n", "# set plot style if no arguments provided\n", "jtplot.style()\n", "\n", "#Rs = oqx.tmm_eval_wsweep(rndtop5(bests[np.argmin(bfits)]),0, lam_pts=50)\n", "Rs = oqx.tmm_eval_wsweep(rndtop5(bests_g[ np.random.randint(0,20) ]),0, lam_pts=50)\n", "\n", "#Rs = qn.tmm_eval_wsweep(qx, d_min=2 , d_max=10, inc_ang=0, lam_low=400, lam_high=800, lam_pts=50, n_subs=1.52) # in nm\n", "lams = np.linspace(400, 800, endpoint=True, num=50)\n", "\n", "meanl = np.ones_like(lams)*np.mean(oqx.tmm_eval_wsweep(rndtop5(bests[np.argmin(bfits)]),0))\n", "plt.plot(lams, Rs )\n", "#plt.plot(lams, R_ref)\n", "plt.xlabel('Wavelength (nm)')\n", "plt.ylabel('Reflectance (%)')\n", "plt.ylim([0,10])\n", "plt.xlim([500,600])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "ExecuteTime": { "end_time": "2018-12-24T16:19:52.888956Z", "start_time": "2018-12-24T16:19:52.800125Z" } }, "outputs": [ { "data": { "text/plain": [ "array([400. , 408.16326531, 416.32653061, 424.48979592,\n", " 432.65306122, 440.81632653, 448.97959184, 457.14285714,\n", " 465.30612245, 473.46938776, 481.63265306, 489.79591837,\n", " 497.95918367, 506.12244898, 514.28571429, 522.44897959,\n", " 530.6122449 , 538.7755102 , 546.93877551, 555.10204082,\n", " 563.26530612, 571.42857143, 579.59183673, 587.75510204,\n", " 595.91836735, 604.08163265, 612.24489796, 620.40816327,\n", " 628.57142857, 636.73469388, 644.89795918, 653.06122449,\n", " 661.2244898 , 669.3877551 , 677.55102041, 685.71428571,\n", " 693.87755102, 702.04081633, 710.20408163, 718.36734694,\n", " 726.53061224, 734.69387755, 742.85714286, 751.02040816,\n", " 759.18367347, 767.34693878, 775.51020408, 783.67346939,\n", " 791.83673469, 800. ])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R_ref = np.linspace(400.0, 800.0, endpoint=True, num=50)\n", "# narrow band transmission filter\n", "#R_ref[0:83] = 0.0\n", "R_ref" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-12-08T17:35:57.288922Z", "start_time": "2018-12-08T17:13:28.915427Z" } }, "outputs": [], "source": [ "%reload_ext autoreload\n", "%autoreload 2\n", "import warnings\n", "warnings.filterwarnings(\"ignore\",category =RuntimeWarning)\n", "import numpy as np\n", "import de2 as de\n", "import multiprocessing as mp\n", "import makeqx as mkq\n", "import qxnew as qn \n", "\n", "def rndtop5(x):\n", " return np.round(x*2.0)/2\n", "\n", "def tmm_wrapper2(arg):\n", " args, kwargs = arg\n", " return qn.tmm_eval_wsweep(*args, **kwargs)\n", "\n", "def arc_par(pop, **kwargs):\n", " jobs = []\n", " pool=mp.Pool(90)\n", " for indiv in pop:\n", " indiv = indiv.reshape((int(indiv.size/2), 2))\n", " indiv[:,1] = mkq.digitize_qx(indiv[:,1], dlevels=2)\n", " indiv[:,0] = rndtop5(indiv[:,0])\n", " indiv = indiv.flatten()\n", " jobs.append((indiv, 0, 1, 0))\n", " arg = [(j, kwargs) for j in jobs]\n", " answ = np.array(pool.map(tmm_wrapper2, arg))\n", " pool.close()\n", " \n", " c1 = np.mean(answ, axis=1)\n", " c2 = np.zeros_like(c1)\n", " for idx, indiv in enumerate(pop):\n", " c2[idx] = np.sum(indiv[::2])\n", " if c2[idx] <= 480:\n", " c2[idx] = 480/c2[idx]\n", " else:\n", " c2[idx] = 0.0\n", " return c1\n", "\n", " \n", "num_layers = 25\n", "d_min = 0.5\n", "d_max = 20 \n", "\n", "bnds = [(d_min, d_max), (0,1)]*num_layers\n", "its_first = 0\n", "psnew = 40\n", "islands = 9\n", "its_second = 256\n", "numgens = 5\n", "\n", "isl = np.ones((psnew*islands, 2*num_layers))\n", "for indiv in range(int(psnew*islands)):\n", " isl[indiv] = np.random.uniform(0,1, 2*num_layers)\n", " #isl[indiv] = qn.make_qxn(num_layers, dlevels=2)\n", "poplist = np.split(isl, islands)\n", "\n", "bids = np.zeros(islands, dtype=int)\n", "bfits = np.zeros(islands)\n", "bests = isl[0:islands]\n", "\n", "\n", "for gen in range(numgens):\n", " print(\"==============================\")\n", " print(\"Epoch #:\" + str(gen + 1))\n", " print(\"==============================\")\n", " \n", " for isln in range(islands):\n", " print(\"----------------- I-\" + str(isln + 1)+ \"---------------------\")\n", " poplist[isln], bids[isln], bfits[isln], bests[isln] = de.de_cp(\n", " fobj=arc_par, \n", " bounds=bnds, \n", " pop=poplist[isln], \n", " history=[], \n", " it_start=its_first, \n", " popsize=psnew, \n", " its=its_second, \n", " lam_low=400, \n", " lam_high=800, \n", " lam_pts=50)\n", " print(np.sum(bests[isln][::2]))\n", " \n", " if its_second > 64:\n", " its_second = int(its_second/2)\n", " \n", " if gen < (numgens - 1):\n", " print(\"Round robin best migration\")\n", " stmp = np.copy(poplist[islands-1][bids[islands-1]])\n", " for isln in range(1, islands):\n", " poplist[isln][bids[isln]] = poplist[isln-1][bids[isln-1]]\n", " poplist[0][bids[0]] = stmp \n", " \n", "print(bfits) \n", "print(bests[np.argmin(bfits)][::2])\n", "print(bests[np.argmin(bfits)][1::2])\n", "print(np.sum(bests[np.argmin(bfits)][::2]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-12-02T16:56:30.208676Z", "start_time": "2018-12-02T16:56:30.117250Z" } }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from jupyterthemes import jtplot\n", "# currently installed theme will be used to\n", "# set plot style if no arguments provided\n", "jtplot.style()\n", "bri = bests[np.argmin(bfits)][1::2]\n", "brx = bests[np.argmin(bfits)][::2]\n", "xarr = np.cumsum(brx)\n", "print(bri)\n", "# plt.plot(xarr, bri)\n", "# plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-27T12:04:52.963380Z", "start_time": "2018-11-27T12:04:52.942435Z" } }, "outputs": [], "source": [ "def rndtop5(x):\n", " return np.round(x*2.0)/2\n", "rndtop5(1.63)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-12-20T08:01:38.243818Z", "start_time": "2018-12-20T08:01:38.177561Z" } }, "outputs": [], "source": [ "lams" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-12-20T08:03:54.562143Z", "start_time": "2018-12-20T08:03:54.497758Z" } }, "outputs": [], "source": [ "lams[88]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2018-12-21T05:43:35.814848Z", "start_time": "2018-12-21T05:43:35.798642Z" } }, "outputs": [], "source": [ "a = np.linspace(1, 10, num=10)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2018-12-21T05:45:48.731087Z", "start_time": "2018-12-21T05:45:48.715074Z" } }, "outputs": [], "source": [ "left_r = a[a<4].size\n", "right_r = a[a<=8].size\n", "a[left_r:right_r] = 0.0" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2018-12-21T05:45:52.864078Z", "start_time": "2018-12-21T05:45:52.846815Z" } }, "outputs": [ { "data": { "text/plain": [ "array([ 1., 2., 3., 0., 0., 0., 0., 0., 9., 10.])" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }