<?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/"
	>

<channel>
	<title>Code crumbs, by Clément Pit-Claudel</title>
	<atom:link href="http://pit-claudel.fr/clement/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://pit-claudel.fr/clement/blog</link>
	<description>Personal thoughts on maths and programming, often illustrated with code snippets</description>
	<lastBuildDate>Thu, 06 Feb 2014 12:50:21 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.8</generator>
	<item>
		<title>The cereal box problem: How many boxes does it take to find all prizes?</title>
		<link>https://pit-claudel.fr/clement/blog/the-cereal-box-problem-how-many-boxes-does-it-take-to-find-all-prizes/</link>
					<comments>https://pit-claudel.fr/clement/blog/the-cereal-box-problem-how-many-boxes-does-it-take-to-find-all-prizes/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Fri, 20 Dec 2013 17:48:29 +0000</pubDate>
				<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[Probabilities]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[cereal box problem]]></category>
		<category><![CDATA[harmonic series]]></category>
		<category><![CDATA[probabilities]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=764</guid>

					<description><![CDATA[Children's cereal manufacturers often attract the attention of young clients by including small prizes and toys in every box; sometimes all prizes are identical, but most often individual prizes are part of a collection, and kids are encouraged to collect them and try to complete a full collection. How long does it take ?]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" class="wrap" style="margin-top: 5px; margin-bottom: 1.5em" src="http://pit-claudel.fr/clement/blog/images/chocapic.jpg" alt="Chocapic cereals" />Children&#8217;s cereal manufacturers often attract the attention of young clients by including small prizes and toys in every box; sometimes all prizes are identical, but most often individual prizes are part of a collection, and kids are encouraged to collect them and try to complete a full collection. How long does it take ?</p>
<p>Simple probabilistic modeling shows that on average \(n (1 + 1/2 + \ldots + 1/n)\) boxes are required to complete a full set of \(n\) prizes: for example, it takes on average \(14.7\) boxes to complete a full set of six prizes.</p>
<p><span id="more-764"></span></p>
<h2 id="calc">Numerical and experimental simulation</h2>
<p>The expected number of boxes to buy before finding all \(n\) prices is shown below:</p>
<div class="illustration">
  <a href="http://pit-claudel.fr/clement/blog/images/cereals-time-to-completion.png"><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/cereals-time-to-completion.png" alt="Theoretical time to completion chart" /></a></p>
<p>This histogram shows the calculated average number of purchases required to accumulate at least one copy of each prize, for various sizes \(n\) of prizes sets: for example, finding all prizes in a series of twelve requires on average 37.24 purchases. Note that the curve is somewhat steeper than linear, due to a multiplicative logarithmic factor \(\left(1 + \frac12 + \frac13 + \ldots + \frac1{n}\right) \sim \log(n)\)</p>
</div>
<p>And here is an experimental simulation for \(n = 6\): the graph below shows how many purchases were required to obtain six prizes out of six, over 1,000,000 simulations.</p>
<div class="illustration">
  <a href="http://pit-claudel.fr/clement/blog/images/cereals-completion-distribution.png"><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/cereals-completion-distribution.png" alt="Experimental time to completion distribution chart" /></a></p>
<p>This histogram shows the experimental probability distribution of \(T_6\); that is, of the number of cereal boxes that one needs to purchase before finding all prizes in a series of six. Interestingly, despite the peak at \(t = 11\), the distribution&#8217;s long tail offsets the average to \(14.65\) in this experiment — close to the theoretical prediction of \(14.7\).</p>
</div>
<p class="fast-forward">Interested in how these plots were obtained? Read on to find out, or <a href="#conclusion">skip directly to the comments</a>  to share your thoughts!</p>
<h2>Calculations and simulation code</h2>
<h3>Theoretical average</h3>
<p>Assume there are \(n\) different prizes, all of which are equally distributed in cereal boxes. Model buyer behavior as a sequence of purchases, and call \(T_k\) the time at which they find the \(k\)<sup>th</sup> prize : clearly \(T_0 = 0\) (no purchases are needed to find 0 prizes) and \(T_1 = 1\) (one finds their first prize immediately after buying their first cereal box). Naturally, \(T_n\) denotes the time required to find all prizes.</p>
<p>To calculate \(\newcommand{\E}[1]{\mathrm{\mathbf{E}}\left[#1\right]}\E{T_n}\), call \(\Delta_k\) the elapsed time between the \(k\)<sup>th</sup> and \(k+1\)<sup>th</sup> prizes, i.e. \(\Delta_k = T_{k+1} &#8211; T_k\). Summing over \(k\) yields \(\sum_{k=0}^{n-1} \Delta_k = T_n &#8211; T_0\) which, given the linearity of the expectation operator, yields $$<br />
	\sum_{k=0}^{n-1} \E{\Delta_k} = \E{T_n}<br />
$$</p>
<p>All that remains to be done now is to calculate \(\E{\Delta_k}\) for all \(k \in \{ 0, \ldots, n-1 \}\). By definition $$<br />
	\newcommand{\P}[1]{\mathrm{\mathbf{P}}\left(#1\right)}\E{\Delta_k} = \sum_{\delta = 1}^\infty \P{T_{k+1} = T_{k} + \delta} · \delta<br />
$$</p>
<p>\(\P{T_{k+1} = T_{k} + \delta}\) is the probability of finding the \(k+1\)<sup>th</sup> exactly \(\delta\) purchases after obtaining the \(k\)<sup>th</sup>; that is, the probability of completing \(\delta &#8211; 1\) unproductive purchases, then a successful one. Now the probability of hitting a sequence of \(\delta &#8211; 1\) unproductive purchases is exactly \((k/n)^{\delta-1}\); hence $$<br />
	\P{T_{k+1} = T_{k} + \delta} = \left(\frac{k}{n}\right)^{\delta-1}\left(1 &#8211; \frac{k}{n}\right)<br />
$$</p>
<p>Summing over positive values of \(\delta\) yields $$<br />
	\begin{align*}<br />
		\E{\Delta_k} &#038;= \sum_{\delta = 1}^\infty \P{T_k = T_{k-1} + \delta} · \delta = \sum_{\delta = 1}^\infty (k/n)^{\delta-1} · (1 &#8211; k/n) · \delta\\<br />
					 &#038;= (1 &#8211; k/n) \sum_{\delta = 1}^\infty \delta (k/n)^{\delta-1} = (1 &#8211; k/n) \frac{1}{(1 &#8211; k/n)^2}\\<br />
					 &#038;= \frac{1}{1 &#8211; k/n} = \frac{n}{n-k}<br />
	\end{align*}<br />
$$</p>
<p>And summing over \(k\) yields $$<br />
	\begin{align*}<br />
		\E{T_n} &#038;= \sum_{k=0}^{n-1} \E{\Delta_k} = \sum_{k=0}^{n-1} \frac{n}{n-k} = n \sum_{k=1}^{n} \frac{1}{k}\\<br />
				&#038;= n \left(1 + \frac12 + \frac13 + \ldots + \frac1{n}\right)<br />
	\end{align*}<br />
$$</p>
<p>Which, for large \(n\), is \(n \left(\log(n) + \gamma + \frac1{2n} + o\left(\frac1n\right)\right)\) (where \(\gamma \approx 0.57722\) denotes the Euler–Mascheroni constant).</p>
<p class="details">Note that, as expected, \(\E{\Delta_k}\) quickly increases as \(k\) grows larger: the more prizes have already been found, the harder it is to get a new one, to the point that finding the last prize requires \(n\) purchases on average.</p>
<h3>Numerical simulations</h3>
<p class="detail">The experimental data above was simulated using the following code:</p>
<pre class="brush: python; title: ; notranslate">
	repeat = 1000*1000
	time_to = defaultdict(Counter)
	
	for _ in range(repeat):
		purchased = 0
		collected_prizes = set()
		
		while len(collected_prizes) &lt; n: # Until all prizes have been found
			purchased += 1 # Purchase one more box
			prize = random.randint(1, n) # Open it
			if prize not in collected_prizes: # Is it a new prize ?
				time_to&#x5B;len(collected_prizes) + 1]&#x5B;purchased]  += 1 # Yes, count it !
				collected_prizes.add(prize)	# And add it to list of already found prizes
</pre>
<h2 id="conclusion">Conclusion</h2>
<p>One might want to find some intuitive way to comprehend the formula derived above, \(\E{T_n} = n\left(1 + 1/2 + \ldots + 1/n\right)\). A relatively easy way to get such an intuition is to summarize the calculation above, realizing that each new packet bought after finding the \(k\)<sup>th</sup> prize brings an extra prize with probability \((n-k)/n\) ; since each purchase is independent, it takes on average \(n / (n-k)\) purchases to find a new prize; then summing over \(k\) yields the final formula.</p>
<p class="conclusion">Have you ever completed a full set of cereal box prizes? How long did it take?</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/the-cereal-box-problem-how-many-boxes-does-it-take-to-find-all-prizes/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>An experimental estimation of the entropy of English, in 50 lines of Python code</title>
		<link>https://pit-claudel.fr/clement/blog/an-experimental-estimation-of-the-entropy-of-english-in-50-lines-of-python-code/</link>
					<comments>https://pit-claudel.fr/clement/blog/an-experimental-estimation-of-the-entropy-of-english-in-50-lines-of-python-code/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Sat, 07 Dec 2013 23:49:04 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Information theory]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[Probabilities]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[entropy]]></category>
		<category><![CDATA[information rate]]></category>
		<category><![CDATA[probabilities]]></category>
		<category><![CDATA[redundancy]]></category>
		<category><![CDATA[sampling]]></category>
		<category><![CDATA[statistics]]></category>
		<category><![CDATA[streaming]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=691</guid>

					<description><![CDATA[How does one quantify the intrinsic redundancy of a written language? This article introduces the notions of Shannon entropy and information rate, and experimentally estimates the information rate of written English by training a Markov model on a large corpus of English texts. This model is finally used to generate gibberish that presents all the statistical properties of written English. Best of all, the entire source code fits in 50 lines of elegant Python code.]]></description>
										<content:encoded><![CDATA[
<p class="hangman" style="margin-bottom: 0">
	&#8220;Th_ onl_ wa_ to ge_ ri_ of a tempta____ is to yie__ to it. Resi__ it, an_ you_ soul gro__ sic_ wi__ longi__ fo_ th_ thin__ it ha_ forbi____ to itse__.&#8221;
</p>
<p class="hangman" style="text-align:right">(Osc__ Wil__, <em>The Picture __ ______ ____</em>)</p>
<p><img decoding="async" class="wrap" alt="entrop_" style="margin-top:-2px" src="http://pit-claudel.fr/clement/blog/images/entropy.png" />Thanks to the verbosity of the English language, proficient English speakers generally find it relatively easy to decipher the above passage despite the numerous omissions.</p>
<p>How does one quantify this redundancy? This article introduces the notions of Shannon entropy and information rate, and experimentally estimates the information rate of written English by training a Markov model on a large corpus of English texts. This model is finally used to generate gibberish that presents all the statistical properties of written English. Best of all, the entire source code fits in 50 lines of elegant Python code.</p>
<p><span id="more-691"></span></p>
<h1>Introduction and theoretical background</h1>
<p>Entropy, a notion formalized in the context of information theory by Claude Shannon in his 1948 article &#8220;<a href="http://cm.bell-labs.com/cm/ms/what/shannonday/shannon1948.pdf">A Mathematical Theory of Communication</a>&#8220;, is a measure of how much information an observer can gain by learning the result of a certain random process. </p>
<p>Similarly, the entropy of an information source, also known as its <em>information rate</em>, or its <em>source entropy</em>, is defined as the limit of the conditional entropy of each consecutive letter given the previous ones; in other words, the entropy of an information source quantifies how much extra information is gained by reading one extra letter of a text.</p>
<p>As the example above demonstrates, not every letter of a text is needed to decipher it properly; indeed, humans rely on a huge amount of statistical knowledge to speed up their reading: for example, they know that &#8216;q&#8217; is almost always followed by &#8216;u&#8217;, and that &#8216;wh&#8217; is most often followed by &#8216;o&#8217; (&#8216;who&#8217;), &#8216;y&#8217; (&#8216;why&#8217;), &#8216;at&#8217; (&#8216;what&#8217;), &#8216;en&#8217; (&#8216;when&#8217;), &#8216;ere&#8217; (&#8216;where&#8217;), or &#8216;ich&#8217; (&#8216;which&#8217;). ((This statistical knowledge extends far beyond character sequences: indeed, anyone can easily fill in the blanks in the following quote: <span class="hangman">&#8220;To be or ___ __ __, ____ __ ___ ________&#8221;</span>.)) Source entropy yields a simple, practical measurement of this intrinsic predictability, and of the amount of information carried by each character in a language. </p>
<div style="display:none">
\(\newcommand{\P}[1]{\mathrm{\mathbf{P}}{\left(#1\right)}}\)<br />
\(\newcommand{\lg}{\log_2}\)
</div>
<h2>Definitions</h2>
<p>Given a random variable \(X\), Shannon define its <em>entropy</em> as<br />
	$$ H(X) = &#8211; \sum_{x} \P{X=x} \lg(\P{X=x}) $$</p>
<p>Generalizing, the entropy of \(X\) conditioned on \(Y\) is defined as the expected entropy of \(X\), conditioned on the values of \(Y\):<br />
	$$<br />
		\begin{align*}<br />
			H(X|Y) 	&#038;= \sum_{y} \P{Y = y} H(X|Y=y)\\<br />
					&#038;= &#8211; \sum_{y, x} \P{Y = y} \P{X=x|Y=y} \lg(\P{X=x|Y=y})\\<br />
					&#038;= &#8211; \sum_{y, x} \P{X = x, Y = y} \lg(\P{X=x|Y=y})<br />
		\end{align*}<br />
	$$</p>
<p>Finally, the entropy rate of an information source is the limit of the entropy of the \(n+1\)<sup>th</sup> symbol conditioned on the \(n\) previous ones (if that sequence converges):<br />
	$$ h(X) = \lim_{n \to \infty} H(X_{n+1} | X_1, \ldots, X_n) $$</p>
<h2>Experimental estimation of the entropy rate of English</h2>
<p>This section presents an algorithm to estimate the entropy of English text, using a large corpus of texts. As entropy fundamentally deals with streams, the code presented below handles textual samples as streams of tokens (either characters or words, depending on whether we&#8217;re estimating the entropy per character of the entropy per word).</p>
<p class="details">Note: this algorithm assumes that the distribution of the Markov process being modelled is stationary; that is, that any infinite stream of English text satisfies the property that<br />
	$$	\forall k, \forall n, \P{X_{k+n+1}|X_{k+1}, \ldots, X_{k+n}} = \P{X_{n+1}|X_{1}, \ldots, X_{n}} $$
</p>
<p>First, define a utility function that reads the content a file and turns them into a continuous stream of tokens (characters, words, etc.). <samp>tokenize</samp> takes a path <samp>file_path</samp>, and a function <samp>tokenizer</samp> that splits a line of text into a list of tokens.</p>
<pre class="brush: python; title: ; notranslate">
	def tokenize(file_path, tokenizer):
		with open(file_path, mode=&quot;r&quot;, encoding=&quot;utf-8&quot;) as file:
			for line in file:
				for token in tokenizer(line.lower().strip()):
					yield token
</pre>
<p>Two typical tokenizers are presented below (the <samp>words</samp> function will be useful in the next section, when we start generating random English text):</p>
<pre class="brush: python; title: ; notranslate">
	def chars(file_path):
		return tokenize(file_path, lambda s: s + &quot; &quot;)
		
	import re
	def words(file_path):
		return tokenize(file_path, lambda s: re.findall(r&quot;&#x5B;a-zA-Z']+&quot;, s))
</pre>
<p>Then, define a function to build a statistical model of a stream. Since computing the limit \(h(X)\) presented above is not possible in practice, we approximate it by computing the sum for large enough values of \(n\). The <samp>model_order</samp> parameter below denotes \(n-1\). This function, called <samp>markov_model</samp>, returns two objects: <samp>stats</samp> and <samp>model</samp></p>
<ul>
<li>
		<samp>stats</samp> is a <samp>Counter</samp> that matches each key in <samp>model</samp> to its total number of occurrences. For example:</p>
<pre class="brush: plain; title: ; notranslate">
	stats = {	
		('w', 'h'): 53, 
		('t', 'h'): 67,
		...
	}
</pre>
</li>
<li>
		<samp>model</samp> is a dictionary mapping \((n-1)\)-character prefixes to a <samp>Counter</samp>; that <samp>Counter</samp> maps each possible \(n\)<sup>th</sup> character to the number of times this character followed the \((n-1)\)-character prefix. For example, <samp>model</samp> could be </p>
<pre class="brush: plain; title: ; notranslate">
	model = {
		('w', 'h'): {'y':25, 'o':12, 'a':16, ...}, 
		('t', 'h'): {'i':15, 'a':18, 'e':34, ...},
		...
	}
</pre>
<p>		indicating that &#8216;why&#8217; appeared 25 times, &#8216;who&#8217; 12 times, &#8216;wha&#8217; 16 times, &#8216;thi&#8217; 15 times, &#8216;tha&#8217; 18 times, &#8216;the&#8217; 34 times, and so on.
	</li>
</ul>
<p>To construct these objects, iterate over the stream of tokens, keeping the last \(n-1\) tokens in a buffer and progressively building <samp>stats</samp> and <samp>model</samp>:</p>
<pre class="brush: python; title: ; notranslate">
	from collections import defaultdict, deque, Counter
	def markov_model(stream, model_order):
		model, stats = defaultdict(Counter), Counter()
		circular_buffer = deque(maxlen = model_order)
		
		for token in stream:
			prefix = tuple(circular_buffer)
			circular_buffer.append(token)
			if len(prefix) == model_order:
				stats&#x5B;prefix] += 1
				model&#x5B;prefix]&#x5B;token] += 1
			
		return model, stats
</pre>
<p>Finally, implement the calculation of the entropy:</p>
<pre class="brush: python; title: ; notranslate">
	import math
	def entropy(stats, normalization_factor):
		return -sum(proba / normalization_factor * math.log2(proba / normalization_factor) for proba in stats.values())

	def entropy_rate(model, stats):
		return sum(stats&#x5B;prefix] * entropy(model&#x5B;prefix], stats&#x5B;prefix]) for prefix in stats) / sum(stats.values())
</pre>
<p>And pack everything together using (for a model of order 3)</p>
<pre class="brush: python; title: ; notranslate">
	model, stats = markov_model(chars(&quot;sample.txt&quot;), 3)
	print(&quot;Entropy rate:&quot;, entropy_rate(model, stats))
</pre>
<p>&#8230;all in <a href="http://pit-claudel.fr/clement/blog/files/entropy-rate.py">less than 40 lines of neat python code</a>!</p>
<h2>Experimental results</h2>
<p>Running this algorithm on the entire <a href="http://www.americannationalcorpus.org/">Open American National Corpus</a> (about 95 million characters) yields the following results:</p>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/english-entropy-rate.png" alt="Estimated entropy per character vs model order" /></p>
<p>Estimated entropy rates using increasingly complex Markov models. As expected, the estimated entropy rate decreases as the order of the model (i.e. the number of characters being taken into account) increases.</p>
</div>
<p class="details">Note that, because the Markov model being constructed is based on a necessarily finite corpus of textual samples, estimating the entropy rate for large values of \(n\) will yield artificially low information rates. Indeed, increasing the order of the model will decrease the number of samples per \(n\)-letters prefix, to the point that for very large values of \(n\), knowledge the first \(n-1\) letters of a passage uniquely identifies the passage in question, deterministically yielding the \(n\)<sup>th</sup> letter.</p>
<p class="details">In the graph presented above, it is therefore likely that the estimates for \(n\) over 5 or 6 are already plagued by a significant amount of sampling error; indeed, for any given \(n\) there are in total \(27^{n}\) possible \(n\)-grams consisting only of the 26 alphabetic letters and a space, which exceeds the size of the corpus used in this experiment as soon as \(n > 5\).</p>
<p>Extrapolating these results to large values of \(n\) is particularly tricky, as in the general case nothing is known about the shape of this sequence of values except for the fact that it&#8217;s positive decreasing: deriving the limit entropy rate from this set of measurements requires building a model of the consecutive estimates, and fitting this model to the measured estimates.</p>
<p class="details">As a rough example, call this sequence of values \(F_k\) and assume that it verifies the recurrence equation \(F_{k+1} &#8211; F_k = \alpha (F_{n} &#8211; F_{n-1})\). Then the \(\alpha\) that yields the best approximation (taking the two initial values for granted since they are less likely to suffer from sampling errors) is \(\alpha \approx 0.68\) (\(\mathcal{L}^2\) error: \(6.7 · 10^{-3}\)), and the corresponding entropy rate is \(h \approx 1.14\) bits/character.
</p>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/english-entropy-rate-rough-extrapolation.png" alt="Estimated entropy per character vs model order, extrapolated" /></p>
<p>Extrapolated entropy rate values for \(\alpha \approx 0.68\). In this heuristic model, the limit entropy rate is \(h \approx 1.14\) bits/character.</p>
</div>
<h2>Generating fake English text</h2>
<p>The statistical model of English built in the previous section can be used to generate fake English text : to this end, we introduce a <samp>pick</samp> function that, given a <samp>Counter</samp> (that is, a mapping from elements to numbers of occurrences), picks an element at random, respecting the distribution described by that <samp>Counter</samp> object. </p>
<pre class="brush: python; title: ; notranslate">
	import random
	def pick(counter):
		sample, accumulator = None, 0
		for key, count in counter.items():
			accumulator += count
			if random.randint(0, accumulator - 1) &lt; count:
				sample = key
		return sample
</pre>
<p class="details">A detailed explanation of this function will be the subject of a later post: efficiently sampling from an unordered, non-uniformly distributed sequence without pre-processing it is a non-trivial problem.</p>
<p>Given a length-\(n\) prefix, the generation algorithm obtains a new token by sampling from the distribution of tokens directly following this prefix. The token thus obtained is then appended to the prefix and the first token of the prefix is dropped, thus yielding a new prefix. The procedure is then repeated as many times as the number of characters that we want to obtain.</p>
<p>The following snippet implements this logic: <samp>model</samp> is a model obtained using the previously listed functions, <samp>state</samp> is the initial prefix to use, and <samp>length</samp> is the number of tokens that we want to generate. </p>
<pre class="brush: python; title: ; notranslate">
	def generate(model, state, length):
		for token_id in range(0, length):
			yield state&#x5B;0]
			state = state&#x5B;1:] + (pick(model&#x5B;state]), ) 
</pre>
<p>All that remains to be done is to pick a random initial prefix, using <samp>pick</samp> once again (the <samp>fill</samp> function wraps text at 80 columns to make the display prettier):</p>
<pre class="brush: python; title: ; notranslate">
	prefix = pick(stats)
	gibberish = &quot;&quot;.join(generate(model, prefix, 100)
	
	import textwrap 
	print(textwrap.fill(gibberish))
</pre>
<h3>Results: a collection of random Shakespeare samples</h3>
<p>Feeding the whole of Shakespeare&#8217;s works into the model yields the following samples. Note how increasing the order of the model yields increasingly realistic results.</p>
<h5>\(n=2\): second-order approximation</h5>
<blockquote class="tight-quote"><p>me frevall mon; gown good why min to but lone&#8217;s and the i wit, gresh, a wo.  blace. belf, to thouch theen. anow mass comst shou in moster. she so, hemy gat it, hat our onsch the have puck.</p></blockquote>
<h5>\(n=3\): third-order approximation</h5>
<blockquote class="tight-quote"><p>glouces: let is thingland to come, lord him, for secress windeepskirrah, and if him why does, we think, this bottle be a croyal false we&#8217;ll his bein your be of thou in for sleepdamned who cond!</p></blockquote>
<h5>\(n=5\): fifth-order approximation</h5>
<blockquote class="tight-quote"><p>a gentlewomen, to violence, i know no matter extinct. before moment in pauncheon my mouth to put you in this image, my little join&#8217;d, as weak them still the gods! she hath been katharine; and sea and from argies, in the sun to be a strawberries &#8216;god servant here is ceremonious and heard.</p></blockquote>
<h5>\(n=8\): eigth-order approximation</h5>
<blockquote class="tight-quote"><p>gloucester, what he was like thee by my lord, we were cast away, away! mark that seeth not a jar o&#8217; the tiger; take it on him as i have, and without control the whole inherit of this.</p></blockquote>
<h3>Words as tokens</h3>
<p>The code above defines tokens as characters, and builds a model of sequences of \(n\) consecutive characters. Yet, to generate more realistic-looking text, we can also split the training corpus by words, using</p>
<pre class="brush: python; title: ; notranslate">
	model, stats = markov_model(words('sample.txt', encoding='utf-8'), 3)
	print(textwrap.fill(&quot; &quot;.join(generate(model, pick(stats), 100))))
</pre>
<p>Here&#8217;s an example of a statistically sound sequence of English words, generated using a Markov model of order 3 of Shakespeare&#8217;s writings:</p>
<h5>Third-order word approximation</h5>
<blockquote class="tight-quote"><p>he rouseth up himself and makes a pause while she the picture of an angry chafing boar under whose sharp fangs on his back doth lie an image like thyself all stain&#8217;d with gore whose blood upon the fresh flowers being shed doth make them droop with grief and extreme age.</p></blockquote>
<h2>Conclusion</h2>
<p>Shannon&#8217;s <a href="http://cm.bell-labs.com/cm/ms/what/shannonday/shannon1948.pdf">1948 article</a> laid the foundations of a whole new science, information theory. The original paper is an easy yet extremely interesting read; it extends the notions presented here to derive theorems that link source entropy to the maximal possible compression of a source, and goes on to describe a mathematical framework for error correction.</p>
<p>Shannon himself also worked on <a href="https://ia601504.us.archive.org/34/items/bstj30-1-50/bstj30-1-50.pdf">the estimation of the information rate of English</a>. However, since large-scale statistical experiments were impractical then, Shannon instead constructed an experiment involving humans: subjects were asked to guess the letters of a text one by one, and incorrect guesses per character were recorded to estimate the source entropy of sentences; in this experimental setting Shannon obtained a an estimate of the information rate of English between 0.6 and 1.3 bits per letter, in line with the results presented in this article.</p>
<p>Want to experiment by yourself? Download the <a href="http://pit-claudel.fr/clement/blog/files/entropy-rate.py">full source code</a> (also available for <a href="http://pit-claudel.fr/clement/blog/files/entropy-rate-2.7.py">python 2.7</a>)!</p>
<p class="conclusion">Did you find the initial quote hard to decipher? Does that pseudo-Shakespeare text look realistic? Do you know other beautiful applications of information theory? Let us know in the comments!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/an-experimental-estimation-of-the-entropy-of-english-in-50-lines-of-python-code/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Linear time probabilistic pattern matching and the Rabin-Karp algorithm</title>
		<link>https://pit-claudel.fr/clement/blog/linear-time-probabilistic-pattern-matching-and-the-rabin-karp-algorithm/</link>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Sat, 30 Nov 2013 21:41:14 +0000</pubDate>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Probabilities]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[assembler]]></category>
		<category><![CDATA[hashing]]></category>
		<category><![CDATA[pattern matching]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[polynomials]]></category>
		<category><![CDATA[prime numbers]]></category>
		<category><![CDATA[rabin-karp]]></category>
		<category><![CDATA[randomized algorithms]]></category>
		<category><![CDATA[randomness]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[string searching]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=685</guid>

					<description><![CDATA[This article presents the Rabin-Karp algorithm, a simple probabilistic string searching algorithm based on hashing and polynomial equality testing, along with a Python implementation. Various optimizations and variants are also described.]]></description>
										<content:encoded><![CDATA[
<p><img decoding="async" class="wrap" style="margin-bottom: 0;" alt="Output of a multi-patterns string searching algorithm" src="http://pit-claudel.fr/clement/blog/images/penguins-string-searching.png" />Most linear-time string searching algorithms are tricky to implement, and require heavy preprocessing of the pattern before running the search. This article presents the Rabin-Karp algorithm, a simple probabilistic string searching algorithm based on hashing and polynomial equality testing, along with a Python implementation. A streaming variant of the algorithm and a generalization to searching for multiple patterns in one pass over the input are also described, and performance aspects are discussed.</p>
<p>The algorithm is probabilistic in that it doesn&#8217;t always return correct results; more precisely, it returns all valid matches and (with reasonably small probability) a few incorrect matches (algorithms such as this one that tend to be over-optimistic in reporting their results are usually said to be <em>true-biased</em>).</p>
<p><span id="more-685"></span></p>
<h2>Algorithm</h2>
<p>Given a string <code>s</code> of length \(n\), and a pattern of length \(k\), the algorithm computes rolling checksums for both the pattern (&#8220;needle&#8221;) and consecutive substrings of length \(k\) of the searched string (&#8220;haystack&#8221;). Every time a substring&#8217;s checksum equals that of the pattern, a match is reported.</p>
<pre class="brush: plain; title: Pseudo-code; notranslate">
matches = {}

pattern_checksum = checksum(pattern)
substring_checksum = checksum(s&#x5B;0 : k&#x5B;)

for position from 0 to n - k - 1 do
	update substring_checksum to checksum(s&#x5B;position : position + k&#x5B;)
	if substring_checksum = pattern_checksum then
		add position to matches

return matches
</pre>
<h3>Checksum functions</h3>
<p>Formally, checksum functions map fixed-length strings to numbers, with good checksum functions satisfying two properties: first, collisions (two different strings being mapped to the same checksum) must be rare  — indeed, the higher the collision rate, the more likely incorrect matches are to turn up. Second, checksums must be computed in a way that allows for efficient updating: that is, the value of the checksum of <code>s[i+1:i+k+1[</code> should be quickly derivable from that of <code>s[i:i+k[</code>.</p>
<h4>Polynomial hash functions</h4>
<p>One easily implemented such hash function is based on polynomials. Given a list of \(k\) numbers \(a_0, \ldots, a_{k-1}\), we define a polynomial ((Using \(\sum_{j &lt; k} a_j X^{(k-1)-j}\) instead of \(\sum_{j &lt; k} a_j X^j\) yields a cleaner rolling checksum update formula in the next section.))<br />
	$$ H(a)(X) = a_0 X^{k-1} + a_1 X^{k-2} + \ldots + a_{k-2} X + a_{k-1} = \sum_{j &lt; k} a_j X^{(k-1)-j} $$<br />
Assuming that each character of a string \(s\) can be matched to numbers, we then define the checksum of a substring <code>s[i:i+k[</code> of length \(k\) of \(s\) as \(H(s[i:i+k[)(X) = \sum_{j &lt; k} s_{i + j} X^{(k-1)-j}\). ((The weakness of this approach is that it may require a normalization pass to successfully process some strings using extended character sets; indeed, some Unicode characters can be represented in multiple ways: the capital A with diaeresis character Ä, for example, can be represented either as U+00C4 (Ä), or U+0041 (A) + U+0308 (¨) yielding Ä. Similarly, Unicode includes support for ligatures — that is one can encode the pair &#8220;fi&#8221; as either U+0066 U+0069 &#8220;fi&#8221; or the ligature U+FB01 &#8220;ﬁ&#8221;. <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd374126(v=vs.85).aspx">MSDN</a> and <a href="https://en.wikipedia.org/wiki/Unicode_normalization">Wikipedia</a> have more details on this.))</p>
<h4>Polynomial identity testing</h4>
<p>As it stands, the mapping from <code>s[i:i+k[</code> to \(H(s_{[i:i+k[})\) is bijective, and the problem of checking whether <code>s[i:i+k[</code> matches a pattern <code>p</code> can thus be reformulated as checking whether \(H(s_{[i:i+k[})(X) = H(p)(X)\). This problem is usually called <em>polynomial identity testing</em>, and can be deterministically solved in time \(O(k)\) by comparing polynomials coefficient-wise.</p>
<p>Allowing for infrequent errors, however, takes the complexity of this process down to probabilistic \(O(1)\): instead of comparing two polynomials \(P\) and \(Q\), one can pick a random value \(a\) and compare the values of \(P(a)\) and \(Q(a)\), accepting if and only if \(P(a) = Q(a)\) (since values of \(P(a)\) and \(Q(a)\) may be too large to fit in standard-sized integers, computations are generally made modulo a certain large prime modulus \(m\)). The reasoning is that if indeed \(P=Q\) then the test will always accept \(P\) and \(Q\) as equal, while if \(P \not= Q\) then the probability of hitting a bad witness and incorrectly accepting \(P\) and \(Q\) as equal is low. </p>
<p class="details">More precisely, if \(P\) and \(Q\) are polynomials of degree \(≤ k\), and \(m\) is a prime number larger than the largest coefficient of \(P &#8211; Q\), then the probability of hitting a root of \(P-Q\) is lower than \(k/m\) if \(P\) and \(Q\) differ ((Given a prime number \(m\), \(\mathbb{Z}/(m\mathbb{Z})\) is a finite field and a \(k\)-polynomial whose coefficients fall in the range \(0 \ldots m-1\) has at most \(k\) roots in \(\mathbb{Z}/(m\mathbb{Z})\).)).</p>
<p>Picking a large enough random prime modulus \(m\) and a random seed \(a \in \{ 0 \ldots m &#8211; 1 \} \) therefore allows for the safe definition of $$h_i = H(s_{[i:i+k[})(a) \mod m = \sum_{0 ≤ j &lt; k} s_{i + j} a^{(k-1)-j} \mod m$$ as the checksum of <code>s[i:i+k[</code>.</p>
<h4>Rolling checksum update</h4>
<p>This definition allows for the checksum \(h_{i+1}\) of <code>s[i+1:i+k+1[</code> to be derived from that of <code>s[i:i+k[</code> (\(h_i\)) in constant time (provided the value of \(a^k\) is pre-computed once and for all before running the algorithm), using the formula \(h_{i+1} = a · h_i &#8211; s_i a^k + s_{i+k}\). Indeed,<br />
$$<br />
\begin{align}<br />
	h_i = H(s_{[i+1:i+k+1[})(a)	&#038;= \sum_{0 ≤ j &lt; k} s_{i + 1 + j} a^{(k-1)-j}\\<br />
								&#038;= \sum_{1 ≤ j &lt; k + 1} s_{i + j} a^{(k-1)-(j-1)}\\<br />
								&#038;= \sum_{0 ≤ j &lt; k} s_{i + j} a^{(k-1)-j+1} &#8211; s_i a^k + s_{i+k}\\<br />
								&#038;= a · H(s_{[i:i+k[})(a) &#8211; s_i a^k + s_{i+k}\\<br />
								&#038;= a · h_i &#8211; s_i a^k + s_{i+k}<br />
\end{align}<br />
$$</p>
<h2>Python implementation</h2>
<pre class="brush: python; title: ; notranslate">
import random
# See the implementation notes below for details. &quot;(→ n)&quot; indicates a footnote. 

def checksum(string, seed, modulus, length):
	&quot;&quot;&quot;Computes the checksum of string&#x5B;0 : length+1]&quot;&quot;&quot;
	checksum = 0
	for pos in range(0, length):
		checksum = (checksum * seed + ord(string&#x5B;pos])) % modulus
	return checksum

def string_search(haystack, needle):
	&quot;&quot;&quot;Yields the list of positions p such that 
	   haystack&#x5B;p : p + len(needle) - 1] == needle&quot;&quot;&quot;
	
	LARGEST_CODEPOINT = 0x10FFFF # (→ 1)
	
	# Sanity check
	
	if len(haystack) &lt; len(needle): 
		return
	
	# Initialization
	
	needle_length = len(needle)
	haystack_length = len(haystack)
	modulus = 0xB504F32D # (→ 2)
	
	seed = random.randint(0, modulus - 1)
	seed_k = pow(seed, needle_length, modulus) # Pre-compute a^k
	
	needle_checksum = checksum(needle,   seed, modulus, needle_length)
	substr_checksum = checksum(haystack, seed, modulus, needle_length) # (→ 3)
	
	# String processing
	
	for pos in range(0, haystack_length - needle_length + 1):
		if needle_checksum == substr_checksum: # (→ 4)
			yield pos
			
		if pos &lt; haystack_length - needle_length: # (→ 5)
			substr_checksum = (seed * substr_checksum
			                   - ord(haystack&#x5B;pos]) * seed_k 
			                   + ord(haystack&#x5B;pos + needle_length])) % modulus
</pre>
<h3>Implementation notes</h3>
<dl class="implementation-notes">
<dt class="implementation-detail">LARGEST_CODEPOINT = 0x10FFFF</dt>
<dd>Characters are mapped to polynomial coefficients using the python <code>ord</code> function, which returns the Unicode code point of any character. The largest such code point is <a href="http://unicode.org/faq/utf_bom.html">0x10FFFF</a>.</dd>
<dt class="implementation-detail">modulus = 0xB504F32D</dt>
<dd>
	Checksum polynomials coefficients are smaller than <code>LARGEST_CODEPOINT</code>, and as the modulus must exceed all checksum polynomial coefficients it must exceed <code>LARGEST_CODEPOINT</code> ((Using a modulus smaller than <code>LARGEST_CODEPOINT+1</code> would introduce spurious polynomial equalities; for example, \(X^3 + 3X^2 + 1 \not= X^3 + 1 \mod 7\), but \(X^3 + 3X^2 + 1 = X^3 + 1 \mod 3\).)). Further requiring that the modulus be as large as possible helps reduce the probability of checksum collisions, and hence of spurious matches. Finally, enforcing that it be prime bounds the number of integer roots of degree-k polynomials. <code>0xB504F32D</code> was chosen as it is the largest value satisfying these requirements whose square fits in a 64-bit signed integer. ((This definition definition could be rewritten as follows, assuming the availability of a the availability of a <code>random_prime(n)</code> function to sample a random integer from the range \(n, \ldots, 2n &#8211; 1\): <code>modulus = random_prime( max(2**30.5, LARGEST_CODEPOINT + 1) )</code>))
	</dd>
<dt class="implementation-detail">substr_checksum = checksum(haystack, seed, modulus, needle_length)</dt>
<dd>Before starting the rolling computation, <code>substr_checksum</code> is initialized to the checksum of \(s[0:k[\).</dd>
<dt class="implementation-detail">if needle_checksum == substr_checksum:</dt>
<dd>To prevent checksum collisions from yielding incorrect matches, one could explicitly verify matches ((If such a verification is implemented, then this algorithm is exactly the Rabin-Karp string searching algorithm)) by defining </p>
<pre class="brush: python; title: ; notranslate">
		def verify(haystack, pos, needle):
			return all(haystack&#x5B;pos+k] == needle&#x5B;k] for k in range(0, len(needle)))
</pre>
<p>	and replacing the checksum test with </p>
<pre class="brush: python; title: ; notranslate">if needle_checksum == substr_checksum and verify(haystack, needle, pos):</pre>
<p>	This slows down the algorithm a bit, however, taking its worst-case performance to \(O(nk)\) ((This worst-case bound is attained when both the haystack and the needle are composed of only one character, e.g. when searching for \(aaa\) in \(aaa \ldots aaa\))) — in general, however, the performance remains good as long as the pattern is not redundant. ((One could furthermore argue that the cost of this additional post-checking step is not significant, as string searching programs like <code>grep</code> generally display matches anyway, taking linear time in the length of the pattern for each match. Since verifications only occur on matches detected by checksum comparison, all that remains to be checked is that spurious matches are rare enough to not adversely affect execution time.))
	</dd>
<dt class="implementation-detail">if pos &lt; haystack_length &#8211; needle_length:</dt>
<dd>This check prevents an out-of-bounds access after the last comparison.</dd>
<dt>32- vs 64-bits performance</dt>
<dd>The sample code above manipulates relatively large numbers (close to \(2^{31.5}\)), with intermediate calculation results reaching close to \(2^{63}\). Such calculations are fast on 64 bit machines, but will trigger promotion to Python&#8217;s arbitrary-size integers on 32-bit machines, thus causing the code to perform more poorly. Redefining <code>modulus</code> as <code>0xB501</code> would do, at the cost of increasing the rate of erroneous matches.</dd>
</dl>
<h2>Incorrect matches: theoretical bounds and experimental results.</h2>
<p>As previously noted, the probability of a spurious match turning up at position \(i \in \{0, \ldots, n-1\}\) is lower than \(k/m\) (\(n\) denotes the length of the haystack, \(k\) that of the needle, and \(m\) is the modulus). The probability of at least one incorrect match turning up at <em>any</em> position in the string, however, is higher — indeed, in the general case, it can only be shown to be lower than \(n\) times probability of an error popping up at an arbitrary given position ; that is, \(n · k/m\). An ideal implementation would choose \(m\) to be as large as \(n · k\) times a certain large constant \(C\), thus taking the probability of one or more incorrect matches popping up down to \(1/C\).</p>
<p>Real-life implementations, however, are constrained by the size of machine integers (avoiding <a href="http://www.python.org/dev/peps/pep-0237/">automatic promotion to Python&#8217;s arbitrary-sized integers</a> is crucial to ensuring acceptable performance). The implementation above therefore chooses the largest safe modulus value on a 64-bits architecture, <code>0xB504F32D</code> ((Python standard integers can go up to \(2^{63} &#8211; 1\) before being promoted to arbitrary-precision integers)). This takes the probability of obtaining one or more incorrect matches down to about \( n · k / 2^{32} \), which is below \(0.5\%\) for typical string searching problems ((For example, searching for a 10-character string like &#8220;Petersburg&#8221; in the plain text version of Dostoyevsky&#8217;s <em><a href="http://www.gutenberg.org/cache/epub/2554/pg2554.txt">Crime and punishment</a></em> (~ 1.1 million characters long).)).</p>
<p class="details">
	The culprit here is the checksum update calculation, and in particular the <code>seed * substr_checksum</code> multiplication, which yields values as big as the square of the modulus. Unfortunately there is no way (that I am aware of) to perform the multiplication and integer division that does not resort to large integers if the intermediary multiplication result exceeds the size of machine integers. And it gets even worse on 32-bit machines, where the modulus must be chosen smaller than \(2^{15} &#8211; 1\).</p>
<p>	Low-level optimizations, however, allow for the use of larger moduli: </p>
<ul>
<li>In C, one bit can be saved by using unsigned integers, pushing the modulus up to <code>0xFFFFFFFB</code>. In that case, special care must be taken in the checksum update code, so that the subtraction does not cause wrapping. The naïve implementation, shown below, performs incorrectly:
<pre class="brush: cpp; title: ; notranslate"> substr_checksum = (seed * substr_checksum - outgoing * seed_k + incoming) % modulus </pre>
<p>		Specifically, if the result of the <code>seed * substr_checksum - outgoing * seed_k</code> is below 0, then the value is wrapped modulo <code>(1 &lt;&lt; 64) - 1</code> ((Wrapping behaviour is defined in sub-clause 6.2.5 paragraph 9 of the C Standard: &#8220;A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type&#8221;.)). Instead, the correct calculation is as show below:</p>
<pre class="brush: cpp; title: ; notranslate">
	uint64_t mul = (seed * substr_checksum) % modulus;
	uint64_t sub = ( (modulus - outgoing) * seed_k ) % modulus;
	substr_checksum = (mul + sub + incoming) % modulus;
</pre>
</li>
<li>In 64-bits assembler, using the unsigned multiplication <code>MUL</code> instruction to calculate the product above yields a 128-bits result stored in the <code>EDX:EAX</code> registers, whose remainder in the division by a 64-bits modulus can be calculated using the <code>DIV</code> instruction (<code>MOD</code> on HLA).</li>
</ul>
<p>More importantly, this \(n · k/m\) bound on the error rate is only theoretical, and the effective error rate on real-life texts will often be much lower. Experimental results are hard to obtain given the time it takes to search through large files, but searching 200 times for a 5000-characters random string in Project Gutenberg&#8217;s <a href="http://www.gutenberg.org/cache/epub/2554/pg2554.txt">pg2554</a> (<em>Crime and punishment</em>), didn&#8217;t return a single false positive, though the theoretical bound that can be derived from the formula above regarding the probability of getting at least one erroneous match in such an experiment was above one.</p>
<p>In a second experiment, I searched for the string <code>TATAAA</code> (<a href="https://en.wikipedia.org/wiki/TATA_box">TATA box</a> consensus sequence, length 6) in the <a href="http://www.ensembl.org/Ornithorhynchus_anatinus/Info/Index">genome of a female platypus</a> (length 1 684 663 807). Again, no incorrect matches were found.</p>
<h2>Streaming</h2>
<p>One nice property of the algorithm above is that it does not require that the entire string be loaded into memory; instead, it just requires a buffer whose length equals that of the pattern being searches for. This makes it especially suitable for looking for relatively small patterns in huge strings, like gene patterns in DNA strings. In this particular case verifying each match is especially advisable, given that the input stream is discarded after being processed, making it impossible to verify matches after the algorithm has finished running. Plus, the enormous length of the input does increase the probability of an incorrect match popping up at some point.</p>
<p>The modifications required to allow for streaming are presented below:</p>
<pre class="brush: python; title: ; notranslate">
import random, itertools

def verify(match, needle):
	return all(match&#x5B;k] == needle&#x5B;k] for k in range(0, len(needle)))

def checksum(input, seed, modulus):
	checksum = 0
	for byte in input: # (→ 1)
		checksum = (checksum * seed + byte) % modulus
	return checksum

def stream_search(stream, needle):
	&quot;&quot;&quot;Yields the list of positions p such that 
	   stream&#x5B;p : p + len(needle) - 1] == needle&quot;&quot;&quot;
	
	# Initialization
	
	needle_length = len(needle)
	modulus = 0xB504F32D
	
	seed = random.randint(0, modulus - 1)
	seed_k = pow(seed, needle_length, modulus) # Pre-compute a^k
	
	prefix = list(itertools.islice(stream, needle_length - 1)) # (→ 2)
	needle_checksum = checksum(needle, seed, modulus, needle_length)
	substr_checksum = checksum(prefix, seed, modulus, needle_length - 1)
	
	# Stream processing
	
	pos = 0
	substr = collections.deque(prefix) # (→ 3)
	
	for incoming in stream:
		substr.append(added)
		outgoing = substr.popleft() if pos &gt; 0 else 0 # (→ 4)
		substr_checksum = (seed * substr_checksum 
		                   - outgoing * seed_k 
						   + incoming) % modulus
		
		if needle_checksum == substr_checksum and verify(substr, needle):
			yield pos
		
		pos += 1
</pre>
<h3>Streaming implementation notes</h3>
<dl class="implementation-notes">
<dt class="implementation-detail">for byte in input:</dt>
<dd>We now process <code>bytes</code> objects instead of <code>string</code> objects, as we are mostly going to process huge byte streams loaded from files or from a network.</dd>
<dt class="implementation-detail">prefix = list(itertools.islice(stream, needle_length &#8211; 1))</dt>
<dd>The <code>itertools.islice(stream, n)</code> function consumes <code>n</code> values from a stream. We only take the <code>needle_length - 1</code> first ones here, and the first round of update will complete the checksum calculation.</dd>
<dt class="implementation-detail">substr = collections.deque(prefix)</dt>
<dd>Values corresponding to the substring whose checksum is being calculated are stored in a sliding window implemented as a double-ended queue. This window is required as the first and last values that it contains are needed to update the rolling checksum.</dd>
<dt class="implementation-detail">outgoing = substr.popleft() if pos > 0 else 0</dt>
<dd>This conditional check prevents <code>popleft</code> from being called on an incomplete window in the first rolling checksum update step. This is needed because on the first iteration of the loop the checksum is incomplete, and the sliding window is not full yet.</dd>
</dl>
<h2>Performance</h2>
<p>As it stands, the algorithm presented above performs rather poorly for two reasons: </p>
<ul>
<li>Implementation weaknesses: Using iterators to loop over the input string introduces a heavy overhead in Python</li>
<li>Algorithm weaknesses: Extracting a modulus is a slow operation. Plus, the algorithm used processes all characters; CPython&#8217;s default implementation, in contrast, uses <a href="http://svn.python.org/view/python/trunk/Objects/stringlib/fastsearch.h?view=markup">a deterministic algorithm based on two popular string searching algorithms</a>, Boyer-Moore and Horsepool, that skips parts of the input.</li>
</ul>
<p>Though it performs acceptably, the python implementation of this algorithm is therefore no match for the highly optimized built-in <code>string.find</code> CPython function. The first culprit pointed out above can easily be fixed by moving to another, more low-level language ((Indeed, a C implementation of this simple algorithm runs only about 20 times slower than Python&#8217;s heavily-optimized routines)); the second, which is directly related to the algorithm being used, is much harder to mitigate. </p>
<p class="details">
Using a non-prime modulus is sometimes advocated; in that case, the modulus most often chosen is generally \(2^{64}\) (or whatever the size of machine integers is (+1), the idea being that C wrapping semantics guarantee that the modulus operation will be performed almost for free by the hardware; in that case the modulus operations can be removed altogether, but care must be taken to ensure a proper choice of seed, so as to minimize the probability of checksum collisions. This yields an experimental speedup of about 4 times in C; the resulting code is in the order of 5 to 10 times slower than the optimized CPython routine, but it is deterministic, and hence vulnerable to collision-based attacks.
</p>
<h2>Multi-pattern search</h2>
<p>Where Rabin-Karp does shine is when searching for multiple, same-length patterns. With trivial modifications, the algorithm above can indeed be extended to match the current substring&#8217;s checksum against a list of pre-computed pattern checksums. Provided this lookup operation is implemented efficiently enough, Rabin-Karp becomes an efficient alternative to repeatedly running a more efficient single-pattern search algorithm.</p>
<p>The modified pseudo-code is presented below:</p>
<pre class="brush: plain; title: Pseudo-code; notranslate">
matches = {}

patterns_checksums = &#x5B;checksum(pattern) for pattern in patterns]
substring_checksum = checksum(s&#x5B;0 : k&#x5B;)

for position from 0 to n - k - 1 do
	update substring_checksum
	if substring_checksum belongs to pattern_checksum then # (→ 1)
		add position to matches

return matches
</pre>
<p>All that remains is to find a proper implementation of the <samp>belongs to</samp> (<samp>→ 1</samp>) operation. Hash-tables, though they might seem appropriate, require a large amount of memory to not introduce extra collisions ((The streaming implementation presented above only requires keeping the last \(k\) tokens in memory, and is hence rather memory-efficient)), and they introduce a slight performance overhead. Instead, sorting patterns checksums and binary-searching the resulting array does not require any additional memory, and introduces very low overhead for reasonable patterns count.</p>
<p>The following graph demonstrates the effects of using this modified algorithm to search for large numbers of patterns. Four implementations are compared:</p>
<ul>
<li><strong>Naive python, C implementations</strong>:
<pre class="brush: python; title: ; notranslate">
	for pattern in patterns:
		if haystack.find(pattern) &gt; 0:
			return True
</pre>
<pre class="brush: cpp; title: ; notranslate">
	for (int pattern_id = 0; pattern_id &lt; patterns_count; pattern++)
		if (strstr(haystack, patterns&#x5B;pattern_id]))
			return true;
</pre>
<p>		Execution time grows linearly with the number of patterns. Useless for more than 50 patterns. Requires multiple passes on the input.
	</li>
<li><strong>Regular-expressions–based python implementation</strong>:
<pre class="brush: python; title: ; notranslate">
	regexp = &quot;|&quot;.join(patterns)
	if re.search(regexp, haystack):
		return True
</pre>
<p>		Execution time also grows linearly with the number of patterns, but the growth is much slower, making this solution practical for patterns counts under 5000. ((Ideally, though, the regular expression being generated would be transformed into a deterministic automaton whose performance would only marginally depend on the number of patterns (incidentally, this is the basis of the Aho-Corasick algorithm). Unfortunately, Python doesn&#8217;t do that by default.)) Requires only one pass on the data. Requires sanitization of the input patterns for the regular expression to compile properly.
	</li>
<li><strong>C++ multi-patterns Rabin-Karp implementations</strong>:<br />
		Based on the description above. Execution time grows logarithmically in the number of patterns. Much slower than other techniques for small patterns count, but reasonable for patterns count above 50, and optimal above ~2000/5000 depending on implementation-dependent details. Requires only one pass. Using a hardware-based modulus (wrapping at \(2^{64}\)) does yield a significant performance improvement.
	</li>
</ul>
<p>The following graph shows the respective performance of these implementations.</p>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/rabin-karp-performance.png" alt="Time vs. number of patterns" /></p>
<p>Multi-pattern search performance. While naive implementations quickly become impractical, the regex-based implementation yields pretty good performance. It is eventually superseded, however, by Rabin-Karp–based implementations, notably by the hardware modulus implementation. <span class="details">(Experimental settings: searching for random strings of length 11 in <a href="http://www.gutenberg.org/cache/epub/2554/pg2554.txt">pg2554</a>.)</span></p>
</div>
<h2>Conclusion &amp; further reading</h2>
<p>Although its performance if only middling on single-pattern string searching problems, the randomized algorithm presented above shines by its conceptual simplicity, its ease of implementation, and its performance on multi-string searching problems. One of its most successful applications is the implementation of similarity-detection tools, which search for a large number of known sentences in newly submitted texts (articles, exams, &hellip;).</p>
<p>The <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.86.9502&#038;rep=rep1&#038;type=pdf">original paper by Rabin &amp; Karp</a> (1986) is a fascinating read; it includes much more details on the algorithm&#8217;s expected performance in various settings, and generalizations to a broader class of problems. Further results on the average-case complexity of this algorithm were presented by <a href="http://gonnet.com/papers/InfProcLetters1990.pdf">Gonnet &amp; Baeza-Yates</a> in 1990.</p>
<p>Another approach to the multi-string matching problem, that relies on the remarks made above on converting regular expressions to finite automaton, was presented by <a href="ftp://163.13.200.222/assistant/bearhero/prog/%A8%E4%A5%A6/ac_bm.pdf">Aho &amp; Corasick</a> in 1975. It basically preprocesses the patterns input set to construct a finite deterministic automaton, thus achieving one-pass, linear-time matching of all patterns in the set. Its implementation, however, is much trickier than that of Rabin-Karp.</p>
<p class="conclusion">Have you ever had to use string searching functions other than that provided by the standard library of you programming language? Which algorithms did you use?</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Six months of Windows Phone Development — Tips, tricks, and performance considerations</title>
		<link>https://pit-claudel.fr/clement/blog/six-months-of-windows-phone-development-tips-tricks-and-performance-considerations/</link>
					<comments>https://pit-claudel.fr/clement/blog/six-months-of-windows-phone-development-tips-tricks-and-performance-considerations/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Sat, 09 Mar 2013 00:35:10 +0000</pubDate>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Windows Phone]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[code snippets]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[performance tips]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<category><![CDATA[windows phone]]></category>
		<category><![CDATA[wp7]]></category>
		<category><![CDATA[wp8]]></category>
		<category><![CDATA[xap]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=490</guid>

					<description><![CDATA[This article covers a collection of notes gathered while developing my latest app, YiXue Chinese Dictionary, including performance tips, best practices, and plenty of code snippets for Windows Phone.]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/stroke-order.png" class="wrap" style="margin-bottom: 2em;" alt="A stroke order diagram for the character 羲" /> <strong>TL;DR:</strong> I&#8217;ve taken plenty of notes while developing my <a href="http://pit-claudel.fr/clement/yixue/">YiXue Chinese dictionary for Windows Phone</a>. Topics covered in this article include performance tips, best practices, and plenty of code snippets for Windows Phone.</p>
<h2>Introduction</h2>
<p>This article presents notes and remarks that I gathered while working on a Chinese Dictionary App for Windows Phone, <a href="http://www.windowsphone.com/s?appid=0e7909fd-2a7b-45d7-bef8-2878f5aace73">YiXue Chinese Dictionary</a>: mistakes I made, fun tips I wrote down, and so on.<br />
I initially didn&#8217;t really intend to create a full blog post out of these notes, but their increasing number, and my app recently placing second in Microsoft France&#8217;s App Awards contest, gave me enough motivation to share them with the community. Along with various tips and tricks and answers to often-asked (but seldom answered) questions, I will discuss a number of performance improvements that specifically apply to Windows Phone apps.</p>
<p><span id="more-490"></span></p>
<p><span class="fast-forward">You can skip the DOs and DON&#8217;Ts and jump directly to the <a href="#tips">tips and tricks</a> section, or even straight to the <a href="#performance">performance tips</a> section, if you feel really confident with Windows Phone development.</span></p>
<h2>App development tips: <strong>DO</strong>s and <strong>DON&#8217;T</strong>s</h2>
<h3><strong>DO</strong> keep the size of your XAP package (reasonably) small</h3>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/xap-zip.png" alt="Contents of the YiXue Dictionary XAP file" /></p>
<p>XAP files are just ZIP files with a fancy file extension.Shown above, the contents of the YiXue Dictionary XAP package.</p>
</div>
<p>As of March 2013, the limit for users to be able to download your app over the air is <em><a href="http://download.microsoft.com/download/D/B/1/DB1C07F8-176B-4D57-83E6-F71DD361CA4C/S17%20The%20Windows%20Phone%20Store.pdf">20MB</a></em>. <em>Above this limit</em>, users will have to switch to connect to a WiFi network before they can download your app. <em>Below 20MB, you&#8217;re safe</em>.<br />
That said, keeping an eye on your XAP size is definitely a good idea. PC World ran <a href="http://www.pcworld.com/article/253808/3g_and_4g_wireless_speed_showdown_which_networks_are_fastest_.html">two</a> <a href="https://www.pcworld.com/article/254888/3g_4g_performance_map_data_speeds_for_atandt_sprint_t_mobile_and_verizon.html">studies</a> in 2012, concluding that <em>the average 3G download speed in the United States is about 2.5mbps</em>. That&#8217;s about 3.2 seconds per MB in your app&#8217;s XAP &#8212; about 1 minute for a 20MB app download over 3G. In areas with less good coverage, this will probably climb up to 2 or 3 minutes (assuming 1mbps). </p>
<h3><strong>DO</strong> use the Silverlight Toolkit for Windows Phone</h3>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/wp-toolkit.png" alt="Logo of the Windows Phone toolkit" />
</div>
<p>The <a href="https://phone.codeplex.com/">Silverlight toolkit for Windows Phone</a> is a library distributed by Microsoft, which includes a number of controls which didn&#8217;t make it into the official SDK. It&#8217;s frequently updated, it contains a number of gems that can widely improve your app, and you can download it using nuget  straight from Visual studio (more information <a href="https://phone.codeplex.com/">here</a>).</p>
<p>Though I was initially reluctant to increase my download size by bundling a 500kB dll with my app, I quickly realized it can dramatically improve the user experience. I&#8217;ll focus on just two things here: The <code>PerformanceProgressBar</code>, and page transitions (the <a href="http://www.windowsphonegeek.com/upload/ebooks/Windows%20Phone%20Toolkit%20Aug%202011%20in%20depth-v1.pdf">Windows Phone Geek</a> website has covered in great details pretty much every control in the toolkit).</p>
<h4>The <code>PerformanceProgressBar</code></h4>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/performance-progressbar.png" alt="The performance progressbar" />
</div>
<p>It&#8217;s been said pretty much <a href="http://www.jeff.wilcox.name/2010/08/performanceprogressbar/"> everywhere</a>, but using the default Windows Phone <code>ProgressBar</code> in <code>Indeterminate</code> mode is a bad idea. The animation is based on custom-themed sliders, which eat up a lot of processing power to display the animation (more on that <a href="#performance">below</a>). The <code>PerformanceProgressBar</code> included in the Silverlight Toolkit fixes that.</p>
<p>Load the toolkit by adding the following to the <code>phone:PhoneApplicationPage</code> tag: </p>
<pre class="brush: xml; title: ; notranslate">xmlns:tk=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit&quot;</pre>
<p>and create a progress bar using the following: </p>
<pre class="brush: xml; title: ; notranslate">&lt;tk:PerformanceProgressBar IsIndeterminate=&quot;true&quot; /&gt;</pre>
<h4>Page transitions (<code>toolkit:TransitionService.NavigationInTransition</code>)</h4>
<p>It&#8217;s pretty standard in all system apps on Windows Phone; when you tap a button or a link, the current page will flip out, and a new page will flip in.</p>
<p>Apart from the eye candy, the main advantage of this animation is that it vastly improves the perceived speed of your app, by virtually supressing the delay that separates user actions (tap a button, click a link, pick a <code>ListBox</code> item) and the corresponding reaction; the animation starts immediately, and the constructor and <code>OnNavigatedTo</code> method of your new page are called while the animation runs.</p>
<p>This way, your users have direct feedback that their tap was taken into account. I initially implemented that in YiXue because the pretty complex layout of the Dictionary page would take a split second to render, and users would tap two or three times on the &#8220;Dictionary&#8221; button, thinking the tap hadn&#8217;t been taken into account.</p>
<p>To improve the visual consistency of your app, I recommend using the animation on all your pages. One neat thing is that this animation can be bundled in a style, and reused on all pages without repeating the same code on each. That&#8217;s something I didn&#8217;t know at first, and that was another reason I was reluctant to generalize the use of that animation to all my pages. But it&#8217;s actually rather simple: </p>
<p>First declare the <code>toolkit</code> namespace in your <code>App.xaml</code> using the following line : </p>
<pre class="brush: xml; title: ; notranslate">xmlns:toolkit=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit&quot;</pre>
<p>Then declare the following style in your <code>App.xaml</code> file:</p>
<pre class="brush: xml; title: ; notranslate">
	&lt;Style x:Key=&quot;TransitionPageStyle&quot; TargetType=&quot;phone:PhoneApplicationPage&quot;&gt;
		&lt;Setter Property=&quot;toolkit:TransitionService.NavigationInTransition&quot;&gt;
			&lt;Setter.Value&gt;
				&lt;toolkit:NavigationInTransition&gt;
					&lt;toolkit:NavigationInTransition.Backward&gt;
						&lt;toolkit:TurnstileTransition Mode=&quot;BackwardIn&quot;/&gt;
					&lt;/toolkit:NavigationInTransition.Backward&gt;
					&lt;toolkit:NavigationInTransition.Forward&gt;
						&lt;toolkit:TurnstileTransition Mode=&quot;ForwardIn&quot;/&gt;
					&lt;/toolkit:NavigationInTransition.Forward&gt;
				&lt;/toolkit:NavigationInTransition&gt;
			&lt;/Setter.Value&gt;
		&lt;/Setter&gt;
		
		&lt;Setter Property=&quot;toolkit:TransitionService.NavigationOutTransition&quot;&gt;
			&lt;Setter.Value&gt;
				&lt;toolkit:NavigationOutTransition&gt;
					&lt;toolkit:NavigationOutTransition.Backward&gt;
						&lt;toolkit:TurnstileTransition Mode=&quot;BackwardOut&quot;/&gt;
					&lt;/toolkit:NavigationOutTransition.Backward&gt;
					&lt;toolkit:NavigationOutTransition.Forward&gt;
						&lt;toolkit:TurnstileTransition Mode=&quot;ForwardOut&quot;/&gt;
					&lt;/toolkit:NavigationOutTransition.Forward&gt;
				&lt;/toolkit:NavigationOutTransition&gt;
			&lt;/Setter.Value&gt;
		&lt;/Setter&gt;
	&lt;/Style&gt;
</pre>
<p>Finally, reuse your new style on all pages like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;phone:PhoneApplicationPage 
    (...)
    Style=&quot;{StaticResource TransitionPageStyle}&quot;&gt;
</pre>
<h3><strong>DON&#8217;T</strong> show a minimized application bar on a page with TextBoxes</h3>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/appbar-over-keyboard.png" alt="The application bar going over the keyboard" /></p>
<p>Trying to hit the &#8220;change language&#8221; button (繁) of the keyboard when the application bar is minimized generally results in a lot of frustration.</p>
</div>
<p>That&#8217;s a usability tip which plenty of apps on the market place fail to follow, especially translation / dictionary apps. If have <code>TextBox</code>es on a page showing an <code>ApplicationBar</code>, make sure it is not minimized. Otherwise, your international users will have the frustration of hitting the application bar instead of the &#8220;change language&#8221; button on the keyboard, thereby expanding the application bar, above the keybord. See the screenshot if you&#8217;re not sure what I mean by that.</p>
<p>The solution is pretty simple : either hide the application bar when your TextBox gets the focus, or just set the <code>ApplicationBar</code>&#8216;s <code>Mode</code> to <code>Default</code> instead of <code>Minimized</code>.</p>
<p><em>DO</em>: </p>
<pre class="brush: xml; title: ; notranslate">&lt;shell:ApplicationBar Mode=&quot;Default&quot;&gt;</pre>
<p><em>DON&#8217;T</em>: </p>
<pre class="brush: xml; title: ; notranslate">&lt;shell:ApplicationBar Mode=&quot;Minimized&quot;&gt;</pre>
<h3><strong>DON&#8217;T</strong> use the <code>GestureService</code> from the Silverlight toolkit</h3>
<p><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/flick-gesture.png" alt="The flick gesture" class="wrap" /> However awesome it might be, the Silverlight toolkit still has a few rough edges. In particular, it doesn&#8217;t unregister it&#8217;s listener when you use a <code>GestureService</code> (<code>GestureService</code> allows you to catch touch events like Flick, Slide, and so on). This will bite you if you use an <code>InkSurface</code> for drawing at some point, because a GestureService loaded on another page will keep firing touch events although the page it initially came from should have been disposed. Using the <code>GestureService</code>, furthermore, will prevent your pages from being properly disposed.<br />
Fortunately, there&#8217;s a pretty simple workaround: use the XNA <code>TouchPanel</code> instead. </p>
<p>First, enable the listener (can be done in yoru app initialization code):</p>
<pre class="brush: csharp; title: ; notranslate">
	Microsoft.Xna.Framework.Input.Touch.TouchPanel.EnabledGestures = 
		Microsoft.Xna.Framework.Input.Touch.GestureType.Flick;
</pre>
<p>Then, register the <code>ManipulationCompleted</code> event on a control:</p>
<pre class="brush: csharp; title: ; notranslate">
	private void Control_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
		GestureSample sample = TouchPanel.ReadGesture();
		int delta_x = gesture.Delta.X, delta_y = gesture.Delta.Y;
		
		if (gesture.GestureType == GestureType.Flick 
				&amp;&amp; Math.Abs(delta_x) &gt; 1.5 * Math.Abs(delta_y))
					//User flicked horizontally (delta_x &lt; 0: flicked left; otherwise right)
	}
</pre>
<p>That works well, but not perfectly. Can you guess why? — The catch is that the <code>TouchPanel</code> will record all gestures made on the page; even if only part of your page is touch-enabled using <code>ManipulationCompleted</code>, the call to <code>TouchPanel.ReadGesture</code> will also report gestures made outside of that area.</p>
<p>The problem, luckily, is easily fixed by discarding all gestures but the last when <code>ManipulationCompleted</code> fires; add the following snippet to the previous function:</p>
<pre class="brush: csharp; title: ; notranslate">
	GestureSample? sample = null;
	while (TouchPanel.IsGestureAvailable) //Discard all gestures but the last
		sample = TouchPanel.ReadGesture();
	
	if (sample.HasValue)
		if (gesture.GestureType == GestureType.Flick 
				&amp;&amp; Math.Abs(delta_x) &gt; 1.5 * Math.Abs(delta_y))
					//User flicked horizontally (delta_x &lt; 0: flicked left; otherwise right)
</pre>
<h2 id="tips">Cool development tips and code snippets</h2>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/background-color.png" alt="Choice between light and dark themes" /></p>
<p>Windows Phone users can choose between light and dark themes, which at the core are just white text on a dark background, or black text on a light background.</p>
</div>
<h3>Override system-default colors and brushes if your app uses a custom background</h3>
<p>If your app includes a background image (see my tip on that <a href="#background">below</a>), you&#8217;ll probably want to force one of the color themes (light / dark). If you do that I&#8217;d advise going for a rather dark background, since that will use much less battery ; in that case you will want to enfore the dark theme in your app. I did that in YiXue dictionary, including a piece of famous Chinese calligraphy in the background, and users told me they really liked it.</p>
<p>First, note that you can&#8217;t directly replace an existing value in the <code>App.Current.Resources</code> dictionary. Removing the key and adding it again, however, does work (took me a while to find out):</p>
<pre class="brush: csharp; title: ; notranslate">
	private static void SetAppResource(object key, object value) {
		//Cannot replace an existing value:
		//using 'App.Current.Resources&#x5B;foo] = bar' won't work.
		
		if (App.Current.Resources.Contains(key)) 
			App.Current.Resources.Remove(key);

		App.Current.Resources.Add(key, value);
	}
</pre>
<p>You can also override properties of already existing objects, like system brushes. For your convenience, here is a quick snippet setting most of the common color settings to their default Light Theme values.</p>
<pre class="brush: csharp; title: ; notranslate">
//Code from http://pit-claudel.fr/clement/blog/ ; attribution much appreciated!
(App.Current.Resources&#x5B;&quot;PhoneForegroundBrush&quot;] as SolidColorBrush).Color = Colors.White;
(App.Current.Resources&#x5B;&quot;PhoneBackgroundBrush&quot;] as SolidColorBrush).Color = Colors.Black;

(App.Current.Resources&#x5B;&quot;PhoneDisabledBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(102, 255, 255, 255);
(App.Current.Resources&#x5B;&quot;PhoneInactiveBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(51, 255, 255, 255);

(App.Current.Resources&#x5B;&quot;PhoneContrastBackgroundBrush&quot;] as SolidColorBrush).Color = Colors.White;
(App.Current.Resources&#x5B;&quot;PhoneContrastForegroundBrush&quot;] as SolidColorBrush).Color = Colors.Black;

(App.Current.Resources&#x5B;&quot;PhoneTextBoxBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(191, 255, 255, 255);
(App.Current.Resources&#x5B;&quot;PhoneTextBoxForegroundBrush&quot;] as SolidColorBrush).Color = Colors.Black;
(App.Current.Resources&#x5B;&quot;PhoneTextBoxSelectionForegroundBrush&quot;] as SolidColorBrush).Color = Colors.White;
(App.Current.Resources&#x5B;&quot;PhoneTextBoxEditBackgroundBrush&quot;] as SolidColorBrush).Color = Colors.White;
(App.Current.Resources&#x5B;&quot;PhoneTextBoxEditBorderBrush&quot;] as SolidColorBrush).Color = Colors.White;
(App.Current.Resources&#x5B;&quot;PhoneTextBoxReadOnlyBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(119, 0, 0, 0);

(App.Current.Resources&#x5B;&quot;PhoneRadioCheckBoxBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(191, 255, 255, 255);
(App.Current.Resources&#x5B;&quot;PhoneRadioCheckBoxCheckBrush&quot;] as SolidColorBrush).Color = Colors.Black;
(App.Current.Resources&#x5B;&quot;PhoneRadioCheckBoxCheckDisabledBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(102, 0, 0, 0);
(App.Current.Resources&#x5B;&quot;PhoneRadioCheckBoxDisabledBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(102, 255, 255, 255);
(App.Current.Resources&#x5B;&quot;PhoneRadioCheckBoxPressedBrush&quot;] as SolidColorBrush).Color = Colors.White;
(App.Current.Resources&#x5B;&quot;PhoneRadioCheckBoxPressedBorderBrush&quot;] as SolidColorBrush).Color = Colors.White;

(App.Current.Resources&#x5B;&quot;PhoneBorderBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(191, 255, 255, 255);
(App.Current.Resources&#x5B;&quot;PhoneSubtleBrush&quot;] as SolidColorBrush).Color = Color.FromArgb(153, 255, 255, 255);
</pre>
<p>As a side note, remember that you can&#8217;t set the application bar&#8217;s color to pure white. Just set it to something like <code>#EFEFEF</code> instead, and it will look just as if it was all white.</p>
<p><em>DO</em>: </p>
<pre class="brush: xml; title: ; notranslate">shell:SystemTray.ForegroundColor=&quot;#FEFEFE&quot;</pre>
<p><em>DON&#8217;T</em>: </p>
<pre class="brush: xml; title: ; notranslate">shell:SystemTray.ForegroundColor=&quot;#FFFFFF&quot;</pre>
<h3>Let users select and copy text</h3>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/textblock-textbox-text-selection.png" alt="Text highlighted in a control that looks like a textblock" /></p>
<p>A <code>TextBox</code> styled like a <code>TextBlock</code>, with some text highlighted</p>
</div>
<p>Since text can&#8217;t be directly copied from <code>TextBlock</code>s, most websites advise that you use a <code>ReadOnly</code> <code>TextBox</code> instead, styled to look just like a <code>TextBox</code>. That&#8217;s pretty sweet, but it fails to mention that users need to give input focus to a <code>TextBox</code> before they can select text. Which means that they&#8217;ll have to tap on your modified <code>TextBox</code> twice: once to give it focus (but the caret won&#8217;t appear, since the <code>TextBox</code> is read-only), and a second time to actually select text. As a user, this drives me nut.</p>
<p>Luckily there&#8217;s a pretty simple work-around: if it&#8217;s a very small block of text, intercept the <code>Tap</code> event, and select all text immediately. Otherwise, use the <code>GotFocus</code> event. Users can then refine their selection if they want, but they can also copy all contents straight away if they want to.</p>
<pre class="brush: csharp; title: ; notranslate">
	private void CopyableTextArea_Tap(object sender, GestureEventArgs e) {
		(sender as TextBox).SelectAll();
	}
</pre>
<h3 id="background">Share a background on all your pages</h3>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/uniform-background.png" alt="Pages sharing a common background" /></p>
<p>Pages sharing a common background, with the <code>Background</code> property of their <code>LayoutRoot</code> set to <code>Transparent</code>.</p>
</div>
<p>If you want to set an app-level background image (perhaps the same as your splash screen, although I&#8217;d advise using something a bit darker to improve the legibility of text over your background), manually setting the background image on all your pages is not the best, especially if you use page-turning animations.<br />
Indeed, if you set the background on a per-page level, you&#8217;ll quickly notice that the background flips with the rest of the page content when you change pages. It would be much better if it stayed in place, and only page contents flipped out when changing pages. It&#8217;s actually pretty easy to do if you know the trick (that, too, took me a while to find):</p>
<p>In <code>App.xaml</code>:</p>
<pre class="brush: xml; title: ; notranslate">&lt;ImageBrush x:Key=&quot;MainBackground&quot; ImageSource=&quot;/resources/MainBackground.jpg&quot; /&gt;</pre>
<p>In <code>App.xaml.cs</code></p>
<pre class="brush: csharp; title: ; notranslate">(App.Current as App).RootFrame.Background = App.Current.Resources&#x5B;&quot;MainBackground&quot;] as Brush;</pre>
<p>Now the catch is, if some of your pages show an application bar, and other don&#8217;t, your background will be resized to fit only the available space: the application bar will force it to shrink — that&#8217;s pretty ugly. Instead, what I do is add a 72 pixels high row to the LayoutRoot grid, and set the ApplicationBar&#8217;s transparency to .99 (choosing a value other than 1 draws the app bar above your page instead of shrinking it). That way, the Application bar is drawn above your page, and nothing is drawn below it because there&#8217;s an empty row of just the right height below:</p>
<p><em>DO</em>:<br />
In your <code>Grid</code>&#8216;s <code>RowDefinitions</code>: </p>
<pre class="brush: xml; title: ; notranslate">&lt;RowDefinition Height=&quot;72&quot; /&gt;</pre>
<p>Further below:</p>
<pre class="brush: xml; title: ; notranslate">
	&lt;phone:PhoneApplicationPage.ApplicationBar&gt;
		&lt;shell:ApplicationBar IsVisible=&quot;True&quot; Opacity=&quot;0.99&quot; Mode=&quot;Default&quot;&gt;
			(...)
		&lt;/shell:ApplicationBar&gt;
	&lt;/phone:PhoneApplicationPage.ApplicationBar&gt;
</pre>
<h3 id="performance">Performance tips</h3>
<h4>Load your data files faster</h4>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/loading-text-no-progressbar.png" alt="Pages sharing a common background" /></p>
<p>Abandonning your <code>ProgressBar</code>s in favour of text-only loading messages can yield substantial performance improvements.</p>
</div>
<p>Really that&#8217;s pretty universal advice. If you never tried, you&#8217;ll probably be  surprised how much performance you can gain by simply disabling your &#8220;loading&#8221; progressbar and replacing it with a <code>Loading...</code> message, possible including a percentage at the end, as in <code>Loading... 10%</code>. In Yixue, where the initial loading of the dictionary has been an area that I&#8217;ve worked a lot on, disabling the <code>Loading...</code> progressbar has reduced the overall loading time from 3.2 seconds to 2.7s. That&#8217;s a sizable 0.5 seconds, or 15% percent performance improvement :)</p>
<p>Another common mistake when displaying progress is to use a timer running in the background and firing every x milliseconds to update your progressbar. I did this in YiXue, because the animation of the progress bar that I used back then would be smoother that way. The loading time was 3.8 second then, and the UI timer fired every 20ms. Increasing this delay to 100ms took the loading time down to 3.5 seconds. Removing the UI timer altogether and firing a ReportProgress event after each significant loading step took that down to 3.2 seconds&#8230; and getting rid of the progress bar I went down to 2.7s.</p>
<h4>Load your pages faster</h4>
<p>XAML complexity is, in my experience, the main cause for pages loading slowly. Complex bindings (or even simple ones, really, if you&#8217;re populating a list) are also very time-consuming. If you&#8217;re after the last bit of performance, consider populating your list manually, possibly be removing your listbox alltogether, and using a vertical StackPanel to which you directly add your items, in code-behind. I know that doesn&#8217;t really fit in the MVVM pattern, but when I had to display a grid of 214 elements, binding a ListBox using a WrapPanel as its ItemsPanel took close to 2 seconds, while populating a StackPanel only took 0.3 seconds.</p>
<p><em>To the best of my knowledge, the toolkit&#8217;s <code>WrapPanel</code> doesn&#8217;t do any kind of UI virtualization, making it useless for displaying moderately large amounts of information.</em></p>
<h4>Don&#8217;t use the <code>PivotControl</code> for what it&#8217;s not made for</h4>
<p>The <code>PivotControl</code> has to render <em>all</em> its pages before it&#8217;s displayed. That&#8217;s a huge performance killer when you use it to diplay multiple data sets (plus, it&#8217;s against the design guidelines: Pivots are used throughout the system to show multiple visualisations of the same data set (all mail, unread, starred, and so on, for example)).</p>
<p>In YiXue Dictionary I have study lists (roughly equivalent to stacks of flash cards, only better ;), and I initially displayed them using a Pivot control, one list per pivot page. When I tested that page with 12 study lists contining about 40 words each, not only did it take 2 seconds to render the page, but the memory profiler reported a 130MB memory usage (!). I&#8217;ve now replaced it with a single list, letting users flip between each page using gestures, which doesn&#8217;t use more than a few MBs.</p>
<h3>Get better I/O performance</h3>
<p>The WP emulator is really neat, but there&#8217;s one thing that it really doesn&#8217;t mimic realistically, namely IO performance. Although it&#8217;s much better on my Lumia than on my old HTC, I/O is still much slower on a phone than on your development computer. That&#8217;s really something to keep in mind when testing your app, especially if you don&#8217;t have a device to test on. Very roughly, my testing indicates that an I/O operation that takes 1 seconds on your computer will take 2 or 3 seconds on the Lumia 920, 3 to 5 seconds one Lumia 800, and 5 to 7 seconds on the Trophy. Take these timings with a pitch of salt since they are really gross approximations, but the general figures are about that. Similarly, garbage collections will be much slower on your phone than in the emulator; if your loading procedure involves a lot of text parsing, it&#8217;ll suffer a lot from that on your phone.</p>
<p>So how do you improve that loading performance? Turns out that there is a number of simple tricks that you can use. I won&#8217;t get into too much details here, because there&#8217;s so much to say, and because you obviously should run benchmarks for your micro-optimisations, but the following general principles will help :</p>
<h4>Ditch String.Split</h4>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/performance-problems-string.split.png" alt="Pages sharing a common background" /></p>
<p>Screenshot from MDSN&#8217;s remarks section regarding <code>String.Split</code>.</p>
</div>
<p><code>String.Split</code> is nice, but it&#8217;s a garbage collector nightmare. It allocates plenty of intermediate buffers (and the documentation is <a href="http://msdn.microsoft.com/en-us/library/b873y76a(v=vs.80).aspx">pretty straightforward about that</a>, with a section called &#8220;Performance Considerations&#8221; well worth reading), and it&#8217;s too generic to be as fast as it could be. If you&#8217;re really after the last bit of performance, re-code the split function by hand. It&#8217;s really not hard, but here it is:</p>
<pre class="brush: csharp; title: ; notranslate">
	int start = -1, end = -1;
	List&lt;string&gt; parts = new List&lt;string&gt;();
	
	while (end + 1 &lt; string_to_split.Length) { //Assumes that the string to split ends with a '\t'
		start = ++end;
		while (string_to_split&#x5B;end] != '\t')
			++end;

		parts.Add(string_to_split.Substring(start, end - start));
	}
</pre>
<p>In YiXue, that shaved an extra 30% off the loading time.</p>
<h4>Set images as Content, not resource</h4>
<p>Changing the build action of your images from <code>Resource</code> to <code>Content</code> will neatly improve the splash screen time, because your images will only be loaded when needed, instead of being loaded when your app starts.</p>
<h4>Minify your XML files.</h4>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/xml-minification.png" alt="Minified/Not-minified XML files comparison" /></p>
<p>Left: efficient representation. Right: Human-readable version of the <em>same</em> data. Smaller is better.</p>
</div>
<p>Most apps store use data as XML, using an <code>XMLSerializer</code>. That&#8217;s really neat, but it can get slow if you don&#8217;t take a few precautions. There are two things that really helped me in YiXue: first one is disabling white space in the XML output; your files won&#8217;t be as legible by a human as they were before, but it easily saved me 20% off the size of my user data files, and the parser won&#8217;t see the difference. </p>
<pre class="brush: csharp; title: ; notranslate">
	XmlWriterSettings settings = new XmlWriterSettings { Indent = false, NewLineHandling = NewLineHandling.None };
</pre>
<h4>Use defaults in your XML serialization attributes</h4>
<p>Second one is specifying defaults. In YiXue there can be plenty of info associated to each word in your study lists, but most words don&#8217;t have all that info filled in. You can get the Xml serializer to omit the empty properties by simply specifying the default value for the attribute this way:</p>
<pre class="brush: csharp; title: ; notranslate">
	&#x5B;DefaultValue(0)] public int CorrectAnswersGiven;
</pre>
<p>I&#8217;d also advise choosing very short aliases for your attributes and elements names; for example:</p>
<pre class="brush: csharp; title: ; notranslate">
	&#x5B;XmlAttribute(AttributeName = &quot;f&quot;)] public string foo;
</pre>
<p>This will further shrink your data files, and will make it much easier to rename your variables should you want to. </p>
<h4>Improve perceived performance by showing a message with actual content while the app loads</h4>
<p><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/tips-while-loading.png" class="wrap" alt="Tips show while loading the app" />If you need time to load app resources (beyond the split-second), entertain your users while your app is loading by including tips and fun facts: they won&#8217;t notice the delay if they have something else to focus on — game developers know this, and always include tips in their loading screens. This principle is easily extended to other apps.<br />
In YiXue, I show tips and fun facts about learning Chinese while the app loads.</p>
<h2>Conclusion</h2>
<p>That&#8217;s pretty much all for now. Hopefully that helps you create even better apps!</p>
<p>You can follow me on Twitter <a href="http://twitter.com/CreateSoftware">here (me)</a> and <a href="http://twitter.com/YiXueDictionary">here (my YiXue Dictionary app)</a>. Of course, links to <a href="http://pit-claudel.fr/clement/yixue/">http://pit-claudel.fr/clement/yixue/</a> and to <a href="http://pit-claudel.fr/clement/blog/">this blog</a> are most appreciated. And since I&#8217;m sure I forgot plenty:</p>
<p><em><strong>DO</strong>: share your own tips and tricks in the comments!</em></p>
<p>Happy WP development!<br />
Clément.</p>
<p>PS: If you liked this article, you can flattr this blog post using the link below, or even better <a href="http://www.windowsphone.com/s?appid=0e7909fd-2a7b-45d7-bef8-2878f5aace73">buy the app</a>!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/six-months-of-windows-phone-development-tips-tricks-and-performance-considerations/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Modeling and measuring string comparison performance in C, C++, C# and Python.</title>
		<link>https://pit-claudel.fr/clement/blog/modeling-and-measuring-string-comparison-performance-in-c-cpp-csharp-and-python/</link>
					<comments>https://pit-claudel.fr/clement/blog/modeling-and-measuring-string-comparison-performance-in-c-cpp-csharp-and-python/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Sun, 30 Sep 2012 00:57:08 +0000</pubDate>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[Probabilities]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[amortized complexity]]></category>
		<category><![CDATA[complexity]]></category>
		<category><![CDATA[locality]]></category>
		<category><![CDATA[misconceptions]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[probabilities]]></category>
		<category><![CDATA[randomness]]></category>
		<category><![CDATA[strings]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=458</guid>

					<description><![CDATA[Comparing strings is often -- erroneously -- said to be a costly process. In this article I derive the theoretical asymptotic cost of comparing random strings of arbitrary length, and measure it in C, C++, C# and Python.]]></description>
										<content:encoded><![CDATA[<p> <img decoding="async" class="wrap" style="padding-top:10px" alt="O(1)" src="http://pit-claudel.fr/clement/blog/images/O(1).png"/> Comparing strings is often &#8212; erroneously &#8212; said to be a costly process. In this article I derive the theoretical asymptotic cost of comparing random strings of arbitrary length, and measure it in C, C++, C# and Python.</p>
<p><span id="more-458"></span></p>
<h2>Theoretical amortized cost</h2>
<h3>Infinite strings</h3>
<p>Suppose one draws two random strings \(A = &#8220;a_0a_1a_2&#8230;&#8221;\) and \(B = &#8220;b_0b_1b_2&#8230;&#8221;\) of infinite length, with \(a_n\) and \(b_n\) respectively denoting the \(n\)<sup>th</sup> character of \(A\) and \(B\). We will assume that characters are independent, and uniformly drawn over the set \(\{a, b, c, &#8230;, z\}\). For now, we will consider all strings to be of infinite length &#8212; we&#8217;ll study bounded-length strings in the next section.</p>
<p>Given that characters making up \(A\) and \(B\) are independent, the probability of \(A\) differing from \(B\) at index \(n\) is \(25/26\). Conversely, the probability of \(A\) matching string \(B\) at index \(n\) is \(1/26\).</p>
<p>Consequently, the probability of \(A\) matching \(B\) up to index \(n &#8211; 1\), and differing at index \(n\), is \((1/26)^n &sdot; (25/26)\). Therefore, given that comparing strings up to index \(n\) included is \((n+1)\) the expected number of characters to compare to discriminate \(A\) and \(B\) is $$ C = \sum_{n=0}^{\infty} (n+1) &sdot; (1/26)^n &sdot; (25/26) = 26/25$$</p>
<p class="details">Indeed, defining \(C(x) = (1-x) &sdot; \sum_{n=0}^{\infty} (n+1) x^n\), the expected number of comparisons \(C\) required to discriminate \(A\) and \(B\) is \(C(1/26)\). Now \(C(x) = (1-x) &sdot; \sum_{n=0}^{\infty} \frac{&part; x^n}{&part; x} = (1-x) &sdot; \frac{&part; \sum_{n=0}^{\infty} x^{n+1}}{&part; x} = (1-x) &sdot; (1-x)^{-2} = 1/(1-x)\). Plugging \(x=1/26\) yields \(C = 26/25 \approx 1.04\).</p>
<p>In other words, it takes an average of \(1.04\) character comparisons to discriminate two random strings of infinite length. That&#8217;s rather cheap. </p>
<h3>Finite strings</h3>
<p>In this section we assume that \(A\) and \(B\) are bounded in length by a constant \(L\). This implies that the probability of the comparison routine reaching any index greater than \((L-1)\) is \(0\); hence the expected number of comparisons \(C_L\) is $$C_L = \sum_{n=0}^{L-1} (n+1) &sdot; (1/26)^n &sdot; (25/26) = (26/25) &sdot; (1 &#8211; \frac{25L + 26}{26^{L+1}})$$<br />
For any \(L > 3\), this is virtually indistinguishable from the previously calculated value \(C = 1.04\).</p>
<h3>Conclusion</h3>
<p>The theoretical amortized time required to compare two strings is constant &#8212; independent of their length. Of course, there may be a sizeable overhead associated to comparing strings instead of ints: experimental measurements of this overhead are presented below.</p>
<h2>Experimental measurements</h2>
<p>The following charts present the time it took to perform 100&#8217;000 string comparisons on my laptop, compared to a baseline of 100&#8217;000 integer comparisons, in 3 different programming languages and for string lengths varying from 1 to 500 characters. Despite large variations for small string lengths, measured times quickly converge to a fixed limit as strings lengthen ((If you want to experiment with the tests, you can download the full <a href="http://pit-claudel.fr/clement/blog/files/string-comparison-performance.py">python</a>, <a href="http://pit-claudel.fr/clement/blog/files/string-comparison-performance.cpp">C++</a>, or <a href="http://pit-claudel.fr/clement/blog/files/string-comparison-performance.cs">C#</a> source code.)).</p>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/python-string-comparison-performance.png" alt="Chart comparing the relative performance of strings and integer comparisons" /></p>
<p>Time required to compare 100&#8217;000 pairs of random strings, as a function of string length, in Python (3.2.3)</p>
</div>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/csharp-string-comparison-performance.png" alt="Chart comparing the relative performance of strings and integer comparisons" /></p>
<p>Time required to compare 100&#8217;000 pairs of random strings, as a function of string length, in C# (csc 4.0.30319.17929)</p>
</div>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/c++-string-comparison-performance.png" alt="Chart comparing the relative performance of strings and integer comparisons" /></p>
<p>Time required to compare 100&#8217;000 pairs of random strings, as a function of string length, in C++ (gcc 4.3.4).</p>
</div>
<h3>Remarks</h3>
<p>Though large strings (over ~200 characters) experimentally match our statistical model, small strings exhibit a much more complex behaviour. I can think of a two causes for such variations:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/String_interning">String interning</a>: Python <a href="http://docs.python.org/library/functions.html#intern">interns</a> some strings &#8212; exactly which depends on the implementation. On my laptop, this turns small (< 64 characters) string comparisons into direct pointer comparisons, which are about as fast as integer comparisons.</li>
<li><a href="http://en.wikipedia.org/wiki/Locality_of_reference">Locality</a>: In C++ in particular, under <a href="http://pit-claudel.fr/clement/blog/flies/locality.cpp">certain conditions</a>, applying a function to a <samp>char*</samp> gets slower as the referred string lengthens, even if the function only access the first few elements. The effect is barely noticeable for strings over 200 characters.</li>
</ul>
<h2>Conclusion</h2>
<p>Comparing strings, especially small strings, is very fast. The amortized time required to compare two strings is bounded by a constant, which is experimentally about twice the time required to compare two integers in high level languages like Python or C#, and 5 to 7 times higher in low-levels languages like C++.</p>
<p class="conclusion">Do you usually try to avoid comparing strings? Do you have a more detailed explanation of the irregularities observed for lengths < 200 characters? Tell us comments!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/modeling-and-measuring-string-comparison-performance-in-c-cpp-csharp-and-python/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Generating uniformly random data from skewed input: biased coins, loaded dice, skew correction, and the Von Neumann extractor</title>
		<link>https://pit-claudel.fr/clement/blog/generating-uniformly-random-data-from-skewed-input-biased-coins-loaded-dice-skew-correction-and-the-von-neumann-extractor/</link>
					<comments>https://pit-claudel.fr/clement/blog/generating-uniformly-random-data-from-skewed-input-biased-coins-loaded-dice-skew-correction-and-the-von-neumann-extractor/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Mon, 03 Sep 2012 21:38:48 +0000</pubDate>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Brain teasers]]></category>
		<category><![CDATA[Life hacking]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Probabilities]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[bias]]></category>
		<category><![CDATA[biased coin]]></category>
		<category><![CDATA[coins]]></category>
		<category><![CDATA[dice]]></category>
		<category><![CDATA[loaded dice]]></category>
		<category><![CDATA[probabilities]]></category>
		<category><![CDATA[random walks]]></category>
		<category><![CDATA[randomness]]></category>
		<category><![CDATA[skew correction]]></category>
		<category><![CDATA[uniform randomness]]></category>
		<category><![CDATA[Von Neumann extractor]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=410</guid>

					<description><![CDATA[In 1951, John von Neumann presented a way of bias-correcting a loaded coin. This article introduces a generalisation to random dice, so a loaded die can be used to uniformly draw numbers from the set {1, 2, 3, 4, 5, 6}.]]></description>
										<content:encoded><![CDATA[<p><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/spinning-coin.jpg" class="wrap" style="margin-bottom: 2em;" alt="A spinning coin, about to fall on tails" />In a famous article published 1951 ((Various techniques used in connection with random digits. NIST journal, Applied Math Series, 12:36-38, 1951. This article does not seem to be available online, though it is widely cited. It is reprinted in pages 768-770 of Von Neumann&#8217;s collected works, Vol. 5, Pergamon Press 1961)), John Von Neumann presented a way of skew-correcting a stream of random digits so as to ensure that 0s and 1s appeared with equal probability. This article introduces a simple and mentally workable generalization of his technique to random dice, so a loaded die can be used to uniformly draw numbers from the set \(\{1, 2, 3, 4, 5, 6\}\), with reasonable success.</p>
<p><span id="more-410"></span></p>
<h2>Von Neumann skew-correction algorithm</h2>
<h3>Biased coins</h3>
<p>Von Neumann&#8217;s originally proposes the following technique for getting an unbiased result from a biased coin :</p>
<blockquote><p>If independence of successive tosses is assumed, we can reconstruct a 50-50 chance out of even a badly biased coin by tossing twice. If we get heads-heads or tails-tails, we reject the tosses and try again. If we get heads-tails (or tails-heads), we accept the result as heads (or tails). </p></blockquote>
<p>This algorithm is illustrated below:</p>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/von-neumann-biased-coins-correction.png" alt="Biased coin correction flowchart" /></p>
<p>Flowchart recapitulating Von Neumann&#8217;s bias-suppressing algorithm</p>
</div>
<p>This amazingly simple strategy does yield heads and tails with equal probabilities, because coin tosses, though biased, are assumed to be independent. Therefore, if <i>heads</i> come out with probability \(p\), and tails with probability \(1-p\), then both <i>(head, tails)</i> and <i>(tails, heads)</i> sequences occur with probability \(p(1-p)\).</p>
<h3>Removing the bias from a stream of random digits</h3>
<p>Generalizing this technique to a stream of random digits is straightforward: pack digits two-by-to, discard any pair of two equal digits (00 or 11), and finally convert 01 to 0 and 10 to 1.</p>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/von-neumann-biased-bit-streams-correction.png" alt="Biased bit stream correction example" /></p>
<p>Illustration of Von Neumann&#8217;s biased-suppressing algorithm on a stream of random digits</p>
</div>
<h3>Probabilistic remarks</h3>
<h4>Expected rejection rate</h4>
<p>Continuing on previous calculations, since each coin toss is taken to be independent from the others, both <i>(heads, tails)</i> and <i>(tails, heads)</i> sequences will occur with probability \(p(1-p)\), while <i>(heads, heads)</i> and <i>(tails, tails)</i> sequences will occur with respective probabilities \(p^2\) and \((1-p)^2\).<br />
Define the expected rejection rate \(r\) to be the the probability of obtaining <i>(heads, heads)</i> or <i>(tails, tails)</i> (and thus of discarding the sequence). Then \(r = p^2 + (1-p)^2  = 1 &#8211; 2 &sdot; p(1 &#8211; p) = (1/2) + 2 &sdot; (p &#8211; 1/2)^2\), which implies that \(r &ge; 1/2\). In other words, in the best case (when the coin is perfectly balanced), half of the coin sequences will be discarded.</p>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/rejection-rate.png" alt="Rejection rate as a function of p" /></p>
<p>Rejection rate as a function of <i>heads</i> probability</p>
</div>
<h4>Expected number of tosses</h4>
<p>Since the rejection rate is \(r = 1 &#8211; 2 &sdot; p(1 &#8211; p)\), the odds of discarding exactly \(n\) two-coins sequences before obtaining an acceptable sequence are \(r^n &sdot; (1-r)\), and the expected number of two-coins sequences to be discarded is \(d = \sum_{k=0}^\infty k &sdot; r^k &sdot; (1-r) = \frac{r}{1-r}\).</p>
<p class="details">Indeed, $$\sum_{k=0}^\infty k &sdot; r^k &sdot; (1-r) = r(1-r) &sdot; \sum_{k=0}^\infty k r^{k-1} = r(1-r) &sdot; \frac{&part;}{&part;r} \sum_{k=0}^\infty r^k = r(1-r) &sdot; \frac{&part;}{&part;r} \frac{1}{1-r} = \frac{r}{1-r}$$</p>
<p>Now, if \(d\) two-coins sequences are discarded before an acceptable sequence is obtained, then the number of coin tosses required is \(2 &sdot; (1 + d) = \frac{1}{p(1-p)} &ge; 4\). In other words, it will take in the best case an average of 4 single-coin tosses to obtain an acceptable sequence. Or, as Von Neumann puts it,</p>
<blockquote><p>The resulting process is rigorously unbiased, although the amended process is at most 25 percent as efficient as ordinary coin-tossing.</p></blockquote>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/number-of-tosses.png" alt="Expected number of tosses" /></p>
<p>Expected number of tosses before an acceptable two-coins sequence is found, plotted as a function of <i>heads</i> probability</p>
</div>
<h2>A generalization to loaded dice</h2>
<p>The general idea behind Von-Neumann style skew-correction techniques is to consider sequences of coin tosses instead of isolate ones, and pick a sequence length long enough that an even number of possible outcomes have equal probabilities. These outcomes can then be split in two groups, one representing heads and the other representing tails, while other outcomes are discarded.</p>
<p>Generalizing this strategy to weighted dice excludes picking a sequence length \(n &le; 2\), since no subset of possible outcomes of equal probability for \(n=1\) or \(n = 2\) has a cardinal divisible by six. For \(n=3\), on the other hand, the outcomes of any dice (crooked or not) can be partitioned into six categories of equal probability according to the relative ordering of the successive numbers rolled, provided these numbers are all different &#8212; that is, sequences can be grouped according to whether the second number is greater (&uarr;) or smaller (&darr;) than the first, and whether the third number is greater (&uarr;&uarr;&uarr;, &darr;&uarr;&uarr;) or smaller (&uarr;&darr;&darr;, &darr;&darr;&darr;) than both the first and the second, or between them (&uarr;&uarr;&darr;, &darr;&darr;&uarr;).</p>
<p>This strategy is illustrated in the diagram below, which provides a reference table for interpreting sequences of three rolls of a loaded dice to produce unbiased results. Should the same number occur twice, all three rolls should be discarded, and the process should be started over.</p>
<div class="illustration">
	<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/loaded-dice-correction.png" alt="Reference table for my dice bias-suppression algorithm" /></p>
<p>Decision table for suppressing dice bias. Given a sequence of three throws, chart the three throws so as to form an arrow pattern, and use this table to obtain the corresponding result. Examples are given in green for each pattern. Using this table, rolling \(1&nbsp;2&nbsp;5\) would yield a \(1\), while \(1&nbsp;5&nbsp;2\) would yield a \(2\), and \(5&nbsp;2&nbsp;1\), a \(4\).</p>
</div>
<p>All six possible orderings will occur with equal probability, because each of the sequences belonging to any of these orderings matches exactly one sequence of equal probability in every other ordering: for example, \(1&nbsp;2&nbsp;4\) matches the ordering &uarr;&uarr;&uarr;, whereas \(2&nbsp;1&nbsp;4\), which is equally likely, matches &darr;&uarr;&uarr;.</p>
<h3>Implementation</h3>
<p>Given a sequence of three independent rolls of a possibly biased die, this function returns a fair dice roll using the previously exposed technique:</p>
<pre class="brush: python; title: ; notranslate">
	def translate(*rolls):  
		# returns False if 'rolls' contains duplicates, and a fair dice roll otherwise
		
		# Possible relative ordering of the three rolls. 1 2 3 is ↑↑↑, 2 1 3 is ↓↑↑.
		deltas = &#x5B;(True, True, True),   (True, True, False), 
				  (True, False, False), (False, False, False),
				  (False, False, True), (False, True, True)] # True stands for ↑
		
		(r1, r2, r3) = rolls;
		unique = len(set(rolls)) &gt;= 3
		return unique and 1 + sequences.index((r2 &gt; r1, r3 &gt; r1, r3 &gt; r2))</pre>
<p>Here&#8217;s a test function. The <samp>bias</samp> parameters measures how unbalanced the die is: the higher the bias, the higher the probability to roll a 6.</p>
<pre class="brush: python; title: ; notranslate">
	def unfair_roll(bias):
		return random.choice(&#x5B;1, 2, 3, 4, 5] + &#x5B;6]*bias)

	def test(number_of_rolls, bias):
		count = &#x5B;0]*7
		bias = max(bias, 1)
		
		for roll_id in range(0, number_of_rolls):
			rolls = unfair_roll(bias), unfair_roll(bias), unfair_roll(bias)
			count&#x5B;translate(*rolls) or 0] += 1

		print(&quot;Rejection rate: {:.2f}%&quot;.format(count&#x5B;0] / number_of_rolls * 100))
		print(&quot;Relative digit frequency:&quot;)
		for digit in range(1, 6 + 1):
			print(&quot;  {}: {:.2f}%&quot;.format(digit, count&#x5B;digit] / number_of_rolls * 100))
		print(&quot;Before correction, 6 was {} times more likely to occur&quot;
					&quot; than other digits.&quot;.format(bias))</pre>
<p>Here&#8217;s a single run for 50 000 sequences of three rolls of a die ten times more likely to give a 6:		</p>
<pre class="brush: plain; title: ; notranslate">
	&gt;&gt;&gt; test(50*1000, 10)
	Rejection rate: 80.52%
	Relative digit frequency:
		1: 3.24%
		2: 3.30%
		3: 3.26%
		4: 3.18%
		5: 3.17%
		6: 3.32%
	Before correction, 6 was 10 times more likely to occur than other digits.</pre>
<h2>Conclusion and further remarks</h2>
<p>Though easy to work out mentally, this bias-correction technique for dice is far from optimal. Indeed, the minimal rejection rate (obtained for a perfectly balanced dice) is about 44%, and the rejection rate quickly increases as the bias gets stronger, reaching 64% when 6 is 5 times more likely to occur than other individual digits.</p>
<p>More subtle techniques, which I will discuss in a future article, take the rejection rate down to 1.5% for perfectly balanced dice, and keep it under 7% for dice with a 6 to 1 chance of getting a 6 over any other digit.</p>
<p class="conclusion">Do you know other strategies to even the odds when playing with a loaded dice? Sound off in the comments!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/generating-uniformly-random-data-from-skewed-input-biased-coins-loaded-dice-skew-correction-and-the-von-neumann-extractor/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>The cafeteria paradox: stop using the water dispenser while someone else does!</title>
		<link>https://pit-claudel.fr/clement/blog/the-cafeteria-paradox/</link>
					<comments>https://pit-claudel.fr/clement/blog/the-cafeteria-paradox/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Wed, 22 Aug 2012 18:09:11 +0000</pubDate>
				<category><![CDATA[Brain teasers]]></category>
		<category><![CDATA[Life hacking]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Modeling]]></category>
		<category><![CDATA[cafeteria paradox]]></category>
		<category><![CDATA[misconceptions]]></category>
		<category><![CDATA[parallel processing]]></category>
		<category><![CDATA[saturation]]></category>
		<category><![CDATA[scheduling]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=384</guid>

					<description><![CDATA[Most cafeteria water dispensers will let two (sometimes more) people fill a jug at the same time. This article uses simple maths to prove that it's a waste of time. In other words, two people should never use the same water dispenser at the same time: I call this the cafeteria paradox.]]></description>
										<content:encoded><![CDATA[<p><br />
<img decoding="async" src="http://pit-claudel.fr/clement/blog/images/water-dispenser.jpg" alt="A water dispenser" class="wrap" /> Most cafeteria water dispensers will let two (sometimes more) people fill a jug at the same time. This article uses simple maths to prove that it&#8217;s a waste of time. In other words, two people should never use the same water dispenser at the same time: I call this the <i>cafeteria paradox</i>.</p>
<h2>An intuitive presentation</h2>
<p>Let&#8217;s start with a little brain teaser:</p>
<blockquote><p>
Alice and Bob are at the cafeteria, seating at different tables. Alice stands up to refill her table&#8217;s water jug. Little after, Bob stands up with his own table&#8217;s jug, heading to the same water dispenser. That water dispenser is a perfectly standard one, with two taps, and Bob finds himself standing near Alice. After a small hesitation, Bob starts using the second tap to fill his own jug, thereby diverting part of the output previously devoted to Alice.</p>
<p>This grants him an exasperated and somewhat puzzled look from Alice. Why?
</p></blockquote>
<p><span id="more-384"></span></p>
<p>The reason is quite simple: though most people will act just like Bob, using the water dispenser while someone else does is &#8212; in most of the cases &#8212; a useless waste of time. Indeed, starting to fill his own jug before Alice is done will not save Bob any time, but it will waste some of Alice&#8217;s time. That&#8217;s the <em>cafeteria paradox</em>.</p>
<p>Fortunately, this paradox is readily explained: assuming both Alice and Bob are using similar jugs, and both start with an empty jug, Alice will finish before Bob does; when Bob leaves, therefore, the water dispenser will have dispatched precisely the countenance of two caferetia jugs. <br /> Now, Since the combined output of the two taps equals that of only one, dispatching this amount of water will take a constant time (precisely twice the time that it would take to fill a single jug). Hence Bob will gain no time at all by starting to fill his jug right away, while some of Alice&#8217;s time will be wasted.</p>
<p>Not convinced? Imagine Bob and Alice are waiting for some pizza at a take-away restaurant. Given that Bob and Alice won&#8217;t start eating before they get to their respective homes, should Bob accaparate half of Alice&#8217;s pizza when it arrives, or let Alice get the full pizza first and wait for his own pizza? If Bob asks for half of Alice&#8217;s, both will wait for two pizzas to be ready; on the other hand, if Bob lets Alice go first, Alice will have only waited for one, while Bob will have waited for two. Clearly the second solution is better for Alice, and neutral for Bob; and the situation is exactly similar to that of the water dispenser.</p>
<p><span class="fast-forward">Still not convinced? Read on for a full mathematical description of this situation. Otherwise, <a href="#conclusion">skip to the conclusion</a> (and the sticker!).</span></p>
<h2>A mathematically accurate description</h2>
<p>Let \(t_A\) and \(t_B\) be the respective times when Alice and Bob reach the water dispenser, and \(t_A&#8217;, t_B&#8217;\) the respective times when they leave. Let \(t^*\) be the time when Bob starts using the water dispenser. The water dispenser has a flow rate \(f\), and each jug has a capacity \(c\).</p>
<p>From \(t_A\) to \(t^*\), Alice&#8217;s jug is filling at rate \(f\); from \(t^*\) to \(t_A&#8217;\), at rate \(f/2\). Hence Alice&#8217;s departure time \(t_A&#8217;\) satisfies the following equation: $$ (t^* &#8211; t_A) &sdot; f + (t_A&#8217; &#8211; t^*) &sdot; (f/2) = c$$<br />
which yields \(t_A&#8217; = t^* + \frac{c}{f/2} &#8211; 2 &sdot; (t^* &#8211; t_A)\), so $$ t_A&#8217; = 2 t_A &#8211; t^* + \frac{c}{f/2} $$</p>
<p>Similarly, Bob&#8217;s departure time \(t_B&#8217;\) satisfies the following equation: $$ (t_A&#8217; &#8211; t^*) &sdot; (f/2) + (t_B&#8217; &#8211; t_A&#8217;) &sdot; f = c$$<br />
which yields \(t_B&#8217; = t_A&#8217; + \frac{c}{f} &#8211; (1/2) &sdot; (t_A&#8217; &#8211; t^*) \), so $$ t_B&#8217; = (1 / 2) &sdot; (t_A&#8217; + t^*) + \frac{c}{f} $$</p>
<p>Finally, subtituting \(2 t_A &#8211; t^* + \frac{c}{f/2}\) for \(t_A&#8217;\) yields \(t_B&#8217; = t_A + (1 / 2) \cdot \frac{c}{f/2} + \frac{c}{f}\); that is $$ t_B&#8217; = t_A + 2 &sdot; \frac{c}{f} $$</p>
<p>To summarize, Alice will leave at \(t_A&#8217; = 2 t_A &#8211; t^* + \frac{c}{f/2}\) (the later Bob starts, the earlier Alice will leave), while Bob will leave at \(t_B&#8217; = t_A + 2 &sdot; \frac{c}{f}\), which <em>does not depend on \(t_B\) or \(t^*\)</em>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The socially optimal solution is that Bob waits until Alice is done before starting to use the water dispenser; otherwise, some of Alice&#8217;s time will be wasted, though Bob will not benefit from it. The key to understanding this is that Bob will not leave the water dispenser before both jugs are full, and filling both jugs takes a constant time (the time needed for the water dispenser to deliver twice the volume of a jug, spanning from Alice&#8217;s arrival to Bob&#8217;s departure). Thus using the water dispenser while someone else does is not only selfish: it&#8217;s downright stupid.</p>
<p class="conclusion">Shocked? Leave a message in the comments! Otherwise join our campaing to stop multi-threading in water dispensers: stick the following message on your cafeteria&#8217;s water dispenser and post a picture of your sticker in the comments!</p>
<p><a href="http://pit-claudel.fr/clement/blog/images/cafeteria-paradox-sticker.png"><img decoding="async" src="http://pit-claudel.fr/clement/blog/images/cafeteria-paradox-sticker-small.png" alt="Cafeteria paradox sticker" style="display:block; margin: auto;" /></a></p>
<p class="details">Title image &copy; Cosmetal.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/the-cafeteria-paradox/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Willy Wonka&#8217;s golden tickets: certainly the most profitable marketing campaign of all times</title>
		<link>https://pit-claudel.fr/clement/blog/willy-wonkas-golden-tickets-certainly-the-most-profitable-marketing-campaign-of-all-times/</link>
					<comments>https://pit-claudel.fr/clement/blog/willy-wonkas-golden-tickets-certainly-the-most-profitable-marketing-campaign-of-all-times/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Fri, 27 Jul 2012 00:15:28 +0000</pubDate>
				<category><![CDATA[Litterature]]></category>
		<category><![CDATA[Octave/Matlab]]></category>
		<category><![CDATA[Probabilities]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=360</guid>

					<description><![CDATA[How many chocolate bars did Mr. Salt (from Roald Dahl's "Charlie and the chocolate factory")  have to buy to find a golden ticket? Using simple probabilities, I calculated it would take about 40 million chocolate bars to secure a strong chance of finding one of the golden tickets.]]></description>
										<content:encoded><![CDATA[<p><br />
<img decoding="async" class="wrap" src="http://pit-claudel.fr/clement/blog/images/charlie-chocolate-factory.jpg" /> There&#8217;s something that has troubled me since childhood. In <em>Charlie and the chocolate factory</em>, one of the lucky children (Veruca Salt) gets her golden ticket thanks to her father repruposing his peanut shelling factory in a chocolate-bar-unwrapping factory.</p>
<p>Now, there are only five golden tickets, and chocolate bars in the book seem quite popular. How many bars would one need to buy (and unwrap) just to have a seizable chance of finding one of the tickets? Most likely a lot. After doing the maths, I would estimate the number of chocolate bars that Mr. Salt had to buy to something between <strong>12 and 40 million chocolate bars</strong>; which means this promotional campaign was most certainly one of the most profitable in history. Details below.</p>
<p><span id="more-360"></span></p>
<h2>Background: <em>Charlie and the chocolate factory</em></h2>
<p><img decoding="async" class="wrap" src="http://pit-claudel.fr/clement/blog/images/veruca-salt.jpg" /> In <em>Charlie and the Chocolate Factory</em>, Roald Dahl pictured the archetype of the spoiled little child in the character of Veruca Salt (left). When Willy Wonka, an excentric, genius chocolate maker, announces that five golden tickets have been hidden underneath the wrapping of ordinary chocolate bars, granting their lucky discoverers a visit of his chocolate factory and a lifetime supply of sweets, the world goes into a chocolate-devouring frenzy. It&#8217;s only a few days before the first and second ticket are found, the later by a girl named Veruca Salt. Here is how her father explains the discovery</p>
<blockquote><p>&#8216;You see, boys,&#8217; he had said, &#8216;as soon as my little girl told me that she simply had to have one of those Golden Tickets, I went out into the town and started buying up all the Wonka bars I could lay my hands on. Thousands of them, I must have bought. Hundreds of thousands!</p></blockquote>
<h2>So how many chocolate bars did Mr. Salt actually buy?</h2>
<p><img decoding="async" class="wrap" src="http://pit-claudel.fr/clement/blog/images/chocolate.png" /> Assume Mr. Salt wants to have a reasonable chance of finding one of the tickets, perhaps 70 or 80%. Let \(\alpha\) be the acceptable risk level, so that the probability of actually finding the ticket is \(1 &#8211; \alpha\). Since televisions seem rather common in the book, and it was published in 1964, assume the action takes place in the early 1960&#8217;s. Say the children population of England at the time is \(P\), and assume Mr. Wonka makes most of his business in this country, and only with children (including other countries, or adults, would further reduce Mr. Salt&#8217;s chances of success). There are \(T = 5\) golden tickets in play, and we can estimate the number of bars sold per child to \(b =\) three or more, given that Charlie Bucket, though extremely poor, buys three.</p>
<p>Excluding Mr. Salt compulsive buying, this generates a total static demand \(D = P \times b\). Let \(N\) be the number of chocolate bars sold in total, and \(n\) the number of bars bought by the Salt family, so \(N = D + n\) &#8212; the underlying assumption being that chocolate production is profitable at any level.</p>
<p>The chance of these \(n\) bars yielding no golden ticket is \(\binom{N-T}{n} / \binom{N}{n}\); conversely, the probability of at least one of these \(n\) bars contains a golden ticket is \(1 &#8211; \binom{N-T}{n} / \binom{N}{n}\). Assuming the family is ready to accept a probability of failure of \(\alpha\), \(n\) will be chosen so that \(1 &#8211; \binom{N-T}{n} / \binom{N}{n} > 1 &#8211; \alpha\), or equivalently that $$ \binom{N-T}{n} < \alpha \binom{N}{n} $$

Developing this expression and substituing [latex]N - D[/latex] for [latex]n[/latex] yields [latex](N - T)! / (D - T)! < \alpha (N! / D!)[/latex], which is the same as $$ \frac{D!}{(D - T)!} < \alpha \frac{N!}{(N - T)!} $$

The children population of England in the 60's was about [latex]12.2[/latex] million kids ((Source: World dataBank, indicators SP.POP.0014.TO.ZS and SP.POP.TOTL; the population of the time was 52.4 million people, and the percentage of children aged less than 15 was 23.3%)). Assuming each bought 3 chocolate bars, the static demand was [latex]36.6[/latex] million bars. Finally, setting [latex]T = 5[/latex] and numerically solving the equation above yields [latex]N \approx 49.6[/latex] million chocolate bars, and thus [latex]n = 12.9[/latex] million chocolate bars.

In other words, Mr. Salt would need to buy <strong>12.9 million chocolate bars</strong> to reach a 70% chance of securing a golden ticket. Taking this probability up to 95% would imply buying an extra 28 million chocolate bars, bringing the grand total to about <strong>41 million chocolate bars</strong>. ((If you include English adults in this funny little buying game, the static demand reaches 76.9 million chocolate bars, pushing the 70% to \(N = 104\) million chocolate bars (\(n = 27\) million), and the 95% probability threshold to \(N = 162\) million chocolate bars (\(n = 85.7\) million).))</p>
<h3>Code</h3>
<p>Here&#8217;s the Octave/Matlab code used to numerically solve the inequation above. The key is to notice that \(\frac{D!}{(D &#8211; T)!}\) and \(\frac{N!}{(N &#8211; T)!}\) are both values taken by the monotonically increasing polynomial \(f(X) = \frac{X!}{(X-T)!} = \prod_{k=0}^{T-1} (X &#8211; k)\). Thus the inequation can be rewritten as \(g(N) > 0\), where \(g(N) = (f(N)/f(D)) &#8211; (1/\alpha)\).</p>
<pre class="brush: matlabkey; title: ; notranslate">
function y = f(x, T)
  y = prod(x - (1:(T-1)));
endfunction

function y = g(N, D, T, alpha)
  y = f(N, T)/f(D, T) - 1/alpha;
endfunction

N = fzero(@(x) g(x, 36.7e6, 5, 0.3), &#x5B;10e6, 10e20]);
</pre>
<p class="details">Illustration by Quentin Blake. Title image from <a href="http://commons.wikimedia.org/wiki/File:Chocolate.jpg">wikimedia</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/willy-wonkas-golden-tickets-certainly-the-most-profitable-marketing-campaign-of-all-times/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>How random is pseudo-random? Testing pseudo-random number generators and measuring randomness</title>
		<link>https://pit-claudel.fr/clement/blog/how-random-is-pseudo-random-testing-pseudo-random-number-generators-and-measuring-randomness/</link>
					<comments>https://pit-claudel.fr/clement/blog/how-random-is-pseudo-random-testing-pseudo-random-number-generators-and-measuring-randomness/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Mon, 23 Jul 2012 16:20:18 +0000</pubDate>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Probabilities]]></category>
		<category><![CDATA[atmospheric noise]]></category>
		<category><![CDATA[binomial distribution]]></category>
		<category><![CDATA[central limit theorem]]></category>
		<category><![CDATA[confidence levels]]></category>
		<category><![CDATA[cosmic noise]]></category>
		<category><![CDATA[cryptography]]></category>
		<category><![CDATA[half normal sitribution]]></category>
		<category><![CDATA[law of large numbers]]></category>
		<category><![CDATA[nuclear decay]]></category>
		<category><![CDATA[prng]]></category>
		<category><![CDATA[pseudo random number generators]]></category>
		<category><![CDATA[quantum mechanics]]></category>
		<category><![CDATA[random number generators]]></category>
		<category><![CDATA[random variables]]></category>
		<category><![CDATA[random walks]]></category>
		<category><![CDATA[randomness]]></category>
		<category><![CDATA[rgn]]></category>
		<category><![CDATA[standard normal distribution]]></category>
		<category><![CDATA[trng]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=255</guid>

					<description><![CDATA[After introducing true and pseudo-random number generators, and presenting the methods used to measure randomness, this article details a number of common statistical tests used to evaluate the quality of random number generators.]]></description>
										<content:encoded><![CDATA[
<p class="abstract">After introducing true and pseudo-random number generators, and presenting the methods used to measure randomness, this article details a number of common statistical tests used to evaluate the quality of random number generators.</p>
<p><span id="more-255"></span></p>
<h2>Introduction: true and pseudo-random number generators</h2>
<p>Obtaining long sequences of random numbers, as required by some cryptographic algorithms, is a delicate problem. There are basically two types of random number generators: true random number generators, and pseudo-random number generators.</p>
<p><span class="fast-forward">This article assumes no particular knowledge about the generation of random numbers, so if you already know about TRNGs and PRNGs, you may want to <a href="#testing-prngs">skip to the core of this article</a>.</span></p>
<h3>True random number generators (TRNGs)</h3>
<p>True random number generators rely on a physical source of randomness, and measure a quantity that is either <em>theoretically</em> unpredictable (quantic), or <em>practically</em> unpredictable (chaotic &#8212; so hard to predict that it appears random).</p>
<p>I&#8217;ve compiled a list of sources of true randomness (capable of sufficiently fast output); please let me know in the <a href="#respond">comments</a> if I forgot any.</p>
<ul>
<li><strong>Thermal noise</strong>, due to the thermal agitation of charge carriers in an electronic component, and used by <a href="http://www.cryptography.com/public/pdf/IntelRNG.pdf">some Intel RNGs</a></li>
<li><strong>Imaging of random processes</strong>, used by <a href="http://www.lavarnd.org/">LavaRnd</a></li>
<li><strong>Atmospheric noise</strong>, mostly due to thunder storms happening around the globe, and used by <a href="http://www.random.org">random.org</a></li>
<li><strong>Cosmic noise</strong>, due to distant stars and background radiation</li>
<li><strong>Driver noise</strong>, often used by <code>/dev/random</code> in Unix-like operating systems ((See <a href="http://diceware.blogspot.fr/2012/03/as-promised-here-are-some-suggestions.html">this post</a> by Arnold Reinhold for a discussion on how to manually increase the entropy of <code>/dev/random</code>))</li>
<li><strong>Transmission by a semi-transparent mirror</strong>, used by <a href="http://www.randomnumbers.info/">randomnumbers.info</a></li>
<li><strong>Nuclear decay</strong>, used by <a href="http://www.fourmilab.ch/hotbits/">HotBits</a></li>
<li><strong>Coupled inverters</strong>, used by <a href="http://spectrum.ieee.org/computing/hardware/behind-intels-new-randomnumber-generator/0">Intel&#8217;s new random generators</a>.</li>
</ul>
<p>The <a href="http://spectrum.ieee.org/computing/hardware/behind-intels-new-randomnumber-generator/0">coupled inverters</a> technique devised by Greg Taylor and George Cox at Intel is truly the most fascinating one : it relies on collapsing the wave function of two inverters put in a superposed state.</p>
<h3>Pseudo-random number generators (PRNGs)</h3>
<p>Pseudo-random number generators are very different: they act as a black box, which takes one number (called the <em>seed</em> ((The current system time is commonly used as a default seed, although for more security-sensitive applications user input is sometimes used (most often by asking the user to shake their mouse in a random fashion) )) and produces a sequence of bits; this sequence is said to be pseudo-random if it passes a number of statistical tests, and thus <em>appears</em> random. These tests are discussed in the following section; simple examples include measuring the frequency of bits and bit sequences, evaluating entropy by trying to compress the sequence, or generating random matrices and computing their rank.</p>
<h4>Formal definition</h4>
<p>A pseudo random number generator is formally defined by an <em>initialization function</em>, a <em>state</em> (a sequence of bits of bounded length), a <em>transition function</em>, and an <em>output function</em>:</p>
<ul>
<li>The <strong>initalisation function</strong> takes a number (the seed), and puts the generator in its initial state.</li>
<li>The <strong>transition function</strong> transforms the state of the generator.</li>
<li>The <strong>output function</strong> transforms the current state to produce a fixed number of bit (a zero or a one).</li>
</ul>
<p>A sequence of pseudo-random bits, called a <em>run</em>, is obtained by seeding the generator (that is, initializing it using a given seed to put it in its initial state), and repeatedly calling the transition function and the output function. ((By definition, since the number of possible states is bounded, this sequence will be periodic; in practice however, this period can be made as large as desired by increasing the number of bits in the state.)) This procedure is illustrated by the following diagram:</p>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/prng.png" alt="Schematic diagram of a pseudo-random number generator" /></p>
<p>Schematic diagram of a pseudo-random number generator</p>
</div>
<p>In particular, this means that the sequence of bits produced by a PRNG is fully determined by the seed ((This property is very useful when using PRNGs to simulate experiments; seeds used during the simulation are recorded in case the results of one specific run need to be reproduced)). This has a few disagreeable consequences, among which the fact that a PRNG can only generate as many sequences as it can accept different seeds. Thus, since the range of values that the state can take is usually much wider than that of the seed, it is generally best to only seldom reset (re-seed) the generator ((except when the state risks being compromised &#8212; see the <a href="#csprng">following section</a>)).</p>
<h4 id="csprng">Cryptographically secure pseudo-random number generators</h4>
<p>Since PRNGs are commonly used for cryptographic purposes, it is sometimes asked that the transformation and output functions satisfy two additional properties :</p>
<ol>
<li><strong>Un-predictability</strong>: given a sequence of output bits, the preceding and following bits shouldn&#8217;t be predictable</li>
<li><strong>Non-reversibility</strong>: given the current state of the PRNG, the previous states shouldn&#8217;t be computable.</li>
</ol>
<p>Rule 1 ensures that eavesdropping the output of a PRNG doesn&#8217;t allow an attacker to learn more than the bits they overheard.<br />
Rule 2 ensures that past communications wouldn&#8217;t be compromised should an attacker manage to gain knowledge of the current state of the PRNG (thereby compromising all future communications based on the same run).</p>
<p>When a PRNG satisfies these two properties ((Again, saying that a PRNG satisfies these properties means that either it can be proven that the rules cannot be broken, or that it is not practically possible to break them in a reasonable amount of time)), it is said to be <em>cryptographically secure</em> ((cryptographically secure pseudo-random number generators are often abbreviated as CSPRNGs)).</p>
<h2 id="testing-prngs">Testing pseudo-random number generators</h2>
<p>There are a number of statistical tests devised to distinguish pseudo-random number generators from true ones; the more a PRNG passes, the closer it is considered to be from a true random source. This section presents general methodology, and studies a few example tests.</p>
<h3>Testing methodology</h3>
<h4>Testing a single sequence</h4>
<p>Almost all tests are built on the same structure: the pseudo-random stream of bits produced by a PRNG is transformed (bits are grouped or rearranged, arranged in matrices, some bits are removed, &#8230;), statistical measurements are made (number of zeros, of ones, matrix rank, &#8230;), and these measurements are compared to the values mathematically expected from a truly random sequence.</p>
<p>More precisely, assume that \(f\) is a function taking any finite sequence of zeros and ones, and returning a non-negative real value. Then, given a sequence of independent and uniformly distributed random variables \(X_n\), applying \(f\) to the finite sequence of random variables \((X_1, &#8230;, X_n)\) yields a new random variable, \(Y_n\). This new variable has a certain cumulative probability distribution \(F_n(x) = \mathbb{P}(Y_n \leq x)\), which in some cases<!--, for example when [latex]f(x_1, \ldots, x_n) = \left|(1/\sqrt{n})\sum_{k=1}^n x_k\right|[/latex],--> approaches a function \(F\) as \(n\) grows large. This limit function \(F\) can be seen as the cumulative probability distribution of a new random variable, \(Y\), and in these cases \(Y_n\) is said to converge in distribution to \(Y\).</p>
<p>Randomness tests are generally based on carefully selecting such a function ((In particular, the function is often chosen so that the limit random variable \(Y\) has a monotonous (decreasing) density function)), and calculating the resulting limit probability distribution<!--(in the previous case, the standard normal law {{or more precisely the half standard normal law, given that [latex]f[/latex] is forced to take only positive values.}})-->. Then, given a random sequence \(\epsilon_1, \ldots, \epsilon_n\), it is possible to calculate the value of \(y = f(\epsilon_1, \ldots, \epsilon_n)\), and assess how likely this value was by evaluating the probability \(\mathbb{P}(Y \geq y)\) &#8212; that is, the probability that a single draw of the limit random variable \(Y\) yields a result greater than or equal to \(y\). If this probability is lower than \(0.01\), the sequence \(\epsilon_1, \ldots, \epsilon_n\) is said to be non-random with confidence 99%. Otherwise, the sequence is considered random.</p>
<h4>An example: the bit frequency test</h4>
<p>Let \((X_n)\) be an infinite sequence of independent, identically distributed random variables. Take \(f\) to be \(f(x_1, &#8230;, x_n) = \frac{1}{\sqrt{n}} \sum_{k=1}^n \frac{x_n &#8211; \mu}{\sigma}\) where \(\mu\) is the average, and \(\sigma\) the standard deviation, of any \(X_k\). Define \(Y_n = f(X_1, &#8230;, X_n)\). The central limit theorem states that the distribution of \(Y_n\) tends to the standard normal distribution. This theorem is illustrated below.</p>
<div class="illustration">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/central-limit-theorem.png" /></p>
<p>Example of convergence in distribution to the standard normal distribution, after summing 1, 2, 3, 4, 5, 8, 10, and 50 independent random variables following the same distribution.</p>
</div>
<p>Consider the particular case where \(X_n\) is uniformly distributed over the discrete set \(\{-1,1\}\). The central limit theorem applies, and \(Y_n = f(X_1, &#8230;, X_n)\) converges in distribution to the standard normal law. For practical reasons, however, we choose to consider \(Y_n = |f(X_1, &#8230;, X_n)|\), which converges in distribution to a variable \(Y_\infty\). \(Y_\infty\) has the half-normal distribution (illustrated on the left), which has the nice property of being monotonically decreasing.</p>
<div class="illustration left">
  <img decoding="async" src="http://pit-claudel.fr/clement/blog/images/half-normal-distribution.png" /></p>
<p>In plain colours, the half-normal distribution. In pale colours, the corresponding cumulative distribution function. If a pseudo-random sequence is picked in the red area, it is declared non-random with 99% certainty (the yellow and orange areas correspond to a certainty of 90% and 95% respectively).</p>
</div>
<p>Here is how the test proceeds : the sequence \((\epsilon_1, \ldots, \epsilon_n)\) given by the PRNG is converted to a sequence of elements of \(\{-1, 1\}\) by changing each \(\epsilon_i\) to \(x_i = 2 \cdot \epsilon_i &#8211; 1\). This gives \(x_1, \ldots, x_n\). Then, \(|f(x_1, \ldots, x_n)| = \left|\sum_{k=1}^n \frac{x_k}{\sqrt{n}}\right|\) is numerically calculated, yielding \(y\). Finally, the theoretical likeliness of a truly random sequence yielding a value equal to or greater than \(y\) is evaluated using the cumulative distribution function of \(Y_\infty\) (in pale colours).</p>
<p>If this probability is too low (red area, probability below \(0.01\)), the sequence is rejected as non-random, with 99% certainty. If it is greater than \(0.01\), but less than \(0.05\) (orange area) the sequence is sometimes ((Some papers advise to reject any sequence with a p-value \(\leq 0.05\), but most choose \(0.01\) as the threshold)) rejected as non-random with 95% certainty. Similarly, if it is greater than \(0.05\) but less than \(0.10\) (yellow area), the sequence is sometimes rejected as non-random, with 90% certainty.</p>
<p>High probabilities (green area, probabilities greater than \(0.10\)), finally, do not permit to distinguish the pseudo-random sequence from a truly random one ((Note that this generates false positives: a true random number generator will, in the long run, produce every possible sequence: sequences yielding measurements that fall in the red area will be rare, but they will occur, and will be discarded as non-random. This is very important to the PRNG-testing procedure, as explained in the <a href="#testing-a-prng">next sub-section</a>)).</p>
<h4 id="testing-a-prng">Testing a pseudo-random number generator</h4>
<p>To test whether a pseudo-random number generator is close to a true one, a sequence length is chosen, and \(m\) pseudo-random sequences of that length are retreived from the PRNG, then analysed according to the previous methodology. It is expected, if the confidence level is 1%, that about 99% of the sequences pass, and 1% of the sequences fail; if the observed ratio significantly differs from 99 to 1, the PRNG is said to be non-random. More precisely, the confidence interval is generally chosen to be \(p \pm 3\frac{\sqrt{p(1-p)}}{\sqrt{m}}\), where \(p\) is the theoretical ratio (99% here); this takes the probability of incorrectly rejecting a good number generator down to 0.3%.</p>
<p class="details">
This confidence interval is obtained as follows. For large values of \(m\),  approximate the probability of rejecting \(r\) sequences by \(\binom{m}{r} p^{1-r} (1-p)^r\) (here \(p = 99\%\)). Write \(\sigma_i\) the random variable denoting whether the \(i\)<sup>th</sup> sequence was rejected. Then with the previous approximation all \(\sigma_i\) are independent and take value \(0\) with probability \(p\), \(1\) with probability \(1-p\) (standard deviation: \(\sqrt{p(1-p)}\)). The central limit theorem states that with probability close to \(\displaystyle \int_a^b \frac{e^{-x^2/2}}{\sqrt{2\pi}}\), the observed rejection frequency \(\hat{p}\) lies in the interval \(\left[p + b\frac{\sqrt{p(1-p)}}{\sqrt{m}}, p + a\frac{\sqrt{p(1-p)}}{\sqrt{m}}\right]\). Finally, setting \(b = -a\) and adjusting \(a\) so that this probability is \(\approx 99.7\%\) yields \(a \approx 3\).
</p>
<h3>Tests suites</h3>
<p>A number of test suites have been proposed as standards. The state-of-the-art test suite was for a long time the <a href="http://stat.fsu.edu/pub/diehard/">DieHard test suite</a> (designed by George Marsaglia), though it as eventually superseeded by the National Institute of Standards and Technology <a href="http://csrc.nist.gov/groups/ST/toolkit/rng/documents/SP800-22rev1a.pdf">recommendations</a>. Pierre l&#8217;Ecuyer and Richard Simard, from Montreal university, have recently published a new collection of tests, <a href="http://www.iro.umontreal.ca/~simardr/testu01/tu01.html">TestU01</a>, gathering and implementing a impressive number of previously published tests and adding new ones. ((<a href="http://www.fourmilab.ch/random/">Ent</a> is another implementation of a few tests.))</p>
<p>A subset of these tests is presented below.</p>
<h3>A list of common statistical tests used to evaluate randomness</h3>
<h4>Equidistribution (Monobit frequency test, discussed above)</h4>
<p>
  <strong>Purpose:</strong> Evaluate whether the sequence has a systematic bias towards 0 or 1 (<a href="http://www.random.org/statistics/frequency-monobit/">real-time</a> example on random.org)<br />
  <strong>Description:</strong> Verify that the arithmetic mean of the sequence approaches \(0.5\) (based on the law of large numbers). Alternatively, verify that normalized partial sums \(s_n = \frac{1}{\sqrt{n}} \sum_{k=1}^n \frac{2\cdot\epsilon_k &#8211; 1}{\sqrt{2}}\) approach a standard normal distribution (based on the central limit theorem).<br />
  <strong>Variants:</strong> Block frequency test (group bits in blocks of constant length and perfom the same test), Frequency test in a block (group bits in blocks of constant length and perform the test on every block).
</p>
<h4>Runs test</h4>
<p>
  <strong>Purpose:</strong> Evaluate whether runs of ones or zeros are too long (or too short) (<a href="http://www.random.org/statistics/runs/">real-time</a> example on random.org)<br />
  <strong>Description:</strong> Count the number of same-digits blocks in the sequence. This should follow a binomial distribution \(\mathcal{B}(n, 1/2)\). By noting that the number of same-digits blocks is the sum of the \(\sigma_i\) where \(\sigma_i = 1\) if \(\epsilon_i \not= \epsilon_{i+1}\) and \(\sigma_i = 0\) otherwise, the previous method can be applied.<br />
  <strong>Variants:</strong> Longest run of ones (divide the sequence in blocks and measure the longest run of ones in each block).
</p>
<h4>Binary matrix rank</h4>
<p>
  <strong>Purpose:</strong> Search for linear dependencies between successive blocks of the sequence<br />
  <strong>Description:</strong> Partition the sequence in blocks of length \(n \times p\). Build one \(n \times p\) binary matrix from each block, and compute its rank. The theoretical distribution of all ranks is however not easy to compute &#8212; this problem is discussed in details in <a href="http://www.cs.utoronto.ca/~cvs/coding/random_report.pdf">a paper by Ian F. Blake and Chris Studholme</a> from the university of Toronto.
</p>
<h4>Discrete Fourier transform</h4>
<p>
  <strong>Purpose:</strong> Search for periodic components in the pseudo-random sequence<br />
  <strong>Description:</strong> Compute a discrete Fourier transform of the pseudo-random input \(2\epsilon_1 &#8211; 1, \ldots, 2\epsilon_n &#8211; 1\), and take the modulus of each complex coefficient ((Note that, since the input sequence is real-valued, its DFT is symetrical; hence all the counting need only happen on the first half of the DFT sequence)). Compute the 95% peak height threshold value, defined to be the theoretical value that no more than 5% of the previously calculated moduli should exceed (\(\sqrt{-n\log(0.05)}\) (<a href="http://csrc.nist.gov/publications/nistpubs/800-22-rev1a/SP800-22rev1a.pdf">NIST</a>)), and count the actual number of moduli exceeding this threshold. Assess the likeliness of such a value.
</p>
<h4>Compressibility (Maurer&#8217;s universal statistical test)</h4>
<p>
  <strong>Purpose:</strong> Determine whether the sequence can be compressed without loss of information (evaluate information density). A random sequence should have a high information density.<br />
  <strong>Description:</strong> Partition the sequence in blocks of length \(L\), and separate these block into categories. Call the first \(Q\) blocks the initialisation sequence, and the remaining \(K\) blocks the test sequence. Then, give each block in the test sequence a score equal to the distance that separates it from the previous occurence of a block with the same contents, and sum the binary logarithm of all scores. Divide by the number of blocks to obtain the value of the test function, and verify that this value is close enough to the theoretically expected value. ((Since the binary logarithm is concave, this value gets smaller as the dispersion of the scores increase; informally, since the expected distance between to blocks of equal contents is approximately the number of possible different blocks (\(2^L\) ) the expected value should be about \(\log_2(2^L)\) &#8212; that is \(L\). Computing the actual expected values yields a somewhat smaller number, which approaches \(L &#8211; 0.83\) as \(L \to \infty\) (<a href="http://www.jscoron.fr/publications/universal.pdf">Coron, Naccache</a>) ))
</p>
<h4>Maximum distance to zero, Average flight time, Random excursions</h4>
<p>
  <strong>Purpose:</strong> Verify that the sequence has some of the properties of a truly random walk<br />
  <strong>Description:</strong> Consider the pseudo-random sequence to represent a random walk starting from zero and moving up (down) by one unit every time a zero (a one) occurs in the sequence. Measure the maximum height reached by the walk, as well as the average time and the number of states visited. Also, for each possible state (integer), measure in how many cycle it appears. Evaluate the theoretical probability of obtaining these values.
</p>
<p>The sources previously cited (in particular the <a href="http://csrc.nist.gov/publications/nistpubs/800-22-rev1a/SP800-22rev1a.pdf">NIST recommendation paper</a>) present mathematical background about these tests, as well as lots of other tests.</p>
<p class="conclusion">Did I miss your favourite randomness test? Were you ever confronted to obvious imperfections in a pseudo-random number generator? Tell us in the comments!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/how-random-is-pseudo-random-testing-pseudo-random-number-generators-and-measuring-randomness/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Using abstract classes to simulate tagged unions (aka sum types)</title>
		<link>https://pit-claudel.fr/clement/blog/using-abstract-classes-to-simulate-tagged-unions-aka-sum-types/</link>
					<comments>https://pit-claudel.fr/clement/blog/using-abstract-classes-to-simulate-tagged-unions-aka-sum-types/#comments</comments>
		
		<dc:creator><![CDATA[Clément]]></dc:creator>
		<pubDate>Thu, 19 Jul 2012 22:41:36 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[OCaml]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[abstract classes]]></category>
		<category><![CDATA[inheritance]]></category>
		<category><![CDATA[pattern matching]]></category>
		<category><![CDATA[product types]]></category>
		<category><![CDATA[sum types]]></category>
		<category><![CDATA[syntax trees]]></category>
		<guid isPermaLink="false">http://pit-claudel.fr/clement/blog/?p=186</guid>

					<description><![CDATA[After a short introduction to pattern matching in functional programming languages, this article shows how abstract classes can emulate sum types in Java/C#.]]></description>
										<content:encoded><![CDATA[<p>Most functional languages offer support for tagged unions (also called sum types), a type of data structure capable of successively holding values of several fixed types. This article shows how to use abstract classes to emulate such behaviour in high-level object-oriented languages such as C#, Java, or VB.Net ((.Net languages have the <code>[StructLayout(LayoutKind.Explicit)]</code> attribute, which makes it possible to create structs which behave a lot like C++ unions. But that only works with primitive types.)).</p>
<p><span id="more-186"></span></p>
<p><span class="fast-forward">This article features a rather long introduction to sum types in functional languages. If you already know about this, you can <a href="#abstract-classes">skip to the core of this article</a>.</span></p>
<h2>An introduction to sum types and pattern matching</h2>
<h3>A preliminary example: linked lists</h3>
<p>Starting with a simple example, imagine you want to create a linked list structure. Most C#/Java programmers will write something like</p>
<pre class="brush: csharp; title: ; notranslate">
  class MyList&lt;T&gt; {
    T value;
    MyList&lt;T&gt; next;

    MyList(T value, MyList&lt;T&gt; next) {
      this.value = value;
      this.next = next;
    }
  }

  MyList&lt;int&gt; example = new MyList(1, new MyList(2, null));
</pre>
<p>This relies on a rather ugly trick: <code>null</code> is used to represent the empty list. Functional languages prefer to clearly separate two cases : the empty list (usually called <code>nil</code>), and the concatenation of a value (called the head of the list) and another list (called the tail).</p>
<pre class="brush: fsharp; title: Ocaml/F#; notranslate">
  (* 't is a type variable, just like T above *) 
  type 't MyList = Nil | Cons of 't * ('t MyList);; 
  let example = Cons(1, Cons(2, Nil))
</pre>
<pre class="brush: haskell; title: Haskell; notranslate">
  {- t is a type variable, just like T above -}
  data MyList t = Nil | Cons t (MyList t)
  example = Cons 1 (Cons 2 Nil)
</pre>
<p>This introduces the concept of a sum type; a type in which values belong to one of a number of sets (here, either to the singleton set <code>{Nil}</code>, or to the set of all values of type <code>t</code> &#8212; for example integers if <code>t</code> is <code>int</code>).</p>
<p>Here is another example, where a value of type <code>Value</code> can be either an integer, or a floating-point number, or a string, or a boolean.</p>
<div class="left">
<pre class="brush: fsharp; title: Ocaml/F#; notranslate">
  type Value = 
    | IntegerValue of int 
    | FloatValue of float
    | StringValue of string
    | BooleanValue of bool
</pre>
</div>
<div class="right">
<pre class="brush: haskell; title: Haskell; notranslate">
  data Value = 
      IntegerValue Int
    | FloatValue Float
    | StringValue String
    | BooleanValue Bool
</pre>
</div>
<hr class="clear" />
<p>Quite naturally, functional languages include a special construct to handle values whose type is a sum type. This construct is called  <em>pattern matching</em>; it is a bit like a <code>switch</code> statement, only the switch is on the object&#8217;s inner type (the subset of the sum type which the object belongs to). For example, to identify the contents of a variable whose type is <code>Value</code>, functional programmers write</p>
<div class="left">
<pre class="brush: fsharp; title: Ocaml/F#; notranslate">
  let identify = function
    | IntegerValue (val) -&gt; &quot;int!&quot; 
    | FloatValue (val) -&gt; &quot;float!&quot; 
    | StringValue (str) -&gt; &quot;string&quot;
    | BooleanValue (b) -&gt; &quot;bool!&quot;
</pre>
</div>
<div class="right">
<pre class="brush: haskell; title: Haskell; notranslate">
  identify (IntegerValue val) = "int!" 
  identify (FloatValue val) = "float!" 
  identify (StringValue str) = "string"
  identify (BooleanValue b) = "bool!"
</pre>
</div>
<hr class="clear" />
<p>Here&#8217;s another example, on lists this time: if functional programmers want to count elements in a list, they write</p>
<pre class="brush: fsharp; title: Ocaml/F#; notranslate">
  let rec count = function
    | Nil -&gt; 0
    | Cons (head, tail) -&gt; 1 + (count tail)
  ;;
</pre>
<pre class="brush: haskell; title: Haskell; notranslate">
  count Nil = 0
  count (Cons hd tl) = 1 + count tl
</pre>
<p>Let&#8217;s move on to our last example</p>
<h3>XML node trees</h3>
<p>In this section, we use a sum type to represent the structure of an XML document (some node types have been omitted). We first define an attribute to be a pair of two <code>string</code>s, and a node to be one of <code>DocumentFragment</code> (a list of XML nodes), <code>Element</code> (a name, attributes, and children elements), <code>Commment</code> (some comment text), or <code>Text</code> (plain text).</p>
<div class="left">
<pre class="brush: fsharp; title: Ocaml; notranslate">
  type attr = 
    Attribute of string * string;;

  type xmlnode = 
    | DocumentFragment of xmlnode list
    | Element of string 
                  * (attr list)
                  * (xmlnode list)
    | Comment of string
    | Text of string
  ;;
</pre>
</div>
<div class="right">
<pre class="brush: haskell; title: Haskell; notranslate">
  data XmlNode = 
    | DocumentFragment &#x5B;XmlNode]
    | Attribute String String
    | Element String &#x5B;Attribute]
                     &#x5B;XmlNode]
    | Comment String
    | Text String
</pre>
</div>
<hr class="clear" />
<p>With such a type declaration, writing concise tree-traversal functions is easy: as an example, we define a <code>serialize</code> function, which generate XML code from an <code>xmlnode</code> object.</p>
<pre class="brush: fsharp; title: Ocaml; notranslate">
  let serialize_attribute (Attribute(name, value)) =
    Printf.printf &quot; %s=\&quot;%s\&quot;&quot; name value
  ;;

  let rec serialize = function 
    | DocumentFragment nodes -&gt;
        List.iter serialize nodes (* applies serialize to every xmlnode in nodes *)
    | Element (label, attributes, nodes) -&gt;
        Printf.printf &quot;&lt;%s&quot; label;
          List.iter serialize_attribute attributes;
        Printf.printf &quot;&gt;\n&quot;;
          List.iter serialize nodes;
        Printf.printf &quot;&lt;/%s&gt;\n&quot; label;
    | Comment (str) -&gt;
        Printf.printf &quot;&lt;!-- %s --&gt;&quot; str;
    | Text (str) -&gt;
        Printf.printf &quot;%s\n&quot; str;
  ;;
</pre>
<p>Here is a small example to illustrate the previous function:</p>
<pre class="brush: fsharp; title: ; notranslate">
  serialize (
    Element("a", &#x5B;
      Attribute("href", "http://pit-claudel.fr/clement/blog");
      Attribute("title", "Code crumbs")
    ], &#x5B;
      Text("Code crumbs -- Personal thoughts about programming")
    ])
  );;
</pre>
<p>This prints </p>
<pre class="brush: xml; title: ; notranslate">
&lt;a href=&quot;http://pit-claudel.fr/clement/blog&quot; title=&quot;Code crumbs&quot;&gt;
Code crumbs -- Personal thoughts about programming
&lt;/a&gt;
</pre>
<p>We can now move on to the core of this article:</p>
<h2 id="abstract-classes">Simulating sum types using abstract classes</h2>
<h3>The problem</h3>
<p>Returning to a simpler example, suppose we need to represent a generic binary tree (a tree is defined as being either a branch, containing two sub-trees, or a leaf, containing a value). Functional programmers will write something like</p>
<pre class="brush: fsharp; title: Ocaml/F#; notranslate">
  type 't tree = Branch of ('t tree * 't tree) | Leaf of 't
  let example = Branch (Branch (Leaf 1, Leaf 2), Leaf 3)
</pre>
<pre class="brush: haskell; title: Haskell; notranslate">
  data Tree t = Branch (Tree t) (Tree t) | Leaf t
  example = Branch (Branch (Leaf 1) (Leaf 2)) (Leaf 3)
</pre>
<p>On the other hand, (hurried) C#/Java programmers will often implement this as a product type &#8212; that is, they&#8217;ll pack both cases in a single class, and use an extra field to differentiate branches and leaves:</p>
<pre class="brush: csharp; title: ; notranslate">
  enum TreeType = {BRANCH, LEAF};

  class BadTree&lt;T&gt; {
    TreeType type;
    
    T leaf_value;
    BadTree&lt;T&gt; left_branch, right_branch;

    BadTree(BadTree&lt;T&gt; left_branch, BadTree&lt;T&gt; right_branch) {
         this.type = BRANCH;
         this.left_branch = left_branch;
         this.right_branch = right_branch;
         // Memory waste: leaf_value is unused (!)
    }

    BadTree(T leaf_value) {
         this.type = LEAF;
         this.leaf_value = leaf_value;
         // Memory waste: left_branch and right_branch are unused (!)
    }
  }

  BadTree&lt;int&gt; example = new BadTree(new BadTree(new BadTree(1), 
                                                 new BadTree(2)),
                                     new Tree(3));
</pre>
<p>This representation wastes a lot of memory and, though rather concise, quickly degenerates when more cases are added to the type definition (for example in the <code>xmlnode</code> case &#8212; for another real-world example, see the end of this post).</p>
<h3>The solution</h3>
<p>The idea is to encode the type disjunction (<code>Branch</code> <em>or</em> <code>Leaf</code>, <code>DocumentFragment</code> <em>or</em> <code>Element</code> <em>or</em> <code>Comment</code> <em>or</em> <code>Text</code>) in the inheritance hierarchy; practically speaking, the trick is to define an abstract <code>Tree</code> class, and make two new classes, <code>Leaf</code> and <code>Branch</code>, which both inherit from <code>Tree</code>:</p>
<pre class="brush: csharp; title: ; notranslate">
  abstract class Tree&lt;T&gt; {
    public static class Leaf&lt;T&gt; : Tree&lt;T&gt; {
      public T value;

      public Leaf(T value) {
        this.value = value;
      }
    }

    public static class Branch&lt;T&gt; : Tree&lt;T&gt; {
      public Tree&lt;T&gt; left, right;

      public Branch(Tree&lt;T&gt; left, Tree&lt;T&gt; right) {
        this.left = left;
        this.right = right;
      }
    }
  }

  Tree&lt;int&gt; example = new Tree::Branch(new Tree::Branch(new Tree::Leaf(1),
                                                        new Tree::Leaf(2)),
                                       new Tree::Leaf(3));
</pre>
<p>This allows for much cleaner code ; and the memory waste is gone!</p>
<h2>Pattern matching on abstract classes</h2>
<p>The <code>BadTree</code> class, which uses an <code>enum</code> to distinguish branches and nodes, makes it possible to performe pattern matchings over the <code>Tree<T></code> class, by switching on the <code>Tree<T>.type</code> field. Though this approach directly translates to the <code>Tree</code> abstract class using the <code>is</code> keyword ((Java equivalent: <code>instanceof</code>)), it&#8217;s not ideal.</p>
<div class="left">
<pre class="brush: csharp; title: Original pattern-matching code; notranslate">
  Tree&lt;int&gt; tree = (...);

  switch (tree.type) {
    case TreeType.BRANCH:
      (...); break;
    case TreeType.LEAF:
      (...); break;
  }
</pre>
</div>
<div class="right">
<pre class="brush: csharp; title: Direct translation (not great); notranslate">
  Tree&lt;int&gt; tree = (...);

  if (tree is Tree::Branch) {
    Tree::Branch branch = 
      (Tree::Branch) btree;
    (...);
  } else if (tree is Tree::Leaf) {
    Tree::Leaf leaf = 
      (Tree::Leaf) tree;
    (...);
  }
</pre>
</div>
<hr class="clear" />
<p>Though functional, this new version of the pattern-matching code is not really pretty. A much cleaner approach is to implement the pattern matching directly in the derived classes (<code>Branch</code> and <code>Leaf</code>), by declaring an abstract method in the parent class, <code>Tree</code>. That is, instead of having one big function doing some explicit pattern matching in the <code>Tree</code> class, we&#8217;ll have multiple specialized functions &#8212; one in each class inheriting <code>Tree</code>. Philosophically speaking, just like we implemented <em>type disjunctions</em> as different classes inheriting a common parent, we&#8217;ll implement <em>logical disjunctions</em> as different functions overriding a common parent.</p>
<p>For example, here is how we can write a <code>Fork</code> function, which returns a new <code>Tree</code> with every leaf split in two identical leaves:</p>
<pre class="brush: csharp; highlight: [2,9,10,11,19,20,21]; title: ; notranslate">
  abstract class Tree&lt;T&gt; {
    public abstract Tree&lt;T&gt; Fork();

    public static class Leaf&lt;T&gt; : Tree&lt;T&gt; {
      public T value;

      // Constructor omitted

      public override Tree&lt;T&gt; Fork() {
        return new Tree::Branch(new Tree::Leaf(value), new Tree::Leaf(value));
      }
    }

    public static class Branch&lt;T&gt; : Tree&lt;T&gt; {
      public Tree&lt;T&gt; left, right;

      // Constructor omitted

      public override Tree&lt;T&gt; Fork() {
        return new Tree::Branch(left.Fork(), right.Fork());
      }
    }
  }
</pre>
<h2>Going further: a real-life example</h2>
<p>The benefits of using this abstract class approach are particularly visible when the data types involved get more complex. Below is an example implementation of a data structure used to describe arithmetic expressions.</p>
<pre class="brush: csharp; title: ; notranslate">
  abstract class ArithmeticExpression {
    // Evaluates an arithmetic expression. context is a dictionary mapping variable
    //  names to their values.
    public abstract float? Eval(Dictionary&lt;String, float?&gt; context);

    public class Variable : ArithmeticExpression {
      string label;

      public override float? Eval(Dictionary&lt;String, float?&gt; context) {
        float? value;
        context.TryGetValue(label, out value);
        return value;
      }
    }
    
    public abstract class BinaryOperation : ArithmeticExpression {
      protected ArithmeticExpression left_operand, right_operand;

      public BinaryOperation(ArithmeticExpression left_operand, ArithmeticExpression right_operand) {
        this.left_operand = left_operand;
        this.right_operand = right_operand;
      }

      protected abstract float? Apply(float left_value, float right_value);

      public override float? Eval(Dictionary&lt;String, float?&gt; context) {
        float? left_result = left_operand.Eval(context), right_result = right_operand.Eval(context);

        if (left_result.HasValue &amp;&amp; right_result.HasValue)
          return Apply(left_result.Value, right_result.Value);
        else
          return null;
      }

      class Sum : BinaryOperation {
        public Sum(ArithmeticExpression left_operand, ArithmeticExpression right_operand) : base(left_operand, right_operand) { }

        protected override float? Apply(float left_value, float right_value) {
          return left_value + right_value;
        }
      }

      class Subtraction : BinaryOperation {
        public Subtraction(ArithmeticExpression left_operand, ArithmeticExpression right_operand) : base(left_operand, right_operand) { }

        protected override float? Apply(float left_value, float right_value) {
          return left_value - right_value;
        }
      }

      class Product : BinaryOperation {
        public Product(ArithmeticExpression left_operand, ArithmeticExpression right_operand) : base(left_operand, right_operand) { }

        protected override float? Apply(float left_value, float right_value) {
          return left_value * right_value;
        }
      }

      class Division : BinaryOperation {
        public Division(ArithmeticExpression left_operand, ArithmeticExpression right_operand) : base(left_operand, right_operand) { }

        protected override float? Apply(float left_value, float right_value) {
          return left_value / right_value;
        }
      }
    }
  }
</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://pit-claudel.fr/clement/blog/using-abstract-classes-to-simulate-tagged-unions-aka-sum-types/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
