Skip to content

Instantly share code, notes, and snippets.

@stic
Created May 13, 2014 17:16
Show Gist options
  • Save stic/b1f45cbcabfa0aa7f6c9 to your computer and use it in GitHub Desktop.
Save stic/b1f45cbcabfa0aa7f6c9 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "",
"signature": "sha256:34c4297a270dc9233bf4024584a57c70393089cd59bdd3b1ceec19bb926259c1"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"from IPython import parallel in 15 min"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Based on the [Parallel Monto-Carlo options pricing](http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/Parallel%20Computing/Monte%20Carlo%20Options.ipynb) from [IPython.parallel examples](http://nbviewer.ipython.org/github/ipython/ipython/tree/master/examples/Parallel%20Computing/).\n",
"\n",
"This notebook shows how to use `IPython.parallel` to do Monte-Carlo options pricing in parallel. \n",
"We will compute the price of a large number of options for different strike prices and volatilities."
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Few words about IPython ecosystem"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.display import HTML\n",
"HTML('<iframe src=http://ipython.org/index.html width=1024 height=350></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://ipython.org/index.html width=1024 height=350></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"<IPython.core.display.HTML at 0x1069e0f10>"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://nbviewer.ipython.org/ width=1024 height=350></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://nbviewer.ipython.org/ width=1024 height=350></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"<IPython.core.display.HTML at 0x103fd6ed0>"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://continuum.io/downloads width=1024 height=350></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://continuum.io/downloads width=1024 height=350></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 6,
"text": [
"<IPython.core.display.HTML at 0x10634fa90>"
]
}
],
"prompt_number": 6
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Have we got a cluster running?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![IPython parallel cluster](http://ipython.org/ipython-doc/stable/_images/wideView.png)\n",
"\n",
"First we my need to create a profile (default will be there by default) \n",
"`ipython profile create --parallel --profile=yourProfileName` \n",
"\n",
"You can start it by using the IPython Notebook's [Clusters tab](http://127.0.0.1:8888/tree#clusters) \n",
" \n",
"Or by calling (of it form): \n",
"`ipcluster start -n 4` \n",
"\n",
"Or the combination of \n",
"`ipcontroller --ip=192.169.X.Y` and `ipengine` \n",
"Where you want really want your controller to start up first, whilst engines will checks the ipcontroller-engine.json file it generates (you will copy it from say .ipython/profile_default/security/ipcontroller-engine.json to location from where engine will read it).\n",
"\n",
"If you are on restricted network, don't worry there is support for [SSH tunneling](http://ipython.org/ipython-doc/dev/parallel/parallel_process.html#ssh-tunnels)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.parallel import Client\n",
"c = Client()\n",
"c.history, c.ids"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 1,
"text": [
"([], [0, 1, 2, 3, 4, 5, 6, 7])"
]
}
],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dv = c[:]\n",
"print(type(dv))\n",
"\n",
"lv = c.load_balanced_view()\n",
"print(type(lv))\n",
"\n",
"dv.results.items()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"<class 'IPython.parallel.client.view.DirectView'>\n",
"<class 'IPython.parallel.client.view.LoadBalancedView'>\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"[]"
]
}
],
"prompt_number": 2
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Passing data around"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ar = dv.scatter('x', range(64),block=True)\n",
"print(type(ar))\n",
"\n",
"ar = dv.scatter('x', range(1024*1024*30),block=False)\n",
"ar.get(), ar.progress, ar.elapsed, ar.ready(), ar.serial_time, ar.wall_time"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"<type 'NoneType'>\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"text": [
"([None, None, None, None, None, None, None, None],\n",
" 8,\n",
" 1.509833,\n",
" True,\n",
" 1.4056050000000002,\n",
" 1.509833)"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"l = c[4]['x']\n",
"print(4, min(l), max(l), len(l))\n",
"l = c[6]['x']\n",
"print(6, min(l), max(l), len(l))\n",
"\n",
"c[0].push(dict(x=[0]))\n",
"l= dv.pull('x',targets=0,block=True)\n",
"print(0, min(l), max(l), len(l))\n",
"\n",
"l = c[7].pull('x').get()\n",
"print(7, min(l), max(l), len(l))\n",
"\n",
"dv.push(dict(x=[1]))\n",
"dv.gather('x').get()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(4, 15728640, 19660799, 3932160)\n",
"(6, 23592960, 27525119, 3932160)"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"(0, 0, 0, 1)\n",
"(7, 27525120, 31457279, 3932160)"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"text": [
"[1, 1, 1, 1, 1, 1, 1, 1]"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import gc\n",
"gc.collect()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 6,
"text": [
"0"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"with c[:].sync_imports():\n",
" import gc\n",
"\n",
"%px gc.collect()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"importing gc on engine(s)\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[0:1]: \u001b[0m35"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[1:1]: \u001b[0m32"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[2:1]: \u001b[0m32"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[3:1]: \u001b[0m32"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[4:1]: \u001b[0m32"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[5:1]: \u001b[0m32"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[6:1]: \u001b[0m32"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\u001b[0;31mOut[7:1]: \u001b[0m32"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"with c[:].sync_imports():\n",
" import numpy\n",
" \n",
"%px x = numpy.random.randint(0,1024,10)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"importing numpy on engine(s)\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%px --targets ::2\n",
"x.sort()\n",
"print(x, numpy.average(x))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[stdout:0] (array([ 46, 84, 249, 303, 435, 554, 632, 663, 854, 926]), 474.60000000000002)\n",
"[stdout:2] (array([ 71, 89, 298, 367, 500, 528, 619, 676, 870, 901]), 491.89999999999998)\n",
"[stdout:4] (array([ 61, 77, 93, 144, 215, 282, 418, 512, 714, 813]), 332.89999999999998)\n",
"[stdout:6] (array([ 4, 72, 201, 201, 444, 542, 820, 824, 842, 928]), 487.80000000000001)\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%pxconfig --noblock --targets [0,1,2,3]\n",
"%px print (x, numpy.average(x))\n",
"%pxresult"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[stdout:0] (array([ 46, 84, 249, 303, 435, 554, 632, 663, 854, 926]), 474.60000000000002)\n",
"[stdout:1] (array([668, 983, 168, 522, 232, 540, 547, 673, 310, 842]), 548.5)\n",
"[stdout:2] (array([ 71, 89, 298, 367, 500, 528, 619, 676, 870, 901]), 491.89999999999998)\n",
"[stdout:3] (array([1010, 793, 265, 869, 427, 757, 181, 732, 466, 966]), 646.60000000000002)\n"
]
}
],
"prompt_number": 11
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Debugging"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.parallel import CompositeError\n",
"import random\n",
"\n",
"print( c[0].pull('x').get() )\n",
"c[0].execute('numpy.append(x,[1,2,3])')\n",
"print( c[0].pull('x').get() )\n",
"\n",
"i = random.choice(c.ids)\n",
"c[i].execute('x = numpy.append(x,[0])')\n",
"print( i, c[i].pull('x').get() )\n",
"\n",
"try:\n",
" dv.execute('y = int(numpy.max(x)) / int(numpy.min(x))', block=True)\n",
"except CompositeError, e:\n",
" print e\n",
"\n",
"%px print y\n",
"%pxresult"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[ 46 84 249 303 435 554 632 663 854 926]\n",
"[ 46 84 249 303 435 554 632 663 854 926]\n",
"(7, array([791, 497, 459, 970, 29, 860, 1, 547, 445, 51, 0]))\n",
"one or more exceptions from call to method: execute\n",
"[7:execute]: ZeroDivisionError: integer division or modulo by zero\n",
"[stdout:0] 20\n",
"[stdout:1] 5\n",
"[stdout:2] 12\n",
"[stdout:3] 5\n"
]
}
],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%px --targets 7\n",
"from IPython import parallel\n",
"parallel.bind_kernel()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"<AsyncResult: execute>"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"c[7].execute(\"%qtconsole\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 14,
"text": [
"<AsyncResult: execute>"
]
}
],
"prompt_number": 14
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Just one more word on AsyncResult"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import time, os\n",
"\n",
"def getFewDetailsWithDelay(delay):\n",
" time.sleep(delay)\n",
" return os.getpid()\n",
"\n",
"getFewDetailsWithDelay(0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 15,
"text": [
"1003"
]
}
],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dv.apply_sync(getFewDetailsWithDelay,3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "CompositeError",
"evalue": "one or more exceptions from call to method: getFewDetailsWithDelay\n[0:apply]: NameError: global name 'time' is not defined\n[1:apply]: NameError: global name 'time' is not defined\n[2:apply]: NameError: global name 'time' is not defined\n[3:apply]: NameError: global name 'time' is not defined\n.... 4 more exceptions ...",
"output_type": "pyerr",
"traceback": [
"[0:apply]: ",
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m",
"\u001b[0;32m<ipython-input-15-94d42fdec29e>\u001b[0m in \u001b[0;36mgetFewDetailsWithDelay\u001b[0;34m(delay)\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: global name 'time' is not defined",
"",
"[1:apply]: ",
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m",
"\u001b[0;32m<ipython-input-15-94d42fdec29e>\u001b[0m in \u001b[0;36mgetFewDetailsWithDelay\u001b[0;34m(delay)\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: global name 'time' is not defined",
"",
"[2:apply]: ",
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m",
"\u001b[0;32m<ipython-input-15-94d42fdec29e>\u001b[0m in \u001b[0;36mgetFewDetailsWithDelay\u001b[0;34m(delay)\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: global name 'time' is not defined",
"",
"[3:apply]: ",
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)\u001b[0;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m",
"\u001b[0;32m<ipython-input-15-94d42fdec29e>\u001b[0m in \u001b[0;36mgetFewDetailsWithDelay\u001b[0;34m(delay)\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: global name 'time' is not defined",
"",
"... 4 more exceptions ..."
]
}
],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import random, time, os\n",
"from IPython.parallel import require\n",
"\n",
"@require(random, os,time)\n",
"def getFewDetails():\n",
" delay = random.randint(0,10)\n",
" time.sleep(delay)\n",
" return os.getpid()\n",
"\n",
"ar = dv.apply_async(getFewDetails)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ar.progress"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 20,
"text": [
"6"
]
}
],
"prompt_number": 20
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ar.progress, ar.get(), ar.wall_time, ar.serial_time"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 11,
"text": [
"(8, [958, 959, 960, 962, 964, 966, 968, 970], 11.804897, 42.011956)"
]
}
],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ar.metadata"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"[{'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 3, 58, 285200),\n",
" 'data': {},\n",
" 'engine_id': 0,\n",
" 'engine_uuid': u'ba31eb76-1217-44df-82af-8870c8c17d15',\n",
" 'follow': [],\n",
" 'msg_id': u'fe78a315-1bf9-4f82-aebc-31ebcd093e57',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 4, 2, 240695),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 283631),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 282470)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 4, 0, 286009),\n",
" 'data': {},\n",
" 'engine_id': 1,\n",
" 'engine_uuid': u'05f0a6ff-7715-4062-b575-627f95e29f8a',\n",
" 'follow': [],\n",
" 'msg_id': u'6a995734-8df7-474e-8433-ad7b9137c7a4',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 4, 2, 240962),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 284073),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 282961)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 3, 54, 286427),\n",
" 'data': {},\n",
" 'engine_id': 2,\n",
" 'engine_uuid': u'43d8a2f4-ba1b-4304-8b29-eb45e130a35d',\n",
" 'follow': [],\n",
" 'msg_id': u'f9779891-ffd3-4db7-a5f0-2442f36aaa7b',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 3, 56, 793936),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 284512),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 283322)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 3, 57, 286755),\n",
" 'data': {},\n",
" 'engine_id': 3,\n",
" 'engine_uuid': u'e21503df-6d18-40a3-bffc-8c49ae424d13',\n",
" 'follow': [],\n",
" 'msg_id': u'006c821d-abc0-4343-a34a-a24ac4e0a66c',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 4, 2, 240415),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 284896),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 283772)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 4, 2, 286722),\n",
" 'data': {},\n",
" 'engine_id': 4,\n",
" 'engine_uuid': u'2f57e043-66b9-4c97-8da3-85e3fc0e0f35',\n",
" 'follow': [],\n",
" 'msg_id': u'42758df8-b2d6-42db-9f32-1948995b8875',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 4, 5, 87091),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 285488),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 284333)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 4, 3, 287014),\n",
" 'data': {},\n",
" 'engine_id': 5,\n",
" 'engine_uuid': u'90542186-be03-4f76-a1cc-9ba1f369d923',\n",
" 'follow': [],\n",
" 'msg_id': u'b4aecfae-c65a-4f1c-a327-68e0455cda0b',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 4, 5, 87367),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 285975),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 284746)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 3, 56, 287606),\n",
" 'data': {},\n",
" 'engine_id': 6,\n",
" 'engine_uuid': u'72fc0dc7-6eeb-4aa1-af33-742596df6668',\n",
" 'follow': [],\n",
" 'msg_id': u'b468b05c-e12a-4767-847f-9a5438e43381',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 3, 56, 794206),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 286268),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 285210)},\n",
" {'after': [],\n",
" 'completed': datetime.datetime(2014, 5, 10, 15, 3, 56, 287676),\n",
" 'data': {},\n",
" 'engine_id': 7,\n",
" 'engine_uuid': u'4baa2775-2078-4586-bea4-bc21c0033127',\n",
" 'follow': [],\n",
" 'msg_id': u'bb2eb562-0cca-4b9f-b29a-dec40a32e02c',\n",
" 'outputs': [],\n",
" 'outputs_ready': True,\n",
" 'pyerr': None,\n",
" 'pyin': None,\n",
" 'pyout': None,\n",
" 'received': datetime.datetime(2014, 5, 10, 15, 3, 56, 794437),\n",
" 'started': datetime.datetime(2014, 5, 10, 15, 3, 53, 286610),\n",
" 'status': u'ok',\n",
" 'stderr': '',\n",
" 'stdout': '',\n",
" 'submitted': datetime.datetime(2014, 5, 10, 15, 3, 53, 285613)}]"
]
}
],
"prompt_number": 12
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Let's run a simple simulation"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"import sys\n",
"import time\n",
"import numpy as np"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here are the basic parameters for our computation."
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"price = 100.0 # Initial price\n",
"rate = 0.05 # Interest rate\n",
"days = 260 # Days to expiration\n",
"paths = 100000 # Number of MC paths\n",
"n_strikes = 6 # Number of strike values\n",
"min_strike = 90.0 # Min strike price\n",
"max_strike = 110.0 # Max strike price\n",
"n_sigmas = 5 # Number of volatility values\n",
"min_sigma = 0.1 # Min volatility\n",
"max_sigma = 0.4 # Max volatility"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"strike_vals = np.linspace(min_strike, max_strike, n_strikes)\n",
"sigma_vals = np.linspace(min_sigma, max_sigma, n_sigmas)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print \"Strike prices: \", strike_vals\n",
"print \"Volatilities: \", sigma_vals"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Strike prices: [ 90. 94. 98. 102. 106. 110.]\n",
"Volatilities: [ 0.1 0.175 0.25 0.325 0.4 ]\n"
]
}
],
"prompt_number": 17
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Monte-Carlo option pricing function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following function computes the price of a single option. It returns the call and put prices for both European and Asian style options."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def price_option(S=100.0, K=100.0, sigma=0.25, r=0.05, days=260, paths=10000):\n",
" \"\"\"\n",
" Price European and Asian options using a Monte Carlo method.\n",
"\n",
" Parameters\n",
" ----------\n",
" S : float\n",
" The initial price of the stock.\n",
" K : float\n",
" The strike price of the option.\n",
" sigma : float\n",
" The volatility of the stock.\n",
" r : float\n",
" The risk free interest rate.\n",
" days : int\n",
" The number of days until the option expires.\n",
" paths : int\n",
" The number of Monte Carlo paths used to price the option.\n",
"\n",
" Returns\n",
" -------\n",
" A tuple of (E. call, E. put, A. call, A. put) option prices.\n",
" \"\"\"\n",
" import numpy as np\n",
" from math import exp,sqrt\n",
" \n",
" h = 1.0/days\n",
" const1 = exp((r-0.5*sigma**2)*h)\n",
" const2 = sigma*sqrt(h)\n",
" stock_price = S*np.ones(paths, dtype='float64')\n",
" stock_price_sum = np.zeros(paths, dtype='float64')\n",
" for j in range(days):\n",
" growth_factor = const1*np.exp(const2*np.random.standard_normal(paths))\n",
" stock_price = stock_price*growth_factor\n",
" stock_price_sum = stock_price_sum + stock_price\n",
" stock_price_avg = stock_price_sum/days\n",
" zeros = np.zeros(paths, dtype='float64')\n",
" r_factor = exp(-r*h*days)\n",
" euro_put = r_factor*np.mean(np.maximum(zeros, K-stock_price))\n",
" asian_put = r_factor*np.mean(np.maximum(zeros, K-stock_price_avg))\n",
" euro_call = r_factor*np.mean(np.maximum(zeros, stock_price-K))\n",
" asian_call = r_factor*np.mean(np.maximum(zeros, stock_price_avg-K))\n",
" return (euro_call, euro_put, asian_call, asian_put)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can time a single call of this function using the `%timeit` magic:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit -n1 -r1 print price_option(S=100.0, K=100.0, sigma=0.25, r=0.05, days=260, paths=100000)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(12.374451344147433, 7.4518010512618824, 6.8561124933571236, 4.4580879409633019)\n",
"1 loops, best of 1: 1.06 s per loop\n"
]
}
],
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Parallel computation across strike prices and volatilities"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Client is used to setup the calculation and works with all engines."
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"rc = Client()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 20
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A `LoadBalancedView` is an interface to the engines that provides dynamic load\n",
"balancing at the expense of not knowing which engine will execute the code."
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"view = rc.load_balanced_view()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 21
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Submit tasks for each (strike, sigma) pair. Again, we use the `%%timeit` magic to time the entire computation."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"async_results = []"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 22
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"%%timeit -n1 -r1\n",
"\n",
"for strike in strike_vals:\n",
" for sigma in sigma_vals:\n",
" # This line submits the tasks for parallel computation.\n",
" ar = view.apply_async(price_option, price, strike, sigma, rate, days, paths)\n",
" async_results.append(ar)\n",
"\n",
"rc.wait(async_results) # Wait until all tasks are done."
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 1: 6.82 s per loop\n"
]
}
],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"len(async_results)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 24,
"text": [
"30"
]
}
],
"prompt_number": 24
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Process and visualize results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Retrieve the results using the `get` method:"
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"results = [ar.get() for ar in async_results]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 25
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Assemble the result into a structured NumPy array."
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"prices = np.empty(n_strikes*n_sigmas,\n",
" dtype=[('ecall',float),('eput',float),('acall',float),('aput',float)]\n",
")\n",
"\n",
"for i, price in enumerate(results):\n",
" prices[i] = tuple(price)\n",
"\n",
"prices.shape = (n_strikes, n_sigmas)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 26
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot the value of the European call in (volatility, strike) space."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.figure()\n",
"plt.contourf(sigma_vals, strike_vals, prices['ecall'])\n",
"plt.axis('tight')\n",
"plt.colorbar()\n",
"plt.title('European Call')\n",
"plt.xlabel(\"Volatility\")\n",
"plt.ylabel(\"Strike Price\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 27,
"text": [
"<matplotlib.text.Text at 0x10844f990>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x105325f90>"
]
}
],
"prompt_number": 27
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot the value of the Asian call in (volatility, strike) space."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.figure()\n",
"plt.contourf(sigma_vals, strike_vals, prices['acall'])\n",
"plt.axis('tight')\n",
"plt.colorbar()\n",
"plt.title(\"Asian Call\")\n",
"plt.xlabel(\"Volatility\")\n",
"plt.ylabel(\"Strike Price\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 28,
"text": [
"<matplotlib.text.Text at 0x108948a10>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nDoYQcUTtcWV72YD/YzTazEabFwCWaD1AMxhp5uDgYIVWuseme3l5eTX4vVu3bigvLzf9Xl5ejoCA\nALsfXZNInz17Fr6+vjhx4gTWrl2LnTt34tixY8jJycH06dORk5OD5OTkRvt9//33GkxLRK5KzguP\nMTExKC0tRVlZGbp27YqVK1di+XL7z2+pfnUHANx3332oqqqCp6cn3nzzTQwbNgzV1dVITU3FiRMn\nnO8SPCJySRs2bDBdgjdhwgS88MILdq+hSaSJiMg2bloPUC8/Px8hISG46667MGdO41cFS0pKEBsb\ni1atWmHu3Ll27esocmYOCgpC//79ERkZiYEDB+pi3o8//hjh4eHo378/7r33Xhw4cMDmffU4sxbP\nsS0z5+bmIjw8HJGRkYiOjsbmzZtt3ldv8+r1Oa5XXFwMDw8PrFmzxu59dUPSgdraWik4OFg6duyY\ndP36dSk8PFz65ptvGtzn7NmzUnFxsTRz5kzp9ddft2tfvc0sSZIUFBQkVVVVOXxOe+bdvn27dOHC\nBUmSJGnDhg3SoEGDbN5XbzNLkvrPsa0zX7582fTzgQMHpODgYJv31dO8kqTf57j+fsOGDZMeeugh\nafXq1Xbtqye6OJK+/aJvT09P00Xft+vcuTNiYmLg6elp9756m7mepOKZJlvmjY2NRfv27QEAgwYN\nwsmTJ23eV28z11PzOQZsm7lNmzamny9fvoxOnTrZvK+e5q2nx+cYAN566y089thj6Ny5s9376oku\nIm3uou+KigqH7yuH3McVBAEjRoxATEwM3nvvPUeM2IC98y5atAijRo1q1r5KkTMzoP5zDNg+87p1\n69CnTx88+OCDmDdvnl376mVeQL/PcUVFBXJzc/H73//eNKet++qNLj4FT85F30pdMK72427btg1d\nunTBDz/8gISEBISEhCAuLk6h6RqzZ94tW7Zg8eLF2LZtm937KknOzID6zzFg+8zJyclITk7Gl19+\niSeffBIlJSUOncuS5s773XffAdDvczx16lRkZWXd+rwfSTId7Wv1b1kOXURazkXfSl0wbi+5j9ul\nSxcAt06JPPLIIygqKnLoP25b5z1w4ACefvpp5Ofnw9vb26599TQzoP5zbM/M9eLi4lBbW4vq6moE\nBASo/jw3d96qqip07NhRt8/x7t278fjjjwMAzp07hw0bNsDT01Ozf8uyaHpG/Cc3btyQevbsKR07\ndkz63//+1+TJ/JdeeqnBi3D27KuXma9cuSLV1NRIknTrRZnBgwdLn332mebzHj9+XAoODpZ27Nhh\n9756m1mL59jWmb///nvp5s2bkiRJ0u7du6WePXvavK+e5tXzc3y73/72t9KaNWuata8e6CLSkiRJ\n69evl3r37i0FBwdLr776qiRJkrRgwQJpwYIFkiRJ0unTp6WAgACpXbt2UocOHaTAwEDp0qVLFvfV\n88xHjhyRwsPDpfDwcKlv376qzWxt3gkTJkg+Pj5SRESEFBERIQ0YMKDJffU8s1bPsS0zz5kzR+rb\nt68UEREhDRkyRCoqKmpyX73Oq+fn+Ha3R9rSvnrGN7MQEemYLq7uICIi8xhpIiIdY6SJiHSMkSYi\n0jFGmohIxxhpIiIdY6RJVffffz/++9//Ntj2z3/+E5MnTzZ7/6CgIFRXVze55quvvtrg93vvvRcA\nUFZWhrCwMADArl27MGXKFABAYWEhduzY0az5idTGSJOq0tLSsGLFigbbVq5cibFjx5q9vy2ftTB7\n9uwGv9/++R31YmJikJ2dDeDW53xs377d1pGJNMVIk6pSUlLw6aefora2FsCto91Tp07h5MmT6N+/\nP8LCwjBjxgyz+z7yyCOIiYlBv379TJ+4NmPGDFy7dg2RkZF48sknATT+QlAAKCgowOjRo3H8+HEs\nXLgQb775JqKiorB161b07NnTNE9NTQ169uyJuro6R/z1iezGSJOqfHx8MHDgQKxfvx4AsGLFCowY\nMQLTp0/Hli1bsG/fPhQXF5v9jN/Fixdj165dKC4uxrx583D+/HlkZWXhjjvuwN69e/Hhhx8CaPro\nu3v37pg0aRIyMzOxZ88eDBkyBPHx8fj0009N86SkpMDd3d0Bf3si+zHSpLrbT3msWLEC3bt3x7Bh\nw9CxY0e4u7vjiSeewBdffNFov+zsbERERCA2Nhbl5eUoLS1t9gy3fxrCU089hSVLlgAAPvjgA6Sn\npzd7XSKlMdKkuqSkJGzatAl79+7FtWvXEBER0SCakiQ1OhouKCjApk2bsHPnTuzbtw+RkZH48ccf\nFZln8ODBKCsrQ0FBAerq6hAaGqrIukRKYKRJdV5eXhg2bBjS09MxduxYDBw4EIWFhaiqqkJdXR1W\nrFiBoUOHNtinpqYG3t7eaNWqFUpKSrBz507TbZ6enqZzyrZo27YtLl261GDbuHHj8MQTTyAjI0Pe\nX45IYYw0aSItLQ1ff/010tLS4O/vj6ysLAwbNgwRERGIiYnB6NGjAfx8fnnkyJGora1FaGgoXnjh\nBcTGxprWmjhxIvr372964fD2o3BzP48ePRqffPIJIiMjsXXrVgDA2LFjcf78eaSlpTn2L05kJ35U\nKRGA1atX49///jdycnK0HoWoAV18fRaRlp577jl89tlnpitOiPSER9JERDrGc9JERDrGSBMR6Rgj\nTUSkY4w0EZGOMdJERDrGSBMR6dj/AzIVq1SjmkE+AAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x10893e0d0>"
]
}
],
"prompt_number": 28
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot the value of the European put in (volatility, strike) space."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.figure()\n",
"plt.contourf(sigma_vals, strike_vals, prices['eput'])\n",
"plt.axis('tight')\n",
"plt.colorbar()\n",
"plt.title(\"European Put\")\n",
"plt.xlabel(\"Volatility\")\n",
"plt.ylabel(\"Strike Price\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 29,
"text": [
"<matplotlib.text.Text at 0x1089b1a90>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAXMAAAEZCAYAAABl1cWuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XtYVPW+x/HPQjBDVCATFTAURCC5jJKkRWIJCQgbpa1C\nW03dZbnNbXpOso/tzvLUUTyny8Fbmqmxd4WUqeCFiS6iphJKo1leQBNFQLwgCdJOwXX+IEZGGObC\nrPVbs9b39Tw8jzCzZn2Zp97+/M1i4ARBEEAIIcSuObAegBBCSOdRzAkhRAEo5oQQogAUc0IIUQCK\nOSGEKADFnBBCFIBiTgghCkAxJ2bx8fGBs7MzevToof+YN28e67FEFRUVhfvvvx89evTAgw8+iOTk\nZFy6dMnkcQUFBfD29pZgQkLuopgTs3Ach507d6Kurk7/sWLFCosfRxAE2MvPqXEch9WrV6Ourg4l\nJSWora3FK6+8wnosQtpFMSedxvM8pk6dqv+8rKwMDg4OuHPnDoDmFe5rr72Gxx57DN27d8e5c+dw\n8OBBPPLII3B1dcWIESNw6NAh/fFRUVH429/+hoiICPTq1QtJSUm4fv26/vbCwkKMGjUKbm5uCAsL\nw969e/W3bdq0CUFBQejZsyd8fX3x/vvv628rKCiAl5cX3nnnHXh4eKB///748MMPzfoe3dzcMHHi\nRPz0008AAAcHB/z888/625977jn8/e9/R0NDA2JjY1FZWYkePXqgZ8+eZq3mCeksijkxm7EVNcdx\nJo/96KOP8MEHH6C+vh7du3dHfHw85s+fj5qaGixYsADx8fEGwf7nP/+JTZs2oaqqCo6OjvotnYqK\nCowfPx6vv/46rl+/jrfeegvJycm4du0aAMDDwwO7du3CjRs3sGnTJrzyyivQ6XT6x62ursaNGzdQ\nWVmJDRs24C9/+Qt++eUXk9/z1atX8fnnn0Oj0Rh9DjiOg7OzM7RaLfr374+6ujrcuHEDffv2Nfn8\nENJZFHNiFkEQkJSUBDc3N/3Hhg0b9Ld1hOM4PPfccwgMDISDgwPy8/MxZMgQPPvss3BwcMCUKVMQ\nEBCA3Nxc/f2nTZuGoKAgODs744033sCnn36KO3fu4KOPPkJcXBzGjRsHABg7dizCw8Oxa9cuAEBc\nXBwGDhwIAHjiiScQExOD/fv362dxcnLC66+/ji5duiA2NhYuLi44ffq00e953rx5+n8BeHp64p13\n3unwOTLn+SBEDI6sByD2geM45OTk4Mknn7Tq+NYvCFZWVmLAgAEGtz/00EOorKxs9/4DBgzA7du3\ncfXqVZw/fx6fffYZduzYob+9sbFRP1deXh6WLFmC0tJS3LlzBw0NDQgJCdHf94EHHoCDw901jLOz\nM+rr641+zytXrsTMmTOt+p4JkRKtzEmnubi4oKGhQf95e3vErbdiPD09cf78eYPbz58/D09PT/3n\nFy5cMPizk5MTHnzwQQwYMABTp07F9evX9R91dXV49dVX8dtvvyE5ORmvvvoqLl++jOvXryMuLk6U\nlbKzs7PB91xVVaX/Hs3ZdiLE1ijmxGzGohgWFoZ9+/ahvLwcv/zyC5YtW9bhsXFxcSgpKUFWVhYa\nGxuRnZ2NU6dOYfz48fr7fvTRRzh58iQaGhrw+uuv449//CM4jsOf/vQn7NixA/n5+WhqasK//vUv\nFBQUoKKiArdu3cKtW7fQu3dvODg4IC8vD/n5+aJ9zx9//DGampqg1Wqxb98+/W0eHh64du0abty4\n0alzE2IJijkxW0JCgsF15snJyQCa960nT56MkJAQPPLII0hISGizOm39ubu7O3bu3Im3334bvXv3\nxltvvYWdO3fC3d1df9+pU6fiueeeQ79+/XDr1i39ZZBeXl7IycnB0qVL0adPHwwYMABvv/02BEFA\njx49sGLFCkyaNAnu7u7IysrCH/7wB6NzmMPY/TMyMrBjxw64ubnhk08+wYQJE/S3BQQEICUlBYMG\nDYK7uztdzUKkIYhkxowZQp8+fYShQ4fqv/bpp58KQUFBgoODg1BcXGxw/6VLlwp+fn7CkCFDhC++\n+EKssYgdiIqKEjZs2MB6DEI65cKFC0JUVJQQFBQkPPzww0JGRoYgCIJw7do1YezYscLgwYOF6Oho\n4fr16+0en5eXJwwZMkTw8/MT0tPTTZ5PtJX5jBkzoNVqDb4WHByMbdu24YknnjD4+okTJ5CdnY0T\nJ05Aq9Vizpw5+muUiToJdEUIsXNOTk5499138dNPP6GwsBCrV6/GyZMnkZ6ejujoaJSUlOCpp55C\nenp6m2Obmpowd+5caLVanDhxAllZWTh58mSH5xMt5pGRkXBzczP4WkBAAPz9/dvcNycnBykpKXBy\ncoKPjw/8/PxQVFQk1mjEDtCLiMTe9e3bF2FhYQCaLxIIDAxERUUFcnNzMX36dADA9OnTsX379jbH\nFhUVwc/PDz4+PnBycsKUKVOQk5PT4flkcWliZWUlHn30Uf3nXl5eqKioYDgRYWnPnj2sRyDEpsrK\nyqDT6RAREYHq6mp4eHgAaH6xvLq6us39KyoqDC7P9fLywnfffdfhOWT7AiitzAghSlBfX4/k5GRk\nZGSgR48eBre1/OTwvazpnyxW5p6enigvL9d/fvHiRYNrjltwnn5A5VkpRyOE2ClfX1+cOXOmU4/R\nk+NQZ+Z9XVxcUFdneO/bt28jOTkZU6dORVJSEoDm1filS5fQt29fVFVVoU+fPm0e694mlpeXw8vL\nq8PzM4t56xe4EhMTkZqaigULFqCiogKlpaUYMWJE24MqzwJ7O//CWOwTWzv9GOYq5bMxmJ8s2fla\nexHrrDouiz+DFN7PxtOII/FYPvj3AP4l1pNYxuTMyyUbxWz8cYAPts1jHciyzeN05PGznV/41QH4\n1tzz3fOTxIIgYNasWQgKCsL8+fP1X09MTERmZiYWLVqEzMxMfeRbCw8PR2lpKcrKytC/f39kZ2cj\nK6vjJ020bZaUlBSMGjUKp0+fhre3NzZu3Ijt27fD29sbhYWFiI+PR2xsLAAgKCgIkyZNQlBQEGJj\nY7FmzRpRt1ny9k0U7bHlZC1msx5BdLmhMaxHEMci1gOI67EU1hOI78CBA/joo4+wZ88eaDQaaDQa\naLVapKWl4csvv4S/vz+++eYbpKWlAWh+7TA+Ph4A4OjoiFWrVuHpp59GUFAQJk+ejMDAwA7Pxwl2\ndA0Yx3E2WZm3kGKFznJl3sLSFbo9rcyBu/MmHuvcT3tKyaJ/TchklW7LlXkLMVfoj6Pzl7hyHGf+\nytwG5+sM2b4AKgUpVujuUQ+Lfg5TLF2hD41yF2kScbTMa0+r9KhwC+4sk1V6VNut3U5TwwpdKqpe\nmbcm5T46S9buo9sTe1qhW0QmK3Sx2HqVTitzlaJ9dOWwpxW6RWSyQhcLrdI7h2LeCgVdOSjo9omC\nbj2K+T0o6MpBQbdPFHTrUMzbQUFXDgq6faKgW45ibgQFXTko6PaJgm4ZuprFBLrKRTkUe5ULQFe6\ntENtV7NQzM1EUVcOxUadgm5AbTGnbRYz0baLctC2i32ibZeOUcwtQEFXDgq6faKgG0cxtxAFXTko\n6PaJgt4+irkVKOjKQUG3TxT0tijmVqKgK4eig67gqFPQDdHVLDaghitd6CoXO6fCK13oahZiMTWs\n0mmFbucUvEIHaJUOUMxtRi1BV3rUKej2S+1Bp5jbkBqCDih/lZ4bGqPcqFPQFYtibmMUdOWgoNsn\ntQadXgAViRpeFAXohVG7pvAXRbksti+Azpw5E7t27UKfPn1w/PhxAMCUKVNw+vRpAEBtbS1cXV2h\n0+naPJaPjw969uyJLl26wMnJCUVFRaZnpZiLSw1Rp6DbOYVGnXXM9+/fDxcXF0ybNk0f89b+7d/+\nDa6urnjttdfa3DZw4EAUFxfD3d3838dL2ywiU8O2C2252DmFb7uwEhkZCTc3t3ZvEwQBn376KVJS\njO8JWfoXEcVcAhR0ZaCgE1vZv38/PDw84Ovr2+7tHMdh7NixCA8Px/r16816TIq5RNQSdKVHnYJO\nbCErKwupqalGbz9w4AB0Oh3y8vKwevVq7N+/3+Rj0p65xNSwhw4ofx+d9tDlz1Z75oKRnZCCaqDg\n8t3Pl/zY9nxlZWVISEgw2DNvbGyEl5cXvv/+e/Tv39/kDEuWLIGLiwsWLlzY4f1oZS4xNazQAeVv\nu9C16CTKA+CD736Y66uvvkJgYKDRkDc0NKCurg4AcPPmTeTn5yM42PQJKOYMUNCVQ9FBp6h3SkpK\nCkaNGoWSkhJ4e3tj06ZNAIDs7Ow2L3xWVlYiPj4eAHDp0iVERkYiLCwMERERGD9+PGJiTP93Rtss\njKlh20XpWy4AbbvIkdjbLGKcrzNoZc6YGlbptEK3c7RCtwsUcxmgoCsDBZ2wRDGXCQq6MlDQCSsU\ncxlRS9CVHnUKOmHB/mLO//6hUGoIOqD8Vbrig05Rlx37i3kLnvUA4snbN1EVUaeg2zkKuqzYb8wB\nRQcdUMcqXQ1BV3TUKeiyYd8xByjoCqD0oAMKX6VT0GXB/mMOUNAVgIJu5yjozCkj5gAFXQEo6HaO\ngs6UcmIO0JUuCkBBt3MUdGbs771Zxpg5Li/qKMzRe7rYP0W/nwvA/D1d6L1ZlIJnPYC4aJVu/xS9\nQgdolS4x5cYcoKArAAXdzlHQJaPsmAMUdAWgoNs5CroklB9zgIKuABR0O0dBF506Yg5Q0BVADUFX\ndNQp6KJST8wBCroCKD3ogMJX6RR00agr5gAFXQEo6HaOgi4K0WI+c+ZMeHh4GPxW6ZqaGkRHR8Pf\n3x8xMTGora0FAJSVleH++++HRqOBRqPBnDlzxBqrGS/uw7NGQVcGxQdd4VFvr4E8z8PLy0vfOq1W\n2+6xWq0WAQEBGDx4MJYvN++CfdFiPmPGjDaDpqenIzo6GiUlJXjqqaeQnp6uv83Pzw86nQ46nQ5r\n1qwRa6y7ePFPwRIFXRkUHXRA0UFvr4Ecx2HBggX61o0bN67NcU1NTZg7dy60Wi1OnDiBrKwsnDx5\n0uT5RIt5ZGQk3NzcDL6Wm5uL6dOnAwCmT5+O7du3i3V68/BsTy82CroyUNDtU3sNBEz/lGhRURH8\n/Pzg4+MDJycnTJkyBTk5OSbPJ+meeXV1NTw8PAAAHh4eqK6u1t927tw5aDQaREVF4dtvv5VuKF66\nU7FAQVcGCrpyrFy5EqGhoZg1a5Z+q7m1iooKeHt76z/38vJCRUWFycdl9gIox3HN77UCoH///igv\nL4dOp8M777yD1NRU1NXVtX/gOf7ux/UC2wzD2+Zh5IqCrgwU9I4VVAP88bsfYrPmfC+99BLOnTuH\no0ePol+/fli4cGGb+7R00VKOVh1lJQ8PD1y6dAl9+/ZFVVUV+vTpAwDo2rUrunbtCgAYNmwYfH19\nUVpaimHDhrV9kIG8OMPxUHTU8/ZNVPybc63FbMW/OVduaIyy36BrEax+g64oj+aPFkt+tMlERv+S\nifr9Q3++MNMP1dI8APjzn/+MhISENvfx9PREeXm5/vPy8nJ4eXmZfGxJV+aJiYnIzMwEAGRmZiIp\nKQkAcPXqVTQ1NQEAfv75Z5SWlmLQoEFSjtaMl/6UUqIVujLQCt1+VVVV6f+8bds2gytdWoSHh6O0\ntBRlZWW4desWsrOzkZiYaPKxRYt5SkoKRo0ahdOnT8Pb2xubNm1CWloavvzyS/j7++Obb75BWloa\nAGDfvn0IDQ2FRqPBH//4R6xbtw6urq5ijdYxns1ppUJBVwYKuvzd28CNGzdi0aJFCAkJQWhoKPbu\n3Yt3330XAFBZWYn4+HgAgKOjI1atWoWnn34aQUFBmDx5MgIDA02eT7nvZ95ZvDSnYUXpWy6A8t8P\nHaD3RO+Izd7P/KiZ9w2j9zOXJ571AOKiFboyqGKFroBVuhQo5h3hWQ8gLgq6Mig+6AAF3QwUc1N4\n1gOIi4KuDBR0QjE3B896AHFR0JWBgq5uFHNz8awHEBcFXRkU/57oAAXdCIq5JXjWA4iLgq4cFHT1\noZhbimc9gLjUEnQ1RJ2Cri4Uc2vwrAcQlxqCDqhjlU5BVw+KubV41gOIi4KuHBR0daCYdwbPegBx\nUdCVQxVBV3nUKeadxbMeQFwUdOVQfNABVQedYm4LPOsBxEVBVw4KunJRzG2FZz2AuCjoykFBVyaK\nuS3xrAcQFwVdOVQRdJWhmNsaz3oAcVHQlYOCriwUczHwrAcQFwVdOVTx4/8qQTEXC896AHFR0JWF\ngm7/KOZi4lkPIC4KurJQ0O0bxZx0CgVdWSjo9otiLjae9QDio6ArCwXdNmbOnAkPDw8EBwfrv/bv\n//7vCAwMRGhoKCZOnIhffvml3WN9fHwQEhICjUaDESNGmHU+irkUeNYDiI+CriwU9M6bMWMGtFqt\nwddiYmLw008/4dixY/D398eyZcvaPZbjOBQUFECn06GoqMis81HMpcKzHkB8FHRloaB3TmRkJNzc\n3Ay+Fh0dDQeH5uxGRETg4sWLRo8XBMGi81HMpcSzHkB8FHRloaCLZ+PGjYiLi2v3No7jMHbsWISH\nh2P9+vVmPZ6jLYcjZuCh+Kjn7ZuI2Ce2sh5DdGsxGy9iHesxRJcbGoPEY/msx5CdgsNAwRHrjv3v\n//5vdO3aFampqe3efuDAAfTr1w9XrlxBdHQ0AgICEBkZ2eFjcoKla3mGOI4DxtjNuB3jWQ8gPjUE\nHYAqgg7A7oLOhVm+VdHmMTgOOYJ5/zr5A5ff5nxlZWVISEjA8ePH9V/78MMPsX79enz99dfo1q2b\nycddsmQJXFxcsHDhwg7vZ3Kb5ebNm3jjjTfw/PPPAwBKS0uxc+dOkwMQE3jWA4iPtlyUhbZcOk+r\n1eJ///d/kZOTYzTkDQ0NqKurA9Dc3/z8fIMrYowxGfMZM2aga9euOHjwIACgf//+WLx4sSXzE2N4\n1gOIj4KuLPTj/+ZLSUnBqFGjcPr0aXh7e2Pjxo14+eWXUV9fj+joaGg0GsyZMwcAUFlZifj4eADA\npUuXEBkZibCwMERERGD8+PGIiTH9nJvcZhk+fDiKi4uh0Wig0+kAAKGhoTh27Fhnv1eLKWqbpTWe\n9QDioy0X5ZH7tosctlmkZHJlft999+HXX3/Vf3727Fncd999og6lOjzrAcSXt2+iKlbpalmhA7Tt\nIjcmY87zPMaNG4eLFy8iNTUVTz75JJYvXy7FbOrCsx5AGmoJulqiTkGXD7OuZrl69SoKCwsBAI8+\n+ih69+4t+mDtUew2S2s86wHEp5YtF0A92y5y3HKhbZZ7bN26FY6Ojhg/fjzGjx8PR0dHbN++XYrZ\n1IlnPYD41LA6b0ErdCIVkzFfsmQJXF1d9Z+7urqC53kxZyI86wHER0FXHgo6WyZj3t4/G5qamkQZ\nhrTCsx5AfBR05aGgs2My5sOHD8eCBQtw9uxZnDlzBq+88gqGDx8uxWxEBSjoykNBZ8NkzFeuXAkn\nJydMnjwZU6ZMQbdu3bB69WopZmvfnu/YnVtqPOsBpEFBVx4KuvTs771ZUAiMiWA9irR41gNIg65y\nUR6WV7mo7WoWozH/61//ioyMDCQkJLQ9iOOQm5sr+nDtnRdovkSSgq5MFHTlYRV0ivnviouLMXz4\ncOzdu7fNgBzHYfTo0ZIMeO959TEHKOgKRUFXHhZBp5i30tjYiGnTpuGTTz6RciajKOasB5AOBV15\npA662mLe4Qugjo6OuHDhAn777Tep5rGMml4MBVQVc3pRVHnoRVFxmXwBdOrUqTh16hQSExPh7Ozc\nfBDHYcGCBZIM2FqblXkLWqErFq3QlUeqFTqtzO/h6+uL+Ph43LlzB/X19aivr9e/cbps0ApdsWiF\nrjy0QhdHhytznU6HM2fOYOjQoQgMDJRyrnYZXZkD6ludA6qKOq3QlUfsFTqtzH/3X//1X5g8eTK2\nbt2KuLg4vP/++1LOZTm1rc4BVcVcTWiFTqxhNOabN2/G0aNHkZWVhSNHjsg/5gAFXcHUtN0CUNCJ\n5YzG/L777tO/4PnAAw/gzp07kg3VKWoMukpQ0JWJgm4bRmP+888/IyEhQf/R+vPExESTDzxz5kx4\neHgY/FbpmpoaREdHw9/fHzExMaitrdXftmzZMgwePBgBAQHIz5ffG93LGs96AOlQ0JVJiUG3tIGt\nabVaBAQEYPDgwWb/ZjejL4AWFBQYP8iMnwDdv38/XFxcMG3aNBw/fhwA8Oqrr6J379549dVXsXz5\ncly/fh3p6ek4ceIEUlNTcfjwYVRUVGDs2LEoKSmBg4Ph3zUdvgB6L3pBVNHU9IIoQC+KWoP1C6CW\nNLC1pqYmDBkyBF999RU8PT3xyCOPICsry+RFKKK+0VZZWRkSEhL030hAQAD27t0LDw8PXLp0CVFR\nUTh16hSWLVsGBwcHLFq0CAAwbtw48DyPRx991HBYS2IOUNAVjoKuTLYKOuuYA+Y3sLVDhw5hyZIl\n0Gq1AKCPfVpaWofnN3mduS1VV1fDw8MDAODh4YHq6moAQGVlJby8vPT38/LyQkVFRedPqMb9c571\nANKhLRdlUuKWSwtjDWytoqIC3t7e+s/N7aGj7ca0DMdxv6+0jd/evvWt/jwMAP2ijDZ4qCbqefsm\nqmqFvhazVbFCzw2NsXiFXnAYKDgi0kDtOF5Qgx8Laqw+3lgDO+piR8yOeUNDg/7qFmu1/NOib9++\nqKqqQp8+fQAAnp6eKC8v19/v4sWL8PT0NPIoz1t20j3fqXe7hWc8g0Qo6MpkadCjHmn+aLHERk+R\n0X8RRf3+oT9hssnHMtbA1u7tYXl5ucHOhTEmt1kOHjyIoKAgDBkyBABw9OhRzJkzx+QDtycxMRGZ\nmZkAgMzMTCQlJem/vnnzZty6dQvnzp1DaWkpRowYYdU52qXG7RZANTEHaMtFqZS25WKsga2Fh4ej\ntLQUZWVluHXrFrKzs826gtBkzOfPnw+tVovevXsDAMLCwrB3716TD5ySkoJRo0bh9OnT8Pb2xqZN\nm5CWloYvv/wS/v7++Oabb/Qb+kFBQZg0aRKCgoIQGxuLNWvWWP1PDaJeFHRlstegW9LAyspKxMfH\nA2h+t9pVq1bh6aefRlBQECZPnmzW26mYvJplxIgRKCoqgkajgU6nAwCEhobi2LFjnf1eLWbx1Sz3\nUuN2C6CqFTpAV7komSXbLra6miVW+Nys++ZxyfJ8b5YWAwYMwIEDBwAAt27dwltvvSWLN92yCm23\nqAKt0JXLXlfpUjAZ8/feew+rV69GRUUFPD09odPpsHr1ailmEwcFXRUo6MpFQW+fyZgfOXIEn3zy\nCS5fvowrV67g448/xmeffSbFbMTWeNYDSIuCrlwU9LZMxvyNN97A119/rf/8f/7nf7B9+3ZRhxKd\nWlfnAAVd4Sjo6mUy5rm5uVi8eDH279+PxYsX47vvvkNubq4Us4mLgq4aFHTloqDfZTLmvXv3Rm5u\nLubMmYPKykps2bIFXbt2lWI28VHQVYOCrlwU9GZGY+7i4oIePXqgR48e8PX1RUlJCT777DP07NkT\nPXv2lHJGQmyCgq5cFPQOYt7yi5tbPn777Tf9127cuCHljOKi1bmqUNCVS+1BN/pDQ6dOnUJAQAC+\n//77dg8cNmyYqIO1p9M/NNQRtf5AEaDKqNMPFilXyw8Wqe2HhozG/Pnnn8f69esRFRXV7o/W79mz\nR/Th7kUxFxHPegDpUdCVK/FYPsW8tTt37uDQoUN47LHHpJzJKFFjDlDQedYDSI+Crlzt/bIIS9lT\nzDu8msXBwQF/+ctfpJqFPTXvnwOqjDntoROlMHlp4tixY7Flyxamf+NIioKuOhR0ogQmY7527VpM\nmjQJXbt21V+qSJcmKhzPegDpUdCJvTMZ8/r6ety5cwe3b9/WX6aoqEsT26P21blKUdCJPTMZ86ee\nesqsrymO2oPOsx6ADQo6sVdGY/7rr7/i2rVruHLlCmpqavQfZWVlZv2maEWgoKsSBZ3YI6MxX7du\nHcLDw3H69GkMHz5c/5GYmIi5c+dKOSNhiWc9ABsUdGJvTP7auBUrVmDevHlSzdMh0a8zN0bt158D\nqo06XYduv+g6898dPnwYVVVV+pBnZmYiMTER8+bNQ01NjWQDyoLat1sA1cacVujEWqdPn4ZGo9F/\n9OrVCytWrDC4T0FBAXr16qW/z5tvvmn1+YzG/IUXXsB9990HANi3bx/S0tIwffp09OzZEy+88ILV\nJ7RbFHQKukpQ0G1jyJAh0Ol00Ol0KC4uhrOzMyZMmNDmfqNHj9bf77XXXrP6fEZjfufOHbi7uwMA\nsrOzMXv2bCQnJ+PNN99EaWmp1Sckdo5nPQCRAgXdtr766iv4+vrC29u7zW222poxGvOmpibcvn1b\nP8iYMWP0tzU2Ntrk5HaHVueqpbbVOUBBt6XNmzcjNTW1zdc5jsPBgwcRGhqKuLg4nDhxwupzOBq7\nISUlBaNHj0bv3r3h7OyMyMhIAEBpaSlcXV2tPqHd2/MdvSDKQ5Ur9Lx9E1X3guhazFbUi6K2dK3g\nR9QU/GTyfrdu3cKOHTuwfPnyNrcNGzYM5eXlcHZ2Rl5eHpKSklBSUmLVPB1ezXLo0CFcunQJMTEx\n6N69OwCgpKQE9fX1yns/c0upPeiAKoMOqO8KF8A+r3Kx1dUs2GvmY4zm2j1fTk4O3nvvPWi1WpMP\nMXDgQBQXF+u3uC3R4U+Ajhw5EhMmTNCHHAD8/f2ZhJzIEM96ADZoy4VYIisrCykpKe3eVl1drf8L\noKioCIIgWBVywIwf5ydG0P55M571AGxQ0Ik5bt68ia+++goTJ97972XdunVYt675XzpbtmxBcHAw\nwsLCMH/+fGzevNnqc5n8oSE5kdU2SwvabmnGsx6ADdpykS+5bLNIhVbmnUUr9GY86wHYoBU6kQuK\nObEdnvUAbFDQiRxQzG2BVud38awHYIOCTlijmNsKBV31KOiEJYq5LVHQm/GsByBSoqDLA8WciINn\nPQAbalydAxR0OaCY2xqtzu/iWQ/ABgWdsEAxFwMF/S6e9QBsUNCJ1CjmYqGg38WzHoANCjqREsWc\nSINnPQArfBweAAARaklEQVQbFHQiFYq5mGh1bohnPQAbFHQiBYq52CjoBBR0Ij6KuRQo6HfxrAdg\nh4JOxEQxJ9LjWQ/ADgWdiIViLhVanRviWQ/ADgWdiIFiLiUKuiGe9QBEahR08VDMpUZBN8SzHoAN\nta7OAQq6WCjmhD2e9QBsUNCJLVHMWaDVeVs86wHYoKATW2ES84yMDAQHB2Po0KHIyMgAAPA8Dy8v\nL2g0Gmg0Gmi1WhajSYeC3hbPegA2KOjK5ePjg5CQEGg0GowYMaLd+8ybNw+DBw9GaGgodDqd1eeS\nPOY//vgjPvjgAxw+fBjHjh3Dzp07cfbsWXAchwULFkCn00Gn02HcuHFSjyY9Cjr5HQVdmTiOQ0FB\nAXQ6HYqKitrcvnv3bpw5cwalpaV4//338dJLL1l9LsljfurUKURERKBbt27o0qULRo8eja1bm3/D\nOcvfbE1kgmc9ADsUdGXqqGu5ubmYPn06ACAiIgK1tbWorq626jySx3zo0KHYv38/ampq0NDQgN27\nd6O8vBwAsHLlSoSGhmLWrFmora2VejQ2aHXeFs96AHYo6MrCcRzGjh2L8PBwrF+/vs3tFRUV8Pb2\n1n/u5eWFixcvWnUuR6untFJAQAAWLVqEmJgYdO/eHWFhYejSpQvmzJmD119/HQDw97//HQsXLsSG\nDRvaeYTWT8gwAMOlGFtce74DxkSwnkJeeKg26nn7JiL2ia2sx2BiLWbjRayz6tjjBTX4saDGxhPB\n+H+H1wuA2oIODz1w4AD69euHK1euIDo6GgEBAYiMjDS4z70rd47jrBqTExjvbfzHf/wHBgwYgBdf\nfFH/tbKyMiQkJOD48eMG923+JgslnlBCFPS2eNYDsKPWoAOwOuit/YHL7/TWLcdxwBgzH2MP1+H5\nlixZAhcXFyxcuFD/tRdffBFRUVGYMmUKgObF7t69e+Hh4WHxrEyuZrl8+TIA4MKFC9i2bRtSU1NR\nVVWlv33btm0IDg5mMRqRG571AOzQlot9a2hoQF1dHQDg5s2byM/Pb9O1xMRE/OMf/wAAFBYWwtXV\n1aqQAwy2WQDgmWeewbVr1+Dk5IQ1a9agZ8+emDt3Lo4ePQqO4zBw4ECsW9f5v5ntDm23tI+HqqOu\nVp3ZcpGD6upqTJgwAQDQ2NiIZ599FjExMfq2zZ49G3Fxcdi9ezf8/PzQvXt3bNq0yerzMd9msYTi\nt1laUNDbx7MegA01b7cA1m+5yG2bRWz0E6ByRFe4kFbUvN0CKGPLRQoUc2I/eNYDsENBp6CbQjGX\nK1qdt49nPQA7FHQKekco5nJGQW8fz3oAdijoFHRjKOZyR0FvH896AHYo6BT09lDMif3iWQ/ADgWd\ngn4virk9oNW5cTzrAdihoFPQW6OY2wsKunE86wHYoaBT0FtQzO0JBZ2QNijozSjmRBl41gOwo/bV\nOUBBByjm9odW58bxrAdgh4JOKOb2iIJuHM96AHbUHnS1r84p5vaKgm4cz3oAdijo6g06xZwQhaGg\nqzPoFHN7Rqtz43jWA7BFQVdf0Cnm9o6CbhzPegC21B50taGYE2XjWQ/AFgVdPSjmSkCr847xrAdg\ni4KuDhRzpaCgkw5Q0KVXXl6OMWPG4OGHH8bQoUOxYsWKNvcpKChAr169oNFooNFo8Oabb1p9Pia/\n0JkQyfGgFfq+iar/faJScnJywrvvvouwsDDU19dj+PDhiI6ORmBgoMH9Ro8ejdzc3E6fj1bmSkKr\n847xrAdgj1bo0unbty/CwsIAAC4uLggMDERlZWWb+9nql0BTzJWGgt4xnvUARI3Kysqg0+kQERFh\n8HWO43Dw4EGEhoYiLi4OJ06csPocFHNCVIZW59Kqr6/HM888g4yMDLi4uBjcNmzYMJSXl+PYsWN4\n+eWXkZSUZPV5OMFWa3wJcBwHoJD1GPZhTITp+6gZz3oA9pS+f57HJXd6C6Pj5hQD+L7V5xvanO/2\n7dsYP348YmNjMX/+fJPnGzhwIIqLi+Hu7m7xrLQyVyrabukYz3oA9miF3lnDATzf6sOQIAiYNWsW\ngoKCjIa8urpa/xdAUVERBEGwKuQArcyVj1boHeNZD8CeUlfo4q/M7/Wowfm+/fZbPPHEEwgJCfn9\ncYClS5fiwoULAIDZs2dj9erVeO+99+Do6AhnZ2e88847ePTRR62blWKucBRz03jWA7CnxKCzjrnU\naJtF6Wi7hZiBtlzsH8VcDSjoHeNZDyAPFHT7RjEnBKCg/46Cbr8o5mpBq3PTeNYDyAMF3T5RzNWE\ngm4az3oAeaCg2x+KOSGkXRR0+0IxVxtanZvGsx5APijo9oNirkYUdNN41gPIBwXdPlDMCTGGZz2A\nfFDQ5Y9irla0OjcPz3oA+aCgyxvFXM0o6MRCFHT5opirHQXdNJ71AISYRjEnxBw86wHkg1bn8kQx\nJ7Q6NxfPegD5oKDLD8WcNKOgm4dnPYB8UNDlhWJOCLEaBV0+KObkLlqdm4dnPYC8UNDlgWJODFHQ\nzcOzHkBeKOjsUcwJsRbPegB5oaCzxSTmGRkZCA4OxtChQ5GRkQEAqKmpQXR0NPz9/RETE4Pa2loW\noxGAVueW4FkPIC8UdENarRYBAQEYPHgwli9f3u595s2bh8GDByM0NBQ6nc7qc0ke8x9//BEffPAB\nDh8+jGPHjmHnzp04e/Ys0tPTER0djZKSEjz11FNIT0+XejSRFLMewArF9hX06wWsJ7CcroD1BJYz\nc2YKerOmpibMnTsXWq0WJ06cQFZWFk6ePGlwn927d+PMmTMoLS3F+++/j5deesnq80ke81OnTiEi\nIgLdunVDly5dMHr0aHz++efIzc3F9OnTAQDTp0/H9u3bpR5NJN+zHsAKdjZzbQHb8/NWHHO0wMZD\nSMCCmSnoQFFREfz8/ODj4wMnJydMmTIFOTk5Bvdp3b2IiAjU1taiurraqvNJHvOhQ4di//79qKmp\nQUNDA3bv3o2LFy+iuroaHh4eAAAPDw+rvyFiQ/a0OmeNZz2A/Kg96BUVFfD29tZ/7uXlhYqKCpP3\nuXjxolXnkzzmAQEBWLRoEWJiYhAbG4uwsDB06dLF4D4cx4HjOKlHI+2hoJuPZz2A/Kg56OY2TBAE\nq467l6NVR3XSzJkzMXPmTADA4sWL4eXlBQ8PD1y6dAl9+/ZFVVUV+vTp0+Y4X19fnD37qNTj2sAG\n1gNYodXMe9hNYbayJawnaGbJc/WhTGa2hBUz54kwhjl8fX1t9EjmNcfFxcXgc09PT5SXl+s/Ly8v\nh5eXV4f3uXjxIjw9Pa2akknML1++jD59+uDChQvYunUrCgsLce7cOWRmZmLRokXIzMxEUlJSm+PO\nnDnDYFpCiFrdu2q2RHh4OEpLS1FWVob+/fsjOzsbWVlZBvdJTEzEqlWrMGXKFBQWFsLV1VW/3Wwp\nJjF/5plncO3aNTg5OWHNmjXo1asX0tLSMGnSJGzYsAE+Pj749NNPWYxGCCE24ejoiFWrVuHpp59G\nU1MTZs2ahcDAQKxbtw4AMHv2bMTFxWH37t3w8/ND9+7dsWnTJqvPxwmd+auHEEKILMjmJ0BNXVx/\n6tQpjBw5Et26dcPbb79t0bFi6czMPj4+CAkJgUajwYgRI2Qx78cff4zQ0FCEhITgscceww8//GD2\nsXKcmcVzbM7MOTk5CA0NhUajwfDhw/HNN9+Yfazc5pXrc9zi8OHDcHR0xOeff27xsXZHkIHGxkbB\n19dXOHfunHDr1i0hNDRUOHHihMF9Ll++LBw+fFhYvHix8NZbb1l0rNxmFgRB8PHxEa5duyb6nJbM\ne/DgQaG2tlYQBEHIy8sTIiIizD5WbjMLgvTPsbkz19fX6//8ww8/CL6+vmYfK6d5BUG+z3HL/caM\nGSPEx8cLW7ZssehYeySLlbk5F9c/+OCDCA8Ph5OTk8XHym3mFoKEO1zmzDty5Ej06tULQPMPMLRc\n7yrn59jYzC2kfI4B82bu3r27/s/19fXo3bu32cfKad4WcnyOAWDlypV45pln8OCDD1p8rD2SRczN\nubhejGM7o7Pn5TgOY8eORXh4ONavXy/GiAYsnXfDhg2Ii4uz6lhb6czMgPTPMWD+zNu3b0dgYCBi\nY2OxYsUKi46Vy7yAfJ/jiooK5OTk6H88vuXabVb/LUuBydUs9+rMDwix+uGizp73wIED6NevH65c\nuYLo6GgEBAQgMjLSRtO1Zcm8e/bswcaNG3HgwAGLj7WlzswMSP8cA+bPnJSUhKSkJOzfvx9Tp07F\nqVOnRJ3LGGvnPX36NAD5Psfz589Heno6OI6DIAj6fz0o+YcRZRFzcy6uF+PYzujsefv16wegeStm\nwoQJKCoqEvV/AnPn/eGHH/D8889Dq9XCzc3NomPlNDMg/XNsycwtIiMj0djYiJqaGnh5eUn+PFs7\n77Vr1/DAAw/I9jkuLi7GlClTAABXr15FXl4enJycmP23LAmmO/a/u337tjBo0CDh3Llzwm+//dbh\nixL/+Z//afBioiXHymXmmzdvCjdu3BAEofnFpVGjRglffPEF83nPnz8v+Pr6CocOHbL4WLnNzOI5\nNnfmM2fOCHfu3BEEQRCKi4uFQYMGmX2snOaV83Pc2nPPPSd8/vnnVh1rT2QRc0EQhN27dwv+/v6C\nr6+vsHTpUkEQBGHt2rXC2rVrBUEQhKqqKsHLy0vo2bOn4OrqKnh7ewt1dXVGj5XzzGfPnhVCQ0OF\n0NBQ4eGHH5ZsZlPzzpo1S3B3dxfCwsKEsLAw4ZFHHunwWDnPzOo5Nmfm5cuXCw8//LAQFhYmPP74\n40JRUVGHx8p1Xjk/x621jrmxY5WAfmiIEEIUQBZXsxBCCOkcijkhhCgAxZwQQhSAYk4IIQpAMSeE\nEAWgmBNCiAJQzImknnzySeTn5xt87f/+7/8wZ86cdu/v4+ODmpqaDh9z6dKlBp8/9thjAICysjIE\nBwcDAI4cOYK//vWvAIC9e/fi0KFDVs1PiFxRzImkUlJSsHnzZoOvZWdnIzU1td37m/NeGsuWLTP4\nvPX7s7QIDw9HRkYGgOb3cTl48KC5IxNiFyjmRFLJycnYtWsXGhsbATSvnisrK3Hx4kWEhIQgODgY\naWlp7R47YcIEhIeHY+jQofp36EtLS8Ovv/4KjUaDqVOnAmj7i3UBoKCgAAkJCTh//jzWrVuHd999\nF8OGDcO3336LQYMG6ee5ceMGBg0ahKamJjG+fUJEQzEnknJ3d8eIESOwe/duAMDmzZsxduxYLFq0\nCHv27MHRo0dx+PDhdt9jeuPGjThy5AgOHz6MFStW4Pr160hPT8f9998PnU6Hf/7znwA6Xs0/9NBD\nePHFF7FgwQJ8//33ePzxxxEVFYVdu3bp50lOTkaXLl1E+O4JEQ/FnEiu9VbL5s2b8dBDD2HMmDF4\n4IEH0KVLFzz77LPYt29fm+MyMjIQFhaGkSNHory8HKWlpVbP0PpdLP785z/rf5Huhx9+iBkzZlj9\nuISwQjEnkktMTMTXX38NnU6HX3/9FWFhYQZxFQShzeq6oKAAX3/9NQoLC3H06FFoNBr861//ssk8\no0aNQllZGQoKCtDU1ISgoCCbPC4hUqKYE8m5uLhgzJgxmDFjBlJTUzFixAjs3bsX165dQ1NTEzZv\n3ozRo0cbHHPjxg24ubmhW7duOHXqFAoLC/W3OTk56fe8zdGjRw/U1dUZfG3atGl49tlnMXPmzM59\nc4QwQjEnTKSkpOD48eNISUlB3759kZ6ejjFjxiAsLAzh4eFISEgAcHf/e9y4cWhsbERQUBD+9re/\nYeTIkfrHeuGFFxASEqJ/AbT1qr69PyckJGDbtm3QaDT49ttvAQCpqam4fv06UlJSxP3GCREJvQUu\nIQC2bNmCHTt2IDMzk/UohFhFFr82jhCWXn75ZXzxxRf6K2wIsUe0MieEEAWgPXNCCFEAijkhhCgA\nxZwQQhSAYk4IIQpAMSeEEAWgmBNCiAL8P8OIHLNSSbuQAAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x108976c10>"
]
}
],
"prompt_number": 29
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot the value of the Asian put in (volatility, strike) space."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.figure()\n",
"plt.contourf(sigma_vals, strike_vals, prices['aput'])\n",
"plt.axis('tight')\n",
"plt.colorbar()\n",
"plt.title(\"Asian Put\")\n",
"plt.xlabel(\"Volatility\")\n",
"plt.ylabel(\"Strike Price\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 30,
"text": [
"<matplotlib.text.Text at 0x108f42050>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\njv0/aUhspMVrYxEAAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x10898ae50>"
]
}
],
"prompt_number": 30
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Using dill to pickle (especially closure)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://nbviewer.ipython.org/gist/minrk/5241793 width=1024 height=550></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://nbviewer.ipython.org/gist/minrk/5241793 width=1024 height=550></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 149,
"text": [
"<IPython.core.display.HTML at 0x1080b9f50>"
]
}
],
"prompt_number": 149
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"CPU affinity and numpy"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://nbviewer.ipython.org/gist/minrk/5500077 width=1024 height=550></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://nbviewer.ipython.org/gist/minrk/5500077 width=1024 height=550></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 148,
"text": [
"<IPython.core.display.HTML at 0x1080b9a50>"
]
}
],
"prompt_number": 148
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"IPython slated"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Daniel Rodriguez](https://github.com/danielfrg) covers an handly way of deploying clusters with [salt](http://www.saltstack.com/)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://danielfrg.com/blog/2014/04/20/ipython-parallel-cluster-salt/ width=1024 height=550></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://danielfrg.com/blog/2014/04/20/ipython-parallel-cluster-salt/ width=1024 height=550></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 154,
"text": [
"<IPython.core.display.HTML at 0x1080b9810>"
]
}
],
"prompt_number": 154
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"StarCluster (for AWS):"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://star.mit.edu/cluster/docs/latest/plugins/ipython.html width=1024 height=550></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://star.mit.edu/cluster/docs/latest/plugins/ipython.html width=1024 height=550></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 150,
"text": [
"<IPython.core.display.HTML at 0x1080b9610>"
]
}
],
"prompt_number": 150
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://badhessian.org/2013/11/cluster-computing-for-027hr-using-amazon-ec2-and-ipython-notebook/ width=1024 height=550></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://badhessian.org/2013/11/cluster-computing-for-027hr-using-amazon-ec2-and-ipython-notebook/ width=1024 height=550></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 152,
"text": [
"<IPython.core.display.HTML at 0x1080b9750>"
]
}
],
"prompt_number": 152
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"... and it works on Azure as well"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is quite extensive walk-through at Microsoft Research [webpage](http://research.microsoft.com/en-us/projects/azure/technical-papers.aspx). \n",
"However, for few details you might want to check the [MATLAB Distributed Computing Server with HPC Cluster in Microsoft Azure](http://research.microsoft.com/en-US/projects/azure/mdcs-with-hpc-cluster-on-microsoft-azure.pdf) \n",
"[Wenming Ye](https://github.com/wenming) shared a link to materials from an [Azure lab](http://research.microsoft.com/en-us/UM/redmond/projects/azure/Azure-training-course-0.51.zip) (which cover IPython as well)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"HTML('<iframe src=http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-python-ipython-notebook/ width=1024 height=550></iframe>')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<iframe src=http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-python-ipython-notebook/ width=1024 height=550></iframe>"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 153,
"text": [
"<IPython.core.display.HTML at 0x1080b9a90>"
]
}
],
"prompt_number": 153
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[IPython cluster helper](https://github.com/roryk/ipython-cluster-helper)\n",
"\n",
"ipython-cluster-helper creates a throwaway parallel IPython profile, launches a cluster and returns a view. \n",
"On program exit it shuts the cluster down and deletes the throwaway profile. Schedulers supported: Platform LSF (\"lsf\"), Sun Grid Engine (\"sge\"), Torque (\"torque\") and SLURM (\"slurm\")."
]
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Learning materials:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. IPython.parallel documentation [http://ipython.org/ipython-doc/stable/parallel/parallel_intro.html](http://ipython.org/ipython-doc/stable/parallel/parallel_intro.html) and [parallel computing examples](https://github.com/ipython/ipython/tree/master/examples/Parallel%20Computing)\n",
"\n",
"2. The [IPython in-depth: high-productivity interactive and parallel python](https://github.com/ipython/ipython-in-depth) tutorial by [Brian E. Granger](http://brianegranger.com) , [Fernando P\u00e9rez](http://fperez.org) and [Min Ragan-Kelley](https://github.com/minrk) featuring from time to time at Python conferences. As far as I know IPython.parallel was covered last time at [PyCon US 2013](https://us.pycon.org/2013/schedule/presentation/20/).\n",
"[![IPython in-depth: high-productivity interactive and parallel python](http://img.youtube.com/vi/bP8ydKBCZiY/0.jpg)](http://www.youtube.com/watch?v=bP8ydKBCZiY)\n",
"\n",
"4. University of Colorado Boulder's [presentation](https://www.rc.colorado.edu/node/217) on IPython.parallel\n",
"\n",
"3. Min RK's recent (24th April 2014) [talk at BayPiggies](https://github.com/minrk/baypiggies-2014-04-24)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.display import YouTubeVideo\n",
"YouTubeVideo('z1DQzrpXN_U')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"\n",
" <iframe\n",
" width=\"400\"\n",
" height=300\"\n",
" src=\"https://www.youtube.com/embed/z1DQzrpXN_U\"\n",
" frameborder=\"0\"\n",
" allowfullscreen\n",
" ></iframe>\n",
" "
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 25,
"text": [
"<IPython.lib.display.YouTubeVideo at 0x1094620d0>"
]
}
],
"prompt_number": 25
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment