<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><atom:link href="http://claudiusmaximus.goto10.org/cm/haskell.xml" rel="self" type="application/rss+xml"/><title>haskell :: ClaudiusMaximus</title><link>http://claudiusmaximus.goto10.org/cm/haskell.html</link><description>ClaudiusMaximus haskell feed</description><item><title>hp2pretty-0.1 released</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p>
<img id="hp2pretty20100729hp2pretty" src="2010-07-29_hp2pretty_hp2pretty.png" alt="hp2pretty"/>
<img id="hp2pretty20100729hp2ps" src="2010-07-29_hp2pretty_hp2ps.png" alt="hp2ps"/>
</p>
<script type="text/javascript">// 

var hp2pretty20100729pretty = document.getElementById('hp2pretty20100729hp2pretty');
var hp2pretty20100729ps     = document.getElementById('hp2pretty20100729hp2ps');

function hp2pretty20100729hp2pretty() {
  hp2pretty20100729ps    .style.display = "none";
  hp2pretty20100729pretty.style.display = "inline";
}

function hp2pretty20100729hp2ps() {
  hp2pretty20100729ps    .style.display = "inline";
  hp2pretty20100729pretty.style.display = "none";
}

function hp2pretty20100729both() {
  hp2pretty20100729ps    .style.display = "inline";
  hp2pretty20100729pretty.style.display = "inline";
}

function hp2pretty20100729toggle() {
  var t = hp2pretty20100729ps.style.display;
  hp2pretty20100729ps    .style.display = hp2pretty20100729pretty.style.display;
  hp2pretty20100729pretty.style.display = t;
}

hp2pretty20100729hp2pretty();

