<?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>Michi's blog &#187; Computer</title>
	<atom:link href="http://blog.mikael.johanssons.org/archive/category/computer/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mikael.johanssons.org</link>
	<description>Because my LiveJournal is too silly</description>
	<lastBuildDate>Sat, 12 Nov 2011 15:09:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>A quick python hack for a mathematical puzzle</title>
		<link>http://blog.mikael.johanssons.org/archive/2011/11/a-quick-python-hack-for-a-mathematical-puzzle/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2011/11/a-quick-python-hack-for-a-mathematical-puzzle/#comments</comments>
		<pubDate>Sat, 12 Nov 2011 15:09:36 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[mathematics puzzle]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=314</guid>
		<description><![CDATA[So, today I saw this in my Twitter feed: «Phil Harvey wants us to partition {1,…,16} into two sets of equal size so each subset has the same sum, sum of squares and sum of cubes.» &#8212; posted by @MathsJam and retweeted @haggismaths. Sounds implausible was my first though. My second thought was that there [...]]]></description>
			<content:encoded><![CDATA[<p>So, today I saw this in my Twitter feed:</p>
<blockquote><p>«Phil Harvey wants us to partition {1,…,16} into two sets of equal size so each subset has the same sum, sum of squares and sum of cubes.» &#8212; posted by @MathsJam and retweeted @haggismaths.
</p></blockquote>
<p>Sounds implausible was my first though. My second thought was that there aren&#8217;t actually ALL that many of those: we can actually test this.</p>
<p>So, here&#8217;s a short collection of python lines to _do_ that testing.</p>
<p><code>import itertools<br />
allIdx = range(1,17)<br />
sets = itertools.combinations(allIdx,8)<br />
setpairs = [(list(s), [i for i in allIdx if i not in s]) for s in sets]<br />
def f((s1,s2)): return (sum(s1)-sum(s2), sum(map(lambda n: n**2, s1))-sum(map(lambda n: n**2, s2)), sum(map(lambda n: n**3, s1))-sum(map(lambda n: n**3, s2)))</p>
<p>goodsets = [ss for ss in setpairs if f(ss) == (0,0,0)]<br />
</code><br />
And back comes one single response (actually, two, because the comparison is symmetric).</p>
<p><code>[([1, 4, 6, 7, 10, 11, 13, 16], [2, 3, 5, 8, 9, 12, 14, 15]),<br />
 ([2, 3, 5, 8, 9, 12, 14, 15], [1, 4, 6, 7, 10, 11, 13, 16])]<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2011/11/a-quick-python-hack-for-a-mathematical-puzzle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Species, derivatives of types and Gröbner bases for operads</title>
		<link>http://blog.mikael.johanssons.org/archive/2010/12/species-derivatives-of-types-and-grobner-bases-for-operads/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2010/12/species-derivatives-of-types-and-grobner-bases-for-operads/#comments</comments>
		<pubDate>Sat, 18 Dec 2010 01:05:30 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Category theory]]></category>
		<category><![CDATA[Combinatorics]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Operads and PROPs]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=270</guid>
		<description><![CDATA[This is a typed up copy of my lecture notes from the combinatorics seminar at KTH, 2010-09-01. This is not a perfect copy of what was said at the seminar, rather a starting point from which the talk grew. In some points, I&#8217;ve tried to fill in the most sketchy and un-articulated points with some [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a typed up copy of my lecture notes from the combinatorics seminar at KTH, 2010-09-01. This is not a perfect copy of what was said at the seminar, rather a starting point from which the talk grew.</p>
<p>In some points, I&#8217;ve tried to fill in the most sketchy and un-articulated points with some simile of what I ended up actually saying.<br />
</em></p>
<p>Combinatorial species started out as a theory to deal with enumerative combinatorics, by providing a toolset &#038; calculus for formal power series. (see Bergeron-Labelle-Leroux and Joyal)</p>
<p>As it turns out, not only is species useful for manipulating generating functions, btu it provides this with a categorical approach that may be transplanted into other areas.</p>
<p>For the benefit of the entire audience, I shall introduce some definitions.</p>
<p><strong>Definition</strong>: A <em>category</em> C is a collection of <em>objects</em> and <em>arrows</em> with each arrow assigned a <em>source</em> and <em>target</em> object, such that </p>
<ol>
<li>Each object has its own <em>identity arrow</em> 1.</li>
<li>Chains of arrows are associatively <em>composable</em>, with 1 the identity of this composition.</li>
</ol>
<p><strong>Examples</strong>: Sets, Finite sets, k-Vector spaces, left and right R-Modules, Graphs, Groups, Abelian groups.</p>
<p><img src='/latexrender/pictures/e19c41413e1b974679b02bd79d5d494c.png' title='\mathbb B' alt='\mathbb B' align='middle' />: finite sets with only bijections as morphisms.</p>
<p><strong>Examples</strong>: </p>
<ul>
<li>Category of a monoid.</li>
<li>Category generated by a graph</li>
<li>Category of a group (groupoid version of the category of a monoid)</li>
<li>Category of a poset</li>
<li>Category of Haskell types and functions.</li>
</ul>
<p><strong>Definition</strong>: A <em>functor</em> F is a map of categories, in other words, a pair of maps Fo on objects and Fa on arrows, such that the identity arrow maps to identity arrows and compositions of maps map to compositions of their images.</p>
<p><strong>Examples</strong>:<br />
Constant functor: sends every object to A, every map to 1.</p>
<p>Identity functor: sends objects and arrows to themselves.</p>
<p>Underlying set functor, free monoid/vector space/module/&#8230; functors.</p>
<p>We are now equipped to define Species:<br />
<strong>Definition</strong>: A <em>species of structures</em> is a functor <img src='/latexrender/pictures/248ed9b3523a819e669addcfca0dd9e1.png' title='\mathbb B\to\mathbb B' alt='\mathbb B\to\mathbb B' align='middle' />.</p>
<p>The idea is a set gets mapped to the set of all structures labelled by the elements in the original set. A bijection on labels maps to the <em>transport of structures</em> along the relabeling. </p>
<p><strong>Examples</strong>:<br />
<img src='/latexrender/pictures/7fc56270e7a70fa81a5935b72eacbe29.png' title='A' alt='A' align='middle' />: rooted trees, labels on vertices<br />
<img src='/latexrender/pictures/dfcf28d0734569a6a693bc8194de62bf.png' title='G' alt='G' align='middle' />: simple graphs, labels on vertices<br />
<img src='/latexrender/pictures/68306c3af365d0638ca6a65e96012770.png' title='Gc' alt='Gc' align='middle' />: connected simple graphs, labels on vertices.<br />
<img src='/latexrender/pictures/0cc175b9c0f1b6a831c399e269772661.png' title='a' alt='a' align='middle' />: trees, labels on vertices.<br />
<img src='/latexrender/pictures/f623e75af30e62bbd73d6df5b50bb7b5.png' title='D' alt='D' align='middle' />: directed graphs, labels on vertices<br />
<img src='/latexrender/pictures/1a13d972a2c8473f075ded6eca465169.png' title='\wp' alt='\wp' align='middle' />: subsets, <img src='/latexrender/pictures/ab03f17fcfe3bf3f9f730c032cf12151.png' title='\wp[U] = \{S: S\subseteq U\}' alt='\wp[U] = \{S: S\subseteq U\}' align='middle' />.<br />
<img src='/latexrender/pictures/87557f11575c0ad78e4e28abedc13b6e.png' title='End' alt='End' align='middle' />: endofunctions<br />
<img src='/latexrender/pictures/a7e871520a392b978d3c9e6344c4407f.png' title='Inv' alt='Inv' align='middle' />: involutions<br />
<img src='/latexrender/pictures/5dbc98dcc983a70728bd082d1a47546e.png' title='S' alt='S' align='middle' />: permutations<br />
<img src='/latexrender/pictures/0d61f8370cad1d412f80b84d143e1257.png' title='C' alt='C' align='middle' />: cycles<br />
<img src='/latexrender/pictures/d20caec3b48a1eef164cb4ca81ba2587.png' title='L' alt='L' align='middle' />: linear orders<br />
<img src='/latexrender/pictures/3a3ea00cfc35332cedf6e5e9a32e94da.png' title='E' alt='E' align='middle' />: sets: <img src='/latexrender/pictures/4784af6daa47ce1b4dc27c7f968b48a3.png' title='E[U] = \{U\}' alt='E[U] = \{U\}' align='middle' /><br />
<img src='/latexrender/pictures/e1671797c52e15f763380b45e841ec32.png' title='e' alt='e' align='middle' />: elements: <img src='/latexrender/pictures/8f19454f9794245cdbaabf2330720444.png' title='e[U] = U' alt='e[U] = U' align='middle' /><br />
<img src='/latexrender/pictures/02129bb861061d1a052c592e2dc6b383.png' title='X' alt='X' align='middle' />: singletons: <img src='/latexrender/pictures/eedeabedbaf43a4ce7a1b347c32faf43.png' title='X[U] = U' alt='X[U] = U' align='middle' /> if <img src='/latexrender/pictures/a03dbebf1f9af1a9557fff5ace5c7534.png' title='|U|=1' alt='|U|=1' align='middle' /> and <img src='/latexrender/pictures/0118beed08546bf49c98e18e68f4e401.png' title='X[U] = \emptyset' alt='X[U] = \emptyset' align='middle' /> otherwise<br />
<img src='/latexrender/pictures/c4ca4238a0b923820dcc509a6f75849b.png' title='1' alt='1' align='middle' />: empty set: <img src='/latexrender/pictures/09f8d10bb99358b7c16cdbe36bea58a0.png' title='1[\emptyset]=\{\emptyset\}' alt='1[\emptyset]=\{\emptyset\}' align='middle' />, <img src='/latexrender/pictures/926ff03720b581dc624f4de2af07bac3.png' title='1[U] = \emptyset' alt='1[U] = \emptyset' align='middle' /> otherwise<br />
<img src='/latexrender/pictures/cfcd208495d565ef66e7dff9f98764da.png' title='0' alt='0' align='middle' />: empty species: <img src='/latexrender/pictures/e864d4557560227f5f4276edab39b730.png' title='0[U] = \emptyset' alt='0[U] = \emptyset' align='middle' />.</p>
<p>In enumerative combinatorics, the power of species resides in the association to each species a number of generating functions:</p>
<p>The generating series of a species F is the exponential formal power series<br />
<img src='/latexrender/pictures/4d16123f57c0b624af2c2edf792d1cd8.png' title='F(x) = \sum_{n=0}^\infty |F[n]|\frac{x^n}{n!}' alt='F(x) = \sum_{n=0}^\infty |F[n]|\frac{x^n}{n!}' align='middle' /><br />
where we use the convention <img src='/latexrender/pictures/aa863c04e18ac592a7560ac3e3a581b1.png' title='[n] = \{1,2,\dots,n\}' alt='[n] = \{1,2,\dots,n\}' align='middle' />, and <img src='/latexrender/pictures/e246dceb6995c5555b1eeb2d505e1708.png' title='F[n] = F[[n]]' alt='F[n] = F[[n]]' align='middle' />.<br />
Thus:<br />
<img src='/latexrender/pictures/3263ff4d9c8a689eae466290bc3052c8.png' title='L(x) = \frac{1}{1-x}' alt='L(x) = \frac{1}{1-x}' align='middle' /><br />
<img src='/latexrender/pictures/3f525bcdaa7612df493b0d76e1364151.png' title='S(x) = \frac{1}{1-x}' alt='S(x) = \frac{1}{1-x}' align='middle' /><br />
<img src='/latexrender/pictures/f77a81e173d3ac51473b37a36e4b323c.png' title='E(x) = e^x' alt='E(x) = e^x' align='middle' /><br />
<img src='/latexrender/pictures/7c5625058ffe6ddb20482fc3079c784a.png' title='e(x) = xe^x' alt='e(x) = xe^x' align='middle' /><br />
<img src='/latexrender/pictures/9063d24c51c77a8c1f84d329a2bed613.png' title='\wp(x) = e^{2x}' alt='\wp(x) = e^{2x}' align='middle' /><br />
<img src='/latexrender/pictures/38d07f869ac97a6ed1deb8574ed0953e.png' title='X(x) = x' alt='X(x) = x' align='middle' /><br />
<img src='/latexrender/pictures/da2ca5efb767fbf1d7d2b4409f3c83f0.png' title='1(x) = 1' alt='1(x) = 1' align='middle' /><br />
<img src='/latexrender/pictures/a78d5784bdd192b7dc4c1b784d719d26.png' title='0(x) = 0' alt='0(x) = 0' align='middle' /></p>
<p>There are a number other in use for combinatorics, but for my purposes, this is the one I&#8217;ll focus on.</p>
<h2>Operations on species</h2>
<p>The real power, though, emerges when we start combining species, and carry over the combinations to actions on the corresponding power series.</p>
<h3>Addition</h3>
<p>The number of ways to form either, say, a graph or a linear order on a set of labels is the sum of the numbers of ways to form either in isolation.</p>
<p>This corresponds cleanly to the coproduct in Set, and we may write F+G for the species<br />
<img src='/latexrender/pictures/d6b9d55d36e1ef2d9b3cce2ce7b09615.png' title='(F+G)[U] = F[U] + G[U]' alt='(F+G)[U] = F[U] + G[U]' align='middle' /><br />
(where the second + is the coproduct — i.e. disjoint union — of sets)</p>
<p>In the power series, we get <img src='/latexrender/pictures/66cb1c86460c5b712cc3ba8b2a0d173b.png' title='(F+G)(x) = F(x) + G(x)' alt='(F+G)(x) = F(x) + G(x)' align='middle' />.</p>
<p>Examples: We may define the species of all non-empty sets <img src='/latexrender/pictures/335d135de25fe2dbf0ccd0f20e0150e1.png' title='E_+' alt='E_+' align='middle' /> by<br />
<img src='/latexrender/pictures/d3315d79ecf2826aaf6b198de80e58d7.png' title='E = 1 + E_+' alt='E = 1 + E_+' align='middle' /><br />
This kind of functional equations is where the theory of species starts to really <em>shine</em>.</p>
<h3>Multiplication</h3>
<p>A tricoloring of a set is a subdivision of the set into three disjoint subsets covering the original set. The number of tricolorings of size n is<br />
<img src='/latexrender/pictures/2cfc95b03d7d4f37d4b7410b9361c214.png' title='\sum_{i+j+k=n} \#\text{sets of size i}\cdot\#\text{sets of size j}\cdot\#\text{sets of size k}' alt='\sum_{i+j+k=n} \#\text{sets of size i}\cdot\#\text{sets of size j}\cdot\#\text{sets of size k}' align='middle' /></p>
<p>A permutation fixes some set of points. The permutation restricted to the non-fixed points is a <em>derangement</em>. Total number of permutations on n elements is<br />
<img src='/latexrender/pictures/475edeb2b536c63ecf62bc9221c06f10.png' title='\sum_{i+j=n}\#\text{sets of size i}\cdot\#\text{derangements of size j}' alt='\sum_{i+j=n}\#\text{sets of size i}\cdot\#\text{derangements of size j}' align='middle' /></p>
<p>In both of these cases, the total generating series is a product of the component series, and we end up defining<br />
<img src='/latexrender/pictures/f05a2036cc62d20e8b6c8a7262f09461.png' title='F\cdot G[U] = \{(f,g): f\in F[U_1], g\in G[U_2], U_1\cap U_2 = \emptyset, U_1\cup U_2 = U\}' alt='F\cdot G[U] = \{(f,g): f\in F[U_1], g\in G[U_2], U_1\cap U_2 = \emptyset, U_1\cup U_2 = U\}' align='middle' /><br />
So <img src='/latexrender/pictures/25b126e16d73bffde96f15011ec62ba6.png' title='F\cdot G[U] = \sum_{U_1,U_2\text{ decompose }U} F[U_1]\times G[U_2]' alt='F\cdot G[U] = \sum_{U_1,U_2\text{ decompose }U} F[U_1]\times G[U_2]' align='middle' />.</p>
<p>Thus, tricolorings are <img src='/latexrender/pictures/77d013a0d46948384f8cd9b41535b43c.png' title='E\cdot E\cdot E' alt='E\cdot E\cdot E' align='middle' /> and permutations are <img src='/latexrender/pictures/65637937dfc1372e746af745b30dabe8.png' title='S = E\cdot Der' alt='S = E\cdot Der' align='middle' />, where the set is that of fixed points, and the derangement captures the actual action of the permutation.</p>
<h3>Composition</h3>
<p>Endofunctions of sets decompose in their actions on the points as cycles or directed trees leading in to these cycles.</p>
<p>Since a collection of disjoint cycles corresponds to a permutation, we can consider such endofunctions to be permutations decorated with rooted trees attached to points of the permutations; or even permutations of rooted trees.</p>
<p>To form such a structure on a set U, we&#8217;d first partition U into subsets, put the structure of a rooted tree on each subset, and then the structure of a permutation on the set of these subsets.</p>
<p>Thus, the number of such structures on n elements is<br />
<img src='/latexrender/pictures/335e2e52de4ab24686357d7fff2b2b15.png' title='\sum_{r\leq n}\sum_{\sum_{k=1}^n i_k = n} \#\tex{permutations on [r]}\cdot\prod_{k=1}^r\#\text{rooted trees on [i_k]}' alt='\sum_{r\leq n}\sum_{\sum_{k=1}^n i_k = n} \#\tex{permutations on [r]}\cdot\prod_{k=1}^r\#\text{rooted trees on [i_k]}' align='middle' /></p>
<p>This corresponds to the power series <img src='/latexrender/pictures/e0411f63150f22a2f99be1510b5910f0.png' title='S(A(x))' alt='S(A(x))' align='middle' />, and we write, in general, <img src='/latexrender/pictures/31029fa092055be1deacf9e244f20333.png' title='F\circ G[U]' alt='F\circ G[U]' align='middle' /> for the species of F-structures of G-structures on subsets.</p>
<p><strong>Examples</strong>:<br />
A = X·E(A)<br />
L = 1 + X·L<br />
B = 1 + X·B·B</p>
<h3>Pointing</h3>
<p>Picking out a single point in a structure on n points can be done in precisely n ways.</p>
<p>Thus the corresponding generating function will be<br />
<img src='/latexrender/pictures/149891bfc400f34cdb0f99d080acc7ef.png' title='\sum n\cdot f_n\cdot\frac{x^n}{n!}' alt='\sum n\cdot f_n\cdot\frac{x^n}{n!}' align='middle' /><br />
for f-structures with a single label distinguished.</p>
<p>Since we&#8217;re working with exponential power series, we may notice that<br />
<img src='/latexrender/pictures/c561d318629404536b769f934f360554.png' title='\frac{\partial}{\partial x} \sum f_n\frac{x^n}{n!} = \sum f_{n+1}\frac{x^n}{n!}' alt='\frac{\partial}{\partial x} \sum f_n\frac{x^n}{n!} = \sum f_{n+1}\frac{x^n}{n!}' align='middle' /><br />
and thus that derivatives are shifts.<br />
Furthermore, <img src='/latexrender/pictures/be3a9d4b57954e8b767df9234c2529b4.png' title='x\cdot\sum f_n\frac{x^n}{n!} = \sum f_n\frac{x^{n+1}}{n!} = \sum f_{n-1}n\cdot{x^n}{n!}' alt='x\cdot\sum f_n\frac{x^n}{n!} = \sum f_n\frac{x^{n+1}}{n!} = \sum f_{n-1}n\cdot{x^n}{n!}' align='middle' /><br />
so that the generating function for F-structures with a single distinguished are<br />
<img src='/latexrender/pictures/594ef9019767eed975d7e51efbddf20a.png' title='F^\bullet(x) = x\cdot\frac{\partial}{\partial x}F(x)' alt='F^\bullet(x) = x\cdot\frac{\partial}{\partial x}F(x)' align='middle' /></p>
<p>In species, this process is called pointing.</p>
<p>In functional programming, Conor McBride related this construction to Huet&#8217;s Zipper datatypes.</p>
<p>As it turns out, many of the constructions for species make eminent sense outside the category <img src='/latexrender/pictures/e19c41413e1b974679b02bd79d5d494c.png' title='\mathbb B' alt='\mathbb B' align='middle' />. In fact, species in Hask are known to programming language researchers as <em>container datatypes</em> and the whole calculus translates relatively cleanly.</p>
<p>Functional equations translate to the standard new data type definitions in Haskell.</p>
<p><strong>Examples</strong>:<br />
L = 1 + X·L<br />
<code><br />
data List a = Nil | Cons a (List a)<br />
</code></p>
<p>B = 1 + X·B·B<br />
<code><br />
data BinaryTree a = Leaf | Node (BinaryTree a) a (BinaryTree a)<br />
</code></p>
<p>A = X·E(A)<br />
<code><br />
data RootedTree a = Node a (Set (RootedTree a))<br />
</code><br />
usually, we simulate the Set here by a List. If we need for our rooted trees to be planar, we can in fact impose a Linear Order structure instead, and get something like<br />
Ap = X·L(Ap)</p>
<p>The species interpretation of <img src='/latexrender/pictures/4d6c379f66675645b3ffe28a15306857.png' title='\frac{\partial}{\partial x}' alt='\frac{\partial}{\partial x}' align='middle' /> corresponding to leaving a hole in the structure carries over cleanly, so that <img src='/latexrender/pictures/27f5948c4a69349055a73e917f5f5b6e.png' title='\frac{\partial}{\partial x}T' alt='\frac{\partial}{\partial x}T' align='middle' /> is the type of T-with-a-hole.</p>
<h2>Two derivatives of lists</h2>
<p>We can deal with  <img src='/latexrender/pictures/12b5d0430c70edf45c18de84a4609c6b.png' title='\frac{\partial}{\partial x}L' alt='\frac{\partial}{\partial x}L' align='middle' /> in two different ways:</p>
<p>1.<br />
DL = D(1+X·L) = D1 + D(X·L) = 0 + DX·L+X·DL<br />
and thus<br />
DL-X·DL = 1·L<br />
so (1-X)·DL = L<br />
and thus<br />
DL = L·1/(1-X)</p>
<p>Now, from L=1+X·L follows by a similar cavalier use of subtraction and division — which, by the way, in species theory is captured by the idea of a <em>virtual species</em>, and dealt with relatively cleanly — that<br />
L = 1+X·L<br />
so<br />
L-X·L = 1<br />
and thus<br />
(1-X)·L = 1<br />
so<br />
L = 1/(1-X)</p>
<p>Thus, we can conclude that<br />
DL = L·1/(1-X) = L·L<br />
and thus, a list with a hole is a pair of lists: the stuff before the hole and the stuff after the hole.</p>
<p>2.<br />
We could, instead of using implicit differentiation, as in 1, attack the derivation we had of<br />
L = 1/(1-X) = 1+X+X·X+X·X·X+…</p>
<p>Indeed,<br />
DL = D(1/(1-X)) = D(1+X+X·X+…) = 0+1+2X+3X·X+…<br />
which we can observe factors as<br />
= (1+X+X·X+X·X·X+…)·(1+X+X·X+X·X·X+…) = L·L</p>
<p>Or we can just use the division rule<br />
DL = D(1/(1-X)) = D(1/u)·D(1-X) = -1/(u·u)·(-1) = 1/[(1-X)·(1-X)] = L·L</p>
<h2>Gröbner bases for operads</h2>
<p>All of this becomes relevant to the implementation of Buchberger&#8217;s algorithm on shuffle operads (see Dotsenko—Khoroshkin and Dotsenko—Vejdemo-Johansson)  in the step where the S-polynomials (and thereby also the reductions) are defined. With a common multiple defined, we need some way to extend the modifications that take the initial term to the common multiple to the rest of that term.</p>
<p>For this, it turns out, that the derivative of the tree datatype used provides theoretical guarantees that only partially filled in trees of the right size, with holes the right size, can be introduced; and also provides an easy and relatively efficient algorithm for contructing the hole-y trees and later filling in the holes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2010/12/species-derivatives-of-types-and-grobner-bases-for-operads/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Stanford] MATH 198: Category Theory and Functional Programming</title>
		<link>http://blog.mikael.johanssons.org/archive/2009/08/stanford-math-198-category-theory-and-functional-programming/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2009/08/stanford-math-198-category-theory-and-functional-programming/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 06:19:27 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Category theory]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Teaching]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=226</guid>
		<description><![CDATA[Category theory, with an origin in algebra and topology, has found use in recent decades for computer science and logic applications. Possibly most clearly, this is seen in the design of the programming language Haskell &#8211; where the categorical paradigm suffuses the language design, and gives rise to several of the language constructs, most prominently [...]]]></description>
			<content:encoded><![CDATA[<p>Category theory, with an origin in algebra and topology, has found use in recent decades for computer science and logic applications. Possibly most clearly, this is seen in the design of the programming language Haskell &#8211; where the categorical paradigm suffuses the language design, and gives rise to several of the language constructs, most prominently the Monad.</p>
<p>In this course, we will teach category theory from first principles with an eye towards its applications to and correspondences with Haskell and the theory of functional programming. We expect students to previously or currently be taking CS242 and to have some level of mathematical maturity. We also expect students to have had contact with linear algebra and discrete mathematics in order to follow the motivating examples behind the theory expounded.</p>
<p>Wednesdays at 4.15.</p>
<p>Online notes will appear successively on the Haskell wiki on http://haskell.org/haskellwiki/User:Michiexile/MATH198</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2009/08/stanford-math-198-category-theory-and-functional-programming/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Soliciting advice</title>
		<link>http://blog.mikael.johanssons.org/archive/2009/07/soliciting-advice/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2009/07/soliciting-advice/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 14:28:55 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Category theory]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Teaching]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=224</guid>
		<description><![CDATA[Dear blogosphere, come this fall, I shall be teaching. My first lecture course, ever. The subject shall be on introducing Category Theory from the bottom up, in a manner digestible for Computer Science Undergraduates who have seen Haskell and been left wanting more from that contact. And thus comes my question to you all: what [...]]]></description>
			<content:encoded><![CDATA[<p>Dear blogosphere, </p>
<p>come this fall, I shall be teaching. My first lecture course, ever.</p>
<p>The subject shall be on introducing Category Theory from the bottom up, in a manner digestible for Computer Science Undergraduates who have seen Haskell and been left wanting more from that contact.</p>
<p>And thus comes my question to you all: what would you like to see in such a course? Is there any advice you want to give me on how to make the course awesome?</p>
<p>The obvious bits are obvious. I shall have to discuss categories, functors, (co)products, (co)limits, monads, monoids, adjoints, natural transformations, the Curry-Howard isomorphism, the Hom-Tensor adjunction, categorical interpretation of data types. And all of it with explicit reference to how all these things influence Haskell, as well as plenty of mathematical examples.</p>
<p>But what ideas can you give me to make this greater than I&#8217;d make it on my own?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2009/07/soliciting-advice/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Mapping zipcodes in R</title>
		<link>http://blog.mikael.johanssons.org/archive/2009/05/mapping-zipcodes-in-r/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2009/05/mapping-zipcodes-in-r/#comments</comments>
		<pubDate>Wed, 13 May 2009 14:51:51 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[R]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=209</guid>
		<description><![CDATA[I started fiddling around with R again, and ended up playing with a zipcode database. So, first I downloaded the zipcode database at Mapping Hacks, and unpacked the zipfile in my working directory. Then, I loaded the data into R &#62; zips &#60;- read.table(&#34;zipcode.csv&#34;,sep=&#34;,&#34;,quote=&#34;\&#34;&#34;,header=TRUE) &#62; names(zips) [1] &#34;zip&#34; &#160; &#160; &#160; &#34;city&#34; &#160; &#160; &#160;&#34;state&#34; [...]]]></description>
			<content:encoded><![CDATA[<p>I started fiddling around with R again, and ended up playing with a zipcode database.</p>
<p>So, first I downloaded the zipcode database at <a href="http://www.mappinghacks.com/data">Mapping Hacks</a>, and unpacked the zipfile in my working directory. </p>
<p>Then, I loaded the data into R</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; zips &lt;- read.table(&quot;zipcode.csv&quot;,sep=&quot;,&quot;,quote=&quot;\&quot;&quot;,header=TRUE)<br />
&gt; names(zips)<br />
[1] &quot;zip&quot; &nbsp; &nbsp; &nbsp; &quot;city&quot; &nbsp; &nbsp; &nbsp;&quot;state&quot; &nbsp; &nbsp; &quot;latitude&quot; &nbsp;&quot;longitude&quot;<br />
[6] &quot;timezone&quot; &nbsp;&quot;dst&quot; &nbsp; &nbsp; &nbsp;<br />
&nbsp;</div>
<p>So, now I have an R frame containing a lot of US cities, their geographical coordinates, and their zip codes. So we can start playing with the plot command! After rooting around a bit, I ended up settling on the smallest footprint plot dot I could make R produce, by setting the option <span lang="R">pch=20</span> in the plot options. Hence, I ended up with a command basically like this:</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; plot(zips$longitude,zips$latitude,type=&quot;p&quot;,col=((zips$zip/10000)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.1)<br />
&nbsp;</div>
<p>where the +1 after the modulus is to make even 0-values plot, and the cex parameter sets the point size to something small and pretty.<br />
<a href="http://blog.mikael.johanssons.org/wp-content/usZip1.png"><img src="http://blog.mikael.johanssons.org/wp-content/usZip1.png" alt="First digit of the USPS zip code" width="400" /></a></p>
<p>We can continue this, tweaking the divisor to extract all the other digits of the zip code, and we end up getting:</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; plot(zips$longitude,zips$latitude,type=&quot;p&quot;,col=((zips$zip/1000)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.1)<br />
&nbsp;</div>
<p>and the result<br />
<a href="http://blog.mikael.johanssons.org/wp-content/usZip2.png"><img src="http://blog.mikael.johanssons.org/wp-content/usZip2.png" alt="Second digit of the USPS zip code" width="400" /></a></p>
<div class="dean_ch" style="white-space: wrap;">
&gt; plot(zips$longitude,zips$latitude,type=&quot;p&quot;,col=((zips$zip/100)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.1)<br />
&nbsp;</div>
<p>and the result<br />
<a href="http://blog.mikael.johanssons.org/wp-content/usZip3.png"><img src="http://blog.mikael.johanssons.org/wp-content/usZip3.png" alt="Third digit of the USPS zip code" width="400" /></a></p>
<div class="dean_ch" style="white-space: wrap;">
&gt; plot(zips$longitude,zips$latitude,type=&quot;p&quot;,col=((zips$zip/10)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.1)<br />
&nbsp;</div>
<p>and the result<br />
<a href="http://blog.mikael.johanssons.org/wp-content/usZip4.png"><img src="http://blog.mikael.johanssons.org/wp-content/usZip4.png" alt="Fourth digit of the USPS zip code" width="400" /></a></p>
<p>and finally</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; plot(zips$longitude,zips$latitude,type=&quot;p&quot;,col=((zips$zip/1)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.1)<br />
&nbsp;</div>
<p>and the result<br />
<a href="http://blog.mikael.johanssons.org/wp-content/usZip5.png"><img src="http://blog.mikael.johanssons.org/wp-content/usZip5.png" alt="Fifth digit of the USPS zip code" width="400" /></a></p>
<p>And then, of course, we can zoom in on data too. So we can do things like extracting Californian zip codes</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; cazips &lt;- zips[zips$state == &quot;CA&quot;,]<br />
&gt; plot(cazips$longitude,cazips$latitude,type=&quot;p&quot;,col=((cazips$zip/1000)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.5)<br />
&nbsp;</div>
<p>to get<br />
<a href="http://blog.mikael.johanssons.org/wp-content/caZip2.png"><img src="http://blog.mikael.johanssons.org/wp-content/caZip2.png" alt="Second digit of the Californian USPS zip code" width="400" /></a><br />
or, we could extract New York zip codes:</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; nyzips &lt;- zips[zips$state == &quot;NY&quot;,]<br />
&gt; plot(nyzips$longitude,nyzips$latitude,type=&quot;p&quot;,col=((nyzips$zip/100)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=0.5)<br />
&nbsp;</div>
<p><a href="http://blog.mikael.johanssons.org/wp-content/nyZip3.png"><img src="http://blog.mikael.johanssons.org/wp-content/nyZip3.png" alt="Third digit of the New York USPS zip code" width="400" /></a><br />
or even extract, say, the zip codes starting with 10 or 11, covering New York City and surroundings and take a closer look</p>
<div class="dean_ch" style="white-space: wrap;">
&gt; ny10zips &lt;- nyzips[nyzips$zip&lt;12000,]<br />
&gt; ny10zips &lt;- ny10zips[ny10zips$zip&gt;9999,]<br />
&gt; plot(ny10zips$longitude,ny10zips$latitude,type=&quot;p&quot;,col=((ny10zips$zip/100)%%10)+1,pch=20,axes=FALSE,xlab=&quot;&quot;,ylab=&quot;&quot;,cex=1.0)<br />
&nbsp;</div>
<p><a href="http://blog.mikael.johanssons.org/wp-content/ny10Zip3.png"><img src="http://blog.mikael.johanssons.org/wp-content/ny10Zip3.png" alt="Third digit of the USPS zip codes 10xxx and 11xxx" width="400" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2009/05/mapping-zipcodes-in-r/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Gröbner bases for Operads — or what I did in my vacation</title>
		<link>http://blog.mikael.johanssons.org/archive/2009/05/grobner-bases-for-operads-or-what-i-did-in-my-vacation/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2009/05/grobner-bases-for-operads-or-what-i-did-in-my-vacation/#comments</comments>
		<pubDate>Fri, 08 May 2009 17:28:57 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Operads and PROPs]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=206</guid>
		<description><![CDATA[This post is to give you all a very swift and breakneck introduction to Gröbner bases; not trying to be a nice and soft introduction, but much more leading up to announcing the latest research output from me. Recall how you would run the Gaussian algorithm on a matrix. You&#8217;d take the leftmost upmost non-zero [...]]]></description>
			<content:encoded><![CDATA[<p>This post is to give you all a very swift and breakneck introduction to Gröbner bases; not trying to be a nice and soft introduction, but much more leading up to announcing the latest research output from me.</p>
<p>Recall how you would run the Gaussian algorithm on a matrix. You&#8217;d take the leftmost upmost non-zero entry, divide its row by its value, and then use that row to eliminate anything in the corresponding column.</p>
<p>Once we have the matrix on echelon form, we can then do lots of things with it. Importantly, we can use substitution using the leading terms to do equation system solving.</p>
<p>The starting point for the theory of Gröbner bases was that the same method could be used &#8211; with some modification &#8211; to produce something from a bunch of polynomials that ends up being as useful as a row-reduced echelon form.</p>
<p>Basically, the central theorem-definition of Gröbner bases (by Buchberger, named for his thesis advisor Gröbner), says that a Gröbner basis for some ideal in some polynomial ring is a bunch of generators for that ideal such that if we do polynomial division of any element of the polynomial in the ring with the generators, one after the other, until no more divisions could be performed, then what we get out of it all is uniquely determined.</p>
<p>This need not necessarily be the case, even to begin with &#8211; we could get weird loops and various kinds of bad behaviour that screws up the concept of dividing, with remainder, by a whole bunch of polynomials. Having a Gröbner basis means this is no longer a problem.</p>
<p>The important bit of the theorem is that we can GET a Gröbner basis by just iteratively trying out combinations of the generators, trying to find overlaps of the leading terms, and generating &#8220;bad examples&#8221;. Any bad example that doesn&#8217;t get completely reduced to 0 by division by the generators is also needed to complete the Gröbner basis, and by adjoining it we grow our generating set, but not the things it generates. And the method works by growing the generating set until anything we can build out of two of the generators really will reduce completely to 0.</p>
<p>And, the central theorem says, if THIS works, then reduction works in general, and we have a tool as good for solving systems of polynomial equations as the echelon form is for linear equation systems.</p>
<h2>Losing commutativity</h2>
<p>The next interesting step is to look at non-commutative polynomial rings. Here, we suddenly have a deep theoretic issue popping up. We know that the <i>word problem</i> for monoids &#8211; i.e. whether a specific string can be reduced with rewriting rules to an empty string &#8211; is unsolvable in general. It hooks up to Turing machines and the limits of theoretical computer science, but in essence we can encode problems as Gröbner basis computations for non-commutative algebras that we know cannot possibly be solved in finite time.</p>
<p>So we cannot hope for the situation to be as good as for commutative algebras. However, there is a theorem floating around &#8211; the Diamond lemma by Bergman &#8211; that says that if we DO get a Gröbner basis computation that halts in finite time, then all the good things that we had in the commutative case &#8211; such as reductions modulo the generators being well defined &#8211; hold for the things we&#8217;ve computed. In other words, the only thing that could go wrong would be that the computation of the Gröbner basis doesn&#8217;t finish in finite time.</p>
<h2>Operads</h2>
<p>Now, what I really wanted to talk about was <i>operads</i>.</p>
<p>Here, an operad is a collection {O(n) : n?1} of vector spaces with permutations attached to them. Hence, for each n, there is a map S<sub>n</sub> &larr; Hom(O(n),O(n)), or in other words, we can apply any permutation of n things to any element in the component O(n) and get something back out of it.</p>
<p>Furthermore, an operad O = {O(n)} has defined on it structure operations. These behave like the composition of multilinear functions &#8211; so we have a way of plugging one function into another:<br />
f(a1,a2,&#8230;,g(ai,&#8230;,aj),&#8230;,an)<br />
and this composition is associative, so the order we figure out some sequence of compositions doesn&#8217;t matter.</p>
<p>These gadgets show up in modern approaches to universal algebra like questions, and also all over the place in topology; some of the earliest instances were from homotopy theory. </p>
<p>Recently, Dotsenko and Khoroshkin released a paper on <a href=http://arxiv.org/abs/0812.4069>Gröbner bases for operads</a>. In the paper, they figure out a way to find the kind of canonical and ordered basis that you need in order to mimic the whole workflow of Gröbner bases above; and specified how one should go about producing a Diamond Lemma for operads. It turns out that Gröbner bases would be useful to prove operads to be Koszul &#8211; something I won&#8217;t discuss here, but which is important in the operad theory context.</p>
<p>Basically, instead of working in a polynomial ring on some set of variables, we start out with out variables in one of these graded sets {V(n)}. Then we can build rooted trees, whose internal vertices of degree n+1 are labeled by elements from V(n).</p>
<p>The vector space spanned by all such trees forms an operad where the composition operation works by taking a tree and attaching the root to the leaf numbered by whatever position we need to compose at. </p>
<p>The resulting construction is the free operad on the generating set and takes the role that the polynomial ring had in the previous examples. And what Dotsenko and Khoroshkin pointed out was that if we restrict the kinds of actions we allow from permutations on these trees somewhat, we end up with something that has exactly one representative that fits in the restricted context for each tree that occurs as a basis element of the free operad.</p>
<p>So we can impose some sort of ordering on these trees, and use them to mimic the Diamond lemma.</p>
<p>Indeed, what we end up doing is forming the overlaps between leading terms by finding trees that parts of the trees from the leading terms from pairs of operad elements can embed into, and using the resulting procedure to build the same kind of  bad cases we need to test for Buchberger&#8217;s algorithm.</p>
<p>And again, it turns out that while we may not always get an answer within finite time, if we&#8217;re lucky then the answer we DO get has all the properties we could dream of. And not only that &#8211; all the previous kinds of Gröbner bases embed as special cases of doing it this way.</p>
<p>I heard of this, and got my hands on the paper, when I first arrived in CIRM in Luminy, outside Marseille, for 2 weeks of operad theory with a master&#8217;s course and a conference on the subject. And I got so excited &#8211; once upon a time this was essentially my proposal for PhD thesis project &#8211; that I decided to sit down and code the whole thing up right away!</p>
<p>And code away I did. Once the two weeks were gone, with the valuable help from Vladimir Dotsenko and Eric Hoffbeck, I had ended up with a working implementation in Haskell of the whole paradigm. It&#8217;s now <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Operads">available from the HackageDB</a>, and runs at least in GHC 6.8 and 6.10:</p>
<div class="dean_ch" style="white-space: wrap;">
ghci -cpp Math.Operad<br />
GHCi, version <span class="nu0">6.10</span><span class="nu0">.1</span>: http://www.haskell.org/ghc/ &nbsp;:? for help<br />
Loading package ghc-prim &#8230; linking &#8230; done.<br />
Loading package integer &#8230; linking &#8230; done.<br />
Loading package base &#8230; linking &#8230; done.<br />
<span class="br0">&#91;</span><span class="nu0">1</span> <span class="kw1">of</span> <span class="nu0">6</span><span class="br0">&#93;</span> Compiling Math.Operad.PPrint <span class="br0">&#40;</span> Math/Operad/PPrint.hs, interpreted <span class="br0">&#41;</span><br />
<span class="br0">&#91;</span><span class="nu0">2</span> <span class="kw1">of</span> <span class="nu0">6</span><span class="br0">&#93;</span> Compiling Math.Operad.OrderedTree <span class="br0">&#40;</span> Math/Operad/OrderedTree.hs, interpreted <span class="br0">&#41;</span><br />
<span class="br0">&#91;</span><span class="nu0">3</span> <span class="kw1">of</span> <span class="nu0">6</span><span class="br0">&#93;</span> Compiling Math.Operad.Map &nbsp;<span class="br0">&#40;</span> Math/Operad/Map.hs, interpreted <span class="br0">&#41;</span><br />
<span class="br0">&#91;</span><span class="nu0">4</span> <span class="kw1">of</span> <span class="nu0">6</span><span class="br0">&#93;</span> Compiling Math.Operad.MapOperad <span class="br0">&#40;</span> Math/Operad/MapOperad.hs, interpreted <span class="br0">&#41;</span><br />
<span class="br0">&#91;</span><span class="nu0">5</span> <span class="kw1">of</span> <span class="nu0">6</span><span class="br0">&#93;</span> Compiling Math.Operad.OperadGB <span class="br0">&#40;</span> Math/Operad/OperadGB.hs, interpreted <span class="br0">&#41;</span><br />
<span class="br0">&#91;</span><span class="nu0">6</span> <span class="kw1">of</span> <span class="nu0">6</span><span class="br0">&#93;</span> Compiling Math.Operad &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span> Math/Operad.hs, interpreted <span class="br0">&#41;</span><br />
Ok, modules loaded: Math.Operad, Math.Operad.OperadGB, Math.Operad.OrderedTree, Math.Operad.PPrint, Math.Operad.MapOperad, Math.Operad.Map.</p>
<p>*Math.Operad&gt; <span class="kw1">let</span> v = corolla <span class="nu0">2</span> <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">2</span><span class="br0">&#93;</span><br />
Loading package mtl<span class="nu0">-1.1</span><span class="nu0">.0</span><span class="nu0">.2</span> &#8230; linking &#8230; done.<br />
*Math.Operad&gt; <span class="kw1">let</span> g1t1 = nsCompose <span class="nu0">1</span> v v <br />
Loading package syb &#8230; linking &#8230; done.<br />
Loading package array<span class="nu0">-0.2</span><span class="nu0">.0</span><span class="nu0">.0</span> &#8230; linking &#8230; done.<br />
Loading package containers<span class="nu0">-0.2</span><span class="nu0">.0</span><span class="nu0">.0</span> &#8230; linking &#8230; done.<br />
*Math.Operad&gt; <span class="kw1">let</span> g1t2 = nsCompose <span class="nu0">2</span> v v<br />
*Math.Operad&gt; <span class="kw1">let</span> g2t2 = shuffleCompose <span class="nu0">1</span> <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">3</span>,<span class="nu0">2</span><span class="br0">&#93;</span> v v<br />
*Math.Operad&gt; <span class="kw1">let</span> g1 = <span class="br0">&#40;</span>oet g1t1<span class="br0">&#41;</span> + <span class="br0">&#40;</span>oet g1t2<span class="br0">&#41;</span> :: FreeOperad <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Integer"><span class="kw4">Integer</span></a><br />
*Math.Operad&gt; <span class="kw1">let</span> g2 = <span class="br0">&#40;</span>oet g2t2<span class="br0">&#41;</span> &#8211; <span class="br0">&#40;</span>oet g1t2<span class="br0">&#41;</span> :: FreeOperad <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Integer"><span class="kw4">Integer</span></a><br />
*Math.Operad&gt; <span class="kw1">let</span> ac = <span class="br0">&#91;</span>g1,g2<span class="br0">&#93;</span><br />
*Math.Operad&gt; :set +s<br />
*Math.Operad&gt; <span class="kw1">let</span> acGB = operadicBuchberger ac<br />
<span class="br0">&#40;</span><span class="nu0">0.00</span> secs, <span class="nu0">524996</span> bytes<span class="br0">&#41;</span><br />
*Math.Operad&gt; pP acGB<br />
<span class="br0">&#91;</span><br />
<span class="nu0">+1</span> % <span class="nu0">1</span>*m2<span class="br0">&#40;</span><span class="nu0">1</span>,m2<span class="br0">&#40;</span><span class="nu0">2</span>,m2<span class="br0">&#40;</span><span class="nu0">3</span>,<span class="nu0">4</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>,</p>
<p><span class="nu0">+1</span> % <span class="nu0">1</span>*m2<span class="br0">&#40;</span>m2<span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">2</span><span class="br0">&#41;</span>,<span class="nu0">3</span><span class="br0">&#41;</span><br />
<span class="nu0">+1</span> % <span class="nu0">1</span>*m2<span class="br0">&#40;</span><span class="nu0">1</span>,m2<span class="br0">&#40;</span><span class="nu0">2</span>,<span class="nu0">3</span><span class="br0">&#41;</span><span class="br0">&#41;</span>,</p>
<p><span class="nu0">+1</span> % <span class="nu0">1</span>*m2<span class="br0">&#40;</span>m2<span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">3</span><span class="br0">&#41;</span>,<span class="nu0">2</span><span class="br0">&#41;</span><br />
+<span class="br0">&#40;</span><span class="nu0">-1</span><span class="br0">&#41;</span> % <span class="nu0">1</span>*m2<span class="br0">&#40;</span><span class="nu0">1</span>,m2<span class="br0">&#40;</span><span class="nu0">2</span>,<span class="nu0">3</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
<span class="br0">&#40;</span><span class="nu0">0.41</span> secs, <span class="nu0">55184352</span> bytes<span class="br0">&#41;</span><br />
&nbsp;</div>
<p>And we see here that with the particular set of generators given, namely using m2 as the variable, and for a generating set, we pick<br />
m2(m2(x1,x2),x3) + m2(x1,m2(x2,x3))<br />
and<br />
m2(m2(x1,x3),x2) &#8211; m2(x1,m2(x2,x3))</p>
<p>we get a Gröbner basis almost instantly containing additionally the generator<br />
m2(x1,m2(x2,m2(x3,x4)))</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2009/05/grobner-bases-for-operads-or-what-i-did-in-my-vacation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>J, or how I learned to stop worrying and love the matrix</title>
		<link>http://blog.mikael.johanssons.org/archive/2008/12/j-or-how-i-learned-to-stop-worrying-and-love-the-matrix/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2008/12/j-or-how-i-learned-to-stop-worrying-and-love-the-matrix/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 07:50:17 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[J]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=186</guid>
		<description><![CDATA[Or actually, I haven&#8217;t quite yet. But, out of a whim, I downloaded J and started to play with it while reading this set of neat notes on Functional Programming and J. And &#8230; well &#8230; my reaction so far is kinda &#8220;Buh!? What the *** just happened there?&#8221; The first example I ran across, [...]]]></description>
			<content:encoded><![CDATA[<p>Or actually, I haven&#8217;t quite yet.</p>
<p>But, out of a whim, I downloaded <a href="http://www.jsoftware.com">J</a> and started to play with it while reading <a href="http://www.cs.trinity.edu/~jhowland/math-talk/functional1/">this</a> set of neat notes on Functional Programming and J.</p>
<p>And &#8230; well &#8230; my reaction so far is kinda &#8220;Buh!? What the *** just happened there?&#8221;</p>
<p>The first example I ran across, tried to read, and finally managed to is the following:</p>
<div class="dean_ch" style="white-space: wrap;">
+/ , 5 = q: &gt;: i. 100<br />
&nbsp;</div>
<p>This snippet is supposed to tell us how many 0s are trailing 100!. To get at this, we first need to figure out what, exactly, is done here. First observation is that 100! is the product of all integers from 1 to 100. The second is that the number of 0s trailing this is the same as the lower of the orders of 2 and 5, respectively, dividing 100!. Which, in turn is the lower of the numbers of 2s and 5s occurring in the totality of all prime decompositions of all the integers from 1 to 100.</p>
<p>Now, if <img src='/latexrender/pictures/ebc139755bf12a13ba04795b06a8123a.png' title='k\cdot 5^n&lt;100' alt='k\cdot 5^n&lt;100' align='middle' />, then certainly <img src='/latexrender/pictures/2f4c31ed665290ef6adc71ebca6d6ad9.png' title='k\cdot 2^n&lt;100' alt='k\cdot 2^n&lt;100' align='middle' />, so the sum of orders of 2 is guaranteed to be larger than the sum of orders of 5, so it is enough to count the number of 5s dividing any of the numbers along the way. And THIS is what the program above computes.</p>
<p>Next thing to figure out is how it does this. It turns out, after some experimenting, that the best way of reading this is to go through from right to left and figure out what it all does. All the functions we're looking at end up being applied in a <i>monadic</i> fashion &#8211; which means something completely different in J than in Haskell &#8211; here it means that the function gets applied to a single argument. So, here goes:<br />
<code lang="J">i. n</code> lists the first n integers, starting at 0. So <code lang="J">i. 100</code> is the 1&#215;100 matrix containing 0, 1, 2, &#8230;, 99.<br />
<code lang="J">&gt;:</code>, when applied monadically, increments each element it sees by one. So <code lang="J">&gt;: i. 100</code> is the 1&#215;100 matrix containing 1, 2, 3, &#8230;, 100.<br />
<code lang="J">q:</code> yields a prime factorization of the integers it sees. So from <code lang="J">q: &gt;: i. 100</code> we get a matrix where each row carries the primes dividing the row number, with 0 padding at the end.<br />
Then we see the one <i>dyadic</i> (as opposed to monadic) application in this program. <code lang="J">5 = mtx</code> yields a matrix of the same shape as mtx, but with a 1 whenever the corresponding entry is a 5, and 0 otherwise. So <code lang="J">5 = q: &gt;: i. 100</code> picks out the entries in all the prime factorizations that are equal to 5.<br />
Then <code lang="J">,</code>. This is one of two complementary operators to reshape matrices. <code lang="J">,</code> gets us an 1xn matrix with the same entries, read row by row, from left to right, as we started with &#8211; whereas <code lang="J">n m $ mtx</code> takes the matrix in mtx and builds an nxm matrix out of it. Thus, <code lang="J">, 5 = q: &gt;: i. 100</code> flattens out the matrix with the 0 and 1 we got out above.<br />
And finally, <code lang="J">+/</code> is an example of a J adverb being used. <code lang="J">+</code> is a dyadic function corresponding to, as expected, usual addition. <code lang="J">/</code> is a monadic adverb that takes a dyadic function, and inserts it between all the elements in the following list. This is essentially identical to the Haskell call <code lang="Haskell">foldr</code>. So <code lang="J">+/</code> is more commonly known as &#8220;sum&#8221;. And thus, <code lang="J">+/ , 5 = q: &gt;: i. 100</code> sums up the 0s and 1s produced by picking out all the entries in the prime factorization matrix that are equal to 5, after flattening the matrix. Or, in other words, counts the 1 entries. Which is the same as counting the number of 5s in the prime factorizations of all the integers between 1 and 100.<br />
Note that if we skipped the flattening step given by <code lang="J">,</code> then the application of <code lang="J">+/</code> would have just summed each column in the matrix. So, we would have needed to apply it again to get the total tally.</p>
<p>So far, my impression is essentially that WHOA! That language is compact to the point of insanity. Once you master the vocabulary, it kinda gives the feeling that the system has insane amounts of power &#8211; but the vocabulary is kinda imposing, as is the shift in the way I think about programming. I foresee learning J giving me the same kinds of epiphanies and major brain twists as Haskell did &#8211; so it might well be an appropriate next challenge.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2008/12/j-or-how-i-learned-to-stop-worrying-and-love-the-matrix/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>R and topological data analysis</title>
		<link>http://blog.mikael.johanssons.org/archive/2008/08/r-and-topological-data-analysis/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2008/08/r-and-topological-data-analysis/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 15:38:00 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Homology and Homotopy]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Topology]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=179</guid>
		<description><![CDATA[This is extremely early playing around. It touches on things I&#8217;m going to be working with in Stanford, but at this point, I&#8217;m not even up on toy level. We&#8217;ll start by generating a dataset. Essentially, I&#8217;ll take the trefolium, sample points on the curve, and then perturb each point ever so slightly. idx &#60;- [...]]]></description>
			<content:encoded><![CDATA[<p>This is extremely early playing around. It touches on things I&#8217;m going to be working with in Stanford, but at this point, I&#8217;m not even up on toy level.</p>
<p>We&#8217;ll start by generating a dataset. Essentially, I&#8217;ll take the trefolium, sample points on the curve, and then perturb each point ever so slightly.</p>
<div class="dean_ch" style="white-space: wrap;">
idx &lt;- 1:2000<br />
theta &lt;- idx*2*pi/2000<br />
a &lt;- cos(3*theta)<br />
x &lt;- a*cos(theta)<br />
y &lt;- a*sin(theta)<br />
xper &lt;- rnorm(2000)<br />
yper &lt;- rnorm<br />
xd &lt;- x + xper/100<br />
yd &lt;- y + yper/100<br />
cd &lt;- cbind(xd,yd)<br />
&nbsp;</div>
<p>As a result, we get a dataset that looks like this:<br />
<img src="http://blog.mikael.johanssons.org/wp-content/uploads/2008/08/trifolium_data.png" alt="Trifolium data" /></p>
<p>So, let&#8217;s pick a sample from the dataset. What I&#8217;d really want to do now would be to do the witness complex construction, but I haven&#8217;t figured enough out about how R ticks to do quite that. So we&#8217;ll pick a sample and then build the 1-skeleton of the Rips-Vietoris complex using Euclidean distance between points. This means, we&#8217;ll draw a graph on the dataset with an edge between two sample points whenever they are within &epsilon; from each other.</p>
<p>So we pick a sample from this sample. Every 31 points might be good. (number arrived at by guessing wildly, and drawing the resulting images until they looked pretty enough)</p>
<div class="dean_ch" style="white-space: wrap;">
csamp &lt;- cd[seq(1,dim(csamp)[1],31),]<br />
&nbsp;</div>
<p>We&#8217;d get, from this, the following result:<br />
<img src="http://blog.mikael.johanssons.org/wp-content/uploads/2008/08/trifolium_sample.png" alt="Trifolium sample" /></p>
<p>Now, we&#8217;ll want to build the corresponding skeleton. Let&#8217;s do it for a few different &epsilon;s to demonstrate the difference.</p>
<div class="dean_ch" style="white-space: wrap;">
d &lt;- function(x,y,z,w) { sqrt((x-z)^2+(y-w)^2) }<br />
par(mfrow=c(2,2))<br />
eps &lt;- c(0.05,0.1,0.15,0.2)<br />
cols &lt;- c(&quot;cyan&quot;,&quot;green&quot;,&quot;yellow&quot;,&quot;red&quot;)<br />
for (ei in 1:length(eps)) {<br />
&nbsp; plot(cd,col=&quot;gray&quot;)<br />
&nbsp; points(csamp,col=&quot;blue&quot;)<br />
&nbsp; title(eps[ei])<br />
&nbsp; for (i in 1:dim(csamp)[1]) {<br />
&nbsp; &nbsp; for (j in 1:dim(csamp)[1]) {<br />
&nbsp; &nbsp; &nbsp; x &lt;- csamp[i,1]; y &lt;- csamp[i,2]<br />
&nbsp; &nbsp; &nbsp; z &lt;- csamp[j,1]; w &lt;- csamp[j,2]<br />
&nbsp; &nbsp; &nbsp; e &lt;- eps[ei]<br />
&nbsp; &nbsp; &nbsp; if(d(x,y,z,w) &lt; 2*e) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; segments(x,y,z,w,col=cols[ei])<br />
&nbsp; &nbsp; &nbsp; } else {<br />
&nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; }<br />
&nbsp; }<br />
}<br />
&nbsp;</div>
<p>The result is:<br />
<img src="http://blog.mikael.johanssons.org/wp-content/uploads/2008/08/trifolium_skeleta.png" alt="Trifolium skeleta" /></p>
<p>We notice that as the radius we observe grows, we connect all the loops, but by the time the loops are completely connected, there are also cross connections forming toward the middle. However, with any luck, these cross connections will be so short-lived, in terms of the radii we use, so that the homology classes we extract from the Rips-Vietoris complexes are noticably more persistent.</p>
<p>Doing the corresponding computation relies on me figuring enough out to use the Plex software suite, or writing my own, and thus will be subject of a much later blog post. This one was mainly &#8220;Look &#8211; I use R&#8221; and &#8220;Look &#8211; pretty pictures&#8221;. Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2008/08/r-and-topological-data-analysis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallel and cluster computing with MPI4Py</title>
		<link>http://blog.mikael.johanssons.org/archive/2008/05/parallell-and-cluster-mpi4py/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2008/05/parallell-and-cluster-mpi4py/#comments</comments>
		<pubDate>Sun, 18 May 2008 10:46:20 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Geometry]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Parallel]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/?p=168</guid>
		<description><![CDATA[First off, I&#8217;d ask your pardon for the lull in postings &#8211; this spring has been insane. It has been very much fun &#8211; traveling the world, talking about my research and meeting people I only knew electronically &#8211; and also very intense. To break the lull, I thought I&#8217;d try to pick up what [...]]]></description>
			<content:encoded><![CDATA[<p>First off, I&#8217;d ask your pardon for the lull in postings &#8211; this spring has been insane. It has been very much fun &#8211; traveling the world, talking about my research and meeting people I only knew electronically &#8211; and also very intense.</p>
<p>To break the lull, I thought I&#8217;d try to pick up what I did last summer: parallel computing on clusters. It&#8217;s been a bit of <a href="http://vnoel.wordpress.com/2008/05/03/bye-matlab-hello-python-thanks-sage/">blog chatter</a> about <a href="http://www.sagemath.org">SAGE</a> and how SAGE suddenly has transformed from a Really Good Idea to something that starts to corner out most other systems in usability and flexibility. </p>
<p>Matlab? SciPy bundled with SAGE and the Python integration seems to be at least as good, if not better.<br />
Maple? Mathematica? Maxima? Singular? GAP? SAGE interfaces with all those that it doesn&#8217;t emulate.</p>
<p>And also, it allows you to install and interface with almost anything that has a Python module written. Specifically, a SAGE installation comes complete with OpenMPI and MPI4Py, allowing for multi-processor parallelity &#8211; either on an SMP machine, or on a cluster that runs some sort of MPI system. So, using the Python and <a href="http://mpi4py.scipy.org/">MPI4Py</a> that arrives with SAGE, it should be possible to start experimenting with parallel programming; and the rest of the SAGE integration should make it easy to start playing with, say, parallel algorithms for commutative or homological algebra.</p>
<p>But as a first step, I thought I&#8217;d do a &#8220;Hello world&#8221; for mathematics. Computing the <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot fractal</a>.</p>
<p>Now, a Mandelbrot fractal is reasonably easy to compute: we step through all pixels in our image, and we repeat the transformation <img src='/latexrender/pictures/a4f8194ac63d0fe70e3f3ef3d83e37a7.png' title='z_{n+1} = z_n^2+c' alt='z_{n+1} = z_n^2+c' align='middle' /> for c the complex plane point corresponding to the pixel, and <img src='/latexrender/pictures/788c918479548ce20fcd4df8f0be5e51.png' title='z_0=0' alt='z_0=0' align='middle' />. We see whether this iteration diverges within a limited amount of steps.</p>
<p>I&#8217;m going to, for benchmarking reasons, fix some parameters. I&#8217;ll have a 600&#215;600 picture, spanning the area [-2.5,1.5]x[-2.0,2.0] of <img src='/latexrender/pictures/6a187591d2e75f61bc4068b4527c69ba.png' title='\mathbb R^2 = \mathbb C' alt='\mathbb R^2 = \mathbb C' align='middle' />. I&#8217;ll allow 80 iterations, and after that, I want to see whether the square of the magnitude is larger than 4.0.</p>
<p>At the core of the iteration lies the function</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> step<span class="br0">&#40;</span>z,c<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> z**<span class="nu0">2</span>+c<br />
&nbsp;</div>
<p>and for a specific point <img src='/latexrender/pictures/12fab91887b10b4ccc945c3f03390f91.png' title='c=x+yi' alt='c=x+yi' align='middle' />, we can compute the number of iterations needed with the function</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> point<span class="br0">&#40;</span>c,n,d2<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; zo = <span class="nu0">0.0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; zn = zo<br />
&nbsp; &nbsp; &nbsp; &nbsp; i = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">abs</span><span class="br0">&#40;</span>zn<span class="br0">&#41;</span>**<span class="nu0">2</span> &lt; d2 <span class="kw1">and</span> i&lt;n:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; zn = step<span class="br0">&#40;</span>zo,c<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; zo = zn<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i<span class="nu0">+1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> i<br />
&nbsp;</div>
<p>Repeating this for each point in the span we look at, modified for the granularity our pixels force, and choosing a color for each iteration number, we&#8217;ll get the familiar Mandelbrot fractal. I choose to assign colors using the hue in the <a href="http://en.wikipedia.org/wiki/HSL_and_HSV">HSV color space</a>. This gives us rich, nice colors with a continuous and neat progression through them. So, given the number of iterations at a point, and the maximal number of iterations allowed, we compute the corresponding color by</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> colnorm<span class="br0">&#40;</span><span class="br0">&#40;</span>r,g,b<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span><span class="nu0">255</span>*r<span class="br0">&#41;</span><span class="nu0">-1</span>,<span class="kw2">int</span><span class="br0">&#40;</span><span class="nu0">255</span>*g<span class="br0">&#41;</span><span class="nu0">-1</span>,<span class="kw2">int</span><span class="br0">&#40;</span><span class="nu0">255</span>*b<span class="br0">&#41;</span><span class="nu0">-1</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> col<span class="br0">&#40;</span>n,<span class="kw2">max</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> n == <span class="kw2">max</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> colnorm<span class="br0">&#40;</span><span class="kw3">colorsys</span>.<span class="me1">hsv_to_rgb</span><span class="br0">&#40;</span><span class="nu0">1.0</span>-<span class="kw2">float</span><span class="br0">&#40;</span>n<span class="br0">&#41;</span>/<span class="kw2">max</span>,<span class="nu0">1.0</span>,<span class="nu0">1.0</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>the function <code lang="python">colnorm</code> is in there to convert RGB triples with values in [0,1] to RGB triples with values in [0,255].</p>
<p>And from here it&#8217;s just a matter of interfacing with the right kind of image writing library &#8211; I chose the <a href="http://pythonware.com/products/pil/">PIL library</a> &#8211; and then go through all pixels, computing the color implied at each pixel, and placing it in the image.</p>
<p>Run like this, the benchmark fractal takes some 12 seconds on our workgroup&#8217;s workhorse, and 8 seconds on a single node of the Jena Beowulf cluster. </p>
<p>The resulting fractal is<br />
<img src="http://blog.mikael.johanssons.org/wp-content/mandel.png" alt="Mandelbrot fractal" /></p>
<p>As for parallelization, the Mandelbrot fractal is a typical example of what&#8217;s called an embarrassingly parallel problem: each pixel in an image is completely independent from all other pixels, and so we could just let one single processor loose on each pixel, and get things done a lot faster than if we&#8217;d work through the pixels one after the other.</p>
<p>So, to parallelize it, we&#8217;ll need some way of distributing the work among the processors, and some way of gathering the pieces up once we&#8217;re done. In <a href="http://mpi4py.scipy.org/">MPI4Py</a>, initialization and finalization of the MPI library is taken care of under the hood, in the import of the library and in the closing of the program.</p>
<p>My first idea was to use the builtin Scatter and Gather functions. The idea was something like the following:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">def</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp;comm = MPI.<span class="me1">COMM_WORLD</span><br />
&nbsp; &nbsp;rowids = <span class="kw2">range</span><span class="br0">&#40;</span>h<span class="br0">&#41;</span><br />
&nbsp; &nbsp;ids = comm.<span class="me1">Scatter</span><span class="br0">&#40;</span>rowids<span class="br0">&#41;</span><br />
&nbsp; &nbsp;pixs = compute_mandel<span class="br0">&#40;</span>ids<span class="br0">&#41;</span><br />
&nbsp; &nbsp;pixels = comm.<span class="me1">Gather</span><span class="br0">&#40;</span>pixs<span class="br0">&#41;</span><br />
&nbsp; &nbsp;img = generate_image<span class="br0">&#40;</span>pixels<span class="br0">&#41;</span><br />
&nbsp; &nbsp;img.<span class="me1">save</span><span class="br0">&#40;</span><span class="st0">&quot;filename.png&quot;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>but this fails already at the Scatter line. The thing is that you can&#8217;t just hand Scatter a list of things you want distributed, you&#8217;ll need to feed comm.Scatter with a list of lists, one for each recipient. This particular property of comm.Scatter is not actually described anywhere I could find on the web &#8211; the documentation for MPI4Py is minuscule at best, and this is specific to the Python interface setup, so the MPI standard documentation doesn&#8217;t give it away either.</p>
<p>The next problem that appears is that if we just divide the rows of the picture evenly &#8211; first processor gets rows 1,2,3,&#8230;,n; second gets n+1,&#8230;,2n and so on &#8211; then some processor will get the bulk of the actual Mandelbrot set &#8211; which is by definition the pixels that take the most iterations to compute &#8211; so the speedup by pouring more processing power on the problem won&#8217;t be as impressive as it could be. The processors that take care of regions outside the set will finish quickly and then just idle, and the processors that take care of most of the set will churn through as if they had computed the set alone.</p>
<p>There are very many ways to deal with this issue. The approach I&#8217;m taking is to use an interlacing pattern to distribute the rows. With n processors, each processor computes every n rows of the picture, thus getting easy and difficult rows reasonably evenly distributed. Also, with this easy a distribution scheme, there&#8217;s no reason to compute the rows centrally and distributing them with the MPI communication scheme.</p>
<p>Hence, the complete program ends up with the following source code:</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">from</span> mpi4py <span class="kw1">import</span> MPI<br />
<span class="kw1">import</span> Image<br />
<span class="kw1">import</span> <span class="kw3">colorsys</span><br />
<span class="kw1">from</span> <span class="kw3">math</span> <span class="kw1">import</span> ceil</p>
<p>w = <span class="nu0">600</span><br />
h = <span class="nu0">600</span><br />
its = <span class="nu0">80</span><br />
d2 = <span class="nu0">4.0</span></p>
<p>xmax = <span class="nu0">1.5</span><br />
xmin = <span class="nu0">-2.5</span><br />
ymax = <span class="nu0">2.0</span><br />
ymin = <span class="nu0">-2.0</span></p>
<p><span class="kw1">def</span> step<span class="br0">&#40;</span>z,c<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> z**<span class="nu0">2</span>+c</p>
<p><span class="kw1">def</span> point<span class="br0">&#40;</span>c,n,d2<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; zo = <span class="nu0">0.0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; zn = zo<br />
&nbsp; &nbsp; &nbsp; &nbsp; i = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">abs</span><span class="br0">&#40;</span>zn<span class="br0">&#41;</span>**<span class="nu0">2</span> &lt; d2 <span class="kw1">and</span> i&lt;n:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; zn = step<span class="br0">&#40;</span>zo,c<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; zo = zn<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i<span class="nu0">+1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> i</p>
<p><span class="kw1">def</span> colnorm<span class="br0">&#40;</span><span class="br0">&#40;</span>r,g,b<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span><span class="nu0">256</span>*r<span class="br0">&#41;</span><span class="nu0">-1</span>,<span class="kw2">int</span><span class="br0">&#40;</span><span class="nu0">256</span>*g<span class="br0">&#41;</span><span class="nu0">-1</span>,<span class="kw2">int</span><span class="br0">&#40;</span><span class="nu0">256</span>*b<span class="br0">&#41;</span><span class="nu0">-1</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> col<span class="br0">&#40;</span>n,<span class="kw2">max</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> n == <span class="kw2">max</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> colnorm<span class="br0">&#40;</span><span class="kw3">colorsys</span>.<span class="me1">hsv_to_rgb</span><span class="br0">&#40;</span><span class="nu0">1.0</span>-<span class="kw2">float</span><span class="br0">&#40;</span>n<span class="br0">&#41;</span>/<span class="kw2">max</span>,<span class="nu0">1.0</span>,<span class="nu0">1.0</span><span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> row<span class="br0">&#40;</span>n,xmin,xmax,ymin,ymax<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; row = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>w<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p = <span class="kw2">complex</span><span class="br0">&#40;</span><span class="br0">&#40;</span>xmin+x*<span class="br0">&#40;</span>xmax-xmin<span class="br0">&#41;</span>/w<span class="br0">&#41;</span>,<span class="br0">&#40;</span>ymin+n*<span class="br0">&#40;</span>ymax-ymin<span class="br0">&#41;</span>/h<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; row.<span class="me1">append</span><span class="br0">&#40;</span>point<span class="br0">&#40;</span>p,its,d2<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> row</p>
<p><span class="kw1">def</span> <span class="kw3">__main__</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; comm = MPI.<span class="me1">COMM_WORLD</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; rows = <span class="br0">&#91;</span> MPI.<span class="me1">rank</span> + MPI.<span class="me1">size*i</span> <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span><span class="kw2">float</span><span class="br0">&#40;</span>h<span class="br0">&#41;</span>/MPI.<span class="me1">size</span><span class="br0">&#41;</span><span class="nu0">+1</span><span class="br0">&#41;</span> <span class="kw1">if</span> MPI.<span class="me1">rank</span> + MPI.<span class="me1">size*i</span> &lt; h <span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; pixels = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> y <span class="kw1">in</span> rows:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pixels.<span class="me1">append</span><span class="br0">&#40;</span>row<span class="br0">&#40;</span>y,xmin,xmax,ymin,ymax<span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; mandel = comm.<span class="me1">Gather</span><span class="br0">&#40;</span>pixels<span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> MPI.<span class="me1">rank</span> == <span class="nu0">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img = Image.<span class="kw3">new</span><span class="br0">&#40;</span><span class="st0">&quot;RGB&quot;</span>,<span class="br0">&#40;</span>w,h<span class="br0">&#41;</span>,<span class="br0">&#40;</span><span class="nu0">0</span>,<span class="nu0">0</span>,<span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>mandel<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> j <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>mandel<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = mandel<span class="br0">&#91;</span>j<span class="br0">&#93;</span><span class="br0">&#91;</span>i<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows.<span class="me1">append</span><span class="br0">&#40;</span><span class="br0">&#91;</span>col<span class="br0">&#40;</span>p,its<span class="br0">&#41;</span> <span class="kw1">for</span> p <span class="kw1">in</span> r<span class="br0">&#93;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> x <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>w<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> y <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>h<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = rows<span class="br0">&#91;</span>y<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c = r<span class="br0">&#91;</span>x<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img.<span class="me1">putpixel</span><span class="br0">&#40;</span><span class="br0">&#40;</span>x,y<span class="br0">&#41;</span>,c<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img.<span class="me1">save</span><span class="br0">&#40;</span><span class="st0">&quot;/home/mik/public_html/mandel.png&quot;</span><span class="br0">&#41;</span></p>
<p><span class="kw3">__main__</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp;</div>
<p>We can run this program on a single-processor machine by issuing</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="re1">$SAGE_ROOT</span>/<span class="kw3">local</span>/bin/mpirun -np <span class="nu0">1</span> <span class="re1">$SAGE_ROOT</span>/<span class="kw3">local</span>/bin/python mandel.py<br />
&nbsp;</div>
<p>and on a multiprocessor machine by replacing <code>-np 1</code> with the number of processors we&#8217;d want to utilize.</p>
<p>On the quad kernel workhorse my workgroup uses, which currently has two processors fully utilized by group cohomology computations, I get the following results (approximates):</p>
<table>
<tr>
<th># proc</th>
<th>mean walltime</th>
<th>std.dev</th>
</tr>
<tr>
<td>1</td>
<td>12s</td>
<td>0.7</td>
</tr>
<tr>
<td>2</td>
<td>9s</td>
<td>0.7</td>
</tr>
<tr>
<td>3</td>
<td>11s</td>
<td>2</td>
</tr>
</table>
<p>So &#8211; once I used up the free processors, the wall time shoots up, and the spread shoots up. So working on a utilized SMP machine might not be the way to go.</p>
<p>But I do have access to the Jena Beowulf cluster, since the lecture course I audited on cluster computing. And I&#8217;m getting much better results there. Over there, I run jobs by writing a job script</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="re3">#$ -j y</span><br />
<span class="re3">#$-l <span class="re2">hostshare=</span><span class="nu0">1.0</span></span><br />
<span class="re3">#$-q fast.q</span></p>
<p>mpiexec python mandel.py<br />
&nbsp;</div>
<p>and submit it to the job scheduler, to work on &#8211; say &#8211; 3 processors with </p>
<div class="dean_ch" style="white-space: wrap;">
qsub -pe lam7 <span class="nu0">3</span> mandel.job<br />
&nbsp;</div>
<p>I added commands to time the computation part &#8211; stripping out the book-keeping and image writing once the fractal is computed, and thus can get timings for the parallel computation.</p>
<p>As a result, I get the following:</p>
<table>
<tr>
<th># proc</th>
<th>mean walltime</th>
<th>std.dev</th>
</tr>
<tr>
<td>1</td>
<td>8.33</td>
<td>-</td>
</tr>
<tr>
<td>2</td>
<td>4.34</td>
<td>0.020</td>
</tr>
<tr>
<td>3</td>
<td>2.96</td>
<td>0.033</td>
</tr>
<tr>
<td>4</td>
<td>2.32</td>
<td>0.031</td>
</tr>
<tr>
<td>5</td>
<td>2.00</td>
<td>0.060</td>
</tr>
<tr>
<td>6</td>
<td>1.54</td>
<td>0.019</td>
</tr>
<tr>
<td>7</td>
<td>1.29</td>
<td>0.040</td>
</tr>
<tr>
<td>8</td>
<td>1.22</td>
<td>0.028</td>
</tr>
<tr>
<td>9</td>
<td>1.04</td>
<td>0.017</td>
</tr>
<tr>
<td>10</td>
<td>1.00</td>
<td>0.030</td>
</tr>
</table>
<p><img src="http://chart.apis.google.com/chart?chs=250x100&amp;cht=lc&amp;chd=t:83.3,43.3,29.5,23.2,20.0,15.4,12.9,12.2,10.4,10.0"><br />
Walltimes</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2008/05/parallell-and-cluster-mpi4py/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Scripting Games in Haskell</title>
		<link>http://blog.mikael.johanssons.org/archive/2008/02/scripting-games-in-haskell/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2008/02/scripting-games-in-haskell/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 00:15:04 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/archive/2008/02/scripting-games-in-haskell/</guid>
		<description><![CDATA[I saw the Cerebrate solve the first Scripting Games challenge: Pairing off. And immediately thought &#8220;I can do that in Haskell too&#8221;. So, here it is. import Data.List cards = [(1,7),(0,5),(3,7),(2,7),(2,13)] countpairs [] = 0 countpairs [a] = 0 countpairs (a:as) = length . filter (((snd a)==) . snd) $ as pairingOff = sum . [...]]]></description>
			<content:encoded><![CDATA[<p>I saw <a href="http://feeds.feedburner.com/~r/cerebratescontemplations/~3/238385247/scripting-games-event-1beginne.html">the Cerebrate solve</a> the first <a href="http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/bevent1.mspx">Scripting Games challenge: Pairing off</a>. And immediately thought &#8220;I can do that in Haskell too&#8221;.</p>
<p>So, here it is. </p>
<pre lang=haskell>
import Data.List

cards = [(1,7),(0,5),(3,7),(2,7),(2,13)]

countpairs [] = 0
countpairs [a] = 0
countpairs (a:as) = length . filter (((snd a)==) . snd) $ as

pairingOff = sum . map countpairs . tails
</pre>
<p>And that&#8217;s that. Alas, the actual competition only takes Perl, VBScript and PowerShell, so I won&#8217;t be submitting this.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2008/02/scripting-games-in-haskell/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PROPs and patches</title>
		<link>http://blog.mikael.johanssons.org/archive/2008/02/props-and-patches/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2008/02/props-and-patches/#comments</comments>
		<pubDate>Fri, 15 Feb 2008 18:59:26 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Category theory]]></category>
		<category><![CDATA[Operads and PROPs]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/archive/2008/02/props-and-patches/</guid>
		<description><![CDATA[Brent Yorgey wrote a post on using category theory to formalize patch theory. In the middle of it, he talks about the need to commute a patch to the end of a patch series, in order to apply a patch undoing it. He suggests a necessary condition to do this is that, given patches P [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://byorgey.wordpress.com">Brent Yorgey</a> wrote a post on <a href="http://byorgey.wordpress.com/2008/02/13/patch-theory-part-ii-some-basics/">using category theory to formalize patch theory</a>. In the middle of it, he talks about the need to commute a patch to the end of a patch series, in order to apply a patch undoing it. He suggests a necessary condition to do this is that, given patches P and Q, we need to be able to find patches Q&#8217; and P&#8217; such that PQ=Q&#8217;P', and preferably such that Q&#8217; and P&#8217; capture some of the info in P and Q.</p>
<p>However, as such, this is not enough to solve the issue. For one thing, we can set Q&#8217;=P and P&#8217;=Q, and things are the way he asks for.</p>
<p>Now, I wonder whether we can solve this by using PROPs (or possibly di-operads or something like that). Let&#8217;s represent a document as a list of some sort of tokens. We&#8217;ll set <img src='/latexrender/pictures/e4f7629b574dd05d19a2107c87806700.png' title='D_n' alt='D_n' align='middle' /> the set of all lists of length <img src='/latexrender/pictures/7b8b965ad4bca0e41ab51de7b31363a1.png' title='n' alt='n' align='middle' />, and we&#8217;ll set <img src='/latexrender/pictures/8f771bc1b32729794ded2f43f30110d3.png' title='P_n^m' alt='P_n^m' align='middle' /> to denote operations that take a list of length n and returns a list of length m.</p>
<p>One operation here is obvious &#8211; the identity operation. So we&#8217;ll take that into the mix. And we&#8217;ll also want to have some manner of composing operations. So, set <img src='/latexrender/pictures/3b72682c4921e5ee163a8aa583f9ba9e.png' title='\circ_i:P_n^m\times P_r^s\to P_n^{m+s-r}' alt='\circ_i:P_n^m\times P_r^s\to P_n^{m+s-r}' align='middle' /> to be the operation that applies the second argument to the elements i,i+1,&#8230;,i+m of the list outputted by the first argument.</p>
<p>This way, we can make patch trees &#8211; using the identities to fill out when a patch doesn&#8217;t influence everything; and have composition of operations represent composition of patches.</p>
<p>Now, the commutativity that Brent asks for would manifest as an additional relation &#8211; on top of those inherent in the definition of a PROP &#8211; to rebuild trees. One obvious one pops out immediately &#8211; as long as the trees don&#8217;t overlap, in other words, as long as the subtree we want to reorganize is contractible (in the topological sense), we can commute patches freely.</p>
<p>When trees -do- overlap, however, the undo operation Brent asks for is much more tricky. Consider the following sequence of edits:</p>
<p>[] -> [a] -> [b] -> [cbd]</p>
<p>Now, undo the insertion of [a].</p>
<p>Sure, taken this way, we cheat a little. Maybe we want to restrict edit descriptions to explicit deletions and additions. So we would have</p>
<p>[] -> [a] -> [] -> [b] -> [cb] -> [cbd]</p>
<p>and here we could probably move things around a bit easier. I don&#8217;t quite see how to do it, right now, though.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2008/02/props-and-patches/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Riding the Google Charts API bandwagon</title>
		<link>http://blog.mikael.johanssons.org/archive/2007/12/riding-the-google-charts-api-bandwagon/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2007/12/riding-the-google-charts-api-bandwagon/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 14:05:52 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/archive/2007/12/riding-the-google-charts-api-bandwagon/</guid>
		<description><![CDATA[Last week, the news hit the blogosphere that Google had released a beta API for generating graphs using a reasonably easy and transparent GET parametrisation. Inspired by this, and inspired by my early playing around with Ruby on Rails, I decided to whack together a Rails plugin that takes care of building the Google Charts [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, the news hit the blogosphere that Google had released a <a href="http://code.google.com/apis/chart/">beta API for generating graphs</a> using a reasonably easy and transparent GET parametrisation.</p>
<p>Inspired by this, and inspired by my early playing around with Ruby on Rails, I decided to whack together a Rails plugin that takes care of building the Google Charts IMG tag using what I hope is reasonably easy to use syntax.</p>
<p>I have a <a href="http://www.mikael.johanssons.org/testground">test-site using random data</a> up for playing around with it.</p>
<p>The test-site as such runs on Ruby on Rails. The controller does some parsing and setting up of relevant arrays, and primarily generates random data for plotting.</p>
<p>The view has the following source code:</p>
<div class="dean_ch" style="white-space: wrap;">
&lt;%= google_chart<span class="br0">&#40;</span>@data, <span class="re1">@alt_text</span>, <span class="re1">@options</span><span class="br0">&#41;</span> &nbsp;%&gt;</p>
<p>&lt;p&gt;&lt;% form_tag <span class="st0">&quot;&quot;</span> <span class="kw1">do</span> %&gt;</p>
<p>&lt;label <span class="kw1">for</span>=<span class="st0">&quot;options[type]&quot;</span>&gt;Type&lt;/label&gt;<br />
&lt;%= select_tag <span class="st0">&quot;options[type]&quot;</span>, options_for_select<span class="br0">&#40;</span>@typeopts,@options<span class="br0">&#91;</span><span class="st0">&quot;type&quot;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <br />
%&gt; </p>
<p>
&lt;label <span class="kw1">for</span>=<span class="st0">&quot;options[title]&quot;</span>&gt;Title&lt;/label&gt;<br />
&lt;%= text_field_tag <span class="st0">&quot;options[title]&quot;</span>, <span class="re1">@options</span><span class="br0">&#91;</span><span class="st0">&quot;title&quot;</span><span class="br0">&#93;</span> %&gt; </p>
<p>
&lt;label <span class="kw1">for</span>=<span class="st0">&quot;options[encoding]&quot;</span>&gt;Granularity&lt;/label&gt;<br />
&lt;%= select_tag <span class="st0">&quot;options[encoding]&quot;</span>, options_for_select<span class="br0">&#40;</span>@encopts,@options<span class="br0">&#91;</span><span class="st0">&quot;encoding&quot;</span><span class="br0">&#93;</span><span class="br0">&#41;</span> %&gt; </p>
<p>
&lt;%= hidden_field_tag <span class="st0">&quot;datalength&quot;</span>, <span class="nu0">3</span> %&gt;<br />
&lt;%= hidden_field_tag <span class="st0">&quot;dslengthmin&quot;</span>, <span class="nu0">5</span> %&gt;<br />
&lt;%= hidden_field_tag <span class="st0">&quot;dslengthmax&quot;</span>, <span class="nu0">50</span> %&gt;<br />
&lt;%= hidden_field_tag <span class="st0">&quot;dsmin&quot;</span>, <span class="nu0">0</span> %&gt;<br />
&lt;%= hidden_field_tag <span class="st0">&quot;dsmax&quot;</span>, <span class="nu0">10000</span> %&gt;</p>
<p>&lt;%= submit_tag %&gt;<br />
&lt;/p&gt;<br />
&lt;% <span class="kw1">end</span> %&gt;<br />
&nbsp;</div>
<p>where the <code>@options</code> array is populated with the options tag from the input pretty straight off.</p>
<p>The whole plugin resides at a <a href="http://rubyforge.org/projects/googlechart/">project of its own at rubyforge</a>. So far, I have not yet implemented color handling, grid lines or marker setting. I&#8217;m happy to share code responsibility or getting suggestions for how to handle the outstanding issues or improve on the code. Just get in touch with me if you feel like contributing. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2007/12/riding-the-google-charts-api-bandwagon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pluralization in Rails</title>
		<link>http://blog.mikael.johanssons.org/archive/2007/12/pluralization-in-rails/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2007/12/pluralization-in-rails/#comments</comments>
		<pubDate>Sun, 09 Dec 2007 21:13:40 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/archive/2007/12/pluralization-in-rails/</guid>
		<description><![CDATA[So, there is this one big and neat framework called Rails, building on top of this one neat new programming language called Ruby. And one of the things that makes Rails so Damn Neat is that if you only set things up the right way around, it guesses almost everything you need it to guess [...]]]></description>
			<content:encoded><![CDATA[<p>So, there is this one big and neat framework called Rails, building on top of this one neat new programming language called Ruby.</p>
<p>And one of the things that makes Rails so Damn Neat is that if you only set things up the right way around, it guesses almost everything you need it to guess for you.</p>
<p>One of the ways it does this is by <i>pluralization</i>. Basically, the model <code>Foo</code> has a model defined in <code>app/model/foo.rb</code> and it accesses the database table <code>foos</code>.</p>
<p>So, when talking a good friend through the basics, we created the table <code>persons</code> and generated the model <code>Person</code>. And promptly got an error from the framework.</p>
<p>It turns out that the pluralization of <i>person</i> is <i>people</i>. I wonder what else irregularities they built into the system. If I have a model called <code>Index</code>, does Rails expect it to read from the database table <code>indexes</code> or from <code>indices</code>?</p>
<p><i>Edited to add:</i></p>
<p>So, I found out that in the Rails console, I can fiddle around with pluralization myself.</p>
<p>Which lead to this experiment</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="st0">&quot;index&quot;</span>.<span class="me1">pluralize</span><br />
&gt;&gt; <span class="st0">&quot;index&quot;</span>.<span class="me1">pluralize</span><br />
=&gt; <span class="st0">&quot;indices&quot;</span><br />
&gt;&gt; <span class="st0">&quot;simplex&quot;</span>.<span class="me1">pluralize</span><br />
=&gt; <span class="st0">&quot;simplices&quot;</span><br />
&gt;&gt; <span class="st0">&quot;matrix&quot;</span>.<span class="me1">pluralize</span><br />
=&gt; <span class="st0">&quot;matrices&quot;</span><br />
&gt;&gt; <span class="st0">&quot;complex&quot;</span>.<span class="me1">pluralize</span><br />
=&gt; <span class="st0">&quot;complices&quot;</span><br />
&nbsp;</div>
<p>And at this point, the chosen pluralization engine simply Does Not Work. The pluralization of complex, at least as used in mathematics, is under no circumstances complices. We&#8217;d say complexes. Matrices, on the other hand, pluralizes correctly. And simplices pluralize correctly or incorrectly depending on which mathematician you ask. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2007/12/pluralization-in-rails/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Progress</title>
		<link>http://blog.mikael.johanssons.org/archive/2007/09/progress/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2007/09/progress/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 03:25:10 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[A-infinity]]></category>
		<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Homology and Homotopy]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[PhD]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/archive/2007/09/progress/</guid>
		<description><![CDATA[dynkin:~/magma> magma Magma V2.14-D250907 Wed Sep 26 2007 13:19:51 on dynkin [Seed = 1] Type ? for help. Type -D to quit. Loading startup file "/home/mik/.magmarc" > Attach("homotopy.m"); > Attach("assoc.m"); > Aoo := ConstructAooRecord(DihedralGroup(4),10); > S := CohomologyRingQuotient(Aoo`R); > CalculateHighProduct(Aoo,[x,y,x,y]); z > exit; Total time: 203.039 seconds, Total memory usage: 146.18MB And this is one [...]]]></description>
			<content:encoded><![CDATA[<pre>
dynkin:~/magma> magma
Magma V2.14-D250907   Wed Sep 26 2007 13:19:51 on dynkin   [Seed = 1]
Type ? for help.  Type <Ctrl>-D to quit.

Loading startup file "/home/mik/.magmarc"

> Attach("homotopy.m");
> Attach("assoc.m");
> Aoo := ConstructAooRecord(DihedralGroup(4),10);
> S<x,y,z> := CohomologyRingQuotient(Aoo`R);
> CalculateHighProduct(Aoo,[x,y,x,y]);
z
> exit;
Total time: 203.039 seconds, Total memory usage: 146.18MB
</pre>
<p>And this is one major reason for the lack of updates recently.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2007/09/progress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coq and simple group theory</title>
		<link>http://blog.mikael.johanssons.org/archive/2007/08/coq-and-simple-group-theory/</link>
		<comments>http://blog.mikael.johanssons.org/archive/2007/08/coq-and-simple-group-theory/#comments</comments>
		<pubDate>Sun, 05 Aug 2007 20:15:52 +0000</pubDate>
		<dc:creator>Michi</dc:creator>
				<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Computer]]></category>
		<category><![CDATA[Mathematics]]></category>

		<guid isPermaLink="false">http://blog.mikael.johanssons.org/archive/2007/08/coq-and-simple-group-theory/</guid>
		<description><![CDATA[Trying to make the time until my flight leaves tomorrow go by, I played around a bit with the proof assistant Coq. And after wrestling a LOT with the assistant, I ended up being able to prove some pretty basic group theory results. And this is how it goes: Section Groups. Variable U : Set. [...]]]></description>
			<content:encoded><![CDATA[<p>Trying to make the time until my flight leaves tomorrow go by, I played around a bit with the proof assistant Coq. And after wrestling a LOT with the assistant, I ended up being able to prove some pretty basic group theory results.</p>
<p>And this is how it goes:</p>
<div class="dean_ch" style="white-space: wrap;">
Section Groups.</p>
<p>Variable U : Set.<br />
Variable m : U -&gt; U -&gt; U.<br />
Variable i : U -&gt; U.<br />
Variable e : U.</p>
<p>Hypothesis ass : forall x y z : U, m x (m y z) = m (m x y) z.<br />
Hypothesis runit : forall x : U, m x e = x.<br />
Hypothesis rinv : forall x : U, m x (i x) = e.<br />
&nbsp;</div>
<p>This sets the stage. It defines a group as a <a href=http://unapologetic.wordpress.com/2007/08/04/group-objects/>group object in Set</a>, but without the diagonal map. It produces a minimal definition &#8211; the left identity and inverse follow from the right ones, which we shall prove immediately.</p>
<p>First off, the right unit is the only idempotent in the group.</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma unit_uniq : forall x : U, m x x = x -&gt; x = e.<br />
intros.<br />
rewrite &lt;- runit with x.<br />
rewrite &lt;- (rinv x).<br />
rewrite ass.<br />
rewrite H.<br />
reflexivity.<br />
Qed.<br />
&nbsp;</div>
<p>Now, <code>intros.</code> is a way to automatically name all hypotheses in the statement. <code>reflexivity</code> tells us that if we could derive <code>A=A</code>, then we&#8217;re done. And <code>rewrite</code> applies a known result everywhere that it could possibly could be applied. The arrows tell us which direction the equalities should be employed.</p>
<p>Now, our right inverse is a left inverse:</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma linv : forall x : U, m (i x) x = e.<br />
intros.<br />
apply unit_uniq.<br />
rewrite &lt;- ass with (i x) x (m (i x) x).<br />
rewrite ass with x (i x) x.<br />
rewrite rinv.<br />
rewrite ass.<br />
rewrite runit.<br />
reflexivity.<br />
&nbsp;</div>
<p>and our right unit is a left unit:</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma lunit : forall x : U, m e x = x.<br />
intros.<br />
rewrite &lt;- (rinv x).<br />
rewrite &lt;- ass.<br />
rewrite linv.<br />
rewrite runit.<br />
reflexivity.<br />
Qed.<br />
&nbsp;</div>
<p>In a group, we have cancellation laws. We can remove left and right multiplied factors:</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma lcancel: forall x y z : U, y = z -&gt; m x y = m x z.<br />
intros.<br />
replace y with z.<br />
reflexivity.<br />
Qed.</p>
<p>Lemma rcancel: forall x y z : U, x = y -&gt; m x z = m y z.<br />
intros.<br />
replace x with y.<br />
reflexivity.<br />
Qed.<br />
&nbsp;</div>
<p>and we can add them again</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma lcocancel: forall x y z : U, m x y = m x z -&gt; y = z.<br />
intros.<br />
rewrite &lt;- lunit.<br />
rewrite &lt;- (lunit y).<br />
rewrite &lt;- (linv x).<br />
rewrite &lt;- ass.<br />
rewrite &lt;- ass.<br />
rewrite H.<br />
reflexivity.<br />
Qed.</p>
<p>Lemma rcocancel: forall x y z : U, m x z = m y z -&gt; x = y.<br />
intros.<br />
rewrite &lt;- runit.<br />
rewrite &lt;- (runit x).<br />
rewrite &lt;- (rinv z).<br />
rewrite ass.<br />
rewrite ass.<br />
rewrite H.<br />
reflexivity.<br />
Qed.<br />
&nbsp;</div>
<p>There&#8217;s most probably something obscure going on with the proof model in Coq: I often get the feeling that I run backwards when I write the proofs. Thus, the result we need to be able to perform a cancellation when we&#8217;re rewriting our proof goal is <code>y = z -> m x y = m x z</code> and not the other way around, which surprises me a bit.</p>
<p>The inverses are unique:</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma inv_uniq: forall x y : U, m x y = e -&gt; y = i x.<br />
intros.<br />
apply (lcocancel x).<br />
rewrite rinv.<br />
apply H.<br />
Qed.<br />
&nbsp;</div>
<p>and the well known product rule (xy)<sup>-1</sup>=y<sup>-1</sup>x<sup>-1</sup> holds:</p>
<div class="dean_ch" style="white-space: wrap;">
Lemma prod_inv: forall x y : U, i (m x y) = m (i y) (i x).<br />
intros.<br />
apply (lcocancel (m x y)).<br />
rewrite rinv.<br />
rewrite &lt;- ass.<br />
rewrite ass with y (i y) (i x).<br />
rewrite rinv.<br />
rewrite lunit.<br />
symmetry &nbsp;in |- *; apply rinv.<br />
Qed.<br />
&nbsp;</div>
<p>Finally, a slightly larger theorem is the statement that if all elements of a group have order 2, then the group is commutative. This is, in Coq, the following argument:</p>
<div class="dean_ch" style="white-space: wrap;">
Theorem ord2_comm: (forall x : U, m x x = e) -&gt; (forall y z : U, m y z = m z y).<br />
intros.<br />
rewrite &lt;- (runit z).<br />
symmetry &nbsp;in |- *.<br />
rewrite &lt;- lunit.<br />
replace (m e (m y (m z e))) with (m (m z z) (m y (m z (m y y)))).<br />
&nbsp;rewrite ass.<br />
&nbsp; &nbsp;rewrite ass.<br />
&nbsp; &nbsp;rewrite ass.<br />
&nbsp; &nbsp;apply rcancel.<br />
&nbsp; &nbsp;rewrite &lt;- ass.<br />
&nbsp; &nbsp;rewrite &lt;- ass with z z y.<br />
&nbsp; &nbsp;rewrite &lt;- ass with z (m z y) (m z y).<br />
&nbsp; &nbsp;rewrite H.<br />
&nbsp; &nbsp;reflexivity.<br />
&nbsp;rewrite H.<br />
&nbsp; &nbsp;rewrite H.<br />
&nbsp; &nbsp;reflexivity.<br />
Qed.<br />
&nbsp;</div>
<p>It doesn&#8217;t really end up being more legible than if I had written it out myself, but it is machine checkable, and not THAT far from being legible as well. If you step through, you certainly do realize the mapping between Coq and pen-n-paper pretty immediately.</p>
<p>Sometime in the future, I&#8217;ll sit down and do some category theory and topology in Coq. I think the 5-lemma and other diagram chases will end up being amusing.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mikael.johanssons.org/archive/2007/08/coq-and-simple-group-theory/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

