<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Harder, Better, Faster, Stronger</title>
	<atom:link href="http://hbfs.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://hbfs.wordpress.com</link>
	<description>Explorations in better, faster, stronger code.</description>
	<lastBuildDate>Thu, 12 Nov 2009 05:25:48 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='hbfs.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/c22d23f7ac31436d57af00e0027dc364?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Harder, Better, Faster, Stronger</title>
		<link>http://hbfs.wordpress.com</link>
	</image>
			<item>
		<title>Is Python Slow?</title>
		<link>http://hbfs.wordpress.com/2009/11/10/is-python-slow/</link>
		<comments>http://hbfs.wordpress.com/2009/11/10/is-python-slow/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 14:33:29 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Bash (Shell)]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[bit twiddling]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[backtracking]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Chess]]></category>
		<category><![CDATA[chess problem]]></category>
		<category><![CDATA[chess puzzle]]></category>
		<category><![CDATA[constant propagation]]></category>
		<category><![CDATA[constant-folding]]></category>
		<category><![CDATA[eight queens]]></category>
		<category><![CDATA[eight queens problem]]></category>
		<category><![CDATA[eight queens puzzle]]></category>
		<category><![CDATA[g++]]></category>
		<category><![CDATA[gcj]]></category>
		<category><![CDATA[gmcs]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[puzzle]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[python 2.6]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[recursive algorithm]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1665</guid>
		<description><![CDATA[Python is a programming language that I learnt somewhat recently (something like 2, 3 years ago) and that I like very much. It is simple, to the point, and has several functional-like constructs that I am already familiar with. But Python is slow compared to other programming languages. But it was unclear to me just [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1665&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.python.org/" target="_blank">Python</a> is a programming language that I learnt somewhat recently (something like 2, 3 years ago) and that I like very much. It is simple, to the point, and has several <a href="http://en.wikipedia.org/wiki/Functional_programming" target="_blank">functional</a>-like constructs that I am already familiar with. But Python is <em>slow</em> compared to other programming languages. But it was unclear to me just how slow Python was compared to other languages. It just felt slow.</p>
<p><a href="http://en.wikipedia.org/wiki/File:Lewis_chess_queen_.jpg"><img src="http://hbfs.files.wordpress.com/2009/09/lewis_chess_queen_.jpg?w=265&#038;h=300" alt="Lewis_chess_queen_" title="Lewis_chess_queen_" width="265" height="300" class="aligncenter size-medium wp-image-1670"></a></p>
<p>So I have decided to investigate by comparing the implementation of a simple, compute-bound problem, the <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle" target="_blank">eight queens puzzle</a> generalized to any board dimensions. This puzzle is most easily solved using, as <a href="http://en.wikipedia.org/wiki/Edsger_Dijkstra" target="_blank">Dijkstra</a> did, a depth-first <a href="http://en.wikipedia.org/wiki/Backtracking" target="_blank">backtracking</a> program, using bitmaps to test rapidly whether or not a square is free of attack<sup><a href="#1">1</a></sup>. I implemented the same program in <a href="http://en.wikipedia.org/wiki/C%2B%2B" target="_blank">C++</a>, Python, and <a href="http://en.wikipedia.org/wiki/Bash" target="_blank">Bash</a>, and got help from friends for the <a href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)" target="_blank">C#</a> and <a href="http://en.wikipedia.org/wiki/Java_(programming_language)" target="_blank">Java</a> versions<sup><a href="#2">2</a></sup>. I then compared the resulting speeds.</p>
<p><span id="more-1665"></span></p>
<p>The eight queens puzzle consist in finding a way to place 8 queens on a 8&times;8 chessboard so that none of the queen checks another queen. By &#8220;checking&#8221;, we mean that if the other queen was of the opposing camp, you could capture it if it were your turn to play. So this means that no queen is on the same row, column, or diagonal as another queen. Using a real chessboard and pawns in lieu of queens, you can easily find a solution in a few seconds. Now, to make things more interesting, we might be interested in enumerating <em>all</em> solutions (and, for the time being, neglecting to check if a solution is a rotated or mirrored version of another solution).</p>
<p>The basic algorithm to solve the Eight queens puzzle is a relatively simple recursive algorithm. First, we place a queen somewhere on the first row and we mark the row it occupies as menaced. We also do so with the column and two diagonals. We then try to place a second queen somewhere on the second row, on a square that is menace-free, and mark the row, column, and diagonals of the new queen as menaced. And we proceed in the same fashion for other queens. But suppose that at the <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />th stage, we cannot find a menace-free square, preventing us from placing the <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />th queen. If the situation arises, we give up for the <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />th queen and <em>backtrack</em> to the <img src='http://l.wordpress.com/latex.php?latex=%28n-1%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(n-1)' title='(n-1)' class='latex' />th queen. We try a new (and never tried before) location for the <img src='http://l.wordpress.com/latex.php?latex=%28n-1%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(n-1)' title='(n-1)' class='latex' />th queen and we go forth trying to place the <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />th queen. If may happen that we go all the way back to the <img src='http://l.wordpress.com/latex.php?latex=%28n-k%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(n-k)' title='(n-k)' class='latex' />th queen because there are no other solutions for the <img src='http://l.wordpress.com/latex.php?latex=%28n-1%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(n-1)' title='(n-1)' class='latex' />th queen, which asks for the <img src='http://l.wordpress.com/latex.php?latex=%28n-2%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(n-2)' title='(n-2)' class='latex' />th queen to be moved, which can also result in a dead-end; and so forth all the way down to the <img src='http://l.wordpress.com/latex.php?latex=%28n-k%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(n-k)' title='(n-k)' class='latex' />th queen.</p>
<p>Because the algorithm proceeds depth-first and can rear back quite a bit in looking for new solutions, it is called a <em>backtracking</em> algorithm.  Backtracking algorithms are key to many <a href="http://en.wikipedia.org/wiki/Artificial_intelligence" target="_blank">artificial intelligence</a> systems like, well, <a href="http://en.wikipedia.org/wiki/Chess_engine" target="_blank">chess programs</a>.</p>
<p>So I wrote the program for the <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' /> queens puzzle for a <img src='http://l.wordpress.com/latex.php?latex=n%5Ctimes%7B%7Dn&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n\times{}n' title='n\times{}n' class='latex' /> board in C quite sometime ago (circa 1995), then I ported to C++ recently (2006). And just for kicks, I decided to port it to different languages, with help from friends for Java and C# (of which I know about zilch). The C++ versions consist in a generic version that accepts the board size as a command-line argument and in a <a href="http://en.wikipedia.org/wiki/Constant_folding" target="_blank">constant-propagated</a> version where the board size is determined at compile-time. The Python versions, as there are two of them also, differ on how <em>python-esque</em> they are. The first variant is a rather literal translation of the C++ program. The second uses pythonesque idioms such as sets rather than bitmaps and turns out to be quite a bit faster&mdash;about 40% faster in fact. The Bash version is necessarily rather <em>bash-esque</em> as Bash does not offer anything much more sophisticated than arrays in terms of data structures.</p>
<p>All implementations were compiled with all optimizations enabled (<tt>-O3</tt>, inlining, interprocedural optimizations, etc.). For C++, I used g++ 4.2.4, for C#, gmcs 1.2.6.0, for Java, gcj 4.2.4, Python 2.6.2, and, finally, Bash 3.2.39&mdash;all latest versions for Ubuntu 8.04 LTS, which doesn&#8217;t means that they&#8217;re the really latest versions.</p>
<p>So I ran all seven implementations with boards sizes ranging from 1 to 15 on a AMD64 4000+ CPU (the numbers are arbitrary; I wanted to get good data but also limit the CPU time spent as the time increases <a href="http://en.wikipedia.org/wiki/Factorial" target="_blank">factorially</a> in board size!). At first, the results are not very informative:</p>
<div id="attachment_1674" class="wp-caption aligncenter" style="width: 310px"><a href="http://hbfs.files.wordpress.com/2009/09/results-linear-scale1.png"><img src="http://hbfs.files.wordpress.com/2009/09/results-linear-scale1.png?w=300&#038;h=251" alt="Results, Time, Linear Scale" title="results-linear-scale" width="300" height="251" class="size-medium wp-image-1674" /></a><p class="wp-caption-text">Results, Time, Linear Scale</p></div>
<p>As expected, all times shoot up quite fast, with, unsurprisingly, BASH shooting up faster, followed by the two Python implementations. At this scale, Java, C#, C++, C++-fixed (the constant-propagated version) all seems to be more or less similar. To remove the factorial growth (as even with a log plot the data remains rather unclear), I scaled all performances relative to the C++ version. The C++ version is therefore 1.0 regardless of actual run-time; for board size <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />, the time needed by Bash, for example, was divided by the time needed by C++ for board size <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />. We now get:</p>
<div id="attachment_1687" class="wp-caption aligncenter" style="width: 310px"><a href="http://hbfs.files.wordpress.com/2009/09/results-ratio-linear-scale2.png"><img src="http://hbfs.files.wordpress.com/2009/09/results-ratio-linear-scale2.png?w=300&#038;h=251" alt="Speed Ratio, Linear Scale" title="results-ratio-linear-scale" width="300" height="251" class="size-medium wp-image-1687" /></a><p class="wp-caption-text">Speed Ratio, Linear Scale</p></div>
<p>We can use a log-scale for the <img src='http://l.wordpress.com/latex.php?latex=y&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='y' title='y' class='latex' /> axis to better separate the similar results:</p>
<div id="attachment_1678" class="wp-caption aligncenter" style="width: 310px"><a href="http://hbfs.files.wordpress.com/2009/09/results-ratio-log-scale.png"><img src="http://hbfs.files.wordpress.com/2009/09/results-ratio-log-scale.png?w=300&#038;h=251" alt="Speed Ratio, Log Scale" title="results-ratio-log-scale" width="300" height="251" class="size-medium wp-image-1678" /></a><p class="wp-caption-text">Speed Ratio, Log Scale</p></div>
<p>We see three very strange things. The first is Bash shooting up wildly. The second is that C# relative time <em>goes down</em> with the increasing board size. The third is that before <img src='http://l.wordpress.com/latex.php?latex=n%3D8&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n=8' title='n=8' class='latex' />, the results are fluctuating. The first is easily explained: Bash is incredibly slow. About 10,000 times as slow as the optimized compiled C++ version. It is so slow that the two last data points are <em>estimated</em> as it would have taken an extra week, or so, to get them. The second anomaly needs a bit more analysis. Looking at the raw timing data, we can see that the C# version seems to be needing an extra 7ms regardless of board size. I do not know where that comes from, as the timings do not time things such as program load and initialization, but only the solving of the puzzle itself. It may well be the JIT that takes a while to figure out that the recursive function is expensive and the run-time compilation takes 7ms? Anyway, would we remove this mysterious extra 7ms, the odd behaviour of the C# implementation would vanish. The third anomaly is easily explained by the granularity of the timer and the operating system; up to puzzle size of 8, the times are much less than 100 &mu;s for most implementations. Suffice to move the mouse and generate a couple of interrupts to throw timing off considerably.</p>
<p>Removing the small board sizes yields:</p>
<div id="attachment_1680" class="wp-caption aligncenter" style="width: 310px"><a href="http://hbfs.files.wordpress.com/2009/09/results-ratio-log-scale-wo-outliers.png"><img src="http://hbfs.files.wordpress.com/2009/09/results-ratio-log-scale-wo-outliers.png?w=300&#038;h=251" alt="Speed Ratios, Log Scale, Without Outliers" title="results-ratio-log-scale-wo-outliers" width="300" height="251" class="size-medium wp-image-1680" /></a><p class="wp-caption-text">Speed Ratios, Log Scale, Without Outliers</p></div>
<p>which shows that the respective implementations are well behaved (except for C# and its most probably JIT-related extra 7ms).</p>
<p>So we see that Bash is about 10,000 times slower than the optimized C++ version. The constant-propagated version is only a bit (~5%) faster than the generic C++ version. The Java version takes about 1.5&times; the time of the C++ version, which is way better than I expected&mdash;don&#8217;t forget that this is a native-code version of the Java program, it doesn&#8217;t run on the JVM. The C# version is twice as slow as the C++ version, which is somewhat disappointing but not terribly so. The Python versions are 120&times; (for the more pythonesque version) and 200&times; slower. That&#8217;s unacceptably slow, especially that the Python programs aren&#8217;t particularly fancy nor complex. We do see that using pythonesque idioms yields a nice performance improvement&mdash;40%&mdash;but that&#8217;s still nowhere useful.</p>
<p align="center">*<br />*&emsp;*</p>
<p>So what does this tell us? For one thing, that Bash is slow. But that Bash is slow even when it doesn&#8217;t use any external command should not come as a surprise. From what I understand from Bash, data structures are limited to strings and arrays. Lists and strings are the same. Basically, a list is merely a string with items separated by the <tt>IFS</tt> character(s), which causes all array-like accesses to lists to be performed in linear time as each time the string is reinterpreted given the current <tt>IFS</tt>. So even though a construct such as <tt>${x[i]}</tt> looks like random-access, it is not. As for explicitly constructed arrays (as opposed to lists), there seems to be a real random-access capability, but it&#8217;s still very slow. I do not think that bash uses something like a virtual machine and an internal tokenizer to speed up script interpretation. Maybe that&#8217;d be something to put on the to-do list for Bash 5? In any case, I also learnt that Bash is a lot more generic than I thought.</p>
<p>The other thing is that Python is not a programming language for <a href="http://en.wikipedia.org/wiki/CPU_bound" target="_blank">compute-bound</a> problems. This makes me question how far projects such as <a href="http://www.pygame.org/" target="_blank">Pygame</a> (which aims at developing a cromulent gaming framework for Python) can go. While all of the graphics and sound processing can be off-loaded to third party libraries written in C or assembly language and interacting with the platform-specific drivers, the central problem of driving the game itself remains complete. How do you provide strong non-player characters/opponents when everything is 100&times; slower than the equivalent C or C++ program? What about strategy games? How can you build a <a href="http://en.wikipedia.org/wiki/Massively_multiplayer_online_role-playing_game" target="_blank">MMORPG</a> with a Python engine? Is a MMORPG I/O or compute bound? Could you write a championship-grade chess engine in Python?</p>
<p>My guess is that you just can&#8217;t.</p>
<p>And that&#8217;s quite sad because I <em>like</em> Python as a programming language. I used it in a number of (<a href="http://en.wikipedia.org/wiki/I/O_bound" target="_blank">I/O-bound</a>) mini-projects and I was each time delighted with the ease of coding compared to C or C++ (for those specific tasks). It pains me that Python is just too slow to be of any use whatsoever in scientific/high-performance computing. I wish for Python 4 to have a new virtual machine and interpreter to bring Python back with Java and C#, performance-wise. Better yet, why not have a true native compiler like <tt>gcj</tt> for Python?</p>
<p align="center">*<br />*&emsp;*</p>
<p>I am fully aware that the <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' /> queens on a <img src='http://l.wordpress.com/latex.php?latex=n%5Ctimes%7B%7Dn&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n\times{}n' title='n\times{}n' class='latex' /> board puzzle is a toy problem of sorts. But its extreme simplicity and its somewhat universal backtracking structure makes it an especially adequate toy problem. If a language can&#8217;t handle such a simple problem very well, how can we expect it to be able to scale to much more complex problems like, say, a championship-level chess engine?</p>
<p align="center">*<br />*&emsp;*</p>
<p>The raw data (do not forget that the two last timings for Bash are estimated). All times are in seconds.</p>
<table border="1">
<tr>
<td>Language</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<td>C++</td>
<td>0.000000</td>
<td>0.000002</td>
<td>0.000003</td>
<td>0.000046</td>
<td>0.000005</td>
<td>0.000012</td>
<td>0.000036</td>
<td>0.000126</td>
<td>0.000569</td>
<td>0.002973</td>
<td>0.016647</td>
<td>0.080705</td>
<td>0.448602</td>
<td>2.830424</td>
<td>18.648028</td>
</tr>
<tr>
<td>C++-fixed</td>
<td>0.000000</td>
<td>0.000001</td>
<td>0.000001</td>
<td>0.000007</td>
<td>0.000005</td>
<td>0.000011</td>
<td>0.000033</td>
<td>0.000104</td>
<td>0.000500</td>
<td>0.002369</td>
<td>0.011468</td>
<td>0.065407</td>
<td>0.462506</td>
<td>2.765098</td>
<td>18.032639</td>
</tr>
<tr>
<td>C#</td>
<td>0.007315</td>
<td>0.007260</td>
<td>0.008356</td>
<td>0.007302</td>
<td>0.007864</td>
<td>0.007451</td>
<td>0.007421</td>
<td>0.008287</td>
<td>0.008452</td>
<td>0.012481</td>
<td>0.033548</td>
<td>0.154490</td>
<td>0.877194</td>
<td>5.444645</td>
<td>35.769138</td>
</tr>
<tr>
<td>Java</td>
<td>0.000001</td>
<td>0.000002</td>
<td>0.000002</td>
<td>0.000003</td>
<td>0.000005</td>
<td>0.000015</td>
<td>0.000049</td>
<td>0.000198</td>
<td>0.000895</td>
<td>0.004244</td>
<td>0.022947</td>
<td>0.128498</td>
<td>0.692349</td>
<td>4.457763</td>
<td>29.321677</td>
</tr>
<tr>
<td>Python</td>
<td>0.000012</td>
<td>0.000029</td>
<td>0.000054</td>
<td>0.000136</td>
<td>0.000424</td>
<td>0.001708</td>
<td>0.006078</td>
<td>0.026174</td>
<td>0.115218</td>
<td>0.546922</td>
<td>2.822554</td>
<td>15.405020</td>
<td>91.170068</td>
<td>581.983903</td>
<td>3762.739785</td>
</tr>
<tr>
<td>Python-2</td>
<td>0.000012</td>
<td>0.000028</td>
<td>0.000045</td>
<td>0.000109</td>
<td>0.000318</td>
<td>0.001275</td>
<td>0.004125</td>
<td>0.017448</td>
<td>0.077854</td>
<td>0.348823</td>
<td>1.701767</td>
<td>9.349661</td>
<td>55.532111</td>
<td>339.244132</td>
<td>2259.010794</td>
</tr>
<tr>
<td>Bash</td>
<td>0.003054</td>
<td>0.010938</td>
<td>0.006067</td>
<td>0.011355</td>
<td>0.026913</td>
<td>0.091869</td>
<td>0.347451</td>
<td>1.472102</td>
<td>6.483076</td>
<td>30.813085</td>
<td>163.061341</td>
<td>891.828031</td>
<td>5031.663741</td>
<td>31746.000000</td>
<td>209162.000000</td>
</tr>
</table>
<p>The More Pythonesque version:</p>
<pre class="brush: python;">
#!/usr/bin/python -O
# -*- coding: utf-8 -*-

import sys
import time

########################################
##
##   (c) 2009 Steven Pigeon (pythonesque version)
##

diag45=set()
diag135=set()
cols=set()
solutions=0

########################################
##
## Marks occupancy
##
def mark(k,j):
    global cols, diag45, diag135
    cols.add(j);
    diag135.add(j+k)
    diag45.add(32+j-k)

########################################
##
## unmarks occupancy
##
def unmark(k,j):
    global cols, diag45, diag135
    cols.remove(j);
    diag135.remove(j+k)
    diag45.remove(32+j-k)

########################################
##
## Tests if a square is menaced
##
def test(k,j):
    global cols, diag45, diag135
    return not((j in cols) or \
        ((j+k) in diag135) or \
        ((32+j-k) in diag45))

########################################
##
## Backtracking solver
##
def solve( niv, dx ):
    global solutions, nodes
    if niv &gt; 0 :
        for i in xrange(0,dx):
            if test(niv,i) == True:
                mark ( niv, i )
                solve( niv-1, dx)
                unmark ( niv, i )
    else:
        for i in xrange(0,dx):
            if (test(0,i) == True):
                solutions += 1

########################################
##
## usage message
##
def usage( progname ):
    print &quot;usage: &quot;, progname, &quot; &lt;size&gt;&quot;
    print &quot;size must be 1..32&quot;

########################################
##
## c/c++-style main function
##
def main():
    if len(sys.argv) &lt; 2:
        usage(sys.argv[0])
    else:
        try:
            size = int(sys.argv[1])
        except:
            usage(sys.argv[0])
            return

        if (size &lt;= 32) &amp; (size&gt;0):

            start = time.time()
            solve(size-1,size)
            elapsed = time.time()-start

            print &quot;%s %0.6f&quot; % (solutions,elapsed)

        else:
            usage(sys.argv[0])
#
if __name__ == &quot;__main__&quot;:
    main()
</pre>
<p>The other versions can be found here in <a href="http://www.stevenpigeon.org/blogs/hbfs/super_reines.zip">super_reines.zip</a>. The Bash and C++ versions are somewhat Linux-specific.</p>
<hr align="left" width="30%">
<sup><a name="1">1</a></sup>&nbsp;A trick explained in detail in Brassard and Bratley, <i>Introduction à l&#8217;algorithmique</i>, Presses de l&#8217;Université de Montréal. Translated to English: <a href="http://www.amazon.com/gp/product/0133350681?ie=UTF8&amp;tag=hardbettfasts-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=0133350681" target="_blank"><i>Fundamentals of Algorithmics</i></a> (at Amazon.com)</p>
<p><sup><a name="2">2</a></sup>&nbsp;Frédéric Marceau translated the program from C++ to C#. <a href="http://lostwebsite.wordpress.com/" target="_blank">François-Denis Gonthier</a> translated from C++ to Java.</p>
<p align="center">*<br />*&emsp;*</p>
<p>So I added a third Python version to the archive. I also benchmarked it. It is quite a bit faster than the original one, and even than the &#8216;pythonesque&#8217; version. For example:</p>
<pre class="brush: bash;">
$ super-reines.py 12
14200 15.966019
$ super-reines-2.py 12
14200 9.478235
$ super-reines-3.py 12
14200 6.845071
</pre>
<p>So a more &#8216;functional&#8217; version performs about 2.3&times; faster than a direct translation from C++. For the same problem size, however, the C++ (fixed) version takes 0.069s&#8230; Roughly 100&times; faster than the 3rd version.</p>
<div id="attachment_1899" class="wp-caption aligncenter" style="width: 310px"><a href="http://hbfs.files.wordpress.com/2009/11/results-ratio-log-scale-wo-outliers-2.png"><img src="http://hbfs.files.wordpress.com/2009/11/results-ratio-log-scale-wo-outliers-2.png?w=300&#038;h=251" alt="results-ratio-log-scale-wo-outliers-2" title="results-ratio-log-scale-wo-outliers-2" width="300" height="251" class="size-medium wp-image-1899" /></a><p class="wp-caption-text">Speed Ratios, Log Scale, Without Outliers, with 3rd Python version</p></div> 
Posted in algorithms, Artificial Intelligence, Bash (Shell), bit twiddling, C, data structures, hacks, programming, Python Tagged: Artificial Intelligence, backtracking, bash, C, Chess, chess problem, chess puzzle, constant propagation, constant-folding, eight queens, eight queens problem, eight queens puzzle, g++, gcj, gmcs, java, puzzle, pygame, Python, python 2.6, recursion, recursive algorithm <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1665/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1665/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1665/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1665/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1665/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1665/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1665/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1665/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1665/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1665/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1665&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/11/10/is-python-slow/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/09/lewis_chess_queen_.jpg?w=265" medium="image">
			<media:title type="html">Lewis_chess_queen_</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/09/results-linear-scale1.png?w=300" medium="image">
			<media:title type="html">results-linear-scale</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/09/results-ratio-linear-scale2.png?w=300" medium="image">
			<media:title type="html">results-ratio-linear-scale</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/09/results-ratio-log-scale.png?w=300" medium="image">
			<media:title type="html">results-ratio-log-scale</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/09/results-ratio-log-scale-wo-outliers.png?w=300" medium="image">
			<media:title type="html">results-ratio-log-scale-wo-outliers</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/11/results-ratio-log-scale-wo-outliers-2.png?w=300" medium="image">
			<media:title type="html">results-ratio-log-scale-wo-outliers-2</media:title>
		</media:content>
	</item>
		<item>
		<title>Log Watching</title>
		<link>http://hbfs.wordpress.com/2009/11/03/log-watching/</link>
		<comments>http://hbfs.wordpress.com/2009/11/03/log-watching/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 11:28:15 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Bash (Shell)]]></category>
		<category><![CDATA[Life in the workplace]]></category>
		<category><![CDATA[Operating System]]></category>
		<category><![CDATA[Portable Code]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[shell programming]]></category>
		<category><![CDATA[xterm]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[terminal characteristics]]></category>
		<category><![CDATA[stty]]></category>
		<category><![CDATA[tr]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[cut]]></category>
		<category><![CDATA[gnome-terminal]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1643</guid>
		<description><![CDATA[Very often, you have to keep an eye on a log, or maybe more than one log, and a couple of other things while a long-term simulation is running. The GNU/Linux distributions offer the program watch that allows the periodical execution of a command in the current interactive shell. While watch is convenient, you still [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1643&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Very often, you have to keep an eye on a log, or maybe more than one log, and a couple of other things while a long-term simulation is running. The GNU/Linux distributions offer the program <tt>watch</tt> that allows the periodical execution of a command in the current interactive shell. While <tt>watch</tt> is convenient, you still have the problem of displaying the needed information in a terminal geometry aware way. Turns out, there are tools to query the terminal geometry and we can use them to write simple, effective, well displayed scripts.</p>
<p><a href="http://en.wikipedia.org/wiki/File:Emblemata_1624.jpg"><img src="http://hbfs.files.wordpress.com/2009/09/telescope-small.jpg?w=300&#038;h=204" alt="telescope-small" title="telescope-small" width="300" height="204" class="aligncenter size-full wp-image-1647" /></a></p>
<p>So let us see how we can make BASH somewhat aware of the terminal it runs in.</p>
<p><span id="more-1643"></span></p>
<p>The first command we will look at is <tt>stty</tt>. Traditionally, <tt>stty</tt> is used to set the various terminal&#8217;s parameters, but for now, we are interested in its parameter reporting capabilities. Invoking <tt>stty -a</tt> will output the current terminal&#8217;s settings (use the <tt>view plain</tt> option as WordPress messes up the formating a bit):</p>
<pre class="brush: bash;">
.../somewhere/&gt;stty -a
stty -a
speed 38400 baud; rows 29; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = &lt;undef&gt;; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
</pre>
<p>So it seems to be reporting all needed information, including some obsolete or unneeded information (such as the terminal&#8217;s baud-rate for a terminal running on the console in graphics mode). But like most commands, it has its peculiarities. From the above, we may gather that the parameters are separated by semicolons (;) and that new lines are inserted so to more or less separate parameter categories. But if we resize the window to a very weird shape, like a very narrow, very high window, we see that the newlines change places! The first step to extract the information from <tt>stty -a</tt> is to get rid of the newlines altogether, using the <tt>tr</tt> command, replacing newlines (<tt>$'\n'</tt>) by spaces:</p>
<pre class="brush: bash;">
.../somewhere/&gt;stty -a | tr $'\n' ' '
speed 38400 baud; rows 29; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = &lt;undef&gt;; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop
</pre>
<p>Fields are fortunately separated by semicolons. Adding:</p>
<pre class="brush: cpp;">
.../somewhere/&gt;stty -a | tr $'\n' ' ' | cut -d\; -f 2-3
 rows 29; columns 80
</pre>
<p>So we&#8217;re <em>almost</em> done. Now, let us extract the numbers only:</p>
<pre class="brush: bash;">
.../somewhere/&gt;stty -a | tr $'\n' ' ' | cut -d\; -f 2-3 | tr -c [0-9] ' '
      29          80
</pre>
<p>which we wrap in a BASH array:</p>
<pre class="brush: bash;">
.../somewhere/&gt; (z=($(stty -a | tr $'\n' ' ' | cut -d\; -f 2-3 | tr -c [0-9] ' ')); echo ${z[@]} )
29 80
</pre>
<p>Using this in a script lets us get the dimensions of the terminal in characters:</p>
<pre class="brush: bash;">
#!/bin/bash

# get the rows and columns
# in the current window
#
res=($( stty -a |\
        tr $'\n' ' ' |\
        cut -d\; -f 2-3 |\
        tr -c [0-9] ' '\
    ))

cols=${res[1]}
rows=${res[0]}
</pre>
<p>Now, what we have to do is to use the known size of the terminal (<tt>$cols</tt> and <tt>$rows</tt>) for pretty-displaying a log and, say, the used disk space. Let the file <tt>watch-log</tt> contain:</p>
<pre class="brush: bash;">
#!/bin/bash

# get the rows and columns
# in the current window
#
res=($( stty -a |\
        tr $'\n' ' ' |\
        cut -d\; -f 2-3 |\
        tr -c [0-9] ' '\
    ))

cols=${res[1]}
rows=${res[0]}

# du will use du_rows rows
du_rows=$( du -h | wc -l )

# the normal log will take
# what's left (after du,
# watch, and maybe a trailing
# white line)
log_rows=$((rows-du_rows-6))

# check if the number of log rows
# is positive, at least, and if the
# terminal is wide enough
#
if [[ $log_rows -gt 0 &amp;&amp; $cols -ge 20 ]]
then
    echo &quot;Space Used:&quot;
    du -h
    echo
    echo &quot;Log Tail:&quot;

    # here, add your own stuff to
    # watch over
    #
    tail -n $log_rows watched.log | cut -b -${cols}
    exit 0 # success!
else
    echo &quot;window too small for watching!&quot;
    exit 1
fi
</pre>
<p>We invoke <tt>watch-log</tt> through <tt>watch</tt>. The actual frequency that suits you best is up to you, but to get an update every second, you would invoke: <tt>watch -n 1 watch-log</tt>. Now, resizing the window produces a seamless update of the information.</p>
<p align="center">*<br />*&emsp;*</p>
<p>Working with <tt>cut</tt>, <tt>sed</tt> and <tt>tr</tt> is alien at first, but they will prove most useful in basic or advanced scripting. Here, we used two of them to extract and use the terminal&#8217;s resolution (in characters). Another thing that we could have done to beautify the script is to use colors, but I personally think they&#8217;re best used in moderation. Maybe we could display the result of <tt>du</tt> in red should the used disk space exceed, say, 1GB or some other convenient limit, but I will leave that to you.</p>
Posted in Bash (Shell), hacks, Life in the workplace, Operating System, Portable Code, programming Tagged: cut, gnome-terminal, sed, shell, shell programming, stty, terminal, terminal characteristics, tr, xterm <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1643/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1643/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1643/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1643/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1643/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1643/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1643/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1643/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1643/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1643/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1643&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/11/03/log-watching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/09/telescope-small.jpg" medium="image">
			<media:title type="html">telescope-small</media:title>
		</media:content>
	</item>
		<item>
		<title>Of staircases and textbooks</title>
		<link>http://hbfs.wordpress.com/2009/10/27/of-staircases-and-textbooks/</link>
		<comments>http://hbfs.wordpress.com/2009/10/27/of-staircases-and-textbooks/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 10:29:57 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[algebra]]></category>
		<category><![CDATA[college]]></category>
		<category><![CDATA[derivation]]></category>
		<category><![CDATA[discrete mathematics]]></category>
		<category><![CDATA[Gabriel's staircase]]></category>
		<category><![CDATA[math courses]]></category>
		<category><![CDATA[staircase function]]></category>
		<category><![CDATA[sum]]></category>
		<category><![CDATA[textbooks]]></category>
		<category><![CDATA[university]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1599</guid>
		<description><![CDATA[This week, I&#8217;m talking you about a little identity that crops up often in the study of algorithms and which isn&#8217;t found in formula compendia&#8212;anyway, none that I have. I&#8217;m talking about this function:

This is a variation on the Gabriel&#8217;s Staircase function that does not have an infinite number of terms. Let us solve it [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1599&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This week, I&#8217;m talking you about a little identity that crops up often in the study of algorithms and which isn&#8217;t found in formula compendia&mdash;anyway, none that I have. I&#8217;m talking about this function:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+C_%7Bn%2Ca%7D%3D%5Csum_%7Bi%3D1%7D%5En+i+a%5Ei&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle C_{n,a}=\sum_{i=1}^n i a^i' title='\displaystyle C_{n,a}=\sum_{i=1}^n i a^i' class='latex' /></p>
<p>This is a variation on the <a href="http://mathworld.wolfram.com/GabrielsStaircase.html" target="_blank">Gabriel&#8217;s Staircase</a> function that does not have an infinite number of terms. Let us solve it without supposing that <img src='http://l.wordpress.com/latex.php?latex=0%3Ca%3C1&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='0&lt;a&lt;1' title='0&lt;a&lt;1' class='latex' />.</p>
<p><span id="more-1599"></span></p>
<p>Let&#8217;s warm up by solving a similar function (which will be instrumental later on), the sum <img src='http://l.wordpress.com/latex.php?latex=%5Csum_%7Bi%3D1%7D%5En+a%5Ei&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\sum_{i=1}^n a^i' title='\sum_{i=1}^n a^i' class='latex' />. This is known as the <a href="http://mathworld.wolfram.com/GeometricSeries.html" target="_blank">geometric series</a>. Put:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=t_n+%3D+%5Csum_%7Bi%3D1%7D%5En+a%5Ei&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='t_n = \sum_{i=1}^n a^i' title='t_n = \sum_{i=1}^n a^i' class='latex' /></p>
<p>and</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=a+t_n+%3D+a%5Csum_%7Bi%3D1%7D%5En+a%5Ei&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='a t_n = a\sum_{i=1}^n a^i' title='a t_n = a\sum_{i=1}^n a^i' class='latex' /></p>
<p>Let us combine the two:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=t_n+-+a+t_n+%3D+%281-a%29t_n+%3D+%5Csum_%7Bi%3D1%7D%5En+a%5Ei+-+a%5Csum_%7Bi%3D1%7D%5En+a%5Ei&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='t_n - a t_n = (1-a)t_n = \sum_{i=1}^n a^i - a\sum_{i=1}^n a^i' title='t_n - a t_n = (1-a)t_n = \sum_{i=1}^n a^i - a\sum_{i=1}^n a^i' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=t_n-at_n%3D+%28a%2Ba%5E2%2Ba%5E3%2B%5Ccdots%2Ba%5En%29-%28a%5E2%2Ba%5E3%2Ba%5E4%2B%5Ccdots%2Ba%5E%7Bn%2B1%7D%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='t_n-at_n= (a+a^2+a^3+\cdots+a^n)-(a^2+a^3+a^4+\cdots+a^{n+1})' title='t_n-at_n= (a+a^2+a^3+\cdots+a^n)-(a^2+a^3+a^4+\cdots+a^{n+1})' class='latex' /></p>
<p>This is a <a href="http://mathworld.wolfram.com/TelescopingSum.html" target="blank">telescoping sum</a> and terms mostly cancel each other out:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=t_n-at_n%3D%281-a%29t_n+%3D+a-a%5E%7Bn%2B1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='t_n-at_n=(1-a)t_n = a-a^{n+1}' title='t_n-at_n=(1-a)t_n = a-a^{n+1}' class='latex' /></p>
<p>and finally:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+t_n+%3D+%5Cfrac%7Ba-a%5E%7Bn%2B1%7D%7D%7B1-a%7D%3D%5Cfrac%7Ba%281-a%5En%29%7D%7B1-a%7D%3D%5Cfrac%7Ba%28a%5En-1%29%7D%7Ba-1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle t_n = \frac{a-a^{n+1}}{1-a}=\frac{a(1-a^n)}{1-a}=\frac{a(a^n-1)}{a-1}' title='\displaystyle t_n = \frac{a-a^{n+1}}{1-a}=\frac{a(1-a^n)}{1-a}=\frac{a(a^n-1)}{a-1}' class='latex' /></p>
<p>There, we&#8217;re done for this one. Reversing <img src='http://l.wordpress.com/latex.php?latex=%281-a%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(1-a)' title='(1-a)' class='latex' /> into <img src='http://l.wordpress.com/latex.php?latex=%28a-1%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(a-1)' title='(a-1)' class='latex' /> is allowed because we multiply both the numerator and the denominator by <img src='http://l.wordpress.com/latex.php?latex=-1&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='-1' title='-1' class='latex' /> (thus the whole expression by <img src='http://l.wordpress.com/latex.php?latex=1&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='1' title='1' class='latex' />, so it doesn&#8217;t change its value).</p>
<p>Now, back to our main concern, the truncated staircase. Put:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+s%3D%5Csum_%7Bi%3D1%7D%5En+i+a%5Ei&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle s=\sum_{i=1}^n i a^i' title='\displaystyle s=\sum_{i=1}^n i a^i' class='latex' /></p>
<p>and</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+as%3Da%5Csum_%7Bi%3D1%7D%5En+ia%5Ei%3D%5Csum_%7Bi%3D1%7D%5Enia%5E%7Bi%2B1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle as=a\sum_{i=1}^n ia^i=\sum_{i=1}^nia^{i+1}' title='\displaystyle as=a\sum_{i=1}^n ia^i=\sum_{i=1}^nia^{i+1}' class='latex' /></p>
<p>So you&#8217;re guessing right, we&#8217;ll use the same overall trick as we did for the geometric series. Quite so!</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+s-as+%3D+%5Csum_%7Bi%3D1%7D%5En+ia%5Ei-%5Csum_%7Bi%3D1%7D%5Enia%5E%7Bi%2B1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle s-as = \sum_{i=1}^n ia^i-\sum_{i=1}^nia^{i+1}' title='\displaystyle s-as = \sum_{i=1}^n ia^i-\sum_{i=1}^nia^{i+1}' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%281-a%29s%3D%28a%2B2a%5E2%2B3a%5E3%2B%5Ccdots%7B%7D%2Bna%5En%29-%28a%5E2%2B2a%5E3%2B3a%5E4%2B%5Ccdots%7B%7D%2Bna%5E%7Bn%2B1%7D%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(1-a)s=(a+2a^2+3a^3+\cdots{}+na^n)-(a^2+2a^3+3a^4+\cdots{}+na^{n+1})' title='(1-a)s=(a+2a^2+3a^3+\cdots{}+na^n)-(a^2+2a^3+3a^4+\cdots{}+na^{n+1})' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%281-a%29s%3Da%2Ba%5E2%2Ba%5E3%2B%5Ccdots%7B%7D%2Ba%5En-na%5E%7Bn%2B1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='(1-a)s=a+a^2+a^3+\cdots{}+a^n-na^{n+1}' title='(1-a)s=a+a^2+a^3+\cdots{}+a^n-na^{n+1}' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+%281-a%29s%3D%5Csum_%7Bi%3D1%7D%5En+ai+-+na%5E%7Bn%2B1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle (1-a)s=\sum_{i=1}^n ai - na^{n+1}' title='\displaystyle (1-a)s=\sum_{i=1}^n ai - na^{n+1}' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+%281-a%29s%3D%5Cfrac%7Ba%281-a%5En%29%7D%7B1-a%7D-+na%5E%7Bn%2B1%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle (1-a)s=\frac{a(1-a^n)}{1-a}- na^{n+1}' title='\displaystyle (1-a)s=\frac{a(1-a^n)}{1-a}- na^{n+1}' class='latex' /></p>
<p>then</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+%281-a%29s%3D%5Cfrac%7B%281-a%5En%29-%281-a%29na%5E%7Bn%2B1%7D%7D%7B1-a%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle (1-a)s=\frac{(1-a^n)-(1-a)na^{n+1}}{1-a}' title='\displaystyle (1-a)s=\frac{(1-a^n)-(1-a)na^{n+1}}{1-a}' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+%281-a%29s%3D%5Cfrac%7Ba%5E%7Bn%2B1%7D%28na-n-1%29%2Ba%7D%7B1-a%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle (1-a)s=\frac{a^{n+1}(na-n-1)+a}{1-a}' title='\displaystyle (1-a)s=\frac{a^{n+1}(na-n-1)+a}{1-a}' class='latex' /></p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+%281-a%29s%3D%5Cfrac%7Ba%5E%7Bn%2B1%7D%28n%28a-1%29-1%29%2Ba%7D%7B1-a%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle (1-a)s=\frac{a^{n+1}(n(a-1)-1)+a}{1-a}' title='\displaystyle (1-a)s=\frac{a^{n+1}(n(a-1)-1)+a}{1-a}' class='latex' /></p>
<p>After much pericombobulations, we, at last, get our solution:</p>
<p align="center"><img src='http://l.wordpress.com/latex.php?latex=%5Cdisplaystyle+s%3D%5Cfrac%7Ba%5E%7Bn%2B1%7D%28n%28a-1%29-1%29%2Ba%7D%7B%281-a%29%5E2%7D&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\displaystyle s=\frac{a^{n+1}(n(a-1)-1)+a}{(1-a)^2}' title='\displaystyle s=\frac{a^{n+1}(n(a-1)-1)+a}{(1-a)^2}' class='latex' /></p>
<p align="center">*<br />*&emsp;*</p>
<p>Despite all the work, only basic algebra is needed to obtain the desired expression, and, well, a lot of patience. We also note that a difficulty arises when <img src='http://l.wordpress.com/latex.php?latex=a%3D1&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='a=1' title='a=1' class='latex' />. The denominator is zero, which is bad. But fortunately, <img src='http://l.wordpress.com/latex.php?latex=1%5Ex&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='1^x' title='1^x' class='latex' /> is 1, so we have:</p>
<p align="center">
<img src='http://l.wordpress.com/latex.php?latex=s%3D%5Csum_%7Bi%3D1%7D%5E%7Bn%7D+ia%5Ei+%3D+%5Csum_%7Bi%3D1%7D%5E%7Bn%7D+i%281%5Ei%29+%3D%5Csum_%7Bi%3D1%7D%5E%7Bn%7D+i&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='s=\sum_{i=1}^{n} ia^i = \sum_{i=1}^{n} i(1^i) =\sum_{i=1}^{n} i' title='s=\sum_{i=1}^{n} ia^i = \sum_{i=1}^{n} i(1^i) =\sum_{i=1}^{n} i' class='latex' /></p>
<p>which is a sum you should already know:</p>
<p align="center">
<img src='http://l.wordpress.com/latex.php?latex=s%3D%5Csum_%7Bi%3D1%7D%5E%7Bn%7D+i+%3D+%5Cfrac%7B1%7D%7B2%7Dn%28n%2B1%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='s=\sum_{i=1}^{n} i = \frac{1}{2}n(n+1)' title='s=\sum_{i=1}^{n} i = \frac{1}{2}n(n+1)' class='latex' /></p>
<p align="center">*<br />*&emsp;*</p>
<p>A few friends of mine decided to return to school&mdash;well, the university, that is. And all of them have to take (or retake) math classes to enroll in their programs. They&#8217;re not all at the same level, but they&#8217;re quite decided and working hard to get there. However, I do hear complaints now and then and it&#8217;s mostly about how bad introductory-level textbooks are. In one book my friend <a href="http://gnuvince.wordpress.com/" target="_blank">Vincent</a> showed me, a <img src='http://l.wordpress.com/latex.php?latex=b&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='b' title='b' class='latex' /> suddenly becomes a <img src='http://l.wordpress.com/latex.php?latex=6&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='6' title='6' class='latex' />, altering the derivation of the solution in ways that are more tragic than funny. I guess college-level textbooks do not all get that much of a scrutiny before release.</p>
<p>Another complaint I hear is how things are derived. While it may be perfectly acceptable in an advanced textbook to simply state that <img src='http://l.wordpress.com/latex.php?latex=%5Csum_%7Bi%3D1%7D%5En+i+2%5Ei+%3D+2%5E%7Bn%2B1%7D%28n-1%29%2B2&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\sum_{i=1}^n i 2^i = 2^{n+1}(n-1)+2' title='\sum_{i=1}^n i 2^i = 2^{n+1}(n-1)+2' class='latex' /> and move on as you expect your readers to be able to take 5 or 10 minutes to obtain the result by themselves, that&#8217;s not something you can do too often in an introductory- or college-level textbook because, guess what, you&#8217;re teaching math to people that may not know enough math to know beforehand what&#8217;re you&#8217;re trying to teach them. Wait, what?</p>
<p>Clear, step by step, derivations of equations are sometimes necessary, and not always for college-level textbooks. Some authors are notoriously vague in derivation. Sentences like &#8220;it naturally follows&#8221; are proverbially antinomic.</p>
Posted in hacks, Mathematics Tagged: algebra, college, derivation, discrete mathematics, Gabriel's staircase, math courses, staircase function, sum, textbooks, university <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1599/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1599/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1599/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1599/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1599/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1599/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1599/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1599/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1599/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1599/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1599&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/27/of-staircases-and-textbooks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>
	</item>
		<item>
		<title>Code Style: Vertical vs Horizontal?</title>
		<link>http://hbfs.wordpress.com/2009/10/20/code-style-vertical-vs-horizontal/</link>
		<comments>http://hbfs.wordpress.com/2009/10/20/code-style-vertical-vs-horizontal/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 11:06:07 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Inoffensive Rant]]></category>
		<category><![CDATA[Life in the workplace]]></category>
		<category><![CDATA[Zen]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[color scheme]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[eye]]></category>
		<category><![CDATA[eye movement]]></category>
		<category><![CDATA[eyes]]></category>
		<category><![CDATA[Identation]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[reading]]></category>
		<category><![CDATA[Select]]></category>
		<category><![CDATA[speed reading]]></category>
		<category><![CDATA[tab]]></category>
		<category><![CDATA[tabs-are-evil]]></category>
		<category><![CDATA[Wirth]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1582</guid>
		<description><![CDATA[The only difference between coding styles and religion discussions is that coding styles have claimed fewer victims&#8212;at least until now. A few post back I discussed color schemes, and this week I&#8217;ll be discussing code geometry for enhanced clarity.


A few days back I was discussing with a friend whether or not comments in code should [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1582&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>The only difference between coding styles and religion discussions is that coding styles have claimed fewer victims&mdash;at least until now. A few post back I discussed <a href="http://hbfs.wordpress.com/2009/09/15/whats-a-good-color-scheme/">color schemes</a>, and this week I&#8217;ll be discussing code <i>geometry</i> for enhanced clarity.</p>
<p><a href="http://hbfs.files.wordpress.com/2009/08/fish-on-stilts.png"><img src="http://hbfs.files.wordpress.com/2009/08/fish-on-stilts.png?w=215&#038;h=300" alt="fish-on-stilts" title="fish-on-stilts" width="215" height="300" class="aligncenter size-medium wp-image-1584" /></a></p>
<p><span id="more-1582"></span></p>
<p>A few days back I was discussing with a friend whether or not comments in code should be rather narrow, spread vertically in short lines, or if they rather should be &#8220;line long&#8221;, that is, about 70 or so, characters wide. He agreed that short comments broken in many lines are easier to read than very long lines. A coworker came to the opposite conclusion: short, broken comments were &#8220;stocky&#8221;. Of course, like other style matters, that is ultimately to everyone&#8217;s own taste; but I wasn&#8217;t sure why <em>I</em> found them much easier to read.</p>
<p>My personal theory is that <em>eye movement</em> is minimized with short lines. There&#8217;s a certain vision angle in which we seem to be able to just <em>grab</em> a bunch of letters without really scanning them. This angle is not very wide&mdash;maybe 5&deg;&mdash;and very long lines forces us to scan text jumping over every few words. That&#8217;s probably why newspaper, blog templates, and scientific journal all use multiple and rather narrow columns: one can read while essentially scanning the text <em>downward only</em>.</p>
<p>Let us look a piece of code I wrote recently (what it does is somewhat irrelevant right now; let&#8217;s say it&#8217;s an extra goodie). In my default <a href="http://en.wikipedia.org/wiki/EMACS" target="_blank">EMACS</a> view (80&times;60-something) the code appears:</p>
<p><a href="http://hbfs.files.wordpress.com/2009/08/code-1.png"><img src="http://hbfs.files.wordpress.com/2009/08/code-1.png?w=218&#038;h=300" alt="code-1" title="code-1" width="218" height="300" class="aligncenter size-medium wp-image-1585" /></a></p>
<p>Using GIMP I illustrated (&#8220;artist conception&#8221;) the path my eyes take when I read the text:</p>
<p><a href="http://hbfs.files.wordpress.com/2009/08/code-1-w-eyes.png"><img src="http://hbfs.files.wordpress.com/2009/08/code-1-w-eyes.png?w=218&#038;h=300" alt="code-1-w-eyes" title="code-1-w-eyes" width="218" height="300" class="aligncenter size-medium wp-image-1586" /></a></p>
<p>Now, what would it look like if I used long lines instead? The code would now look like this:</p>
<p><a href="http://hbfs.files.wordpress.com/2009/08/code-2.png"><img src="http://hbfs.files.wordpress.com/2009/08/code-2.png?w=218&#038;h=300" alt="code-2" title="code-2" width="218" height="300" class="aligncenter size-medium wp-image-1587" /></a></p>
<p>and I suppose my eyes would scan the text like this:</p>
<p><a href="http://hbfs.files.wordpress.com/2009/08/code-2-w-eyes.png"><img src="http://hbfs.files.wordpress.com/2009/08/code-2-w-eyes.png?w=218&#038;h=300" alt="code-2-w-eyes" title="code-2-w-eyes" width="218" height="300" class="aligncenter size-medium wp-image-1588" /></a></p>
<p>So I think I may improve code legibility quite a lot just by keeping moderately short lines for comments <em>and</em> code. This also implies that <a href="http://en.wikipedia.org/wiki/Indent_style" target="_blank">indentation</a> must also remain rather shallow&mdash;except possibly for <a href="http://en.wikipedia.org/wiki/Python_(programming_language)" target="_blank">Python</a>. Tabs that are 4 space wide now seems too long and indentation too deep. I use a 1 or 2 space variable width tab, as you can see from the above screenshots (I spent some time to tweak EMACS&#8217;s CC mode to get that particular setting).</p>
<p align="center">*<br />*&emsp;*</p>
<p>Bonus technique for EMACSers: the <tt>fill-paragraph-function</tt> packs text in a mode-dependant way using the variable <tt>fill-column</tt> that delimits the maximum number of columns in a line. It is bound to <tt>M-q</tt> by default. Pressing <tt>M-q</tt> will cause a paragraph to pack itself in lines of at most <tt>fill-column</tt> characters. It also behaves correctly in most modes (it understands comments).</p>
Posted in hacks, Inoffensive Rant, Life in the workplace, Zen Tagged: color, color scheme, emacs, eye, eye movement, eyes, Identation, Python, reading, Select, speed reading, tab, tabs-are-evil, Wirth <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1582/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1582/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1582/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1582/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1582/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1582/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1582/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1582/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1582/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1582/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1582&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/20/code-style-vertical-vs-horizontal/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/fish-on-stilts.png?w=215" medium="image">
			<media:title type="html">fish-on-stilts</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/code-1.png?w=218" medium="image">
			<media:title type="html">code-1</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/code-1-w-eyes.png?w=218" medium="image">
			<media:title type="html">code-1-w-eyes</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/code-2.png?w=218" medium="image">
			<media:title type="html">code-2</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/code-2-w-eyes.png?w=218" medium="image">
			<media:title type="html">code-2-w-eyes</media:title>
		</media:content>
	</item>
		<item>
		<title>Cargo Cult Programming (part 1)</title>
		<link>http://hbfs.wordpress.com/2009/10/13/cargo-cult-programming-part-1/</link>
		<comments>http://hbfs.wordpress.com/2009/10/13/cargo-cult-programming-part-1/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 10:47:54 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[theoretical computer science]]></category>
		<category><![CDATA[algorithmics]]></category>
		<category><![CDATA[assumptions]]></category>
		<category><![CDATA[AVL tree]]></category>
		<category><![CDATA[balancing tree]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cargo]]></category>
		<category><![CDATA[cargo cult]]></category>
		<category><![CDATA[complexity]]></category>
		<category><![CDATA[hash table]]></category>
		<category><![CDATA[magic]]></category>
		<category><![CDATA[magic thinking]]></category>
		<category><![CDATA[red-black tree]]></category>
		<category><![CDATA[Scrabble]]></category>
		<category><![CDATA[Splay Tree]]></category>
		<category><![CDATA[std::map]]></category>
		<category><![CDATA[std::unordered_map]]></category>
		<category><![CDATA[stl]]></category>
		<category><![CDATA[TR1]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1534</guid>
		<description><![CDATA[Programmers aren&#8217;t always the very rational beings they please themselves to believe. Very often, we close our eyes and take decisions based on what we think we know, and based on what have been told by more or less reliable sources. Such as, for example, taking red-black trees rather than AVL trees because they are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1534&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Programmers aren&#8217;t always the very rational beings they please themselves to believe. Very often, we close our eyes and take decisions based on what we <em>think</em> we know, and based on what have been told by more or less reliable sources. Such as, for example, taking <a href="http://en.wikipedia.org/wiki/Red-black_tree" target="_blank">red-black</a> trees rather than <a href="http://en.wikipedia.org/wiki/AVL_tree" target="_blank">AVL</a> trees because they are faster, while not being able to quite justify in the details why it must be so. Programming using this kind of decision I call <em>cargo cult programming</em>.</p>
<p><a href="http://en.wikipedia.org/wiki/File:CMA_CGM_Balzac.jpg"><img src="http://hbfs.files.wordpress.com/2009/08/cargo.jpg?w=400&#038;h=179" alt="cargo" title="cargo" width="400" height="179" class="aligncenter size-medium wp-image-1539" /></a></p>
<p>Originally, I wanted to talk about red-black <em>vs.</em> AVL trees and how they compare, but I&#8217;ll rather talk about the STL <tt>std::map</tt> that is implemented using red-black trees with G++ 4.2, and <tt>std::unordered_map</tt>, a <a href="http://en.wikipedia.org/wiki/Hash_table" target="_blank">hash-table</a> based container introduced in <a href="http://en.wikipedia.org/wiki/C%2B%2B_Technical_Report_1" target="_blank">TR1</a>.</p>
<p><span id="more-1534"></span></p>
<p>TR1 <tt>std::unordered_map</tt> is a map that does not maintain any particular order between the keys of the data it contains. It is therefore implemented as a <a href="http://en.wikipedia.org/wiki/Hash_table" target="_blank">hash table</a>. The <tt>std::map</tt> is implemented, at least in G++ 4.2, as a <a href="http://en.wikipedia.org/wiki/Red-black_tree" target="_blank">red-black tree</a>. Self-balancing trees change their shape with each insertion in order to maintain most leaves at an equal depth, ensuring an <img src='http://l.wordpress.com/latex.php?latex=O%28%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(\lg n)' title='O(\lg n)' class='latex' /> access time. The difference between an AVL tree and a red-black tree is the way the tree is rebalanced, and the red-black tree does about half as much operations as an AVL tree on insertion, making somewhat faster&mdash;how much faster remains to be quantified.</p>
<p>So I ran a few simple experiments to compare <tt>std::unordered_map</tt> and <tt>std::map</tt>. First, I got hold of the Zingarelli word list, containing some 585,000 Italian words (I can&#8217;t find a working URL, but I got the list a few years ago on a <a href="http://en.wikipedia.org/wiki/Scrabble" target="_blank">Scrabble</a>-related page). I ran three tests: insertion, successful search, and failed search. The list is broken into two parts, one containing 90% of the words, to be inserted, and 10% of the words where kept for the unsuccessful search test.</p>
<p>The insertion test consisted into inserting all of Zingarelli&#8217;s list into both data structures, in the most simplistic way: scanning the list sequentially and inserting items one by one.</p>
<table align="center" border="1">
<tr>
<td></td>
<td>wall time</td>
<td>op/s</td>
</tr>
<tr>
<td><tt>std::map</tt></td>
<td>0.75s</td>
<td>~699000</td>
</tr>
<tr>
<td><tt>std::unordered_map</tt></td>
<td>0.76s</td>
<td>~690000</td>
</tr>
</table>
<p>Insertion times are about the same; so we cannot conclude anything special here except maybe that the insertion time is largely dominated by memory allocation and copy. For the successful search (10,000 tries in each case):</p>
<table align="center" border="1">
<tr>
<td></td>
<td>wall time</td>
<td>op/s</td>
</tr>
<tr>
<td><tt>std::map</tt></td>
<td>0.047s</td>
<td>~209000</td>
</tr>
<tr>
<td><tt>std::unordered_map</tt></td>
<td>0.006s</td>
<td>~1.6&times;10<sup>6</sup></td>
</tr>
</table>
<p>Map look-up is <em>immensely</em> faster with <tt>std::unordered_map</tt>, a ratio of about 8:1! Failed searches exhibit the same behavior. For ~60,000 failed searches:</p>
<table align="center" border="1">
<tr>
<td></td>
<td>wall time</td>
<td>op/s</td>
</tr>
<tr>
<td><tt>std::map</tt></td>
<td>0.263s</td>
<td>~37700</td>
</tr>
<tr>
<td><tt>std::unordered_map</tt></td>
<td>0.037s</td>
<td>~268000</sup></td>
</tr>
</table>
<p>We see the same kind of differences here again, but the failed searches are much slower than the successful searches.</p>
<p>When we repeat the experiment with integers (with the same kind of numbers; 500,000 integers of which 10% are randomly chosen for the failed searches), we get essentially the same picture but a massive speedup as strings are rather costly to copy. Indeed, for the insertion:</p>
<table align="center" border="1">
<tr>
<td></td>
<td>wall time</td>
<td>op/s</td>
</tr>
<tr>
<td><tt>std::map</tt></td>
<td>0.19s</td>
<td>2.3&times;10<sup>6</sup></td>
</tr>
<tr>
<td><tt>std::unordered_map</tt></td>
<td>0.10s</td>
<td>4.5&times;10<sup>6</sup></td>
</tr>
</table>
<p>Now, we see the algorithmic difference between the two algorithms as the time spent allocating and copying strings is eliminated. For successful and failed searches, we get (again for 10,000 look-ups):</p>
<table align="center" border="1">
<tr>
<td></td>
<td>wall time</td>
<td>op/s</td>
</tr>
<tr>
<td><tt>std::map</tt></td>
<td>0.015s</td>
<td>0.7&times;10<sup>6</sup></td>
</tr>
<tr>
<td><tt>std::unordered_map</tt></td>
<td>0.005s</td>
<td>2.0&times;10<sup>6</sup></td>
</tr>
</table>
<p>and:</p>
<table align="center" border="1">
<tr>
<td></td>
<td>wall time</td>
<td>op/s</td>
</tr>
<tr>
<td><tt>std::map</tt></td>
<td>0.082s</td>
<td>0.1&times;10<sup>6</sup></td>
</tr>
<tr>
<td><tt>std::unordered_map</tt></td>
<td>0.009s</td>
<td>1.1&times;10<sup>6</sup></td>
</tr>
</table>
<p>The <tt>std::unordered_map</tt> therefore seems to be much faster than <tt>std::map</tt>. What have we lost in order to gain this speed? First, a lot of memory as hash table must retain a certain sparseness to sport their average constant-time look-ups; and the ordering of keys. Listing the items sorted in a hash map won&#8217;t produce an ordered list, but rather a randomized version of the list. <tt>std::map</tt> on the other hand, allow lexicographic enumeration of its contents.</p>
<p align="center">*<br />*&emsp;*</p>
<p>So you&#8217;re reading this and are thinking, <em>mmppfh, of course, it&#8217;s a hash table, you nitwit</em>. Well, yes. Maybe so.</p>
<p>But here&#8217;s what prompted me to do the test. Red-black trees offer <img src='http://l.wordpress.com/latex.php?latex=O%28%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(\lg n)' title='O(\lg n)' class='latex' /> access. But that&#8217;s assuming (and quite wrongly) that comparing keys can be performed in constant time. This may be true for simple keys, such as machine-size integers (known in C and C++ as <tt>int</tt>) but not so for more complex data, like strings and other structures. For string, for example, comparison may still be very fast because the cost of comparing two string only depends on the longest common prefix; if two long strings have differences in the first few characters, comparison terminates rapidly and the cost is moderate. If, on the other hand, the string share a very long prefix, then the comparison algorithm must scan both strings until the end is reached or a difference is found; this can be very long. So, lets <img src='http://l.wordpress.com/latex.php?latex=p&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='p' title='p' class='latex' /> be the average common prefix length. The expected search time is now <img src='http://l.wordpress.com/latex.php?latex=O%28p+%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(p \lg n)' title='O(p \lg n)' class='latex' /> which can grow large if <img src='http://l.wordpress.com/latex.php?latex=p&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='p' title='p' class='latex' /> is large.</p>
<p>For a hash table look-up, you must first compute the hash key which can be at best done in linear time in the average key length. In our first case, this length is the average string length. Let this average length be <img src='http://l.wordpress.com/latex.php?latex=h&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='h' title='h' class='latex' />. The number of probe is <img src='http://l.wordpress.com/latex.php?latex=c_n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='c_n' title='c_n' class='latex' /> a small constant that depends on the sparseness of the table and the number of items, <img src='http://l.wordpress.com/latex.php?latex=n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='n' title='n' class='latex' />, it contains. For each of those <img src='http://l.wordpress.com/latex.php?latex=c_n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='c_n' title='c_n' class='latex' /> probes, a string comparison is performed, leading to an expected complexity of <img src='http://l.wordpress.com/latex.php?latex=O%28c_n+h+p%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(c_n h p)' title='O(c_n h p)' class='latex' />.</p>
<p>Now, it is not clear when <img src='http://l.wordpress.com/latex.php?latex=p+%5Clg+n+%5Cgeqslant+c_n+h+p&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='p \lg n \geqslant c_n h p' title='p \lg n \geqslant c_n h p' class='latex' />. Both <img src='http://l.wordpress.com/latex.php?latex=p&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='p' title='p' class='latex' /> cancel, which boils down to <img src='http://l.wordpress.com/latex.php?latex=%5Clg+n+%5Cgeqslant+c_n+h&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='\lg n \geqslant c_n h' title='\lg n \geqslant c_n h' class='latex' />. So, in <em>some</em> conditions, it may be possible to make the tree appear faster than the hash table.</p>
<p>On the average, however, the hash map should win becase we expect <img src='http://l.wordpress.com/latex.php?latex=c_n+%3C%3C+%5Clg+n&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='c_n &lt;&lt; \lg n' title='c_n &lt;&lt; \lg n' class='latex' />.</p>
<p align="center">*<br />*&emsp;*</p>
<p>A <a href="http://en.wikipedia.org/wiki/Cargo_cult" target="_blank">cargo cult</a> is described as:</p>
<blockquote><p>
A cargo cult is a type of religious practice that may appear in primitive tribal societies in the wake of interaction with technologically advanced, non-native cultures. The cults are focused on obtaining the material wealth of the advanced culture through magical thinking, religious rituals and practices, believing that the wealth was intended for them by their deities and ancestors.
</p></blockquote>
<p></p>
<p>Except from the part with ancestor spirits but especially when considering <a href="http://en.wikipedia.org/wiki/Magical_thinking" target="_blank">magical thinking</a>, cargo culting applies very often to how programmers write code and take decisions about data structures and algorithms. Choosing a red-black tree over an AVL, or over a <a href="http://en.wikipedia.org/wiki/Splay_tree" target="_blank">splay</a> tree, because we think that it is somehow always better&mdash;sometimes because Ancestor X (a more or less reliable source or authority, such as a more experience programmer, a teacher, or some Internet <a href="http://en.wikipedia.org/wiki/Dude" target="_blank">dude</a>) said so&mdash;is a form of cargo cult where the programmer does not use rationality to its full extent to make a decision.</p>
<p>When choosing data structures, one must be fully aware of the dual cost of data structures. The first cost is the run-time cost. Theoretical complexity and actual implementation-dependant run-times may be quite different. The second cost is memory usage. Memory is large on modern systems but not infinite. A particularly wasteful method that offers constant-time access to the data may use as much as, say, ten times the memory used by a method that gives you <img src='http://l.wordpress.com/latex.php?latex=O%28%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(\lg n)' title='O(\lg n)' class='latex' /> access. If for small data set this 10&times; memory usage pose no particular problem, it may be quite different with a largish data set. It&#8217;s all a very delicate balancing act between run-time performance and scalability.</p>
<p>It&#8217;s very hard to trust one&#8217;s gut feelings about a data structure and the data put in. Combined with the access patterns, the data structure may yield a very counter-intuitive performance. Rather than giving into magic thinking cargo cult programming, you should <em>always</em> take a little time to validate our assumptions and hypotheses about the data, the data structure, and the access patterns, as data structure behavior is clearly <em>not</em> independent from the data and the access patterns.</p>
<p>Consider this very simple example. We have a simple binary tree and a list of strings. Binary trees offer <img src='http://l.wordpress.com/latex.php?latex=O%28%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(\lg n)' title='O(\lg n)' class='latex' /> insertion and access times, so it is, <i>a priori</i>, a good choice. Now, the list of string is composed of words, but it so happens it&#8217;s already sorted. If we insert the strings in the order they are in the list, we get a degenerate binary-tree that&#8217;s in fact a list! Indeed so: insertions are always performed at the far right of the tree, causing the tree to degenerate into something we could call a <em>vine</em> and then all operations degenerate to linear time. If we randomize the list and insert the words into the tree in that randomized order, we get a ragged tree, but about equally deep everywhere, leading to the expected <img src='http://l.wordpress.com/latex.php?latex=O%28%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(\lg n)' title='O(\lg n)' class='latex' /> access and insertion time.</p>
<p>The sorted list / binary tree example is an over-simplistic one, I admit, but it gets to the point: the programmer used a data structure cargo-culted to offer <img src='http://l.wordpress.com/latex.php?latex=O%28%5Clg+n%29&#038;bg=ffffff&#038;fg=333333&#038;s=0' alt='O(\lg n)' title='O(\lg n)' class='latex' /> access time, but due to his incomplete comprehension of the data (the <em>sorted</em> list) and of the access pattern (inserting items sequentially from the list), the result was disastrous.</p>
<p>But the thing is, we <em>all</em> do that to a certain extent!</p>
Posted in algorithms, data structures, Design, hacks, Mathematics, programming, theoretical computer science Tagged: algorithmics, assumptions, AVL tree, balancing tree, C, cargo, cargo cult, complexity, hash table, magic, magic thinking, red-black tree, Scrabble, Splay Tree, std::map, std::unordered_map, stl, TR1 <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1534/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1534&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/13/cargo-cult-programming-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/cargo.jpg?w=300" medium="image">
			<media:title type="html">cargo</media:title>
		</media:content>
	</item>
		<item>
		<title>More on ISIEA09 (and on Malaysia)</title>
		<link>http://hbfs.wordpress.com/2009/10/07/more-on-isiea09-and-on-malaysia/</link>
		<comments>http://hbfs.wordpress.com/2009/10/07/more-on-isiea09-and-on-malaysia/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 22:19:59 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Conference Update]]></category>
		<category><![CDATA[Inoffensive Rant]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1743</guid>
		<description><![CDATA[One thing I didn&#8217;t notice right away is that the number of female participants (including presenters) at the conference was very high.
In Canada and the U.S., it seems that women are not that interested in the hard sciences like maths, engineering, or computer science. And that&#8217;s not because they are kept out of those faculties; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1743&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>One thing I didn&#8217;t notice right away is that the number of female participants (including presenters) at the conference was very high.</p>
<p>In Canada and the U.S., it seems that women are not that interested in the hard sciences like maths, engineering, or computer science. And that&#8217;s not because they are kept out of those faculties; quite the contrary: there are numerous incentives and wooing programs; or that they can&#8217;t do it: they just don&#8217;t care, it seems. Women study more than men (in a 2:1 ratio in universities, at least in Québec) but they do not choose engineering, maths, or computer science; they prefer health and care studies, like medicine, social works, etc.</p>
<p>Here, in Malaysia, there seems to be a large number of women studying in engineering, computer science and maths; at least a great deal more than in Canada. I wonder if we could borrow their strategies to get women to be interested in engineering and sciences or if it is rather the result of a fundamental cultural difference between our two countries. I say I wonder if it&#8217;s not cultural because a large percentage of the women (but not all) wore a conspicuous hijab headscarf.</p>
<p>Readers, any ideas/impressions on this?</p>
Posted in Conference Update, Inoffensive Rant  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1743/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1743/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1743/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1743/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1743/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1743/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1743/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1743/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1743/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1743/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1743&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/07/more-on-isiea09-and-on-malaysia/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>
	</item>
		<item>
		<title>Nonce and other Frobnulated Words</title>
		<link>http://hbfs.wordpress.com/2009/10/06/nonce-and-other-frobnulated-words/</link>
		<comments>http://hbfs.wordpress.com/2009/10/06/nonce-and-other-frobnulated-words/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 11:01:37 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Inoffensive Rant]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[ambodexter]]></category>
		<category><![CDATA[boanthropy]]></category>
		<category><![CDATA[deasil]]></category>
		<category><![CDATA[expygeous]]></category>
		<category><![CDATA[expygeously]]></category>
		<category><![CDATA[frobnulated]]></category>
		<category><![CDATA[frobulate]]></category>
		<category><![CDATA[frubbish]]></category>
		<category><![CDATA[frubbishing]]></category>
		<category><![CDATA[gadzookery]]></category>
		<category><![CDATA[GNU]]></category>
		<category><![CDATA[gnumplementation]]></category>
		<category><![CDATA[otiose]]></category>
		<category><![CDATA[phrenologize]]></category>
		<category><![CDATA[phrenology]]></category>
		<category><![CDATA[pismire]]></category>
		<category><![CDATA[sciolism]]></category>
		<category><![CDATA[whinge]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1527</guid>
		<description><![CDATA[Language is always fun to use to better effect, whether it is to make your point or break your adversary&#8217;s point. All natural languages are rich and contain a number of regional, rare or made-up words. French has a number of them and so does English.

Rare, nonce, or simply made-up words show up in comedy, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1527&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Language is always fun to use to better effect, whether it is to make your point or break your adversary&#8217;s point. All natural languages are rich and contain a number of regional, rare or made-up words. French has a number of them and so does English.</p>
<p><a href="http://hbfs.files.wordpress.com/2009/08/oldbooks.jpg"><img src="http://hbfs.files.wordpress.com/2009/08/oldbooks.jpg?w=300&#038;h=223" alt="oldbooks" title="oldbooks" width="300" height="223" class="aligncenter size-medium wp-image-1529" /></a></p>
<p>Rare, nonce, or simply made-up words show up in comedy, literature, and even programming. As I am not a native English speaker (which I am sure you gathered by now by reading this blog) I do often read books <em>about</em> English to better my grasp of the anglo-saxon language. Not all of them too serious.</p>
<p><span id="more-1527"></span></p>
<p>In <a href="http://www.amazon.com/gp/product/0688150187?ie=UTF8&amp;tag=hardbettfasts-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=0688150187" target="_blank"><i>Forgotten English</i></a> Jeffery Karcirk presents us a few words with surprising meaning. If <em>bugger</em> today mostly designate someone that is fond of bugging people, we discover that it would still be better to keep the horses well locked in the stables. From boanthropy (thinking that oneself is an ox) to phrenologize (practice <a href="http://en.wikipedia.org/wiki/Phrenology" target="_blank">phrenology</a> on someone&#8217;s skull), you are sure to find a word or two amusing.</p>
<p>But choosing one&#8217;s words carefully may help frubbish a text, but one should also refrain from abusing gadzookery (as one may find in, say, <a href="http://www.amazon.com/gp/product/0641934173?ie=UTF8&amp;tag=hardbettfasts-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=0641934173" target="_blank"><i>Jonathan Strange and Mr. Norell</i></a>). It is quite uncompuctuously that I urge you to use nonce words&mdash;as long as they are perfectly cromulent&mdash; to better effect; certainly extending the wealth of words in the English language.</p>
<p align="center">*<br />*&emsp;*</p>
<p>I have a few of my own invention, that I rather like:</p>
<ul>
<li><b>Expygeous, &middot;ly</b>. From <em>ex</em> from, out of, and <em>pyge</em>, Greek for butt. Replaces advantageously &#8220;out of one&#8217;s butt&#8221; in polite conversation. <em>The constants in this equation have been chosen quite expygeously.</em> In verb form, it becomes <b>expygiate</b>. <em>He keeps expygiating answers.</em></li>
<p></p>
<li><b>Gnumplementation</b>. A re-implementation by <a href="http://www.gnu.org/" target="_blank">GNU</a> of an existing piece of software, just for the sake of making it <a href="http://en.wikipedia.org/wiki/Free_software" target="_blank">free</a>, regardless of whether or not it is actually useful to do so.</li>
<p></p>
<li><b>frobnulate, &middot;d</b>. To make needlessly complicated; akin to contrived, but with deliberate obfuscation in mind. <em>This frobnulated example only shows the tenuity of reasoning.</em></li>
<p></p>
<li><b>upgraditis</b>. The compulsion to upgrade software as soon as a new version comes out. <em>OMG! Ubuntu 10.4 pre-alpha is out! I&#8217;m so dist-upgrading!</em></li>
<p></p>
<li><b>capilotomy, &middot;omania</b>. The action (or habit) of splitting hairs whenever possible. <em>No, that&#8217;s not Frobnisher 4.2, it&#8217;s 4.2.012a.</em> (<i>In French, the word would be tétracapilotomomanie, as the expression is &#8220;cut hairs in four&#8221;</i>)</li>
<p></p>
<li><b>technoodle</b>. Someone devoid of technological acumen (in French, <i>technouille</i> sounds just as funny). <em>Oh, that .exe file? I erased it, it was full of random characters when I looked at the contents. You know, with &#8216;type&#8217;</em></li>
<p>
</ul>
<p align="center">*<br />*&emsp;*</p>
<p><b>Further Readings</b></p>
<p>Books:</p>
<p>Jeffrey Kacirk &mdash; <a href="http://www.amazon.com/gp/product/0688150187?ie=UTF8&amp;tag=hardbettfasts-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=0688150187" target="_blank"><i>Forgotten English: A Merry Guide to Antiquated Words, packed with History, Fun Facts, Literary Excerpts and Charming Drawings</i></a> &mdash; William Morrow and Company, 1997</p>
<p>Jeffrey Kacirk &mdash; <a href="http://www.amazon.com/gp/product/0684857618?ie=UTF8&amp;tag=hardbettfasts-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=0684857618" target="_blank"><i>The Word Museum: The Most Remarkable Words Ever Forgotten</i></a> &mdash; Touchstone, 2000</p>
<p></p>
<p>On the web:</p>
<ul>
<li>Nonce words at <a href="http://en.wikipedia.org/wiki/Nonce_word" target="_blank">wikipedia</a>.</li>
<p></p>
<li><a href="http://www.youtube.com/watch?v=MH5AaZS7RpA" target="_blank">Blackadder</a> causing much pericombobulations to the pedant doctor Johnson.</li>
<p></p>
<li>The <a href="http://www.doubletongued.org/" target="_blank">Doubletongued</a> blog.</li>
<p></p>
<li>Wikipedia about <a href="http://en.wikipedia.org/wiki/Sniglet" target="_blank">sniglets</a>.</li>
<p></br></p>
<li>The complete list of <a href="http://www.unwords.com/alpha/ALL/0.html" target="_blank">unwords</a>.</li>
<p>
</ul>
Posted in Inoffensive Rant, Life Tagged: ambodexter, boanthropy, deasil, expygeous, expygeously, frobnulated, frobulate, frubbish, frubbishing, gadzookery, GNU, gnumplementation, otiose, phrenologize, phrenology, pismire, sciolism, whinge <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1527/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1527&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/06/nonce-and-other-frobnulated-words/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>

		<media:content url="http://hbfs.files.wordpress.com/2009/08/oldbooks.jpg?w=300" medium="image">
			<media:title type="html">oldbooks</media:title>
		</media:content>
	</item>
		<item>
		<title>Third day of ISIEA09</title>
		<link>http://hbfs.wordpress.com/2009/10/06/third-day-of-isiea09/</link>
		<comments>http://hbfs.wordpress.com/2009/10/06/third-day-of-isiea09/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 10:10:54 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Conference Update]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1737</guid>
		<description><![CDATA[On this last day of ISIEA09, a lot of the participants have already left. This gives me the impression that many participants just left as soon as they had presented their paper. I feel sorry for the last presenters who spoke before almost empty rooms. I think that it is rather rude, nay, even cheap [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1737&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>On this last day of ISIEA09, a lot of the participants have already left. This gives me the impression that many participants just left as soon as they had presented their paper. I feel sorry for the last presenters who spoke before almost empty rooms. I think that it is rather rude, nay, even <em>cheap</em> to run away as soon as your paper is presented.</p>
<p>Compounded with the fact that a lot of presenters didn&#8217;t even show up&mdash;there was a lot of them&mdash;the last day at ISIEA09 was rather intimate. On the good side, it meant more time to discuss between talks and some exchanges were rather good. This being said, I think ISIEA should adopt the same &#8216;no show&#8217; policy other conferences have. Unless you cannot show up because some case of <em>force majeure</em>, your paper is withdrawn from the proceeding and you are banned from the conference for a number of years. That&#8217;s harsh, but that prevents situations where 20-25% of the speakers do not even show up.</p>
Posted in Conference Update, Uncategorized  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1737/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1737/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1737/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1737/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1737/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1737/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1737/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1737/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1737/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1737/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1737&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/06/third-day-of-isiea09/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>
	</item>
		<item>
		<title>Second day of ISIEA&#8217;09</title>
		<link>http://hbfs.wordpress.com/2009/10/05/second-day-of-isiea09/</link>
		<comments>http://hbfs.wordpress.com/2009/10/05/second-day-of-isiea09/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 11:29:58 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Conference Update]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1732</guid>
		<description><![CDATA[ISIEA&#8217;09 is the most varied conference I attended so far. Usually, conferences are more or less focussed on a specific topic. Here, everything vaguely industrial is a welcome topic: one speaker discussed optimal pump control to avoid cavitation, another an automatic ablution machine using machine vision&#8230; I think this kind of conference is very stimulating [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1732&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>ISIEA&#8217;09 is the most varied conference I attended so far. Usually, conferences are more or less focussed on a specific topic. Here, everything vaguely industrial is a welcome topic: one speaker discussed optimal pump control to avoid <a href="http://en.wikipedia.org/wiki/Cavitation" target="_blank">cavitation</a>, another an automatic ablution machine using machine vision&#8230; I think this kind of conference is very stimulating because you get to discover areas of research you did not necessarily knew about.</p>
<p align="center">*<br />*&emsp;*</p>
<p>I presented my paper on the speeding up of motion estimation in video coding using SIMD instructions and approximate metrics&mdash;I will put the paper and the slides online when I return. I think the presentation went pretty well, as it drew some attention.</p>
Posted in Conference Update, Uncategorized  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1732/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1732&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/05/second-day-of-isiea09/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>
	</item>
		<item>
		<title>First Impressions on Kuala Lumpur</title>
		<link>http://hbfs.wordpress.com/2009/10/03/first-impressions-on-kuala-lumpur/</link>
		<comments>http://hbfs.wordpress.com/2009/10/03/first-impressions-on-kuala-lumpur/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 07:46:25 +0000</pubDate>
		<dc:creator>Steven Pigeon</dc:creator>
				<category><![CDATA[Conference Update]]></category>

		<guid isPermaLink="false">http://hbfs.wordpress.com/?p=1728</guid>
		<description><![CDATA[I arrived at Kuala Lumpur for ISIEA&#8217;09 yesterday. After a good night sleep (the trip from Montreal takes something like 28h, door to door) I set out to visit a bit. My first impression is that Kuala Lumpur is a safe city, filled with friendly people. I visited the Menara Kuala Lumpur and the Petronas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1728&subd=hbfs&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I arrived at Kuala Lumpur for <a href="http://www.i-cerg.net/isiea2009/" target="_blank">ISIEA&#8217;09</a> yesterday. After a good night sleep (the trip from Montreal takes something like 28h, door to door) I set out to visit a bit. My first impression is that Kuala Lumpur is a safe city, filled with friendly people. I visited the <a href="http://en.wikipedia.org/wiki/Kuala_Lumpur_Tower" target="_blank">Menara Kuala Lumpur</a> and the <a href="http://en.wikipedia.org/wiki/Petronas_Twin_Towers" target="_blank">Petronas Towers</a> (although I will have to return as the skybridge was already sold out for today).</p>
<p>This is the second time I visit a country where I do not speak the language at all, but the people here know a little English and seem to be willing to help if they can. I like the people here. They&#8217;re polite, warm, and industrious.</p>
<p>The conference begins tomorrow. I am eager to see what&#8217;s hot on the Asian computer science scene&mdash;this is an Asia-centric conference, for a change.</p>
Posted in Conference Update  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/hbfs.wordpress.com/1728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/hbfs.wordpress.com/1728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/hbfs.wordpress.com/1728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/hbfs.wordpress.com/1728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/hbfs.wordpress.com/1728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/hbfs.wordpress.com/1728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/hbfs.wordpress.com/1728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/hbfs.wordpress.com/1728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/hbfs.wordpress.com/1728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/hbfs.wordpress.com/1728/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=hbfs.wordpress.com&blog=4426521&post=1728&subd=hbfs&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://hbfs.wordpress.com/2009/10/03/first-impressions-on-kuala-lumpur/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/56c87cdd18d9a97255c0343c80fba38d?s=96&#38;d=identicon" medium="image">
			<media:title type="html">stevenpigeon</media:title>
		</media:content>
	</item>
	</channel>
</rss>