-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfunctional.html
349 lines (330 loc) · 25.6 KB
/
functional.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Python, π and functional programming — bits v0.8 documentation</title>
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.8',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="bits v0.8 documentation" href="index.html" />
<link rel="next" title="Connecting Python and C, using multiples cores" href="faster.html" />
<link rel="prev" title="Every bit counts" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="faster.html" title="Connecting Python and C, using multiples cores"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Every bit counts"
accesskey="P">previous</a> |</li>
<li><a href="index.html">bits v0.8 documentation</a> »</li>
</ul>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Python, π and functional programming</a><ul>
<li><a class="reference internal" href="#the-math-of-the-problem">The math of the problem</a></li>
<li><a class="reference internal" href="#a-procedural-and-a-functional-algorithm">A procedural and a functional algorithm</a></li>
<li><a class="reference internal" href="#better-performance-through-lazyness">Better performance through <em>lazyness</em></a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Every bit counts</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="faster.html"
title="next chapter">Connecting Python and C, using multiples cores</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/functional.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="python-and-functional-programming">
<h1>Python, π and functional programming<a class="headerlink" href="#python-and-functional-programming" title="Permalink to this headline">¶</a></h1>
<p>This article compares the <em>procedural</em> and <em>functional</em> styles of
computer programming, through the example an algorithm approximating
π. The math on which the approximation relies is interesting
because it only requires random numbers and simple knowledge about
circles and squares.</p>
<p>The first part presents the math of the problem, then the second part
compares the differences between the functional and procedural
styles. In the third part, a complexity wall requires us to introduce
the <em>generator</em>, which is a powerful Python object.</p>
<div class="section" id="the-math-of-the-problem">
<h2>The math of the problem<a class="headerlink" href="#the-math-of-the-problem" title="Permalink to this headline">¶</a></h2>
<ol class="arabic">
<li><p class="first">Take a square and the circle which fits into the square. A random
point of the square can be either in the circle or outside of the
circle. Now, the frequency for a random point to be part of the
circle can be calculated as <em>the ratio between the number of points
of the circle and the total number of points</em>. In math, this is
summarised as:</p>
<div class="math">
<p><img src="_images/math/2206bd618bd79b326d66a382c37c0b8a74eea8fb.png" alt="frequency = \frac{number\ of\ points\ in\ the\ circle}{total\ number\ of\ points}" /></p>
</div></li>
<li><p class="first">The <em>number of points in a shape</em> is another name for the <em>surface</em>
of the shape, that is:</p>
<div class="math">
<p><img src="_images/math/ce8467839c160c7771458b91dca0f5fa8b5ed808.png" alt="frequency = \frac{ Circle\ surface}{Square\ surface} = \frac{\pi . radius^2 }{side^2}" /></p>
</div></li>
<li><p class="first">To make things simple, take a circle with a radius of <em>1</em>, and its
containing square with a side length of <em>2</em>, the frequency is
simply:</p>
<div class="math">
<p><img src="_images/math/6e8248603babf8c0b4f1c65e908ed53431583cbf.png" alt="frequency = \frac{\pi.1^2}{2^2} = \frac{\pi}{4}" /></p>
</div><p>This means that if you can build an experiment which gives you an
approximation of the frequency then an approximation of
π is <strong>four times the frequency for a random point of the
square to be in the circle</strong>:</p>
<div class="math">
<p><img src="_images/math/e1f97f1b96aafd3a724e8af5b72fefcc88b386b2.png" alt="\pi = 4 . frequency" /></p>
</div></li>
</ol>
<p>To build such an experiment, let’s picture the square, the circle, and
two random points. The square and circle are centered on zero, the
radius for the circle is 1 and it fits into the square with a side
of 2. A random point is made of two coordinates, one for the
horizontal position and one for the vertical position.</p>
<div class="figure">
<img alt="_images/square-cercle.png" src="_images/square-cercle.png" style="width: 453pt; height: 226pt;" />
</div>
<p>This figure makes it clear is that the point is in the circle if,
<em>and only if,</em> the distance between the point and the center is
smaller than the radius, which means here: smaller than one. The
method to compute the distance to the center has not changed for
thousands years, it is still: <img class="math" src="_images/math/d7a4e731d3312ce4602aa00210e53e2023f0ccb9.png" alt="distance = \sqrt{x^2 + y^2 }"/>,
where x represents the horizontal position and y represents the
vertical position.</p>
<div class="figure">
<img alt="_images/pythagoras.png" src="_images/pythagoras.png" style="width: 453pt; height: 226pt;" />
</div>
<p>To sum up the recipe for π: take a million random points in
the square, count the points in the circle, divide by a million and
multiply by four. Serve with a slice of lemon and a small quantity of
salt.</p>
<div class="figure">
<img alt="_images/frequency.png" src="_images/frequency.png" style="width: 453pt; height: 226pt;" />
</div>
</div>
<div class="section" id="a-procedural-and-a-functional-algorithm">
<h2>A procedural and a functional algorithm<a class="headerlink" href="#a-procedural-and-a-functional-algorithm" title="Permalink to this headline">¶</a></h2>
<p>That was for the theory, let’s <em>implement</em> the recipe which means
let’s make a working example. Actually, we will make two working
examples in the <a class="reference external" href="http://www.python.org/doc/2.6.4/howto/advocacy.html">Python</a> programming language and compare the styles.</p>
<p>In either styles, we will use the functions <a class="reference external" href="http://docs.python.org/dev/library/math.html#math.sqrt" title="(in Python v2.7)"><tt class="xref py py-func docutils literal"><span class="pre">math.sqrt()</span></tt></a> and
<a class="reference external" href="http://docs.python.org/dev/library/random.html#random.uniform" title="(in Python v2.7)"><tt class="xref py py-func docutils literal"><span class="pre">random.uniform()</span></tt></a>: the former returns the <em>square root</em> of the
argument given as input, the latter returns a random decimal number
<em>uniformly</em> distributed between the values of the first and the second
arguments. Also, both scripts will take the number of points (the
sample size) as the first argument, so we will need <tt class="xref py py-attr docutils literal"><span class="pre">sys.argv</span></tt>:
it holds the command line parameters of the script</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">uniform</span>
<span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sqrt</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">nb_points</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>The <strong>procedural algorithm</strong> consists of: as many times as there are
points in the sample, take a random point in the square, then
test whether the point is within the circle or not and when it is
inside: increment a counter by one. When the loop is finished, print
the counter divided by the sample size and multiplied by 4. Here it
is, written in <em>Python</em>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">nb_points_in_circle</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">nb_points</span><span class="p">):</span>
<span class="k">if</span> <span class="n">sqrt</span><span class="p">(</span><span class="n">uniform</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">uniform</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">nb_points_in_circle</span><span class="o">+=</span><span class="mi">1</span>
<span class="n">frequency</span> <span class="o">=</span> <span class="n">nb_points_in_circle</span> <span class="o">/</span> <span class="nb">float</span><span class="p">(</span><span class="n">nb_points</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">"an approximation of Pi is : </span><span class="si">%s</span><span class="s"> "</span> <span class="o">%</span> <span class="p">(</span><span class="n">frequency</span> <span class="o">*</span> <span class="mf">4.0</span><span class="p">))</span>
</pre></div>
</div>
<p>The equivalent <strong>functional algorithm</strong> is: make a function which returns
a list of random points as big a the requested sample size. Then make
another function which tests if the input point is in the
circle. Finally, print the length of the list of points filtered by
the test function, and, as before, divide by the sample size and
multiply by four:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">points</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="p">[(</span><span class="n">u</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="n">u</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">nb_points</span><span class="p">)]</span>
<span class="n">in_circle</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">point</span><span class="p">:</span> <span class="n">sqrt</span><span class="p">(</span> <span class="n">point</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">point</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">**</span><span class="mi">2</span> <span class="p">)</span> <span class="o"><</span> <span class="mi">1</span>
<span class="n">nb_points_in_circle</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="n">in_circle</span><span class="p">,</span> <span class="n">points</span><span class="p">(</span><span class="n">nb_points</span><span class="p">)))</span>
<span class="k">print</span><span class="p">(</span><span class="s">"another approximation of Pi is: </span><span class="si">%s</span><span class="s"> "</span> <span class="o">%</span>
<span class="p">(</span><span class="n">nb_points_in_circle</span> <span class="o">*</span> <span class="mf">4.0</span> <span class="o">/</span> <span class="n">nb_points</span><span class="p">))</span>
</pre></div>
</div>
<p>Now if we test it in a command line, it does approximate π,
it gets more precise with more points but it is rather slow:</p>
<div class="highlight-sh"><div class="highlight"><pre>~<span class="nv">$ </span>./procedural.py 1000
Pi ~ 3.112
~<span class="nv">$ </span>./procedural.py 500000
Pi ~ 3.14192
~<span class="nv">$ </span>./functional.py 500000
Pi ~ 3.140128
</pre></div>
</div>
<p>In your opinion, which style fits the job best? I would say the
procedural style is a sequence of small operations, without much
structure. The functional style better splits the problem into
simpler bits whose integration solve the problem .</p>
</div>
<div class="section" id="better-performance-through-lazyness">
<h2>Better performance through <em>lazyness</em><a class="headerlink" href="#better-performance-through-lazyness" title="Permalink to this headline">¶</a></h2>
<p>When comparing the performance of the two solutions, we hit a problem
which is an opportunity to present the Python magic called
<em>generator</em>. Let’s execute the script with 200 000, one million and
five million points in the sample:</p>
<div class="highlight-sh"><div class="highlight"><pre>~<span class="nv">$ </span><span class="nb">alias time</span><span class="o">=</span><span class="s1">'/usr/bin/time --format " duration: %e seconds"'</span>
~<span class="nv">$ </span>test_it <span class="o">()</span> <span class="o">{</span> <span class="k">for </span>i in 200000 1000000 5000000; <span class="se">\</span>
<span class="k">do </span><span class="nb">echo</span> -en <span class="s2">"For $i points, \t"</span> ;<span class="nb">time</span> <span class="nv">$1</span> <span class="nv">$i</span> ; <span class="k">done</span> ; <span class="o">}</span>
~<span class="nv">$ </span>test_it ./procedural.py
For 200000 points, an approximation of Pi is : 3.13734
duration: 0.47 seconds
For 1000000 points, an approximation of Pi is : 3.14116
duration: 2.25 seconds
For 5000000 points, an approximation of Pi is : 3.1410384
duration: 11.57 seconds
~<span class="nv">$ </span>test_it ./functional.py
For 200000 points, another approximation of Pi is: 3.14172
duration: 0.60 seconds
For 1000000 points, another approximation of Pi is: 3.141108
duration: 3.61 seconds
For 5000000 points, another approximation of Pi is: 3.1415296
duration: 36.09 seconds
~<span class="nv">$ </span><span class="c"># Do not hesitate to send the stop signal if it takes too long</span>
~<span class="nv">$ </span><span class="c"># on your computer: Ctrl-C or Ctrl-Z</span>
</pre></div>
</div>
<p>Mmh, the functional version takes longer and it does not scale. The
problem stems from the fact that <tt class="xref py py-func docutils literal"><span class="pre">points()</span></tt> and <a class="reference external" href="http://docs.python.org/dev/library/functions.html#filter" title="(in Python v2.7)"><tt class="xref py py-func docutils literal"><span class="pre">filter()</span></tt></a>
make up lists of several million elements, all stored in the laptop
memory where the script was tested, which is too small to handle them
all efficiently. It is no use to store them all, in this problem, we
only need one at a time, as the procedural algorithm does.</p>
<p>A solution to avoid the waste of memory is to use is a <a class="reference external" href="http://docs.python.org/reference/expressions.html#yieldexpr">generator</a> , it
is a kind of Python magic which behaves like a list, but which
<em>generates</em> the element of the list on the fly when they are requested
by the function which manipulates the generator. They are not stored,
it is <em>on demand</em>. This technique is also called <em>lazy evaluation</em>
because, like a lazy person would do, the work is done at the very
last moment. This is the goal of the the <tt class="xref py py-meth docutils literal"><span class="pre">yield()</span></tt> Python
statement, if there is a need to create its own custom generator.</p>
<p>The <tt class="xref py py-func docutils literal"><span class="pre">points()</span></tt> function is slightly modified: this expression,
which returns a list</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">[(</span><span class="n">uniform</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="n">uniform</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">size</span><span class="p">)]</span>
</pre></div>
</div>
<p>is substituted by this expression, which returns a generator:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">((</span><span class="n">uniform</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="n">uniform</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
</pre></div>
</div>
<p>Yes, only the brackets are transformed into parenthesis. Then, the
<a class="reference external" href="http://docs.python.org/dev/library/functions.html#filter" title="(in Python v2.7)"><tt class="xref py py-func docutils literal"><span class="pre">filter()</span></tt></a> function is substituted by its <em>generator-returning</em>
counterpart <a class="reference external" href="http://docs.python.org/dev/library/itertools.html#itertools.ifilter" title="(in Python v2.7)"><tt class="xref py py-func docutils literal"><span class="pre">ifilter()</span></tt></a> in the <a class="reference external" href="http://docs.python.org/dev/library/itertools.html#module-itertools" title="(in Python v2.7)"><tt class="xref py py-mod docutils literal"><span class="pre">itertools</span></tt></a>
module. One last change: a generator has no length, as elements are
generated on demand and can be infinite, so <a class="reference external" href="http://docs.python.org/dev/library/functions.html#len" title="(in Python v2.7)"><tt class="xref py py-func docutils literal"><span class="pre">len()</span></tt></a> is substituted
by a trick: sum a list of <em>ones</em> for each point which are <em>in</em> the
circle:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">nb_points</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">)</span>
<span class="n">points</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="p">((</span><span class="n">u</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="n">u</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
<span class="n">in_circle</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">point</span><span class="p">:</span> <span class="n">sqrt</span><span class="p">(</span><span class="n">point</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="n">point</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span> <span class="o"><</span> <span class="mi">1</span>
<span class="n">nb_points_in_circle</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">ifilter</span><span class="p">(</span><span class="n">in_circle</span><span class="p">,</span> <span class="n">points</span><span class="p">(</span><span class="n">nb_points</span><span class="p">)))</span>
<span class="k">print</span><span class="p">(</span><span class="s">"A slightly faster implementation: </span><span class="si">%s</span><span class="s"> "</span> <span class="o">%</span>
<span class="p">(</span><span class="n">nb_points_in_circle</span> <span class="o">*</span> <span class="mf">4.0</span> <span class="o">/</span> <span class="n">nb_points</span><span class="p">))</span>
</pre></div>
</div>
<p>The <tt class="xref py py-func docutils literal"><span class="pre">test_it()</span></tt> function shows that <em>lazy</em> functional
implementation operates with a performance boost of 14%, 25% and 55%
over the previous functional implementation:</p>
<div class="highlight-sh"><div class="highlight"><pre>~<span class="nv">$ </span>test_it ./harder_better_stronger_faster.py
For 200000 points, A slightly faster implementation: 3.14206
duration: 0.58 seconds
For 1000000 points, A slightly faster implementation: 3.143328
duration: 2.77 seconds
For 5000000 points, A slightly faster implementation: 3.1425456
duration: 13.56 seconds
</pre></div>
</div>
<p>At this point, the two styles are technically roughly equivalent, the
functional style is 10% slower than the procedural counterpart. Maybe,
those 10% are the small efficiencies that Knuth was telling us about:
“we should forget about small inefficiencies, say about 97% of the
time: premature optimization is the root of all evil”.</p>
<p>The <a class="reference internal" href="faster.html"><em>second part</em></a> of this article shows multiple ways to
accelerate this Python code: using the C language, making use of
multiple cores or processors. But if you really need an approximation
of π, you’ll see that it really is the algorithm that needs
to be changed.</p>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="faster.html" title="Connecting Python and C, using multiples cores"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Every bit counts"
>previous</a> |</li>
<li><a href="index.html">bits v0.8 documentation</a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2009, Jean Daniel Browne.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.4.
</div>
</body>
</html>