// 
</script>
<p>
<a href="javascript:hp2pretty20100729hp2pretty()" title="hp2pretty">hp2pretty</a> |
<a href="javascript:hp2pretty20100729hp2ps()" title="hp2ps">hp2ps</a> |
<a href="javascript:hp2pretty20100729both()" title="both">both</a> |
<a href="javascript:hp2pretty20100729toggle()" title="toggle">toggle</a>
</p>
<p>I recently wrote about
<a href="2010-07-26_graphing_heap_profiles.html" title="graphing heap profiles">graphing heap profiles</a>,
and now it's easier to try out my work-in-progress hp2ps rewrite as I
uploaded <strong>hp2pretty</strong> version 0.1 to Hackage.  Currently it
has no options and works as a filter from heap profiles to scalable vector
graphics, for example:</p>
<blockquote><pre>hp2pretty &lt;in.hp &gt;out.svg</pre></blockquote>
<p>Some rough benchmarks on a huge (37MB) .hp file give almost identical
timings for hp2pretty and hp2ps, though hp2pretty does use more memory.
I haven't yet benchmarked the more common case of small .hp files.</p>
<p>The code is available at
<a href="http://gitorious.org/hp2pretty/hp2pretty" title="hp2pretty">hp2pretty/hp2pretty</a>
on Gitorious, or you can download
<a href="/code/hp2pretty/hp2pretty-0.1.tar.gz" title="hp2pretty-0.1.tar.gz">hp2pretty-0.1.tar.gz</a>,
or you can get it with <strong>cabal install hp2pretty</strong>.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-07-29_hp2pretty-0.1_released.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-07-29_hp2pretty-0.1_released.html</guid><pubDate>29 Jul 2010 17:17:17 GMT</pubDate><category>haskell</category></item><item><title>Graphing heap profiles</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="2010-07-26_graphing_heap_profiles.png" alt="graphing heap profiles"/></p>
<p><strong>EDIT (2010-07-29):</strong> this post is somewhat misleading
regarding #2 below.  See
<a href="http://hackage.haskell.org/trac/ghc/ticket/4225" title="GHC ticket #4225">GHC ticket #4225</a>
for some additional clarification.</p>
<p><strong>hp2ps</strong> is a tool for generating graphs (in the
PostScript file format) from heap profile logs dumped by the GHC RTS
for Haskell programs.  These graphs are invaluable for debugging errant
programs and reducing memory consumption, but there are some problems:</p>
<ol>
<li>hp2ps is written in C that no one seems willing to maintain</li>
<li>heap profile logs have time stamps that include the overhead of profiling</li>
<li>the output graphs aren't as beautiful as they could be</li>
</ol>
<p>In particular, #2 can give very misleading graphs, where periods of
high heap usage appear to dominate the running time.  This warping is
because (fairly obviously) it takes longer to generate a heap profile
sample when the heap is larger.  With the profiling overheads taken out,
you can compare graphs with different heap sample intervals more easily,
because the shape will be the same (only with more or less detail).</p>
<p>I've been working on a replacement for hp2ps, written in Haskell
(which solves #1).  I added an option to graph against sample index
instead of sample time (which solves #2, provided that the heap sample
interval is constant, which is currently the case).  And hopefully the
picture shows that I'm making progress on #3
(<a href="/g/hp2pretty/" title="hp2pretty images">some more pictures</a>)</p>
<p>Currently I'm just building up SVG strings, but I should switch to
using a library such as wumpus-core to get both PostScript and SVG
output (the other alternatives for vector graphics output available on
Hackage seem to have heavy external library dependencies such as Cairo
or OpenGL).</p>
<p>The code is available at
<a href="http://gitorious.org/hp2pretty/hp2pretty" title="hp2pretty">hp2pretty/hp2pretty</a>
on Gitorious.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-07-26_graphing_heap_profiles.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-07-26_graphing_heap_profiles.html</guid><pubDate>26 Jul 2010 22:37:12 GMT</pubDate><category>haskell</category></item><item><title>mandulia-0.5 released</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://www.archive.org/details/mandulia-0.5" title="mandulia-0.5 video"><img src="2010-07-25_mandulia-0.5_released.png" alt="mandulia-0.5 video"/></a></p>
<p>Video download options:</p>
<ul>
<li><a href="http://www.archive.org/download/mandulia-0.5/mandulia-0.5.mpeg" title="mandulia-0.5 (DVD)">DVD (589MB)</a></li>
<li><a href="http://www.archive.org/download/mandulia-0.5/mandulia-0.5.ogv" title="mandulia-0.5 (Ogg)">Ogg  (44MB)</a></li>
<li><a href="http://www.archive.org/download/mandulia-0.5/mandulia-0.5_512kb.mp4" title="mandulia-0.5 (MP4)">MP4  (41MB)</a></li>
</ul>
<p>A new release of <strong>mandulia</strong> (a zooming visualization
of the Mandelbrot Set as many Julia Sets, with Lua scripting support)
is installable from
<a href="http://hackage.haskell.org/package/mandulia-0.5" title="mandulia on hackage">Hackage</a>:</p>
<blockquote><pre>cabal install mandulia</pre></blockquote>
<p>or, if your CPU doesn't support SSE4 instructions:</p>
<blockquote><pre>cabal install mandulia -f-SSE4</pre></blockquote>
<p>After you have installed it, you can try it out by running:</p>
<blockquote><pre>mandulia main</pre></blockquote>
<p>and hit the 'a' key to enter attract mode or use the key controls
listed in the README for interactive navigation.</p>
<p>mandulia-0.5 runs in asymptotic constant space, aesthetics tweaks give
<a href="/g/mandulia/" title="mandulia gallery">more colourful 'neon' output</a>,
and the randomized attract mode picks more interesting places to explore.</p>
<p>O(1) space usage was achieved by recomputing the current path down
from the top of the substitution tiling tree each time, instead of
navigating around a shared tree that could grow indefinitely; and by
using greater strictness in some mutable references (such as the
statistics logger and the scripting interface).</p>
<p>There is one small bug in this release
that I noticed too late (and isn't quite big enough to warrant an
entirely new upload): the program help text states that configurations
'interactive' and 'random' are included, but they have been combined
into one configuration called 'main'.  A feature of this new 'main'
configuration allows you to specify additional personal configuration
in the user settings directory, for example (on Linux)
<strong>~/.mandulia/config.lua</strong>.</p>
<p>Source code is GPLv3+ licensed, Git repository at
<a href="http://gitorious.org/maximus/mandulia" title="maximus/mandulia">maximus/mandulia</a>
on Gitorious, or you can download
<a href="/code/mandulia/mandulia-0.5.tar.gz" title="mandulia-0.5.tar.gz">mandulia-0.5.tar.gz</a>.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-07-25_mandulia-0.5_released.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-07-25_mandulia-0.5_released.html</guid><pubDate>25 Jul 2010 07:37:37 GMT</pubDate><category>fractal</category><category>haskell</category><category>lua</category><category>video</category></item><item><title>mandulia-0.4 released</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="/g/mandulia/" title="mandulia gallery"><img src="2010-07-12_mandulia-0.4_released.png" alt="mandulia gallery"/></a></p>
<p>My project <strong>mandulia</strong> (a zooming visualization of the
Mandelbrot Set as many Julia sets, with Lua scripting support) is
reaching adolescence, and is ready to take its first steps alone into
the outside world. It's now available from
<a href="http://hackage.haskell.org/package/mandulia-0.4" title="mandulia on hackage">Hackage</a>,
the Haskell world's package repository, which makes installing it as simple as:</p>
<blockquote><pre>cabal install mandulia</pre></blockquote>
<p>or, if your CPU doesn't support SSE4 instructions:</p>
<blockquote><pre>cabal install mandulia -f-SSE4</pre></blockquote>
<p>After you have installed it, you can try it out by running:</p>
<blockquote><pre>mandulia random</pre></blockquote>
<p>for a randomized
<a href="http://claudiusmaximus.goto10.org/g/tech/viewport_transformation.png" title="viewport transformation">attract mode</a>,
or:</p>
<blockquote><pre>mandulia interactive</pre></blockquote>
<p>for keyboard controlled navigation.</p>
<p>A couple of short excerpts from the documentation follow, first
the command line help:</p>
<blockquote><pre><strong>$</strong> <em>mandulia --help</em>
Usage: mandulia [OPTION]... CONFIGURATION [ARGUMENT]...

CONFIGURATION is considered (in this order):
  as a file to load directly;
  as a module to load from the current directory;
  as a module to load from the user settings directory;
  as a module to load from the global settings directory.

Configurations available in this package may include:
  interactive
  random

The ARGUMENT list is supplied to the selected configuration.

Options:
  +RTS [OPTION].. -RTS   options for the run time system
                         (Try `mandulia +RTS -? -RTS' for help)
  -?, -h, --help         print this help text
  -V, --version          print program version</pre></blockquote>
<p>and some key bindings documented in the README:</p>
<blockquote><p><strong>interactive</strong> defines the following key bindings:</p>
<dl>
<dt>Escape</dt><dd>quit</dd>
<dt>PageUp</dt><dd>zoom in</dd>
<dt>PageDown</dt><dd>zoom out</dd>
<dt>cursors</dt><dd>move around</dd>
<dt>End</dt><dd>stop moving</dd>
<dt>Home</dt><dd>return to base</dd>
<dt>[ ]</dt><dd>change speed</dd>
<dt>#</dt><dd>reset speed</dd>
</dl>
</blockquote>
<p>Source code is GPLv3+ licensed, Git repository at
<a href="http://gitorious.org/maximus/mandulia" title="maximus/mandulia">maximus/mandulia</a>
on Gitorious, or you can download
<a href="/code/mandulia/mandulia-0.4.tar.gz" title="mandulia-0.4.tar.gz">mandulia-0.4.tar.gz</a>.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-07-12_mandulia-0.4_released.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-07-12_mandulia-0.4_released.html</guid><pubDate>12 Jul 2010 21:05:10 GMT</pubDate><category>fractal</category><category>haskell</category><category>lua</category><category>video</category></item><item><title>Mandulia</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="/g/mandulia/mandulia_2010-07-06_am.html" title="Mandulia gallery"><img src="2010-07-06_mandulia.png" alt="Mandulia"/></a></p>
<p><a href="/v/mandulia/mandulia_2010-07-06_pm.ogv" title="Mandulia video">Mandulia video</a> (47MB, Ogg Theora)</p>
<p>As I <a href="2010-06-24_gpu_julia_sets.html" title="GPU Julia Sets">briefly explained</a>
there's a connection between the Mandelbrot set and Julia sets, of which this project here
takes advantage.  An
<a href="/v/mandulia/mandulia_d_hi.ogv" title="Manulia prototype">earlier prototype</a> (100MB, Ogg Theora)
had an alternating square/diamond lattice, which
was visually a bit unpleasant.  So thanks to some people on #haskell IRC, I got pointed
to substitution tilings, and in particular the
<a href="http://tilings.math.uni-bielefeld.de/substitution_rules/ammann_a3" title="Ammann A3 Tiling">Ammann A3 tiling</a>
caught my eye while browsing the thingy.  What struck me was the semi-regular
spacing of the light blue/grey tiles, and the fact that there is a fixed point
within each of those in the substitution rules: this fit my goal of an aperiodic
point cloud with
<a href="/v/mandulia/ammann_a3_zoom.gif" title="Mandulia concept">new points appearing in the gaps</a> (1MB, Animated GIF)
when zooming in (maintaining stability of the existing points).</p>
<p>The main program is written in Haskell, with the Julia Set
renderer implemented in C (I found that GPU processing is actually less
efficient than using the CPU for this problem, maybe I'm just doing it
wrong but it seems like there are a lot of conditional loops and not enough
data-parallelism).  I learned some stuff about Control.Concurrent things in
Haskell, like using nested MVar's to build a job scheduler and resource
reallocator and whether to use safe or unsafe foreign imports with the
threaded Haskell runtime (I think safe means it's slower for short calls
but for long calls like rendering a fractal it works out faster as the
runtime isn't blocked).</p>
<p>Source code is GPLv3+ licensed, Git repository at
<a href="http://gitorious.org/maximus/mandulia" title="maximus/mandulia">maximus/mandulia</a>
on Gitorious.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-07-06_mandulia.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-07-06_mandulia.html</guid><pubDate>06 Jul 2010 13:45:31 GMT</pubDate><category>fractal</category><category>haskell</category><category>video</category></item><item><title>King James Hyperfuck</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="2010-06-15_king_james_hyperfuck.jpg" alt="King James Hyperfuck"/></p>
<p>(For the sake of this post, it is better to consider the
language non-profane.)</p>
<p><a href="http://en.wikipedia.org/wiki/Brainfuck" title="Brainfuck">Brainfuck</a>
is an esoteric programming language based on a
minimal
<a href="http://en.wikipedia.org/wiki/Turing_machine" title="Turing machine">Turing machine</a>:
it has a data tape and a code array,
the instructions in the code modify the data in cells on the
tape. Despite the presence of only a few simple instructions
in the language it is theoretically possible to compute
everything that can be computed within the Church/Turing
model of computation; further an even more minimal
derivative of Brainfuck,
<a href="http://web.archive.org/web/20070403131306/http://www.rpi.edu/~hughes/boof/" title="Boolfuck">Boolfuck</a>,
restricts the data on
the tape to consist only of single bits (either 0 or 1, instead of
bytes from 0 to 255).</p>
<p>Now, consider changing the structure of the data 'tape', in
particular extending it into a 2D hyperbolic plane.
<a href="http://en.wikipedia.org/wiki/Hyperbolic_geometry" title="Hyperbolic geometry">Hyperbolic geometry</a>
allows many parallel lines to a given
line through a given point not on the line, with the
consequence that the hyperbolic plane has exponentially more
space than the common flat Euclidean plane.</p>
<p>Now, it is possible to
<a href="http://en.wikipedia.org/wiki/Uniform_tilings_in_hyperbolic_plane" title="Uniform tilings in hyperbolic plane">tile the hyperbolic plane</a>
with congruent shapes, in many more ways than flat space can be
tiled.  For example, with one particularly shaped pentagonal
tile, one can tile the hyperbolic plane in uncountably
infinitely many ways.  To navigate in this new arrangement
of cells in this hyperbolic pentagonal tape, one adds three
new instructions to the language: in addition to moving the
cursor in the data tape East and West, new instructions
allow moving North, South-East and South-West.</p>
<p>This best visualised in the
<a href="http://en.wikipedia.org/wiki/Poincar%C3%A9_half-plane_model" title="Poincaré half-plane">Poincaré half-plane</a>
model of hyperbolic geometry, in which shapes are distorted to give a
horizon at infinity to the South (compare with the
<a href="http://en.wikipedia.org/wiki/Poincar%C3%A9_disk_model" title="Poincaré disk model">Poincaré disk model</a>
in which there is a circular horizon at infinity,
most popularized by M C Escher's
<a href="http://en.wikipedia.org/wiki/File:Escher_Circle_Limit_III.jpg" title="Circle Limit III">Circle Limit I-IV</a>
prints).</p>
<p>This 2D hyperbolic modification of Boolfuck I call
<strong>Hyperfuck</strong>, for fairly obvious reasons.</p>
<p>Now, the pentagonal tiling described above has a kind of
tree-like memory property: if you proceed from a starting
location and head North, you might enter the pentagon above
from either its South-East edge or its South-West edge: this
allows information to be encoded in the geometry of the
initial configuration of the system.  By
modifying data in the cells and moving suitably, comparing
the results of the movements with what you expect allows you
to recover the stored bitstream.  Further, this information
need have no bound, for example one could encode an infinite
library of every book ever written and that ever will be
written (compare with
<a href="http://en.wikipedia.org/wiki/The_Library_of_Babel" title="The Library of Babel">Borges</a>,
the
<a href="http://en.wikipedia.org/wiki/Infinite_monkey_theorem" title="Infinite monkey theorem">Shakespeare Typing Monkeys</a>,
and the text entry software
<a href="http://en.wikipedia.org/wiki/Dasher" title="Dasher">Dasher</a>).</p>
<p>However, a suitable source of information if a programmer
is to be able to write useful programs more easily needs to
be widely known and predictable: thus I propose the
<a href="http://en.wikipedia.org/wiki/ASCII" title="ASCII">ASCII</a>
<a href="http://en.wikipedia.org/wiki/Bitstream" title="Bitstream">bitstream</a> of
<a href="http://www.gutenberg.org/etext/10" title="King James version of the Christian Bible">a certain authorized version of the Christian Bible</a>.</p>
<p>This liturgical modification of Hyperfuck I call
<strong>King James Hyperfuck</strong>,
for fairly obvious reasons.</p>
<p>A simple program can reconstruct the text; its source code:</p>
<blockquote><pre>+[^\;^+]</pre></blockquote>
<p>The current King James Hyperfuck interpreter is implemented in Haskell,
using OpenGL to visualize the data tape, code tape, and output text.  It
also sends event information (the current instruction being executed) to
Pure-data for sonification.  There is also a (currently unfinished) SVG
and ECMAScript version to run inside a web browser.  The original prototype
was implemented in C.  Source code is available at
<a href="http://gitorious.org/maximus/kjhf" title="kjhf">maximus/kjhf at gitorious.org</a>.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-06-15_king_james_hyperfuck.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-06-15_king_james_hyperfuck.html</guid><pubDate>15 Jun 2010 07:34:56 GMT</pubDate><category>fractal</category><category>haskell</category><category>hyperspace</category></item><item><title>Cathedral Algorithms Video</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://www.archive.org/details/ClaudiusMaximus_-_Cathedral_Algorithms_Video" title="Cathedral Algorithms_Video"><img src="2010-06-13_cathedral_algorithms_video.png" alt="Cathedral Algorithms Video"/></a></p>
<p>A minimal fractal music video for <a href="2010-06-08_cathedral_algorithms.html" title="Cathedral Algorithms">Cathedral Algorithms</a>.</p>
<p>Download options:</p>
<ul>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Cathedral_Algorithms_Video/ClaudiusMaximus_-_Cathedral_Algorithms.mpeg" title="Cathedral Algorithms (DVD)">DVD (968MB)</a></li>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Cathedral_Algorithms_Video/ClaudiusMaximus_-_Cathedral_Algorithms.ogv" title="Cathedral Algorithms (Ogg)">Ogg (79MB)</a></li>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Cathedral_Algorithms_Video/ClaudiusMaximus_-_Cathedral_Algorithms_512kb.mp4" title="Cathedral Algorithms (MP4)">MP4 (69MB)</a></li>
</ul>
<p>The main code to render the video is ~185 lines of Haskell, available as part of 
<a href="http://gitorious.org/maximus/dr1" title="dr1">maximus/dr1 at gitorious.org</a>.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-06-13_cathedral_algorithms_video.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-06-13_cathedral_algorithms_video.html</guid><pubDate>13 Jun 2010 07:55:55 GMT</pubDate><category>fractal</category><category>haskell</category><category>video</category></item><item><title>Bowntz</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="2010-03-12_bowntz.png" alt="Bowntz"/></p>
<p>Bowntz is a little world of colliding circles, implemented in Haskell
using OpenGL for video and SuperCollider3 for audio.
Its simulation algorithm is based on directly calculating the time until
the next collision rather than stepping through time at a constant rate.</p>
<p><a href="http://gitorious.org/bowntz" title="Bowntz (Gitorious)">Bowntz source code repository at Gitorious</a></p>
<blockquote><pre>git clone git://gitorious.org/bowntz/bowntz.git</pre></blockquote>
<p><a href="http://claudiusmaximus.goto10.org/v/bowntz/bowntz-demo-1.ogv" title="Bowntz (demo 1)">Bowntz (demo 1) video</a></p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-03-12_bowntz.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-03-12_bowntz.html</guid><pubDate>12 Mar 2010 03:13:23 GMT</pubDate><category>haskell</category><category>sc3</category></item><item><title>Temple</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://www.archive.org/details/ClaudiusMaximus_-_Temple" title="Temple"><img src="2010-01-10_temple.jpg" alt="Temple"/></a></p>
<p>brain massage generative music video // fractal video made with <a href="2009-09-24_fl4m6e_in_haskell.html" title="Fl4m6e in Haskell">Fl4m6e</a> // organic audio made with Pure-data using GridFlow and Zexy</p>
<p>Downloads:</p>
<ul class="downloads">
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Temple/ClaudiusMaximus_-_Temple.mpeg" title="Temple (DVD)">DVD</a> (287MB)</li>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Temple/ClaudiusMaximus_-_Temple.ogv" title="Temple (Ogg)">Ogg</a> (24MB)</li>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Temple/ClaudiusMaximus_-_Temple_512kb.mp4" title="Temple (MPEG4)">MPEG4</a> (21MB)</li>
</ul>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2010-01-10_temple.html</link><guid>http://claudiusmaximus.goto10.org/cm/2010-01-10_temple.html</guid><pubDate>10 Jan 2010 22:00:00 GMT</pubDate><category>fractal</category><category>haskell</category><category>pd</category><category>video</category></item><item><title>Heist: busted!</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="2009-12-06_heist_busted.png" alt="Heist: busted!"/></p>
<p>FAuSt has a nifty n-ary block diagram parallel composition operator, in which
you give it a count and a function from numbers to block diagrams.  Something
with the same meaning as:</p>
<blockquote><pre>parallel n f = foldr1 Par (map f [0..(n-1)])</pre></blockquote>
<p>If only life were so simple: that won't compile, because of my decision in
<a href="2009-12-04_heist_dataflow_algebra.html" title="Heist: dataflow algebra">Heist</a>
to express the type system of block diagram algebra within Haskell's type system.
So after about 4 hours of head scratching, I finally figured out how to
generalize from this:</p>
<blockquote><pre>par0 f = empty
par1 f = par0 f `Par` f 0
par2 f = par1 f `Par` f 1
par3 f = par2 f `Par` f 2
par4 f = par3 f `Par` f 3
...</pre></blockquote>
<p>to the point where this compiles successfully:</p>
<blockquote><pre>import Types.Data.Num.Decimal (d2, d4)
import Heist (Bd (Seq), parallel, add)
import Dot (toDot)

main = putStrLn(toDot(

    parallel d4 (const add) `Seq`
    parallel d2 (const add) `Seq`
    add

  ))</pre></blockquote>
<p>Check out the code to see the horrible gory details, where at the time
of writing (Subversion revision 1582) the relevant excerpt is lines
222-256 of Heist.hs:</p>
<blockquote><pre>svn co https://code.goto10.org/svn/maximus/2009/heist heist</pre></blockquote>
<p>At this point I was happy and delighted, but not for long.  I tried to
compile a program containing <em>parallel d8 add</em> and waited, and waited,
only to find (7.5 minutes later...) that GHC reached my operating system's
limit of 3GB per process and gave up.  It was a similar story when explicitly
limiting the heap size.  I ran some tests and it seemed that the compilation
time grew exponentially with the parallel count.</p>
<p>The "shortcut" of embedding FAuSt semantics inside Haskell to avoid
having to write a parser and type checker and all the rest turned out to be
a rather more "scenic route" through type level programming, but in summary:
theoretically beautiful, epic fail in practice.</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2009-12-06_heist_busted.html</link><guid>http://claudiusmaximus.goto10.org/cm/2009-12-06_heist_busted.html</guid><pubDate>06 Dec 2009 02:00:00 GMT</pubDate><category>haskell</category></item><item><title>Heist: dataflow algebra</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><img src="2009-12-04_heist_dataflow_algebra.png" alt="Heist: dataflow algebra"/></p>
<p>So I was playing around with
<a href="http://faust.grame.fr/" title="FAuSt">FAuSt</a>,
a pure functional dataflow language for audio stream processing.  At first I
thought it was great, but then the compiler bugs bit hard: declaring two variables
with the same name in the same scope made the compiler segfault [2010-01-13 update: I have
not been able to reproduce this crash, so I'm probably wrong about the cause], and for some
reason it thought the index variables in my parallel constructs were duplicates
too.  I was trying to build a 16x16 matrix multiplication to implement my
favourite reverb... perhaps too ambitious?  Simple things are very concise
in FAuSt, though: I implemented Pure-data's <strong>vcf~</strong> in roughly
the same number of characters as the number of lines of code that the C
implementation had:</p>
<blockquote><pre>vcf(q,f,x) = w ~ (_,_) with {
  a = max(f * 2 * PI / SR, 0);
  r = max(1 - a / q, 0);
  c = r * cos(a);
  s = r * sin(a);
  k = (2 - 2 / (q + 2)) * (1 - r);
  w(u,v) = (k * x + c * u - s * v) , (s * u + c * v);
};</pre></blockquote>
<p>So I thought to myself, with Haskell's awesomeness I should be able to
embed the core of the FAuSt block diagram algebra semantics in a typesafe way.
Much headsploding followed, figuring out how to bluff my way through type-level
programming, until I managed to express the preconditions and results of each
of the five block diagram composition operators.</p>
<p>It might help to know what a block diagram is and how they can be composed.
For that I recommend Chapter 3 of
<a href="ftp://ftp.grame.fr/pub/Documents/faust_tutorial.pdf" title="A FAuSt Tutorial">A FAuSt Tutorial (PDF)</a>.
I decided that GADTs were what I needed, with constructors for each of the
composition operators, and one for primitives:</p>
<blockquote><pre><strong>-- abstract block diagrams</strong>
data Bd t where
  Rec   :: (...) =&gt; Bd i -&gt; Bd j -&gt; Bd k
  Par   :: (...) =&gt; Bd i -&gt; Bd j -&gt; Bd k
  Seq   :: (...) =&gt; Bd i -&gt; Bd j -&gt; Bd k
  Split :: (...) =&gt; Bd i -&gt; Bd j -&gt; Bd k
  Merge :: (...) =&gt; Bd i -&gt; Bd j -&gt; Bd k
  Prim  :: (...) =&gt; String  -&gt; k -&gt; Bd k
</pre></blockquote>
<p>I've omitted the contexts here, because they are quite long, expressing the
necessary preconditions on the shapes of the block diagram inputs and the resulting
output block diagram shape.  I'm using "shape" to mean a pair of type-level lists,
for example a standard <em>(+) :: Float -&gt; Float -&gt; Float</em> operator lifted
to a block diagram could have a shape like <em>(Float :. Float :. Nil, Float :. Nil)</em>,
depending on how spicy you like your curry.</p>
<p>FAuSt semantics for the recursive composition operator <em>A~B</em> are described
informally like this (where (i|o)X is the number of inputs|outputs of X):</p>
<ul>
<li>the first iB outputs of A are fed into the inputs of B</li>
<li>the outputs of B are fed into the first oB inputs of A</li>
<li>the remaining iA-oB inputs of A are the inputs of A~B</li>
<li>the oA outputs of A are the outputs of A~B</li>
</ul>
<p>From this description it's easy to see the requirement that oA&gt;=iB and iA&gt;=oB,
moreover the types of the inputs must match the types of the outputs they are connected
to.  This precondition on the compatibility of the shapes, and the shape of their
composition, can be expressed like this:</p>
<blockquote><pre><strong>-- recursive composition compatibility and result shape</strong>
type family IsRecCompat x y
type instance IsRecCompat (xi, xo) (yi, yo) = (Take (Length yi) xo `Equals` yi) :&amp;&amp;: (Take (Length yo) xi `Equals` yo)
type family RecShape x y
type instance RecShape (xi, xo) (yi, yo) = (Drop (Length yo) xi, xo)</pre></blockquote>
<p>Here <em>Take</em>, <em>Drop</em>, <em>Length</em>, and <em>Equals</em> operate on
type-level lists.  The full type of the Rec constructor is now:</p>
<blockquote><pre><strong>  -- recursive composition constructor</strong>
  Rec   :: (NaturalT (Length ai), NaturalT (Length ao),
            NaturalT (Length bi), NaturalT (Length bo),
            NaturalT (Length ci), NaturalT (Length co),
            i ~ (ai,ao), j ~ (bi,bo), k ~ (ci,co),
            IsRecCompat   i j ~ True, RecShape   i j ~ k)
        =&gt; Bd i -&gt; Bd j -&gt; Bd k</pre></blockquote>
<p>where the first 4 lines express that the lengths of the lists are non-negative
numbers and that the shapes are pairs of lists - not sure how to simplify this
boilerplate which is present for all the operators, but it seems to work ok.</p>
<p>With the fixities as in FAuSt...</p>
<blockquote><pre>infixl 4 `Rec`
infixl 3 `Par`
infixl 2 `Seq`
infixl 1 `Split`
infixl 1 `Merge`</pre></blockquote>
<p>...and suitable definitions of primitives, it's possible to write expressions
that look like a more verbose FAuSt, and manipulate them in various ways:</p>
<blockquote><pre><strong>-- example</strong>
main = putStrLn (toDot(
  castF `Par` castF
  `Split`
  ( addF `Par` subF `Par` mulF
     `Split`
     (addF `Par` addF `Par` subF `Par` divF `Par` negF)
  ) `Par` addF
  `Merge`
  addF `Par` castI
  ))</pre></blockquote>
<p>I won't talk about the toDot code right now, as it's not too impressive
compared to the rest of the code - but if you want to look the whole lot is
in my messy Subversion repository:</p>
<blockquote><pre>svn co https://code.goto10.org/svn/maximus/2009/heist heist</pre></blockquote>
<p>And why the name Heist?  Maybe I'm trying to steal FAuSt's thunder!  Or it could just
be that it's got an H and an S in it...</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2009-12-04_heist_dataflow_algebra.html</link><guid>http://claudiusmaximus.goto10.org/cm/2009-12-04_heist_dataflow_algebra.html</guid><pubDate>04 Dec 2009 01:23:45 GMT</pubDate><category>haskell</category></item><item><title>Reflex preview</title><description><![CDATA[<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://www.archive.org/details/ClaudiusMaximus_-_Reflex_r1460" title="Reflex r1460"><img src="2009-10-15_reflex_preview.png" alt="Reflex r1460"/></a></p>
<p>The latest experiment in 4D visualisation fresh from the labs. Downloads:</p>
<ul class="downloads">
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Reflex_r1460/reflex-r1460.mpeg">DVD</a> (85MB)</li>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Reflex_r1460/reflex-r1460.ogv">Ogg</a> (6.05MB)</li>
<li><a href="http://www.archive.org/download/ClaudiusMaximus_-_Reflex_r1460/reflex-r1460_512kb.mp4">MPEG4</a> (7.45MB)</li>
</ul>
<p>
What Reflex does first is: given a {p,q,r} specification of a 4D polytope,
calculate the fundamental region (being a collection of 4 planes through
the origin), from which calculate the symmetry group (being the group
closure of the reflections in those planes).
</p><p>
What Reflex does next is: given four non-negative numbers (being the
relative distances from the planes bounding the fundamental region),
find the point thus represented, further find additional points at the
centres of neighbouring 1-lines, 2-surfaces and 3-solids, and then find
all images of that figure under the action of the symmetry group.
</p><p>
What Reflex finally does is a stereographic projection to 3D, assuming
the original 4D figure is in the surface of a sphere, followed by a
normal perspective projection to 2D - with a selection of the figures'
subcomponents displayed (currently each of the six 2-surfaces can be
toggled on/off - earlier versions did the same with the four 1-lines).
</p><p>
Reflex runs in realtime at reasonable frame rate and CPU usage provided
I turn off the interpolation completely (which stops the curves being so
smooth, alas) and don't try to render the mammoth {5,3,3} (which has a
symmetry group with 14400 elements).
</p><p>
But nothing new under the sun, essentially this is all just a clone of
<a href="http://web.mit.edu/~axch/www/Symmetriad/index.html" title="The Symmetriad">The Symmetriad</a>.
I might write up some of the maths in an article later, meanwhile you can
find the totally undocumented code in my mess of a Subversion repository:</p>
<blockquote><pre>svn co https://code.goto10.org/svn/maximus/2009/dualist reflex</pre></blockquote>
<p>(Hint: you need to generate the .4d files first, then ./reflex-jack.sh
will fire up a Pd GUI to send commands to Reflex.  SuperBonusPoints for
anyone who gets it working, like the title says, just a preview...)</p>
</div>]]></description><link>http://claudiusmaximus.goto10.org/cm/2009-10-15_reflex_preview.html</link><guid>http://claudiusmaximus.goto10.org/cm/2009-10-15_reflex_preview.html</guid><pubDate>15 Oct 2009 15:15:15 GMT</pubDate><category>haskell</category><category>hyperspace</category><category>video</category></item></channel></rss>
