##// END OF EJS Templates
Updating a few example notebooks to v3.
Brian Granger -
Show More
This diff has been collapsed as it changes many lines, (570 lines changed) Show them Hide them
@@ -1,193 +1,381 b''
1 {
1 {
2 "worksheets": [
2 "metadata": {
3 {
3 "name": "BackgroundJobs"
4 "cells": [
4 },
5 {
5 "nbformat": 3,
6 "source": "# Simple interactive bacgkround jobs with IPython\n\nWe start by loading the `backgroundjobs` library and defining a few trivial functions to illustrate things with.",
6 "nbformat_minor": 0,
7 "cell_type": "markdown"
7 "worksheets": [
8 },
8 {
9 {
9 "cells": [
10 "cell_type": "code",
10 {
11 "language": "python",
11 "cell_type": "markdown",
12 "outputs": [],
12 "metadata": {},
13 "collapsed": false,
13 "source": [
14 "prompt_number": 35,
14 "# Simple interactive bacgkround jobs with IPython\n",
15 "input": "from IPython.lib import backgroundjobs as bg\n\nimport sys\nimport time\n\ndef sleepfunc(interval=2, *a, **kw):\n args = dict(interval=interval,\n args=a,\n kwargs=kw)\n time.sleep(interval)\n return args\n\ndef diefunc(interval=2, *a, **kw):\n time.sleep(interval)\n raise Exception(\"Dead job with interval %s\" % interval)\n\ndef printfunc(interval=1, reps=5):\n for n in range(reps):\n time.sleep(interval)\n print 'In the background...', n\n sys.stdout.flush()\n print 'All done!'\n sys.stdout.flush()"
15 "\n",
16 },
16 "We start by loading the `backgroundjobs` library and defining a few trivial functions to illustrate things with."
17 {
17 ]
18 "source": "Now, we can create a job manager (called simply `jobs`) and use it to submit new jobs.\n<br>\nRun the cell below and wait a few seconds for the whole thing to finish, until you see the \"All done!\" printout.",
18 },
19 "cell_type": "markdown"
19 {
20 },
20 "cell_type": "code",
21 {
21 "collapsed": false,
22 "cell_type": "code",
22 "input": [
23 "language": "python",
23 "from IPython.lib import backgroundjobs as bg\n",
24 "outputs": [
24 "\n",
25 {
25 "import sys\n",
26 "output_type": "stream",
26 "import time\n",
27 "stream": "stdout",
27 "\n",
28 "text": "Starting job # 0 in a separate thread.\nStarting job # 2 in a separate thread.\nStarting job # 3 in a separate thread.\nStarting job # 4 in a separate thread.\nStarting job # 5 in a separate thread.\n"
28 "def sleepfunc(interval=2, *a, **kw):\n",
29 },
29 " args = dict(interval=interval,\n",
30 {
30 " args=a,\n",
31 "output_type": "stream",
31 " kwargs=kw)\n",
32 "stream": "stdout",
32 " time.sleep(interval)\n",
33 "text": "In the background... 0\n"
33 " return args\n",
34 },
34 "\n",
35 {
35 "def diefunc(interval=2, *a, **kw):\n",
36 "output_type": "stream",
36 " time.sleep(interval)\n",
37 "stream": "stdout",
37 " raise Exception(\"Dead job with interval %s\" % interval)\n",
38 "text": "In the background... 1\n"
38 "\n",
39 },
39 "def printfunc(interval=1, reps=5):\n",
40 {
40 " for n in range(reps):\n",
41 "output_type": "stream",
41 " time.sleep(interval)\n",
42 "stream": "stdout",
42 " print 'In the background...', n\n",
43 "text": "In the background... 2\n"
43 " sys.stdout.flush()\n",
44 },
44 " print 'All done!'\n",
45 {
45 " sys.stdout.flush()"
46 "output_type": "stream",
46 ],
47 "stream": "stdout",
47 "language": "python",
48 "text": "All done!\n"
48 "metadata": {},
49 }
49 "outputs": [],
50 ],
50 "prompt_number": 35
51 "collapsed": false,
51 },
52 "prompt_number": 36,
52 {
53 "input": "jobs = bg.BackgroundJobManager()\n\n# Start a few jobs, the first one will have ID # 0\njobs.new(sleepfunc, 4)\njobs.new(sleepfunc, kw={'reps':2})\njobs.new('printfunc(1,3)')\n\n# This makes a couple of jobs which will die. Let's keep a reference to\n# them for easier traceback reporting later\ndiejob1 = jobs.new(diefunc, 1)\ndiejob2 = jobs.new(diefunc, 2)"
53 "cell_type": "markdown",
54 },
54 "metadata": {},
55 {
55 "source": [
56 "source": "You can check the status of your jobs at any time:",
56 "Now, we can create a job manager (called simply `jobs`) and use it to submit new jobs.\n",
57 "cell_type": "markdown"
57 "<br>\n",
58 },
58 "Run the cell below and wait a few seconds for the whole thing to finish, until you see the \"All done!\" printout."
59 {
59 ]
60 "cell_type": "code",
60 },
61 "language": "python",
61 {
62 "outputs": [
62 "cell_type": "code",
63 {
63 "collapsed": false,
64 "output_type": "stream",
64 "input": [
65 "stream": "stdout",
65 "jobs = bg.BackgroundJobManager()\n",
66 "text": "Completed jobs:\n0 : &lt;function sleepfunc at 0x30e1578&gt;\n2 : &lt;function sleepfunc at 0x30e1578&gt;\n3 : printfunc(1,3)\n\nDead jobs:\n4 : &lt;function diefunc at 0x304d488&gt;\n5 : &lt;function diefunc at 0x304d488&gt;\n\n"
66 "\n",
67 }
67 "# Start a few jobs, the first one will have ID # 0\n",
68 ],
68 "jobs.new(sleepfunc, 4)\n",
69 "collapsed": false,
69 "jobs.new(sleepfunc, kw={'reps':2})\n",
70 "prompt_number": 37,
70 "jobs.new('printfunc(1,3)')\n",
71 "input": "jobs.status()"
71 "\n",
72 },
72 "# This makes a couple of jobs which will die. Let's keep a reference to\n",
73 {
73 "# them for easier traceback reporting later\n",
74 "source": "For any completed job, you can get its result easily:",
74 "diejob1 = jobs.new(diefunc, 1)\n",
75 "cell_type": "markdown"
75 "diejob2 = jobs.new(diefunc, 2)"
76 },
76 ],
77 {
77 "language": "python",
78 "cell_type": "code",
78 "metadata": {},
79 "language": "python",
79 "outputs": [
80 "outputs": [],
80 {
81 "collapsed": false,
81 "output_type": "stream",
82 "prompt_number": 43,
82 "stream": "stdout",
83 "input": "jobs[0].result\nj0 = jobs[0]\nj0.join?"
83 "text": [
84 },
84 "Starting job # 0 in a separate thread.\n",
85 {
85 "Starting job # 2 in a separate thread.\n",
86 "source": "You can get the traceback of any dead job. Run the line\nbelow again interactively until it prints a traceback (check the status\nof the job):\n",
86 "Starting job # 3 in a separate thread.\n",
87 "cell_type": "markdown"
87 "Starting job # 4 in a separate thread.\n",
88 },
88 "Starting job # 5 in a separate thread.\n"
89 {
89 ]
90 "cell_type": "code",
90 },
91 "language": "python",
91 {
92 "outputs": [
92 "output_type": "stream",
93 {
93 "stream": "stdout",
94 "output_type": "stream",
94 "text": [
95 "stream": "stdout",
95 "In the background... 0\n"
96 "text": "Status of diejob1: Dead (Exception), call jobs.traceback() for details\n<span class=\"ansired\">---------------------------------------------------------------------------</span>\n<span class=\"ansired\">Exception</span> Traceback (most recent call last)\n<span class=\"ansigreen\">/home/fperez/usr/lib/python2.6/site-packages/IPython/lib/backgroundjobs.py</span> in <span class=\"ansicyan\">call</span><span class=\"ansiblue\">(self)</span>\n<span class=\"ansigreen\"> 462</span> <span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 463</span> <span class=\"ansigreen\">def</span> call<span class=\"ansiyellow\">(</span>self<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\">--&gt; 464</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">return</span> self<span class=\"ansiyellow\">.</span>func<span class=\"ansiyellow\">(</span><span class=\"ansiyellow\">*</span>self<span class=\"ansiyellow\">.</span>args<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>self<span class=\"ansiyellow\">.</span>kwargs<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n\n<span class=\"ansigreen\">/home/fperez/ipython/ipython/docs/examples/lib/&lt;ipython-input-15-54795a097787&gt;</span> in <span class=\"ansicyan\">diefunc</span><span class=\"ansiblue\">(interval, *a, **kw)</span>\n<span class=\"ansigreen\"> 14</span> <span class=\"ansigreen\">def</span> diefunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">2</span><span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">*</span>a<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>kw<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 15</span> time<span class=\"ansiyellow\">.</span>sleep<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\">---&gt; 16</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">raise</span> Exception<span class=\"ansiyellow\">(</span><span class=\"ansiblue\">&quot;Dead job with interval %s&quot;</span> <span class=\"ansiyellow\">%</span> interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 17</span> <span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 18</span> <span class=\"ansigreen\">def</span> printfunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">1</span><span class=\"ansiyellow\">,</span> reps<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">5</span><span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n\n<span class=\"ansired\">Exception</span>: Dead job with interval 1\n"
96 ]
97 }
97 },
98 ],
98 {
99 "collapsed": false,
99 "output_type": "stream",
100 "prompt_number": 34,
100 "stream": "stdout",
101 "input": "print \"Status of diejob1:\", diejob1.status\ndiejob1.traceback() # jobs.traceback(4) would also work here, with the job number"
101 "text": [
102 },
102 "In the background... 1\n"
103 {
103 ]
104 "source": "This will print all tracebacks for all dead jobs:",
104 },
105 "cell_type": "markdown"
105 {
106 },
106 "output_type": "stream",
107 {
107 "stream": "stdout",
108 "cell_type": "code",
108 "text": [
109 "language": "python",
109 "In the background... 2\n"
110 "outputs": [
110 ]
111 {
111 },
112 "output_type": "stream",
112 {
113 "stream": "stdout",
113 "output_type": "stream",
114 "text": "Traceback for: &lt;BackgroundJob #4: &lt;function diefunc at 0x30df758&gt;&gt;\n<span class=\"ansired\">---------------------------------------------------------------------------</span>\n<span class=\"ansired\">Exception</span> Traceback (most recent call last)\n<span class=\"ansigreen\">/home/fperez/usr/lib/python2.6/site-packages/IPython/lib/backgroundjobs.py</span> in <span class=\"ansicyan\">call</span><span class=\"ansiblue\">(self)</span>\n<span class=\"ansigreen\"> 462</span> <span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 463</span> <span class=\"ansigreen\">def</span> call<span class=\"ansiyellow\">(</span>self<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\">--&gt; 464</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">return</span> self<span class=\"ansiyellow\">.</span>func<span class=\"ansiyellow\">(</span><span class=\"ansiyellow\">*</span>self<span class=\"ansiyellow\">.</span>args<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>self<span class=\"ansiyellow\">.</span>kwargs<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n\n<span class=\"ansigreen\">/home/fperez/ipython/ipython/docs/examples/lib/&lt;ipython-input-15-54795a097787&gt;</span> in <span class=\"ansicyan\">diefunc</span><span class=\"ansiblue\">(interval, *a, **kw)</span>\n<span class=\"ansigreen\"> 14</span> <span class=\"ansigreen\">def</span> diefunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">2</span><span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">*</span>a<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>kw<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 15</span> time<span class=\"ansiyellow\">.</span>sleep<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\">---&gt; 16</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">raise</span> Exception<span class=\"ansiyellow\">(</span><span class=\"ansiblue\">&quot;Dead job with interval %s&quot;</span> <span class=\"ansiyellow\">%</span> interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 17</span> <span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 18</span> <span class=\"ansigreen\">def</span> printfunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">1</span><span class=\"ansiyellow\">,</span> reps<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">5</span><span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n\n<span class=\"ansired\">Exception</span>: Dead job with interval 1\n\nTraceback for: &lt;BackgroundJob #5: &lt;function diefunc at 0x30df758&gt;&gt;\n<span class=\"ansired\">---------------------------------------------------------------------------</span>\n<span class=\"ansired\">Exception</span> Traceback (most recent call last)\n<span class=\"ansigreen\">/home/fperez/usr/lib/python2.6/site-packages/IPython/lib/backgroundjobs.py</span> in <span class=\"ansicyan\">call</span><span class=\"ansiblue\">(self)</span>\n<span class=\"ansigreen\"> 462</span> <span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 463</span> <span class=\"ansigreen\">def</span> call<span class=\"ansiyellow\">(</span>self<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\">--&gt; 464</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">return</span> self<span class=\"ansiyellow\">.</span>func<span class=\"ansiyellow\">(</span><span class=\"ansiyellow\">*</span>self<span class=\"ansiyellow\">.</span>args<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>self<span class=\"ansiyellow\">.</span>kwargs<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n\n<span class=\"ansigreen\">/home/fperez/ipython/ipython/docs/examples/lib/&lt;ipython-input-15-54795a097787&gt;</span> in <span class=\"ansicyan\">diefunc</span><span class=\"ansiblue\">(interval, *a, **kw)</span>\n<span class=\"ansigreen\"> 14</span> <span class=\"ansigreen\">def</span> diefunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">2</span><span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">*</span>a<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>kw<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 15</span> time<span class=\"ansiyellow\">.</span>sleep<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\">---&gt; 16</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">raise</span> Exception<span class=\"ansiyellow\">(</span><span class=\"ansiblue\">&quot;Dead job with interval %s&quot;</span> <span class=\"ansiyellow\">%</span> interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 17</span> <span class=\"ansiyellow\"></span>\n<span class=\"ansigreen\"> 18</span> <span class=\"ansigreen\">def</span> printfunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">1</span><span class=\"ansiyellow\">,</span> reps<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">5</span><span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n\n<span class=\"ansired\">Exception</span>: Dead job with interval 2\n\n"
114 "stream": "stdout",
115 }
115 "text": [
116 ],
116 "All done!\n"
117 "collapsed": false,
117 ]
118 "prompt_number": 33,
118 }
119 "input": "jobs.traceback()"
119 ],
120 },
120 "prompt_number": 36
121 {
121 },
122 "source": "The job manager can be flushed of all completed jobs at any time:",
122 {
123 "cell_type": "markdown"
123 "cell_type": "markdown",
124 },
124 "metadata": {},
125 {
125 "source": [
126 "cell_type": "code",
126 "You can check the status of your jobs at any time:"
127 "language": "python",
127 ]
128 "outputs": [
128 },
129 {
129 {
130 "output_type": "stream",
130 "cell_type": "code",
131 "stream": "stdout",
131 "collapsed": false,
132 "text": "No jobs to flush.\n"
132 "input": [
133 }
133 "jobs.status()"
134 ],
134 ],
135 "collapsed": false,
135 "language": "python",
136 "prompt_number": 25,
136 "metadata": {},
137 "input": "jobs.flush()"
137 "outputs": [
138 },
138 {
139 {
139 "output_type": "stream",
140 "source": "After that, the status is simply empty:",
140 "stream": "stdout",
141 "cell_type": "markdown"
141 "text": [
142 },
142 "Completed jobs:\n",
143 {
143 "0 : &lt;function sleepfunc at 0x30e1578&gt;\n",
144 "cell_type": "code",
144 "2 : &lt;function sleepfunc at 0x30e1578&gt;\n",
145 "language": "python",
145 "3 : printfunc(1,3)\n",
146 "outputs": [],
146 "\n",
147 "collapsed": true,
147 "Dead jobs:\n",
148 "prompt_number": 27,
148 "4 : &lt;function diefunc at 0x304d488&gt;\n",
149 "input": "jobs.status()"
149 "5 : &lt;function diefunc at 0x304d488&gt;\n",
150 },
150 "\n"
151 {
151 ]
152 "source": "It's easy to wait on a job:",
152 }
153 "cell_type": "markdown"
153 ],
154 },
154 "prompt_number": 37
155 {
155 },
156 "cell_type": "code",
156 {
157 "language": "python",
157 "cell_type": "markdown",
158 "outputs": [
158 "metadata": {},
159 {
159 "source": [
160 "output_type": "stream",
160 "For any completed job, you can get its result easily:"
161 "stream": "stdout",
161 ]
162 "text": "Starting job # 7 in a separate thread.\nWill wait for j now...\n"
162 },
163 },
163 {
164 {
164 "cell_type": "code",
165 "output_type": "stream",
165 "collapsed": false,
166 "stream": "stdout",
166 "input": [
167 "text": "Result from j:\n"
167 "jobs[0].result\n",
168 },
168 "j0 = jobs[0]\n",
169 {
169 "j0.join?"
170 "output_type": "pyout",
170 ],
171 "prompt_number": 46,
171 "language": "python",
172 "text": "{&apos;args&apos;: (), &apos;interval&apos;: 2, &apos;kwargs&apos;: {}}"
172 "metadata": {},
173 }
173 "outputs": [],
174 ],
174 "prompt_number": 43
175 "collapsed": false,
175 },
176 "prompt_number": 46,
176 {
177 "input": "j = jobs.new(sleepfunc, 2)\nprint \"Will wait for j now...\"\nsys.stdout.flush()\nj.join()\nprint \"Result from j:\"\nj.result"
177 "cell_type": "markdown",
178 },
178 "metadata": {},
179 {
179 "source": [
180 "input": "",
180 "You can get the traceback of any dead job. Run the line\n",
181 "cell_type": "code",
181 "below again interactively until it prints a traceback (check the status\n",
182 "collapsed": true,
182 "of the job):\n"
183 "language": "python",
183 ]
184 "outputs": []
184 },
185 }
185 {
186 ]
186 "cell_type": "code",
187 }
187 "collapsed": false,
188 ],
188 "input": [
189 "metadata": {
189 "print \"Status of diejob1:\", diejob1.status\n",
190 "name": "BackgroundJobs"
190 "diejob1.traceback() # jobs.traceback(4) would also work here, with the job number"
191 },
191 ],
192 "nbformat": 2
192 "language": "python",
193 "metadata": {},
194 "outputs": [
195 {
196 "output_type": "stream",
197 "stream": "stdout",
198 "text": [
199 "Status of diejob1: Dead (Exception), call jobs.traceback() for details\n",
200 "<span class=\"ansired\">---------------------------------------------------------------------------</span>\n",
201 "<span class=\"ansired\">Exception</span> Traceback (most recent call last)\n",
202 "<span class=\"ansigreen\">/home/fperez/usr/lib/python2.6/site-packages/IPython/lib/backgroundjobs.py</span> in <span class=\"ansicyan\">call</span><span class=\"ansiblue\">(self)</span>\n",
203 "<span class=\"ansigreen\"> 462</span> <span class=\"ansiyellow\"></span>\n",
204 "<span class=\"ansigreen\"> 463</span> <span class=\"ansigreen\">def</span> call<span class=\"ansiyellow\">(</span>self<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
205 "<span class=\"ansigreen\">--&gt; 464</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">return</span> self<span class=\"ansiyellow\">.</span>func<span class=\"ansiyellow\">(</span><span class=\"ansiyellow\">*</span>self<span class=\"ansiyellow\">.</span>args<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>self<span class=\"ansiyellow\">.</span>kwargs<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
206 "\n",
207 "<span class=\"ansigreen\">/home/fperez/ipython/ipython/docs/examples/lib/&lt;ipython-input-15-54795a097787&gt;</span> in <span class=\"ansicyan\">diefunc</span><span class=\"ansiblue\">(interval, *a, **kw)</span>\n",
208 "<span class=\"ansigreen\"> 14</span> <span class=\"ansigreen\">def</span> diefunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">2</span><span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">*</span>a<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>kw<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
209 "<span class=\"ansigreen\"> 15</span> time<span class=\"ansiyellow\">.</span>sleep<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
210 "<span class=\"ansigreen\">---&gt; 16</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">raise</span> Exception<span class=\"ansiyellow\">(</span><span class=\"ansiblue\">&quot;Dead job with interval %s&quot;</span> <span class=\"ansiyellow\">%</span> interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
211 "<span class=\"ansigreen\"> 17</span> <span class=\"ansiyellow\"></span>\n",
212 "<span class=\"ansigreen\"> 18</span> <span class=\"ansigreen\">def</span> printfunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">1</span><span class=\"ansiyellow\">,</span> reps<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">5</span><span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
213 "\n",
214 "<span class=\"ansired\">Exception</span>: Dead job with interval 1\n"
215 ]
216 }
217 ],
218 "prompt_number": 34
219 },
220 {
221 "cell_type": "markdown",
222 "metadata": {},
223 "source": [
224 "This will print all tracebacks for all dead jobs:"
225 ]
226 },
227 {
228 "cell_type": "code",
229 "collapsed": false,
230 "input": [
231 "jobs.traceback()"
232 ],
233 "language": "python",
234 "metadata": {},
235 "outputs": [
236 {
237 "output_type": "stream",
238 "stream": "stdout",
239 "text": [
240 "Traceback for: &lt;BackgroundJob #4: &lt;function diefunc at 0x30df758&gt;&gt;\n",
241 "<span class=\"ansired\">---------------------------------------------------------------------------</span>\n",
242 "<span class=\"ansired\">Exception</span> Traceback (most recent call last)\n",
243 "<span class=\"ansigreen\">/home/fperez/usr/lib/python2.6/site-packages/IPython/lib/backgroundjobs.py</span> in <span class=\"ansicyan\">call</span><span class=\"ansiblue\">(self)</span>\n",
244 "<span class=\"ansigreen\"> 462</span> <span class=\"ansiyellow\"></span>\n",
245 "<span class=\"ansigreen\"> 463</span> <span class=\"ansigreen\">def</span> call<span class=\"ansiyellow\">(</span>self<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
246 "<span class=\"ansigreen\">--&gt; 464</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">return</span> self<span class=\"ansiyellow\">.</span>func<span class=\"ansiyellow\">(</span><span class=\"ansiyellow\">*</span>self<span class=\"ansiyellow\">.</span>args<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>self<span class=\"ansiyellow\">.</span>kwargs<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
247 "\n",
248 "<span class=\"ansigreen\">/home/fperez/ipython/ipython/docs/examples/lib/&lt;ipython-input-15-54795a097787&gt;</span> in <span class=\"ansicyan\">diefunc</span><span class=\"ansiblue\">(interval, *a, **kw)</span>\n",
249 "<span class=\"ansigreen\"> 14</span> <span class=\"ansigreen\">def</span> diefunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">2</span><span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">*</span>a<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>kw<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
250 "<span class=\"ansigreen\"> 15</span> time<span class=\"ansiyellow\">.</span>sleep<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
251 "<span class=\"ansigreen\">---&gt; 16</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">raise</span> Exception<span class=\"ansiyellow\">(</span><span class=\"ansiblue\">&quot;Dead job with interval %s&quot;</span> <span class=\"ansiyellow\">%</span> interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
252 "<span class=\"ansigreen\"> 17</span> <span class=\"ansiyellow\"></span>\n",
253 "<span class=\"ansigreen\"> 18</span> <span class=\"ansigreen\">def</span> printfunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">1</span><span class=\"ansiyellow\">,</span> reps<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">5</span><span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
254 "\n",
255 "<span class=\"ansired\">Exception</span>: Dead job with interval 1\n",
256 "\n",
257 "Traceback for: &lt;BackgroundJob #5: &lt;function diefunc at 0x30df758&gt;&gt;\n",
258 "<span class=\"ansired\">---------------------------------------------------------------------------</span>\n",
259 "<span class=\"ansired\">Exception</span> Traceback (most recent call last)\n",
260 "<span class=\"ansigreen\">/home/fperez/usr/lib/python2.6/site-packages/IPython/lib/backgroundjobs.py</span> in <span class=\"ansicyan\">call</span><span class=\"ansiblue\">(self)</span>\n",
261 "<span class=\"ansigreen\"> 462</span> <span class=\"ansiyellow\"></span>\n",
262 "<span class=\"ansigreen\"> 463</span> <span class=\"ansigreen\">def</span> call<span class=\"ansiyellow\">(</span>self<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
263 "<span class=\"ansigreen\">--&gt; 464</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">return</span> self<span class=\"ansiyellow\">.</span>func<span class=\"ansiyellow\">(</span><span class=\"ansiyellow\">*</span>self<span class=\"ansiyellow\">.</span>args<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>self<span class=\"ansiyellow\">.</span>kwargs<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
264 "\n",
265 "<span class=\"ansigreen\">/home/fperez/ipython/ipython/docs/examples/lib/&lt;ipython-input-15-54795a097787&gt;</span> in <span class=\"ansicyan\">diefunc</span><span class=\"ansiblue\">(interval, *a, **kw)</span>\n",
266 "<span class=\"ansigreen\"> 14</span> <span class=\"ansigreen\">def</span> diefunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">2</span><span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">*</span>a<span class=\"ansiyellow\">,</span> <span class=\"ansiyellow\">**</span>kw<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
267 "<span class=\"ansigreen\"> 15</span> time<span class=\"ansiyellow\">.</span>sleep<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
268 "<span class=\"ansigreen\">---&gt; 16</span><span class=\"ansiyellow\"> </span><span class=\"ansigreen\">raise</span> Exception<span class=\"ansiyellow\">(</span><span class=\"ansiblue\">&quot;Dead job with interval %s&quot;</span> <span class=\"ansiyellow\">%</span> interval<span class=\"ansiyellow\">)</span><span class=\"ansiyellow\"></span>\n",
269 "<span class=\"ansigreen\"> 17</span> <span class=\"ansiyellow\"></span>\n",
270 "<span class=\"ansigreen\"> 18</span> <span class=\"ansigreen\">def</span> printfunc<span class=\"ansiyellow\">(</span>interval<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">1</span><span class=\"ansiyellow\">,</span> reps<span class=\"ansiyellow\">=</span><span class=\"ansicyan\">5</span><span class=\"ansiyellow\">)</span><span class=\"ansiyellow\">:</span><span class=\"ansiyellow\"></span>\n",
271 "\n",
272 "<span class=\"ansired\">Exception</span>: Dead job with interval 2\n",
273 "\n"
274 ]
275 }
276 ],
277 "prompt_number": 33
278 },
279 {
280 "cell_type": "markdown",
281 "metadata": {},
282 "source": [
283 "The job manager can be flushed of all completed jobs at any time:"
284 ]
285 },
286 {
287 "cell_type": "code",
288 "collapsed": false,
289 "input": [
290 "jobs.flush()"
291 ],
292 "language": "python",
293 "metadata": {},
294 "outputs": [
295 {
296 "output_type": "stream",
297 "stream": "stdout",
298 "text": [
299 "No jobs to flush.\n"
300 ]
301 }
302 ],
303 "prompt_number": 25
304 },
305 {
306 "cell_type": "markdown",
307 "metadata": {},
308 "source": [
309 "After that, the status is simply empty:"
310 ]
311 },
312 {
313 "cell_type": "code",
314 "collapsed": true,
315 "input": [
316 "jobs.status()"
317 ],
318 "language": "python",
319 "metadata": {},
320 "outputs": [],
321 "prompt_number": 27
322 },
323 {
324 "cell_type": "markdown",
325 "metadata": {},
326 "source": [
327 "It's easy to wait on a job:"
328 ]
329 },
330 {
331 "cell_type": "code",
332 "collapsed": false,
333 "input": [
334 "j = jobs.new(sleepfunc, 2)\n",
335 "print \"Will wait for j now...\"\n",
336 "sys.stdout.flush()\n",
337 "j.join()\n",
338 "print \"Result from j:\"\n",
339 "j.result"
340 ],
341 "language": "python",
342 "metadata": {},
343 "outputs": [
344 {
345 "output_type": "stream",
346 "stream": "stdout",
347 "text": [
348 "Starting job # 7 in a separate thread.\n",
349 "Will wait for j now...\n"
350 ]
351 },
352 {
353 "output_type": "stream",
354 "stream": "stdout",
355 "text": [
356 "Result from j:\n"
357 ]
358 },
359 {
360 "output_type": "pyout",
361 "prompt_number": 46,
362 "text": [
363 "{&apos;args&apos;: (), &apos;interval&apos;: 2, &apos;kwargs&apos;: {}}"
364 ]
365 }
366 ],
367 "prompt_number": 46
368 },
369 {
370 "cell_type": "code",
371 "collapsed": true,
372 "input": [],
373 "language": "python",
374 "metadata": {},
375 "outputs": []
376 }
377 ],
378 "metadata": {}
379 }
380 ]
193 } No newline at end of file
381 }
This diff has been collapsed as it changes many lines, (532 lines changed) Show them Hide them
@@ -1,228 +1,308 b''
1 {
1 {
2 "nbformat": 2,
2 "metadata": {
3 "metadata": {
3 "name": "rmt"
4 "name": "rmt"
4 },
5 },
5 "nbformat": 3,
6 "worksheets": [
6 "nbformat_minor": 0,
7 {
7 "worksheets": [
8 "cells": [
8 {
9 {
9 "cells": [
10 "source": "# Eigenvalue distribution of Gaussian orthogonal random matrices",
10 {
11 "cell_type": "markdown"
11 "cell_type": "markdown",
12 },
12 "metadata": {},
13 {
13 "source": [
14 "source": "The eigenvalues of random matrices obey certain statistical laws. Here we construct random matrices \nfrom the Gaussian Orthogonal Ensemble (GOE), find their eigenvalues and then investigate the nearest\nneighbor eigenvalue distribution $\\rho(s)$.",
14 "# Eigenvalue distribution of Gaussian orthogonal random matrices"
15 "cell_type": "markdown"
15 ]
16 },
16 },
17 {
17 {
18 "cell_type": "code",
18 "cell_type": "markdown",
19 "language": "python",
19 "metadata": {},
20 "outputs": [],
20 "source": [
21 "collapsed": false,
21 "The eigenvalues of random matrices obey certain statistical laws. Here we construct random matrices \n",
22 "prompt_number": 1,
22 "from the Gaussian Orthogonal Ensemble (GOE), find their eigenvalues and then investigate the nearest\n",
23 "input": "from rmtkernel import ensemble_diffs, normalize_diffs, GOE\nimport numpy as np\nfrom IPython.parallel import Client"
23 "neighbor eigenvalue distribution $\\rho(s)$."
24 },
24 ]
25 {
25 },
26 "source": "## Wigner's nearest neighbor eigenvalue distribution",
26 {
27 "cell_type": "markdown"
27 "cell_type": "code",
28 },
28 "collapsed": false,
29 {
29 "input": [
30 "source": "The Wigner distribution gives the theoretical result for the nearest neighbor eigenvalue distribution\nfor the GOE:\n\n$$\\rho(s) = \\frac{\\pi s}{2} \\exp(-\\pi s^2/4)$$",
30 "from rmtkernel import ensemble_diffs, normalize_diffs, GOE\n",
31 "cell_type": "markdown"
31 "import numpy as np\n",
32 },
32 "from IPython.parallel import Client"
33 {
33 ],
34 "cell_type": "code",
34 "language": "python",
35 "language": "python",
35 "metadata": {},
36 "outputs": [],
36 "outputs": [],
37 "collapsed": true,
37 "prompt_number": 1
38 "prompt_number": 2,
38 },
39 "input": "def wigner_dist(s):\n \"\"\"Returns (s, rho(s)) for the Wigner GOE distribution.\"\"\"\n return (np.pi*s/2.0) * np.exp(-np.pi*s**2/4.)"
39 {
40 },
40 "cell_type": "markdown",
41 {
41 "metadata": {},
42 "cell_type": "code",
42 "source": [
43 "language": "python",
43 "## Wigner's nearest neighbor eigenvalue distribution"
44 "outputs": [],
44 ]
45 "collapsed": true,
45 },
46 "prompt_number": 3,
46 {
47 "input": "def generate_wigner_data():\n s = np.linspace(0.0,4.0,400)\n rhos = wigner_dist(s)\n return s, rhos"
47 "cell_type": "markdown",
48 },
48 "metadata": {},
49 {
49 "source": [
50 "cell_type": "code",
50 "The Wigner distribution gives the theoretical result for the nearest neighbor eigenvalue distribution\n",
51 "language": "python",
51 "for the GOE:\n",
52 "outputs": [],
52 "\n",
53 "collapsed": false,
53 "$$\\rho(s) = \\frac{\\pi s}{2} \\exp(-\\pi s^2/4)$$"
54 "prompt_number": 4,
54 ]
55 "input": "s, rhos = generate_wigner_data()"
55 },
56 },
56 {
57 {
57 "cell_type": "code",
58 "cell_type": "code",
58 "collapsed": true,
59 "language": "python",
59 "input": [
60 "outputs": [
60 "def wigner_dist(s):\n",
61 {
61 " \"\"\"Returns (s, rho(s)) for the Wigner GOE distribution.\"\"\"\n",
62 "output_type": "pyout",
62 " return (np.pi*s/2.0) * np.exp(-np.pi*s**2/4.)"
63 "prompt_number": 17,
63 ],
64 "text": "&lt;matplotlib.text.Text at 0x3828790&gt;"
64 "language": "python",
65 },
65 "metadata": {},
66 {
66 "outputs": [],
67 "output_type": "display_data",
67 "prompt_number": 2
68 "png": "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\nSUVORK5CYII=\n"
68 },
69 }
69 {
70 ],
70 "cell_type": "code",
71 "collapsed": false,
71 "collapsed": true,
72 "prompt_number": 17,
72 "input": [
73 "input": "plot(s, rhos)\nxlabel('Normalized level spacing s')\nylabel('Probability $\\rho(s)$')"
73 "def generate_wigner_data():\n",
74 },
74 " s = np.linspace(0.0,4.0,400)\n",
75 {
75 " rhos = wigner_dist(s)\n",
76 "source": "## Serial calculation of nearest neighbor eigenvalue distribution",
76 " return s, rhos"
77 "cell_type": "markdown"
77 ],
78 },
78 "language": "python",
79 {
79 "metadata": {},
80 "source": "In this section we numerically construct and diagonalize a large number of GOE random matrices\nand compute the nerest neighbor eigenvalue distribution. This comptation is done on a single core.",
80 "outputs": [],
81 "cell_type": "markdown"
81 "prompt_number": 3
82 },
82 },
83 {
83 {
84 "cell_type": "code",
84 "cell_type": "code",
85 "language": "python",
85 "collapsed": false,
86 "outputs": [],
86 "input": [
87 "collapsed": true,
87 "s, rhos = generate_wigner_data()"
88 "prompt_number": 6,
88 ],
89 "input": "def serial_diffs(num, N):\n \"\"\"Compute the nearest neighbor distribution for num NxX matrices.\"\"\"\n diffs = ensemble_diffs(num, N)\n normalized_diffs = normalize_diffs(diffs)\n return normalized_diffs"
89 "language": "python",
90 },
90 "metadata": {},
91 {
91 "outputs": [],
92 "cell_type": "code",
92 "prompt_number": 4
93 "language": "python",
93 },
94 "outputs": [],
94 {
95 "collapsed": true,
95 "cell_type": "code",
96 "prompt_number": 7,
96 "collapsed": false,
97 "input": "serial_nmats = 1000\nserial_matsize = 50"
97 "input": [
98 },
98 "plot(s, rhos)\n",
99 {
99 "xlabel('Normalized level spacing s')\n",
100 "cell_type": "code",
100 "ylabel('Probability $\\rho(s)$')"
101 "language": "python",
101 ],
102 "outputs": [
102 "language": "python",
103 {
103 "metadata": {},
104 "output_type": "stream",
104 "outputs": [
105 "text": "1 loops, best of 1: 1.19 s per loop"
105 {
106 }
106 "output_type": "pyout",
107 ],
107 "prompt_number": 17,
108 "collapsed": false,
108 "text": [
109 "prompt_number": 8,
109 "&lt;matplotlib.text.Text at 0x3828790&gt;"
110 "input": "%timeit -r1 -n1 serial_diffs(serial_nmats, serial_matsize)"
110 ]
111 },
111 },
112 {
112 {
113 "cell_type": "code",
113 "output_type": "display_data",
114 "language": "python",
114 "png": "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\nSUVORK5CYII=\n"
115 "outputs": [],
115 }
116 "collapsed": false,
116 ],
117 "prompt_number": 9,
117 "prompt_number": 17
118 "input": "serial_diffs = serial_diffs(serial_nmats, serial_matsize)"
118 },
119 },
119 {
120 {
120 "cell_type": "markdown",
121 "source": "The numerical computation agrees with the predictions of Wigner, but it would be nice to get more\nstatistics. For that we will do a parallel computation.",
121 "metadata": {},
122 "cell_type": "markdown"
122 "source": [
123 },
123 "## Serial calculation of nearest neighbor eigenvalue distribution"
124 {
124 ]
125 "cell_type": "code",
125 },
126 "language": "python",
126 {
127 "outputs": [
127 "cell_type": "markdown",
128 {
128 "metadata": {},
129 "output_type": "pyout",
129 "source": [
130 "prompt_number": 10,
130 "In this section we numerically construct and diagonalize a large number of GOE random matrices\n",
131 "text": "&lt;matplotlib.text.Text at 0x3475bd0&gt;"
131 "and compute the nerest neighbor eigenvalue distribution. This comptation is done on a single core."
132 },
132 ]
133 {
133 },
134 "output_type": "display_data",
134 {
135 "png": "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\nvDyaNWtGcHAwzZs3N7u/dUNyat2XJSk81FTR/rToO+4JIYQwHbM+JCWEEMJ8SMEQQghhECkYQggh\nDCIFQwghhEGkYIhKZWNjQ3BwsP75v//977/cArTq+fv7c/jwYQACAwNJTU2t0PrCw8MZOnSowa9X\nxbaq0tWrV3nmmWdMuk1hmaRgiEpVs2ZNvv/+e5KSkgDjr8TNy8urcIZ7t7l161bs7e0rvE5r1qJF\nCzZu3Kh1DGEBpGCISmVnZ8cLL7zAokWLii27evUqM2fOxNPTk1mzZnHjxg0AJkyYwMsvv4yvry+v\nvvoqEydO5JVXXsHHx4f27dtz5MgRXnjhBTp06MC8efP06/v73/9O165d6dGjB6tXry4xj7OzM0lJ\nSXz00Ud4e3vj7e1NmzZtePzxx4GCecDGjRuHr68vc+bM0V+RGxsbS9++ffH29mb79u1lfu6MjAw+\n/PBD/Pz8CAwMJDw8HIDu3bsXuZq2cO8nMzOzxPaluXz5MoMGDcLLywtPT0/OnTtHXFwc7u7uTJ48\nGTc3N+bPn6/P//bbb+Pj40PXrl1ZsGBBkfW88soreHt706VLFy5cuEBcXBwdO3YE4IsvvmD06NEM\nHjwYDw8Pli5dqn/vtm3b6N69Oz4+Prz00ktMnz69WM6jR4/St29fvLy86Ny5M7dv3y6z74QFqcjU\nuUL8Vb169VRqaqpydnZWKSkp6t///reaN2+eUkqpWbNmqffff18ppdSCBQvU7NmzlVJKjR8/Xvn5\n+emn3J4wYYIaNGiQysrKUl988YWqV6+eCg8PV1lZWcrNzU0/dXxycrJSSqmsrCzl6+urbt++rZRS\nyt/fXx06dEgppZSzs7NKSkrS58vJyVG9e/dWoaGh+ra3bt1SSik1e/Zs9c033yillOrUqZOKjo5W\nt2/fVgMHDixxeujdu3fr7zPw+eefqyVLliillLp+/bry8fFRSim1aNEiNXfuXKWUUlevXlXt27e/\nb/t713mvuXPnqk8++UT/GTIyMtSFCxeUTqdT3333ncrMzFRPP/20+vbbb4v0TW5urho6dKg6deqU\nvq9XrFih77c7d+6oCxcu6KeS//zzz1WTJk3U1atXVWpqqnrooYdUdna2ysnJUc7OzurChQsqKSlJ\nde7cWU2fPr1YzvHjx6uwsDClVME04Lm5ucXaCMslexii0tWvX59x48YV+dcpwM8//8ykSZMAmDx5\nMlu2bAEKDiGNGDGC+vXr69uOGDGCmjVr0r17dxo2bIifnx81a9bE29tbPxPwzp07CQwMxNvbm/Pn\nz/PLL7+UmW3GjBn07duXwMBADh06xLFjx/D398fb25vQ0FAiIyO5cuUKSil8fHyoW7cuo0aNKnO6\n6k2bNrF69Wq8vb0ZOHAgN27c4MKFC4wcOZJvv/0WgA0bNujHCkpqf/78+VLX37VrVxYvXsx7771H\ncnIyDzzwAFAwLc2wYcOoVasWY8aMYdu2bQAcPHiQ4cOH06lTJw4fPsyOHTvIzs5m9+7dTJkyBSg4\nfFi7du1i2xowYADNmzenfv36uLu7c/jwYaKioujYsSPOzs44ODjwxBNPlNgn3bt3Z86cOSxfvpzc\n3FxsbW3L/J0Iy2H2U4MIy/TSSy/RuXNnJk6cWOT10r54mzdvXuR54fxcNWvWpGHDhvrXa9asSXZ2\nNmlpacyZM4c9e/bw4IMPMmzYMG7evHnfTF988QWXL19m5cqVQME01R4eHuzevbtIu/j4eMM+5D3y\n8/NZsWIFffr0KbascePG/P7772zYsEE/NUNp7Qun6/irwMBAunTpwpo1a+jZsycbN24s0i+FCsdv\npk+fzrfffouHhwezZs3i5s2b6HS6Emco/au/9ndmZiY1atQoMjZU2jqCgoLo37+/fiqS6OhomjZt\net/tCcshexiiSjRq1IiRI0fy6aef6r9oBg8ezJdffkl+fj6fffYZTzzxRLnWrZTi1q1b2NnZ0axZ\nM06fPs2uXbvu+55Dhw6xcOFCvvrqK/1rXbt25caNG/o9lvT0dM6cOcNDDz2Era0tsbGxpKens2HD\nhjIzjR07lpCQENLS0gCKTHk9atQo3nvvPVJTU/Hw8CizfUkuXLign7uob9+++nGRlJQUfvjhB7Ky\nsli/fj0DBw4kMzOTtLQ0nJ2duXLlCps3bwYKxpcee+wxVq9ejVKKrKwsMjIyyvxsOp2Obt268fvv\nvxMXF0dycjKhoaElntBw7tw5XFxc+N///V9cXV3N4l4lovJIwRCV6t4vkVdeeYXExET98+DgYC5d\nuoS3tzc3btzg5ZdfLvF9f31e0rKWLVsyfPhwPDw8mDZtWqmnohb+q3rFihXcvHmTxx57DG9vb154\n4QUAvvrqK1atWkWnTp3o0aMHf/zxBwAff/wxr732Gr169cLT07PEL0edTqd/fcSIEfj4+BAQEICH\nhwdz587VtxsxYgTr169n5MiRRV4rqf2967zXhg0b8PDwoGvXrty5c0e/LldXV3788Ue8vLzw8PAg\nMDCQBx54gDlz5uDj48OoUaMYPHiwfj3vvPMOZ8+exdPTk549e+pPPCjcZmnbt7W1Zfny5YwaNYqB\nAwfSsWNH2rRpU6zdkiVL6NixIz4+Pri6utKjR48Sfy/CMsnkg0JYqLi4OIYOHcrvv/9uku2lp6dT\nt25dUlJSGDJkCJ988gnt27c3ybaFeZAxDCEsmCnvODdv3jzCwsKws7Pj2WeflWJRDckehhBCCIPI\nGIYQQgiDSMEQQghhECkYQgghDCIFQwghhEGkYAghhDCIFAwhhBAG+X8LAxP1Be5fBAAAAABJRU5E\nrkJggg==\n"
135 "cell_type": "code",
136 }
136 "collapsed": true,
137 ],
137 "input": [
138 "collapsed": false,
138 "def serial_diffs(num, N):\n",
139 "prompt_number": 10,
139 " \"\"\"Compute the nearest neighbor distribution for num NxX matrices.\"\"\"\n",
140 "input": "hist_data = hist(serial_diffs, bins=30, normed=True)\nplot(s, rhos)\nxlabel('Normalized level spacing s')\nylabel('Probability $P(s)$')"
140 " diffs = ensemble_diffs(num, N)\n",
141 },
141 " normalized_diffs = normalize_diffs(diffs)\n",
142 {
142 " return normalized_diffs"
143 "source": "## Parallel calculation of nearest neighbor eigenvalue distribution",
143 ],
144 "cell_type": "markdown"
144 "language": "python",
145 },
145 "metadata": {},
146 {
146 "outputs": [],
147 "source": "Here we perform a parallel computation, where each process constructs and diagonalizes a subset of\nthe overall set of random matrices.",
147 "prompt_number": 6
148 "cell_type": "markdown"
148 },
149 },
149 {
150 {
150 "cell_type": "code",
151 "cell_type": "code",
151 "collapsed": true,
152 "language": "python",
152 "input": [
153 "outputs": [],
153 "serial_nmats = 1000\n",
154 "collapsed": true,
154 "serial_matsize = 50"
155 "prompt_number": 11,
155 ],
156 "input": "def parallel_diffs(rc, num, N):\n nengines = len(rc.targets)\n num_per_engine = num/nengines\n print \"Running with\", num_per_engine, \"per engine.\"\n ar = rc.apply_async(ensemble_diffs, num_per_engine, N)\n diffs = np.array(ar.get()).flatten()\n normalized_diffs = normalize_diffs(diffs)\n return normalized_diffs"
156 "language": "python",
157 },
157 "metadata": {},
158 {
158 "outputs": [],
159 "cell_type": "code",
159 "prompt_number": 7
160 "language": "python",
160 },
161 "outputs": [],
161 {
162 "collapsed": true,
162 "cell_type": "code",
163 "prompt_number": 12,
163 "collapsed": false,
164 "input": "client = Client()\nview = client[:]\nview.run('rmtkernel.py')\nview.block = False"
164 "input": [
165 },
165 "%timeit -r1 -n1 serial_diffs(serial_nmats, serial_matsize)"
166 {
166 ],
167 "cell_type": "code",
167 "language": "python",
168 "language": "python",
168 "metadata": {},
169 "outputs": [],
169 "outputs": [
170 "collapsed": true,
170 {
171 "prompt_number": 13,
171 "output_type": "stream",
172 "input": "parallel_nmats = 40*serial_nmats\nparallel_matsize = 50"
172 "stream": "stdout",
173 },
173 "text": [
174 {
174 "1 loops, best of 1: 1.19 s per loop"
175 "cell_type": "code",
175 ]
176 "language": "python",
176 }
177 "outputs": [
177 ],
178 {
178 "prompt_number": 8
179 "output_type": "stream",
179 },
180 "text": "Running with 10000 per engine.\n1 loops, best of 1: 14 s per loop"
180 {
181 },
181 "cell_type": "code",
182 {
182 "collapsed": false,
183 "output_type": "stream"
183 "input": [
184 }
184 "serial_diffs = serial_diffs(serial_nmats, serial_matsize)"
185 ],
185 ],
186 "collapsed": false,
186 "language": "python",
187 "prompt_number": 14,
187 "metadata": {},
188 "input": "%timeit -r1 -n1 parallel_diffs(view, parallel_nmats, parallel_matsize)"
188 "outputs": [],
189 },
189 "prompt_number": 9
190 {
190 },
191 "cell_type": "code",
191 {
192 "language": "python",
192 "cell_type": "markdown",
193 "outputs": [
193 "metadata": {},
194 {
194 "source": [
195 "output_type": "stream",
195 "The numerical computation agrees with the predictions of Wigner, but it would be nice to get more\n",
196 "text": "Running with 10000 per engine."
196 "statistics. For that we will do a parallel computation."
197 }
197 ]
198 ],
198 },
199 "collapsed": false,
199 {
200 "prompt_number": 15,
200 "cell_type": "code",
201 "input": "pdiffs = parallel_diffs(view, parallel_nmats, parallel_matsize)"
201 "collapsed": false,
202 },
202 "input": [
203 {
203 "hist_data = hist(serial_diffs, bins=30, normed=True)\n",
204 "source": "Again, the agreement with the Wigner distribution is excellent, but now we have better\nstatistics.",
204 "plot(s, rhos)\n",
205 "cell_type": "markdown"
205 "xlabel('Normalized level spacing s')\n",
206 },
206 "ylabel('Probability $P(s)$')"
207 {
207 ],
208 "cell_type": "code",
208 "language": "python",
209 "language": "python",
209 "metadata": {},
210 "outputs": [
210 "outputs": [
211 {
211 {
212 "output_type": "pyout",
212 "output_type": "pyout",
213 "prompt_number": 16,
213 "prompt_number": 10,
214 "text": "&lt;matplotlib.text.Text at 0x376c950&gt;"
214 "text": [
215 },
215 "&lt;matplotlib.text.Text at 0x3475bd0&gt;"
216 {
216 ]
217 "output_type": "display_data",
217 },
218 "png": "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\n"
218 {
219 }
219 "output_type": "display_data",
220 ],
220 "png": "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\nvDyaNWtGcHAwzZs3N7u/dUNyat2XJSk81FTR/rToO+4JIYQwHbM+JCWEEMJ8SMEQQghhECkYQggh\nDCIFQwghhEGkYIhKZWNjQ3BwsP75v//977/cArTq+fv7c/jwYQACAwNJTU2t0PrCw8MZOnSowa9X\nxbaq0tWrV3nmmWdMuk1hmaRgiEpVs2ZNvv/+e5KSkgDjr8TNy8urcIZ7t7l161bs7e0rvE5r1qJF\nCzZu3Kh1DGEBpGCISmVnZ8cLL7zAokWLii27evUqM2fOxNPTk1mzZnHjxg0AJkyYwMsvv4yvry+v\nvvoqEydO5JVXXsHHx4f27dtz5MgRXnjhBTp06MC8efP06/v73/9O165d6dGjB6tXry4xj7OzM0lJ\nSXz00Ud4e3vj7e1NmzZtePzxx4GCecDGjRuHr68vc+bM0V+RGxsbS9++ffH29mb79u1lfu6MjAw+\n/PBD/Pz8CAwMJDw8HIDu3bsXuZq2cO8nMzOzxPaluXz5MoMGDcLLywtPT0/OnTtHXFwc7u7uTJ48\nGTc3N+bPn6/P//bbb+Pj40PXrl1ZsGBBkfW88soreHt706VLFy5cuEBcXBwdO3YE4IsvvmD06NEM\nHjwYDw8Pli5dqn/vtm3b6N69Oz4+Prz00ktMnz69WM6jR4/St29fvLy86Ny5M7dv3y6z74QFqcjU\nuUL8Vb169VRqaqpydnZWKSkp6t///reaN2+eUkqpWbNmqffff18ppdSCBQvU7NmzlVJKjR8/Xvn5\n+emn3J4wYYIaNGiQysrKUl988YWqV6+eCg8PV1lZWcrNzU0/dXxycrJSSqmsrCzl6+urbt++rZRS\nyt/fXx06dEgppZSzs7NKSkrS58vJyVG9e/dWoaGh+ra3bt1SSik1e/Zs9c033yillOrUqZOKjo5W\nt2/fVgMHDixxeujdu3fr7zPw+eefqyVLliillLp+/bry8fFRSim1aNEiNXfuXKWUUlevXlXt27e/\nb/t713mvuXPnqk8++UT/GTIyMtSFCxeUTqdT3333ncrMzFRPP/20+vbbb4v0TW5urho6dKg6deqU\nvq9XrFih77c7d+6oCxcu6KeS//zzz1WTJk3U1atXVWpqqnrooYdUdna2ysnJUc7OzurChQsqKSlJ\nde7cWU2fPr1YzvHjx6uwsDClVME04Lm5ucXaCMslexii0tWvX59x48YV+dcpwM8//8ykSZMAmDx5\nMlu2bAEKDiGNGDGC+vXr69uOGDGCmjVr0r17dxo2bIifnx81a9bE29tbPxPwzp07CQwMxNvbm/Pn\nz/PLL7+UmW3GjBn07duXwMBADh06xLFjx/D398fb25vQ0FAiIyO5cuUKSil8fHyoW7cuo0aNKnO6\n6k2bNrF69Wq8vb0ZOHAgN27c4MKFC4wcOZJvv/0WgA0bNujHCkpqf/78+VLX37VrVxYvXsx7771H\ncnIyDzzwAFAwLc2wYcOoVasWY8aMYdu2bQAcPHiQ4cOH06lTJw4fPsyOHTvIzs5m9+7dTJkyBSg4\nfFi7du1i2xowYADNmzenfv36uLu7c/jwYaKioujYsSPOzs44ODjwxBNPlNgn3bt3Z86cOSxfvpzc\n3FxsbW3L/J0Iy2H2U4MIy/TSSy/RuXNnJk6cWOT10r54mzdvXuR54fxcNWvWpGHDhvrXa9asSXZ2\nNmlpacyZM4c9e/bw4IMPMmzYMG7evHnfTF988QWXL19m5cqVQME01R4eHuzevbtIu/j4eMM+5D3y\n8/NZsWIFffr0KbascePG/P7772zYsEE/NUNp7Qun6/irwMBAunTpwpo1a+jZsycbN24s0i+FCsdv\npk+fzrfffouHhwezZs3i5s2b6HS6Emco/au/9ndmZiY1atQoMjZU2jqCgoLo37+/fiqS6OhomjZt\net/tCcshexiiSjRq1IiRI0fy6aef6r9oBg8ezJdffkl+fj6fffYZTzzxRLnWrZTi1q1b2NnZ0axZ\nM06fPs2uXbvu+55Dhw6xcOFCvvrqK/1rXbt25caNG/o9lvT0dM6cOcNDDz2Era0tsbGxpKens2HD\nhjIzjR07lpCQENLS0gCKTHk9atQo3nvvPVJTU/Hw8CizfUkuXLign7uob9+++nGRlJQUfvjhB7Ky\nsli/fj0DBw4kMzOTtLQ0nJ2duXLlCps3bwYKxpcee+wxVq9ejVKKrKwsMjIyyvxsOp2Obt268fvv\nvxMXF0dycjKhoaElntBw7tw5XFxc+N///V9cXV3N4l4lovJIwRCV6t4vkVdeeYXExET98+DgYC5d\nuoS3tzc3btzg5ZdfLvF9f31e0rKWLVsyfPhwPDw8mDZtWqmnohb+q3rFihXcvHmTxx57DG9vb154\n4QUAvvrqK1atWkWnTp3o0aMHf/zxBwAff/wxr732Gr169cLT07PEL0edTqd/fcSIEfj4+BAQEICH\nhwdz587VtxsxYgTr169n5MiRRV4rqf2967zXhg0b8PDwoGvXrty5c0e/LldXV3788Ue8vLzw8PAg\nMDCQBx54gDlz5uDj48OoUaMYPHiwfj3vvPMOZ8+exdPTk549e+pPPCjcZmnbt7W1Zfny5YwaNYqB\nAwfSsWNH2rRpU6zdkiVL6NixIz4+Pri6utKjR48Sfy/CMsnkg0JYqLi4OIYOHcrvv/9uku2lp6dT\nt25dUlJSGDJkCJ988gnt27c3ybaFeZAxDCEsmCnvODdv3jzCwsKws7Pj2WeflWJRDckehhBCCIPI\nGIYQQgiDSMEQQghhECkYQgghDCIFQwghhEGkYAghhDCIFAwhhBAG+X8LAxP1Be5fBAAAAABJRU5E\nrkJggg==\n"
221 "collapsed": false,
221 }
222 "prompt_number": 16,
222 ],
223 "input": "hist_data = hist(pdiffs, bins=30, normed=True)\nplot(s, rhos)\nxlabel('Normalized level spacing s')\nylabel('Probability $P(s)$')"
223 "prompt_number": 10
224 }
224 },
225 ]
225 {
226 }
226 "cell_type": "markdown",
227 ]
227 "metadata": {},
228 "source": [
229 "## Parallel calculation of nearest neighbor eigenvalue distribution"
230 ]
231 },
232 {
233 "cell_type": "markdown",
234 "metadata": {},
235 "source": [
236 "Here we perform a parallel computation, where each process constructs and diagonalizes a subset of\n",
237 "the overall set of random matrices."
238 ]
239 },
240 {
241 "cell_type": "code",
242 "collapsed": true,
243 "input": [
244 "def parallel_diffs(rc, num, N):\n",
245 " nengines = len(rc.targets)\n",
246 " num_per_engine = num/nengines\n",
247 " print \"Running with\", num_per_engine, \"per engine.\"\n",
248 " ar = rc.apply_async(ensemble_diffs, num_per_engine, N)\n",
249 " diffs = np.array(ar.get()).flatten()\n",
250 " normalized_diffs = normalize_diffs(diffs)\n",
251 " return normalized_diffs"
252 ],
253 "language": "python",
254 "metadata": {},
255 "outputs": [],
256 "prompt_number": 11
257 },
258 {
259 "cell_type": "code",
260 "collapsed": true,
261 "input": [
262 "client = Client()\n",
263 "view = client[:]\n",
264 "view.run('rmtkernel.py')\n",
265 "view.block = False"
266 ],
267 "language": "python",
268 "metadata": {},
269 "outputs": [],
270 "prompt_number": 12
271 },
272 {
273 "cell_type": "code",
274 "collapsed": true,
275 "input": [
276 "parallel_nmats = 40*serial_nmats\n",
277 "parallel_matsize = 50"
278 ],
279 "language": "python",
280 "metadata": {},
281 "outputs": [],
282 "prompt_number": 13
283 },
284 {
285 "cell_type": "code",
286 "collapsed": false,
287 "input": [
288 "%timeit -r1 -n1 parallel_diffs(view, parallel_nmats, parallel_matsize)"
289 ],
290 "language": "python",
291 "metadata": {},
292 "outputs": [
293 {
294 "output_type": "stream",
295 "stream": "stdout",
296 "text": [
297 "Running with 10000 per engine.\n",
298 "1 loops, best of 1: 14 s per loop"
299 ]
300 }
301 ],
302 "prompt_number": 14
303 }
304 ],
305 "metadata": {}
306 }
307 ]
228 } No newline at end of file
308 }
@@ -1,56 +1,61 b''
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "name": "gilsleep"
3 "name": "gilsleep"
4 },
4 },
5 "nbformat": 2,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "markdown",
11 "cell_type": "markdown",
12 "metadata": {},
11 "source": [
13 "source": [
12 "Holding the GIL for too long could disrupt the heartbeat due to non-copying sends.",
14 "Holding the GIL for too long could disrupt the heartbeat due to non-copying sends.\n",
13 "",
15 "\n",
14 "The following cell repeatedly calls a function that holds the GIL for five seconds.",
16 "The following cell repeatedly calls a function that holds the GIL for five seconds.\n",
15 "",
17 "\n",
16 "The heartbeat will fail after a few iterations prior to fixing Issue [#1260](https://github.com/ipython/ipython/issues/1260)."
18 "The heartbeat will fail after a few iterations prior to fixing Issue [#1260](https://github.com/ipython/ipython/issues/1260)."
17 ]
19 ]
18 },
20 },
19 {
21 {
20 "cell_type": "code",
22 "cell_type": "code",
21 "collapsed": false,
23 "collapsed": false,
22 "input": [
24 "input": [
23 "import sys",
25 "import sys\n",
24 "import time",
26 "import time\n",
25 "",
27 "\n",
26 "from cython import inline",
28 "from cython import inline\n",
27 "",
29 "\n",
28 "def gilsleep(t):",
30 "def gilsleep(t):\n",
29 " \"\"\"gil-holding sleep with cython.inline\"\"\"",
31 " \"\"\"gil-holding sleep with cython.inline\"\"\"\n",
30 " code = '\\n'.join([",
32 " code = '\\n'.join([\n",
31 " 'from posix cimport unistd',",
33 " 'from posix cimport unistd',\n",
32 " 'unistd.sleep(t)',",
34 " 'unistd.sleep(t)',\n",
33 " ])",
35 " ])\n",
34 " while True:",
36 " while True:\n",
35 " inline(code, quiet=True, t=t)",
37 " inline(code, quiet=True, t=t)\n",
36 " print time.time()",
38 " print time.time()\n",
37 " sys.stdout.flush() # this is important",
39 " sys.stdout.flush() # this is important\n",
38 "",
40 "\n",
39 "gilsleep(5)"
41 "gilsleep(5)"
40 ],
42 ],
41 "language": "python",
43 "language": "python",
42 "outputs": [],
44 "metadata": {},
45 "outputs": [],
43 "prompt_number": 1
46 "prompt_number": 1
44 },
47 },
45 {
48 {
46 "cell_type": "code",
49 "cell_type": "code",
47 "collapsed": true,
50 "collapsed": true,
48 "input": [],
51 "input": [],
49 "language": "python",
52 "language": "python",
50 "outputs": [],
53 "metadata": {},
54 "outputs": [],
51 "prompt_number": "&nbsp;"
55 "prompt_number": "&nbsp;"
52 }
56 }
53 ]
57 ],
58 "metadata": {}
54 }
59 }
55 ]
60 ]
56 } No newline at end of file
61 }
General Comments 0
You need to be logged in to leave comments. Login now