<?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>George MacKerron: code blog</title>
	<atom:link href="http://blog.mackerron.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mackerron.com</link>
	<description>GIS, software development, and other snippets</description>
	<lastBuildDate>Fri, 03 Feb 2012 18:35:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A depthcam? A webkinect? Introducing a new kind of webcam</title>
		<link>http://blog.mackerron.com/2012/02/03/depthcam-webkinect/</link>
		<comments>http://blog.mackerron.com/2012/02/03/depthcam-webkinect/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 18:21:10 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[WebGL]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=1005</guid>
		<description><![CDATA[At CASA we&#8217;ve been looking at using a Kinect or three in our forthcoming ANALOGIES (Analogues of Cities) conference + exhibition. We&#8217;ve been inspired in part by Ruairi Glynn&#8216;s amazing work here at UCL, and Martin has been happily experimenting with the OpenKinect bindings for Processing. Meanwhile, I recently got to grips with the excellent [...]]]></description>
			<content:encoded><![CDATA[<p><strong>At <a href="http://www.bartlett.ucl.ac.uk/casa"><span class="caps">CASA</span></a> we&#8217;ve been looking at using a <a href="http://en.wikipedia.org/wiki/Kinect">Kinect</a> or three in our forthcoming <span class="caps">ANALOGIES </span>(Analogues of Cities) conference + exhibition.</strong> </p>

<p>We&#8217;ve been inspired in part by <a href="http://www.ruairiglynn.co.uk/">Ruairi Glynn</a>&#8216;s amazing work here at <span class="caps">UCL, </span>and <a href="http://martinzaltzaustwick.wordpress.com/">Martin</a> has been happily experimenting with the OpenKinect <a href="http://www.shiffman.net/p5/kinect/">bindings</a> for <a href="http://processing.org/">Processing</a>.</p>

<p>Meanwhile, I <a href="http://mackerron.com/snow-mo/">recently got to grips</a> with the excellent <a href="https://github.com/mrdoob/three.js/">Three.js</a>, which makes WebGL &#8212; aka 3D graphics in modern browsers &#8212; as easy as falling off a log. I&#8217;m also a big fan of making things accessible over the web. And so I began to investigate prospects for working with Kinect data in <span class="caps">HTML5.</span></p>

<p>There&#8217;s <a href="https://github.com/doug/depthjs">DepthJS</a>, an extension for Chrome and Safari, but this requires a locally-connected Kinect and isn&#8217;t very clear on Windows support. There&#8217;s also <a href="http://code.google.com/p/intrael/">Intrael</a>, which serves the depth data as <span class="caps">JPEG </span>files and provides some simple scene recognition output as <span class="caps">JSON.</span> But it&#8217;s closed-source and not terribly flexible.</p>


<h2>The depthcam</h2>

<p>So I decided to roll my own. I give you: <a href="http://depthcam.nodester.com/">the depthcam</a>! </p>

<p><a href="http://depthcam.nodester.com/"><img src="http://blog.mackerron.com/wp-content/uploads/2012/02/Screen-Shot-2012-02-03-at-17.45.02.png" alt="Screenshot" style="border: none; position: relative; left: -55px;" /></a></p>

<p><a href="http://depthcam.nodester.com/">Click here</a> or on the screenshot to connect.</p>

<p>It&#8217;s a live-streaming 3D point-cloud, carried over a binary WebSocket. It responds to movement in the scene by panning the (virtual) camera, and you can also pan and zoom around with the mouse.</p>

<p>Currently you&#8217;ll need <a href="http://www.google.com/chrome">Google Chrome</a> to try it, and the number of people who can tune in at once is limited for reasons of bandwidth. If you can&#8217;t connect, or nothing much is happening, try this <a href="http://www.youtube.com/watch?v=GfRPyh7iubQ">short video on YouTube</a> instead.</p>

<p>It might be the future of video-conferencing. It could also be the start of a new wave of web-based movement-powered games.</p>

<p><span id="more-1005"></span></p>

<h2>How it works</h2>

<p>The code is <a href="https://github.com/jawj/websocket-kinect">on GitHub</a>, and is in three parts:</p>


<ol>
<li><strong>A short Python script</strong> wiring up the <a href="http://openkinect.org/wiki/Python_Wrapper">OpenKinect Python wrapper</a> to the <a href="http://www.tavendo.de/autobahn/">Autobahn WebSockets library</a>. Depending on the arguments it&#8217;s run with, this can either serve a web browser directly, or it can push the depth data up to&#8230;</li>
<li><strong>A simple <a href="http://nodejs.org/">node.js</a> server</strong> that gets us round the <span class="caps">UCL </span>firewall. This accepts depth data pushed from the Python script, and broadcasts it onwards (still using binary WebSockets) to any connected web browsers, which are running&#8230;</li>
<li><strong>The web-based client,</strong> written in <a href="http://coffeescript.org/">CoffeeScript</a>. This connects to the node.js server, receives the depth data, and visualises it as a particle system using Three.js and WebGL.</li>
</ol>



<p>The incoming data from the Kinect is pretty heavy, at 18 MB/s (640 &#215; 480 &#215; 2 bytes per pixel x 30Hz). This is more than we can expect to (or afford to!) push over the Internet. So the Python script does some basic video compression to cut this down by several orders of magnitude, to 30 &#8211; 100 KB/s. It follows this three-step recipe:</p>


<ol>
<li><strong>Reduce the amount of data</strong> by down-sampling and quantizing to 160 &#215; 120 &#215; 1 byte per pixel.</li>
<li><strong>Increase the data&#8217;s compressibility.</strong> First, reduce noise &#8212; which also looks bad &#8212; by making each transmitted depth value (i.e. pixel) the median of the values received in the last three frames. Then express each value as its difference from the previous value, with just an occasional absolute-value <a href="http://en.wikipedia.org/wiki/Keyframe#Video_compression">keyframe</a> to allow new viewers to pick up the stream.</li>
<li><strong>Compress the data</strong> using <a href="http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm"><span class="caps">LZMA</span></a>, which gets better compression ratios than <span class="caps">GZIP </span>or <span class="caps">BZIP2, </span>and decompression times somewhere between the two.</li>
</ol>



<p>Feel free to <a href="https://github.com/jawj/websocket-kinect">fork the code</a> and do something great with it.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2012/02/03/depthcam-webkinect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Polygons from PostGIS to Processing</title>
		<link>http://blog.mackerron.com/2011/11/17/polygons-from-postgis-to-processing/</link>
		<comments>http://blog.mackerron.com/2011/11/17/polygons-from-postgis-to-processing/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 11:28:43 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[GIS]]></category>
		<category><![CDATA[PostGIS]]></category>
		<category><![CDATA[Processing]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=942</guid>
		<description><![CDATA[There are plenty of ways to get spatial data from a PostGIS database into a Processing sketch. You can export to CSV or SVG and load it from there; you can query the database directly; or, depending on context, you might choose to generate Processing commands directly, which is the route I went to display [...]]]></description>
			<content:encoded><![CDATA[<p><strong>There are plenty of ways to get spatial data from a PostGIS database into a <a href="http://processing.org/">Processing</a> sketch.</strong></p>

<p>You can export to <span class="caps">CSV </span>or <span class="caps">SVG </span>and load it from there; you can <a href="http://bezier.de/processing/libs/sql/documentation/de/bezier/data/sql/PostgreSQL.html">query the database directly</a>; or, depending on context, you might choose to generate Processing commands directly, which is the route I went to display a background map of the UK in a recent visualization project.</p>

<p><span id="more-942"></span></p>

<p>First, I load outlines of the 4 constituent countries of the UK into my PostGIS database.</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">shp2pgsql <span style="color: #660033;">-d</span> <span style="color: #660033;">-D</span> <span style="color: #660033;">-I</span> <span style="color: #660033;">-s</span> <span style="color: #000000;">27700</span> <span style="color: #ff0000;">&quot;/pgdata/geodata/Nations/england.shp&quot;</span> eng \
  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #660033;">-u</span> postgres psql mappiness
shp2pgsql <span style="color: #660033;">-d</span> <span style="color: #660033;">-D</span> <span style="color: #660033;">-I</span> <span style="color: #660033;">-s</span> <span style="color: #000000;">27700</span> <span style="color: #ff0000;">&quot;/pgdata/geodata/Nations/wales.shp&quot;</span> wal \
  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #660033;">-u</span> postgres psql mappiness
shp2pgsql <span style="color: #660033;">-d</span> <span style="color: #660033;">-D</span> <span style="color: #660033;">-I</span> <span style="color: #660033;">-s</span> <span style="color: #000000;">27700</span> <span style="color: #ff0000;">&quot;/pgdata/geodata/Nations/scotland.shp&quot;</span> sco \
  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #660033;">-u</span> postgres psql mappiness
shp2pgsql <span style="color: #660033;">-d</span> <span style="color: #660033;">-D</span> <span style="color: #660033;">-I</span> <span style="color: #660033;">-s</span> <span style="color: #000000;">27700</span> <span style="color: #ff0000;">&quot;/pgdata/geodata/Nations/nireland_ol_2001.shp&quot;</span> ni \
  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #660033;">-u</span> postgres psql mappiness</pre></div></div>




<p>Next, I combine these into one table, using <code>st_simplifypreservetopology</code> to discard a lot of unnecessary detail and <code>st_dump</code> to dissolve some English <span class="caps">MULTIPOLYGON</span>s into simple <span class="caps">POLYGONS.</span></p>


<div class="wp_syntax"><div class="code"><pre class="postgresql" style="font-family:monospace;"><span style="color: #005500;">create</span> <span style="color: #005500;">table</span> uk1km <span style="color: #005500;">as</span> <span style="color: #66cc66;">&#40;</span>
        <span style="color: #005500;">select</span> st_simplifypreservetopology<span style="color: #66cc66;">&#40;</span>the_geom, <span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">as</span> the_geom <span style="color: #005500;">from</span> 
          <span style="color: #66cc66;">&#40;</span><span style="color: #005500;">select</span> <span style="color: #66cc66;">&#40;</span>st_dump<span style="color: #66cc66;">&#40;</span>the_geom<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.geom <span style="color: #005500;">as</span> the_geom <span style="color: #005500;">from</span> eng<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">as</span> eng_single
  <span style="color: #005500;">union</span> <span style="color: #005500;">select</span> st_simplifypreservetopology<span style="color: #66cc66;">&#40;</span>the_geom, <span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">as</span> the_geom <span style="color: #005500;">from</span> wal
  <span style="color: #005500;">union</span> <span style="color: #005500;">select</span> st_simplifypreservetopology<span style="color: #66cc66;">&#40;</span>the_geom, <span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">as</span> the_geom <span style="color: #005500;">from</span> sco
  <span style="color: #005500;">union</span> <span style="color: #005500;">select</span> st_simplifypreservetopology<span style="color: #66cc66;">&#40;</span>the_geom, <span style="color: #cc66cc;">1000</span><span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">as</span> the_geom <span style="color: #005500;">from</span> ni
<span style="color: #66cc66;">&#41;</span>;
<span style="color: #005500;">alter</span> <span style="color: #005500;">table</span> uk1km <span style="color: #005500;">add</span> <span style="color: #005500;">column</span> id serial <span style="color: #005500;">primary</span> <span style="color: #005500;">key</span>;
<span style="color: #005500;">drop</span> <span style="color: #005500;">table</span> eng; <span style="color: #005500;">drop</span> <span style="color: #005500;">table</span> wal; <span style="color: #005500;">drop</span> <span style="color: #005500;">table</span> sco; <span style="color: #005500;">drop</span> <span style="color: #005500;">table</span> ni;</pre></div></div>




<p>Finally, I use <code>string_agg</code> to produce the <code>vertex()</code> commands required to reproduce my polygons in Processing. I change the sign on the y-coordinate (from northings to &#8216;southings&#8217;, to match the Processing coordinate space). I scale the <span class="caps">OSGB36 </span>coordinates down from metres to kilometres (I could otherwise have done this with a <code>scale()</code> command in Processing). And I discard a lot of small polygons (comprising 20 <span class="caps">POINT</span>s or fewer) I don&#8217;t need in my output.</p>


<div class="wp_syntax"><div class="code"><pre class="postgresql" style="font-family:monospace;"><span style="color: #005500;">select</span> <span style="color: #ff0000;">'beginShape(); '</span> 
    <span style="color: #66cc66;">||</span> <span style="color: #333399;">string_agg</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'vertex('</span> <span style="color: #66cc66;">||</span> st_x<span style="color: #66cc66;">&#40;</span>geom<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">', '</span> <span style="color: #66cc66;">||</span> -st_y<span style="color: #66cc66;">&#40;</span>geom<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'); '</span>, <span style="color: #ff0000;">''</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'endShape(CLOSE); '</span> 
<span style="color: #005500;">from</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #005500;">select</span> id, <span style="color: #66cc66;">&#40;</span>st_dumppoints<span style="color: #66cc66;">&#40;</span>st_exteriorring<span style="color: #66cc66;">&#40;</span>st_scale<span style="color: #66cc66;">&#40;</span>the_geom, <span style="color: #cc66cc;">0.001</span>, <span style="color: #cc66cc;">0.001</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.geom <span style="color: #005500;">as</span> geom 
  <span style="color: #005500;">from</span> uk1km 
  <span style="color: #005500;">where</span> st_numpoints<span style="color: #66cc66;">&#40;</span>st_exteriorring<span style="color: #66cc66;">&#40;</span>the_geom<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">20</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">as</span> d
<span style="color: #005500;">group</span> <span style="color: #005500;">by</span> id;</pre></div></div>




<p>Then, to draw the UK in a sketch I do this.</p>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">size<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">350</span>, <span style="color: #cc66cc;">620</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
translate<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span>, height<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
scale<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0.5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// paste in the output of the previous query</span></pre></div></div>




<p>Which has this result (with thanks to <a href="http://edina.ac.uk"><span class="caps">EDINA</span></a> for the data):</p>

<p><img src="http://blog.mackerron.com/wp-content/uploads/2011/11/Screen-Shot-2011-11-17-at-11.19.44.png" alt="The UK as drawn by this method" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/11/17/polygons-from-postgis-to-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passcode view controller</title>
		<link>http://blog.mackerron.com/2011/10/28/passcode-view-controller/</link>
		<comments>http://blog.mackerron.com/2011/10/28/passcode-view-controller/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 16:33:25 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=511</guid>
		<description><![CDATA[Need to protect something with a passcode in an iPhone app you&#8217;re developing? Then you may find my MIT-licensed passcode view controller &#8212; as seen in the mappiness app and in the short screencast below &#8212; of use. See Github for the code and (scant) documentation. Download video as MP4, WebM, or Ogg.]]></description>
			<content:encoded><![CDATA[<p><strong>Need to protect something with a passcode in an iPhone app you&#8217;re developing?</strong></p>

<p>Then you may find my <span class="caps">MIT</span>-licensed passcode view controller &#8212; as seen in the <a href="http://www.mappiness.org.uk">mappiness</a> app and in the short screencast below &#8212; of use. </p>

<p>See Github for the <a href="https://github.com/jawj/PasscodeViewController">code and (scant) documentation</a>.</p>

<video width="292" height="622" controls="controls"><br />
  <source src="/wp-content/uploads/2011/07/Passcode1.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'><br />
  <source src="/wp-content/uploads/2011/07/Passcode1.theora.ogv"  type='video/ogg; codecs="theora, vorbis"'><br />
  <source src="/wp-content/uploads/2011/07/Passcode1.webm" type='video/webm; codecs="vp8, vorbis"'><br />
  <object width="292" height="622" type="application/x-shockwave-flash" data="flowplayer-3.2.1.swf"> <br />
    <param name="movie" value="/wp-content/uploads/2011/07/flowplayer-3.2.7.swf" /> <br />
    <param name="allowfullscreen" value="true" /> <br />
    <param name="flashvars" value='config={"clip": {"url": "/wp-content/uploads/2011/07/Passcode1.mp4", "autoPlay":false, "autoBuffering":false}}' /><br />
    <p>Download video as <a href="/wp-content/uploads/2011/07/Passcode1.mp4"><span class="caps">MP4</span></a>, <a href="/wp-content/uploads/2011/07/Passcode1.webm">WebM</a>, or <a href="/wp-content/uploads/2011/07/Passcode1.theora.ogv">Ogg</a>.</p>
  </object><br />
</video>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/10/28/passcode-view-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Approximating kernel-weighted proportions in PostGIS</title>
		<link>http://blog.mackerron.com/2011/08/16/kernel-weighted-proportions-postgis/</link>
		<comments>http://blog.mackerron.com/2011/08/16/kernel-weighted-proportions-postgis/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 13:27:23 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[GIS]]></category>
		<category><![CDATA[PostGIS]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=864</guid>
		<description><![CDATA[Imagine you want compare various locations in terms of the availability of a certain type of environment, such as fresh water. You might want to use a measure of the proximity of that environment &#8212; such as the nearest neighbour distance. You might want to use a measure of the quantity of that environment in [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2010/09/Screen-shot-2010-09-29-at-29-Sep-14.20.53.png" alt="Kernel weighted proportion diagram" height="463" width="663" /></p>

<p><strong>Imagine you want compare various locations in terms of the availability of a certain type of environment, such as fresh water.</strong></p>

<p>You might want to use a measure of the proximity of that environment &#8212; such as the <a href="/2011/03/postgis-nearest-neighbour/">nearest neighbour</a> distance.</p>

<p>You might want to use a measure of the quantity of that environment in the vicinity &#8212; such as the proportion of land within a specific radius that is of that type.</p>

<p>Or you might ideally like a measure that combines both of these: one that incorporates the quantity of that environment, but gives greater weight to areas that are nearer, and lesser weight to those that are further away.</p>

<p>In that third case, what you probably want is a kernel-weighted proportion.</p>

<p><span id="more-864"></span></p>

<h3>How it works</h3>

<p>In this usage, a &#8216;kernel&#8217; just means a distribution function, such as the <a href="http://en.wikipedia.org/wiki/Kernel_%28statistics%29">normal (Gaussian), triangular, or Epanechnikov</a>. The kernel is used to decide what weight should be attached to places at varying distances from the location under consideration.</p>

<p>I find it helpful to imagine the weight assigned to each point as a third dimension: the height at each point. I then imagine the kernel as a solid object positioned with its centre over the point I&#8217;m measuring from. For the normal or Epanechnikov kernels, this object is bell-shaped; for the triangular kernel, it&#8217;s a cone; for the (trivial) uniform kernel, it&#8217;s a cylinder.</p>

<p>The total volume of this object is the denominator of the kernel-weighted proportion. Now I imagine removing all parts of the object that don&#8217;t lie directly above the type of environment being measured. The volume of the remaining parts of the object &#8212; those directly overlying the environment of interest &#8212; is the numerator of the kernel-weighted proportion.</p>

<h3>Implementation in PostGIS</h3>

<p>The following <span class="caps">SQL </span>functions enable you to approximate kernel-weighted proportions in PostGIS. They do so by splitting the 3-dimensional kernel into horizontal slices of equal height, but with radii differing according to the kernel and kernel parameters specified. They calculate the summed volume of the intersections of the slices with the supplied polygons, and divide that by the total summed volume of the complete slices. (Assign each slice a height of 1 and these volumes are helpfully the same as the areas).</p>

<p>This approach is illustrated, for the normal kernel, at the top of this post.</p>


<div class="wp_syntax"><div class="code"><pre class="postgresql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- kernel functions</span>
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> uniform_pdf
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>              <span style="color: #808080; font-style: italic;">-- $1 = x</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">1.0</span>  <span style="color: #808080; font-style: italic;">-- $2 = bandwidth</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">0.0</span>  <span style="color: #808080; font-style: italic;">-- $3 = centre</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    <span style="color: #005500;">case</span>
      <span style="color: #005500;">when</span> $1 <span style="color: #66cc66;">&gt;</span> $3 - $2 <span style="color: #005500;">and</span> $1 <span style="color: #66cc66;">&lt;</span> $3 + $2 <span style="color: #005500;">then</span> <span style="color: #66cc66;">&#40;</span>
        <span style="color: #005500;">select</span> cast<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.5</span> <span style="color: #005500;">as</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#41;</span>
      <span style="color: #005500;">else</span> <span style="color: #cc66cc;">0</span>
    <span style="color: #005500;">end</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> triangular_pdf
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>              <span style="color: #808080; font-style: italic;">-- $1 = x</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">1.0</span>  <span style="color: #808080; font-style: italic;">-- $2 = bandwidth</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">0.0</span>  <span style="color: #808080; font-style: italic;">-- $3 = centre</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    <span style="color: #005500;">case</span>
      <span style="color: #005500;">when</span> $1 <span style="color: #66cc66;">&gt;</span> $3 - $2 <span style="color: #005500;">and</span> $1 <span style="color: #66cc66;">&lt;</span> $3 + $2 <span style="color: #005500;">then</span> <span style="color: #66cc66;">&#40;</span>
        <span style="color: #005500;">select</span> <span style="color: #cc66cc;">1</span> - <span style="color: #333399;">abs</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>$1 - $3<span style="color: #66cc66;">&#41;</span> / $2<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#41;</span>
      <span style="color: #005500;">else</span> <span style="color: #cc66cc;">0</span>
    <span style="color: #005500;">end</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> normal_pdf
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>              <span style="color: #808080; font-style: italic;">-- $1 = x</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">1.0</span>  <span style="color: #808080; font-style: italic;">-- $2 = std dev (bandwidth)</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">0.0</span>  <span style="color: #808080; font-style: italic;">-- $3 = mean (centre)</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1.0</span> / <span style="color: #66cc66;">&#40;</span><span style="color: #333399;">sqrt</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2.0</span> * <span style="color: #333399;">pi</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> * pow<span style="color: #66cc66;">&#40;</span>$2, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> 
       * <span style="color: #333399;">exp</span><span style="color: #66cc66;">&#40;</span>-pow<span style="color: #66cc66;">&#40;</span>$1 - $3, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> / <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2.0</span> * pow<span style="color: #66cc66;">&#40;</span>$2, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> epanechnikov_pdf
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>              <span style="color: #808080; font-style: italic;">-- $1 = x</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">1.0</span>  <span style="color: #808080; font-style: italic;">-- $2 = bandwidth</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">0.0</span>  <span style="color: #808080; font-style: italic;">-- $3 = centre</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    <span style="color: #005500;">case</span>
      <span style="color: #005500;">when</span> $1 <span style="color: #66cc66;">&gt;</span> $3 - $2 <span style="color: #005500;">and</span> $1 <span style="color: #66cc66;">&lt;</span> $3 + $2 <span style="color: #005500;">then</span> <span style="color: #66cc66;">&#40;</span>
        <span style="color: #005500;">select</span> <span style="color: #cc66cc;">0.75</span> * <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span> - pow<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>$1 - $3<span style="color: #66cc66;">&#41;</span> / $2, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#41;</span>
      <span style="color: #005500;">else</span> <span style="color: #cc66cc;">0</span>
    <span style="color: #005500;">end</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">-- current kernel function </span>
<span style="color: #808080; font-style: italic;">-- (uncomment the kernel you want to use, and redefine: the normal is shown here)</span>
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> __current_kernel_pdf
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>              <span style="color: #808080; font-style: italic;">-- $1 = x</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">1.0</span>  <span style="color: #808080; font-style: italic;">-- $2 = std dev/bandwidth</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">default</span> <span style="color: #cc66cc;">0.0</span>  <span style="color: #808080; font-style: italic;">-- $3 = mean/centre</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    normal_pdf
    <span style="color: #808080; font-style: italic;">-- epanechnikov_pdf</span>
    <span style="color: #808080; font-style: italic;">-- triangular_pdf</span>
    <span style="color: #808080; font-style: italic;">-- uniform_pdf</span>
    <span style="color: #66cc66;">&#40;</span>$1, $2, $3<span style="color: #66cc66;">&#41;</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">-- support functions</span>
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> __slice_height
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $1 = kernel std dev</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $2 = kernel radius at top of slice</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $3 = kernel radius at bottom of slice</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span> __current_kernel_pdf<span style="color: #66cc66;">&#40;</span>$2, $1<span style="color: #66cc66;">&#41;</span> - __current_kernel_pdf<span style="color: #66cc66;">&#40;</span>$3, $1<span style="color: #66cc66;">&#41;</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> __slice_radius
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $1 = kernel radius at top of slice</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $2 = kernel radius at bottom of slice</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span> $1 + <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>$2 - $1<span style="color: #66cc66;">&#41;</span> / <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> __kernel_slice_volume
<span style="color: #66cc66;">&#40;</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $1 = kernel std dev</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $2 = kernel radius at top of slice</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $3 = kernel radius at bottom of slice</span>
, <span style="color: #993333;">int</span>               <span style="color: #808080; font-style: italic;">-- $4 = buffer precision</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    <span style="color: #333399;">coalesce</span><span style="color: #66cc66;">&#40;</span>
      st_area<span style="color: #66cc66;">&#40;</span>
        st_buffer<span style="color: #66cc66;">&#40;</span>
          st_makepoint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>,
          __slice_radius<span style="color: #66cc66;">&#40;</span>$2, $3<span style="color: #66cc66;">&#41;</span>,
          $4
        <span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#41;</span>,
      <span style="color: #cc66cc;">0</span>
    <span style="color: #66cc66;">&#41;</span>
    * __slice_height<span style="color: #66cc66;">&#40;</span>$1, $2, $3<span style="color: #66cc66;">&#41;</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> __intersected_slice_volume
<span style="color: #66cc66;">&#40;</span> <span style="color: #993333;">geometry</span>          <span style="color: #808080; font-style: italic;">-- $1 = area geometry</span>
, <span style="color: #993333;">geometry</span>          <span style="color: #808080; font-style: italic;">-- $2 = kernel centre point geometry</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $3 = kernel std dev</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $4 = kernel radius at top of slice</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $5 = kernel radius at bottom of slice</span>
, <span style="color: #993333;">int</span>               <span style="color: #808080; font-style: italic;">-- $6 = buffer precision</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    <span style="color: #333399;">coalesce</span><span style="color: #66cc66;">&#40;</span>
      st_area<span style="color: #66cc66;">&#40;</span>
        st_intersection<span style="color: #66cc66;">&#40;</span>
          $1,
          st_buffer<span style="color: #66cc66;">&#40;</span>
            $2,
            __slice_radius<span style="color: #66cc66;">&#40;</span>$4, $5<span style="color: #66cc66;">&#41;</span>,
            $6
          <span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#41;</span>,
      <span style="color: #cc66cc;">0</span>
    <span style="color: #66cc66;">&#41;</span>
    * __slice_height<span style="color: #66cc66;">&#40;</span>$3, $4, $5<span style="color: #66cc66;">&#41;</span>;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">-- main function</span>
&nbsp;
<span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> kernel_weighted_local_proportion
<span style="color: #66cc66;">&#40;</span> <span style="color: #993333;">geometry</span>          <span style="color: #808080; font-style: italic;">-- $1 = area geometry</span>
, <span style="color: #993333;">geometry</span>          <span style="color: #808080; font-style: italic;">-- $2 = kernel centre point geometry</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $3 = kernel std dev</span>
, <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span>  <span style="color: #808080; font-style: italic;">-- $4 = truncation bandwidth (for normal only -- for others, repeat $3)</span>
, <span style="color: #993333;">int</span>               <span style="color: #808080; font-style: italic;">-- $5 = number of horizontal slices for approximation (for uniform, use 1)</span>
, <span style="color: #993333;">int</span>               <span style="color: #808080; font-style: italic;">-- $6 = buffer precision (number of points per 1/4 circle)</span>
<span style="color: #66cc66;">&#41;</span> <span style="color: #005500;">returns</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span> <span style="color: #005500;">as</span> $$
  <span style="color: #005500;">select</span>
    <span style="color: #333399;">sum</span><span style="color: #66cc66;">&#40;</span>__intersected_slice_volume<span style="color: #66cc66;">&#40;</span>
      $1, $2, $3,
      $4 * <span style="color: #66cc66;">&#40;</span>cast<span style="color: #66cc66;">&#40;</span>s <span style="color: #005500;">as</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span><span style="color: #66cc66;">&#41;</span> / $5<span style="color: #66cc66;">&#41;</span>,     <span style="color: #808080; font-style: italic;">-- kernel radius at top of slice</span>
      $4 * <span style="color: #66cc66;">&#40;</span>cast<span style="color: #66cc66;">&#40;</span>s + <span style="color: #cc66cc;">1</span> <span style="color: #005500;">as</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span><span style="color: #66cc66;">&#41;</span> / $5<span style="color: #66cc66;">&#41;</span>, <span style="color: #808080; font-style: italic;">-- kernel radius at bottom of slice</span>
      $6
    <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    /
    <span style="color: #333399;">sum</span><span style="color: #66cc66;">&#40;</span>__kernel_slice_volume<span style="color: #66cc66;">&#40;</span>
      $3,
      $4 * <span style="color: #66cc66;">&#40;</span>cast<span style="color: #66cc66;">&#40;</span>s <span style="color: #005500;">as</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span><span style="color: #66cc66;">&#41;</span> / $5<span style="color: #66cc66;">&#41;</span>,     <span style="color: #808080; font-style: italic;">-- kernel radius at top of slice</span>
      $4 * <span style="color: #66cc66;">&#40;</span>cast<span style="color: #66cc66;">&#40;</span>s + <span style="color: #cc66cc;">1</span> <span style="color: #005500;">as</span> <span style="color: #005500;">double</span> <span style="color: #005500;">precision</span><span style="color: #66cc66;">&#41;</span> / $5<span style="color: #66cc66;">&#41;</span>, <span style="color: #808080; font-style: italic;">-- kernel radius at bottom of slice</span>
      $6
    <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #005500;">from</span> <span style="color: #333399;">generate_series</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span>, $5 - <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> s;
$$ <span style="color: #005500;">language</span> sql <span style="color: #005500;">immutable</span>;</pre></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/08/16/kernel-weighted-proportions-postgis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL gem for Ruby 1.9.1/1.9.2 on Snow Leopard (Mac OS X 10.6)</title>
		<link>http://blog.mackerron.com/2011/08/04/mysql-gem-snow-leopard/</link>
		<comments>http://blog.mackerron.com/2011/08/04/mysql-gem-snow-leopard/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 14:47:11 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[System admin]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=844</guid>
		<description><![CDATA[The secret to getting the MySQL gem to install and function with Ruby 1.9.1/1.9.2 on Snow Leopard is: Install MySQL using the 64-bit .DMG package installer from dev.mysql.com Install Ruby using RVM (that&#8217;s Ruby 1.9.2 or 1.9.1-p378 &#8212; at the time of writing the latest 1.9.1, p429, is buggy) Add these to lines to ~/.bash_login [...]]]></description>
			<content:encoded><![CDATA[<p><strong>The secret to getting the MySQL gem to install and function with Ruby 1.9.1/1.9.2 on Snow Leopard is:</strong></p>


<ul>
<li>Install MySQL using the 64-bit .DMG package installer from <a href="http://dev.mysql.com/downloads/mysql/">dev.mysql.com</a></li>
<li>Install Ruby using <a href="http://redmine.ruby-lang.org/issues/show/2404"><span class="caps">RVM</span></a> (that&#8217;s Ruby 1.9.2 or 1.9.1-p378 &#8212; at the time of writing the latest 1.9.1, p429, is <a href="http://redmine.ruby-lang.org/issues/show/2404">buggy</a>)</li>
<li>Add these to lines to <code>~/.bash_login</code> or <code>~/.bashrc</code>:</li>
</ul>




<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PATH</span>=<span style="color: #ff0000;">&quot;/usr/local/mysql/bin:<span style="color: #007800;">$PATH</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">DYLD_LIBRARY_PATH</span>=<span style="color: #ff0000;">&quot;/usr/local/mysql/lib:<span style="color: #007800;">$DYLD_LIBRARY_PATH</span>&quot;</span></pre></div></div>





<ul>
<li>In a new shell (Terminal window), type <code>gem install mysql</code> as normal.</li>
</ul>



<p>I&#8217;m posting this mainly as a record for myself, having wasted a lot of time in the past trying strange incantations from comments on various other blogs posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/08/04/mysql-gem-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Overlapping markers on your Google Map? Meet OverlappingMarkerSpiderfier</title>
		<link>http://blog.mackerron.com/2011/06/22/overlapping-marker-spiderfier/</link>
		<comments>http://blog.mackerron.com/2011/06/22/overlapping-marker-spiderfier/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 20:19:25 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[GIS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=553</guid>
		<description><![CDATA[Ever noticed how, in Google Earth, marker pins that overlap each other spring apart gracefully when you click them, so you can pick the one you meant? And ever noticed how, when using the Google Maps API, the exact same thing doesn&#8217;t happen? This code makes Google Maps API version 3 map markers behave in [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Ever noticed how, in Google Earth, marker pins that overlap each other spring apart gracefully when you click them, so you can pick the one you meant?</strong></p>

<p>And ever noticed how, when using the Google Maps <span class="caps">API, </span>the exact same thing <em>doesn&#8217;t</em> happen?</p>

<p>This code makes Google Maps <span class="caps">API </span>version 3 map markers behave in that Google Earth way. Small numbers of markers (up to 8, configurable) spiderfy into a circle. Larger numbers fan out into a (more space-efficient) spiral. </p>

<p><span id="more-553"></span></p>

<p>Try it! (You can reload this page to re-randomise the marker positions).</p>

<p><iframe src="http://jawj.github.com/OverlappingMarkerSpiderfier/demo.html" style="width: 694px; height: 500px; border: 1px solid #444;"></iframe></p>

<p>The code is <span class="caps">MIT </span>licenced, has no dependencies, and is under 3K compiled (from CoffeeScript), minified and gzipped. I wrote it as part of the data download feature for <a href="http://www.mappiness.org.uk">Mappiness</a>.</p>

<p>It&#8217;s on Github, where you can <a href="https://github.com/jawj/OverlappingMarkerSpiderfier">find out more, download or fork the code</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/06/22/overlapping-marker-spiderfier/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Perfect, effortless bread</title>
		<link>http://blog.mackerron.com/2011/06/21/perfect-effortless-bread/</link>
		<comments>http://blog.mackerron.com/2011/06/21/perfect-effortless-bread/#comments</comments>
		<pubDate>Tue, 21 Jun 2011 22:17:23 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Recipes]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=555</guid>
		<description><![CDATA[This post from June 2011 was updated in November 2011 and January 2012. This recipe makes wonderful bread: crusty, open-textured, moist, and beautiful. It needs no kneading, but this doesn&#8217;t imply any sort of trade-off. It&#8217;s a recipe for a perfect loaf which happens to be effortless, and an effortless recipe which happens to make [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post from June 2011 was updated in November 2011 and January 2012.</em></p>

<p><strong>This recipe makes wonderful bread: crusty, open-textured, moist, and beautiful.</strong> </p>

<p>It needs no kneading, but this doesn&#8217;t imply any sort of trade-off. It&#8217;s a recipe for a perfect loaf which happens to be effortless, and an effortless recipe which happens to make a perfect loaf.</p>

<p>It&#8217;s based on <a href="http://www.nytimes.com/2006/11/08/dining/081mrex.html">Jim Lahey&#8217;s recipe</a> from the New York Times in 2006 (also the subject of an <a href="http://www.nytimes.com/2006/11/08/dining/08mini.html">article and accompanying video</a>, and now <a href="http://www.amazon.co.uk/exec/obidos/ASIN/0393066304/mackerroncom-21">a full-length book</a>). But it&#8217;s even easier, as there&#8217;s no awkward middle stage with linen cloths.</p>

<p>In the eight months since we started using it, we&#8217;ve made virtually all our own bread.</p>

<p><img src="/wp-content/uploads/2011/06/rye.jpg" alt="" height="325" width="325" /> <img src="/wp-content/uploads/2011/06/poppy.jpg" alt="" height="325" width="325" /> <span id="more-555"></span><br />
<img src="/wp-content/uploads/2011/06/sesame.jpg" alt="" height="325" width="325" /> <img src="/wp-content/uploads/2011/06/brown.jpg" alt="" height="325" width="325" /></p>

<h2>What you need</h2>

<p><img src="/wp-content/uploads/2011/06/ingredients.jpg" alt="" height="170" width="347" style="border:none;float:right;margin-left:1em;" /></p>

<h3>Ingredients</h3>


<ul>
<li>400g strong white bread flour</li>
<li>400ml water</li>
<li>One third of a teaspoon dried yeast</li>
<li>2 teaspoons salt</li>
</ul>



<p>And:</p>


<ul>
<li>Up to another 100g flour</li>
</ul>



<h3>Equipment</h3>


<ul>
<li>A <a href="http://www.amazon.co.uk/exec/obidos/ASIN/B0026OUXHS/mackerroncom-21" data-asin-com="B002UUTCSO">lidded cast-iron casserole pot</a>, around 21cm diameter. We&#8217;ve been told that a ceramic pot also works, but we haven&#8217;t tried this.</li>
<li>The bread-making usual: <a href="http://www.amazon.co.uk/exec/obidos/ASIN/B00140VYBE/mackerroncom-21" data-asin-com="B001N07KUE">scales</a> (preferably electronic, for accuracy), <a href="http://www.amazon.co.uk/exec/obidos/ASIN/B0000BVEK9/mackerroncom-21" data-asin-com="B001U0O36G">mixing bowl</a>, measuring jug, wooden spoon, wire rack, timer, oven</li>
</ul>



<p><a href="http://www.amazon.co.uk/exec/obidos/ASIN/B0026OUXHS/mackerroncom-21" data-asin-com="B002UUTCSO"><img border="0" src="http://ws.assoc-amazon.co.uk/widgets/q?_encoding=UTF8&amp;Format=_SL160_&amp;ASIN=B0026OUXHS&amp;MarketPlace=GB&amp;ID=AsinImage&amp;WS=1&amp;tag=mackerroncom-21&amp;ServiceVersion=20070822" style="border:none;vertical-align:middle;" /></a>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/B00140VYBE/mackerroncom-21" data-asin-com="B001N07KUE"><img border="0" src="http://ws.assoc-amazon.co.uk/widgets/q?_encoding=UTF8&amp;Format=_SL160_&amp;ASIN=B00140VYBE&amp;MarketPlace=GB&amp;ID=AsinImage&amp;WS=1&amp;tag=mackerroncom-21&amp;ServiceVersion=20070822" style="border:none;vertical-align:middle;" /></a>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/B0000BVEK9/mackerroncom-21" data-asin-com="B001U0O36G"><img border="0" src="http://ws.assoc-amazon.co.uk/widgets/q?_encoding=UTF8&amp;Format=_SL160_&amp;ASIN=B0000BVEK9&amp;MarketPlace=GB&amp;ID=AsinImage&amp;WS=1&amp;tag=mackerroncom-21&amp;ServiceVersion=20070822" style="border:none;vertical-align:middle;" /></a></p>

<p>If you need any of this equipment, the above pictures link to Amazon (who give us a referral fee if you buy something).</p>

<h2>What you do</h2>

<p>There are three short steps separated by two risings.</p>

<h3>Step 1: Mix</h3>

<p>Measure the 400g of flour into the bowl. Add the salt and yeast, and stir briefly to mix in.</p>

<p>Pour in the water, all at once. Stir until fully mixed.</p>

<p>The result will be much stickier and wetter than normal dough, with a consistency more like cake mixture. You couldn&#8217;t knead it if you wanted to.</p>

<p>Notes:</p>


<ul>
<li>In summer, cold water (i.e. room/tap temperature) is fine. In winter, use one part boiling to three or four parts cold to avoid slowing the risings down.</li>
<li>The yeast quantity isn&#8217;t a mistake, though it&#8217;s a lot less than a standard bread recipe (and the back of the yeast packet) calls for. There&#8217;s also no need to reactivate it in the water first.</li>
<li>Too much salt is bad for you, of course, but under-salted bread tastes really disappointing. We use two average-sized teaspoons, slightly over level, of sea salt crystals (which I suspect provide less salt in any given volume than fine table salt would).</li>
</ul>



<h3>Rising 1</h3>

<p>Cover the bowl (e.g. with a large plate) and leave for 12 &#8211; 24 hours. Room temperature is fine in summer. In winter, somewhere a bit warmer &#8212; such as near a stove, boiler or hot water tank &#8212; works better.</p>

<h3>Step 2: Add flour</h3>

<p>The dough will have increased in size and spread out across the bowl. Its level top will dotted with bubbles, and it will be even more wet and gooey than before.</p>

<p>Stir in more flour, probably 50 &#8211; 100g, a handful at a time, until the mixture has just about formed itself into a dough: still stretchy, still sticking to the bowl, but half-capable of holding its shape.</p>

<h3>Rising 2</h3>

<p>Cover the bowl again and leave for another 2 &#8211; 12 hours.</p>

<p>Half an hour from the end of this rising, put the lidded casserole pot in the oven and start pre-heating to 220 degrees C.</p>

<h3>Step 3: Bake</h3>

<p>Take the now-super-hot pot from the oven and remove the lid. </p>

<p>Tip and scrape the re-risen dough into the pot, doing your best not to knock out all the air. It should look rough, ugly, and unpromising! Throw a bit of flour over the top for decorative effect.</p>

<p>Replace the lid and return the pot to the oven.</p>

<p>After half an hour, remove the lid.</p>

<p>After a further 15 minutes, take the pot from the oven. Tip the loaf out and leave it to cool on a wire rack. Admire!</p>

<p>Note:</p>


<ul>
<li>In summary, it&#8217;s: 30 minutes pre-heating the pot, 30 minutes baking with the lid on, and 15 minutes baking with the lid off. A timer/alarm is handy.</li>
<li>A rounded flexible scraper (ours is cut out of the bottom of a plastic take-away carton) is good for smoothly transferring the dough from bowl to pot.</li>
<li>Some oven temperature knobs stop marking temperatures at a point below 220 degrees. In this case you may need to experiment with how far beyond the end of the markings you need to go.</li>
<li>The fully-baked loaf shouldn&#8217;t stick, so there should be no need to flour or grease the pot. If it does stick, it might be that the pot wasn&#8217;t hot enough &#8212; try turning up the oven a bit, and be sure to give the pot plenty of pre-heating time.</li>
</ul>



<h2>Variations</h2>

<p>We rarely keep it quite this simple: various combinations of flours and seeds make a more interesting loaf.</p>

<p>Our favourites are:</p>

<h3>Poppy seed</h3>

<p>Carpet the bottom of the casserole pot with poppy seeds just before you tip the dough in, and carpet the top of the dough with more seeds straight after (mere sprinklings <em>will</em> disappoint). The seeds should stick pretty tight and toast just the right amount during baking.</p>

<p>Optionally, also replace half the plain white bread flour with white spelt flour. This isn&#8217;t stocked that widely &#8212;  we get Doves Farm stuff, from Planet Organic &#8212; but it adds lightness and really enhances the flavour, making a loaf that&#8217;s lovely for simple hot-buttered-toasting&#8230; and pretty much everything else.</p>

<h3>Sesame and barley</h3>

<p>Carpet the pot-bottom and loaf-top as above, this time with plenty of sesame seeds. Also replace around 100g of the normal flour with barley flour. Barley gives a brilliant nutty flavour, and the sesame seeds make for a delicious, crispy, toasty crust.</p>

<p>Barley flour is also not always easy to find. We usually get ours from an independent health food shop (Coopers, Lower Marsh, London <span class="caps">SE1</span>). If you can&#8217;t find it, some fine oatmeal is also nice in this loaf.</p>

<h3>Caraway and rye</h3>

<p>Replace up to 150g of the wheat flour with rye &#8212; which makes a tastier but heavier bread &#8212; and add a good teaspoon of caraway seeds to the dry ingredients at step 1. This loaf comes out looking gorgeous and artisanal if dusted with semolina flour just before baking.</p>

<h3>Six seed</h3>

<p>Obviously you can experiment with adding different seeds and/or multi-seed flours. Bacheldre Mill do a malted 5 seed flour, but the fennel seeds in it are a bit overpowering. Wessex Mill&#8217;s six seed flour is much nicer. We replace 150g of the plain flour with this, and add a good handful of extra linseeds. Semolina flour on the top and bottom looks great on this one too.</p>

<p><img src="http://blog.mackerron.com/wp-content/uploads/2011/06/AeytdTZCMAAfdws.jpg_large.jpg" alt="gluten-free loaf" style="float: right; margin-left: 1em;" /></p>

<h3>Gluten-free</h3>

<p>For some coeliac friends we&#8217;ve made the poppy seed recipe, but replacing all the flour with the Doves Farm gluten-free variety, with surprisingly acceptable results (pictured right). </p>

<p>It&#8217;s a little bit chewy, but if eaten the same day it&#8217;s still really tasty, crusty and moist. </p>

<p>The results of our experiments with adding xanthan gum &#8212; which is sometimes used to give gluten-free doughs a bit of bounce &#8212; have been disastrously sticky and dense, though.</p>

<h2 style="clear:both;">Schedule</h2>

<p>The recipe might sound demanding, but we find the steps quick and the pauses flexible enough that they&#8217;re easy to fit around our schedule.</p>

<p>In the week, we typically do step 1 in the evening after work, step 2 the next morning before work, and step 3 (baking) that evening. One loaf lasts us two days, so we start the next loaf the next evening.</p>

<p>Since the second rising can be done in two hours or so, you can also do the whole thing in one day if you do step 1 first thing and steps 2 and 3 the same evening.</p>

<h2>Saving money (but maybe not the world)</h2>

<p>Even organic flour only costs 50p for 500g, and the yeast is pretty nearly free. I estimate the gas or electricity to keep the oven at 220 degrees for 75 minutes could cost 50 &#8211; 100% of that again (anyone know more exactly?), but you&#8217;re still looking at a pound or less a loaf.</p>

<p>A domestic oven baking one loaf is almost certainly less energy-efficient than a commercial oven baking many, so making your own bread is probably not entirely green. Then again, if your oven&#8217;s electric you could always switch to <a href="http://www.goodenergy.co.uk/">100% renewable electricity</a>.</p>

<script>
(function() {
  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __indexOf = Array.prototype.indexOf || function(item) {
    for (var i = 0, l = this.length; i < l; i++) {
      if (this[i] === item) return i;
    }
    return -1;
  };
  window.AmazonRewriter = (function() {
    function AmazonRewriter(affiliateIDs) {
      var handleLoad;
      this.affiliateIDs = affiliateIDs != null ? affiliateIDs : {};
      this.locationRequested = this.linksRewritten = false;
      handleLoad = __bind(function() {
        return this.rewriteLinks();
      }, this);
      if (typeof document.addEventListener === "function") {
        document.addEventListener('DOMContentLoaded', handleLoad, false);
      }
      if (typeof window.addEventListener === "function") {
        window.addEventListener('load', handleLoad, false);
      }
      if (typeof window.attachEvent === "function") {
        window.attachEvent('onload', handleLoad);
      }
    }
    AmazonRewriter.prototype.rewriteLinks = function() {
      var affiliateID, asin, countryCode, link, script, tld, tldDashed, _i, _len, _ref, _ref2, _ref3, _ref4, _ref5;
      if (this.linksRewritten) {
        return;
      }
      if (window.google) {
        countryCode = (_ref = window.google.loader.ClientLocation) != null ? _ref.address.country_code.toLowerCase() : void 0;
        if (countryCode) {
          tld = (_ref2 = this.codeMap[countryCode]) != null ? _ref2 : countryCode;
          if (__indexOf.call(this.nonComTlds, tld) < 0) {
            tld = 'com';
          }
          tldDashed = tld.replace(/\./g, '-');
          affiliateID = (_ref3 = this.affiliateIDs[tld]) != null ? _ref3 : this.fallbackAffiliateIDs[tld];
          if (affiliateID) {
            _ref4 = document.getElementsByTagName('a');
            for (_i = 0, _len = _ref4.length; _i < _len; _i++) {
              link = _ref4[_i];
              if (link.host.match(/\bamazon\./i)) {
                asin = (_ref5 = link.getAttribute("data-asin-" + tldDashed)) != null ? _ref5 : link.href.match(/\b[A-Z0-9]{10}\b/);
                if (asin) {
                  link.href = "http://www.amazon." + tld + "/exec/obidos/ASIN/" + asin + "/" + affiliateID;
                }
              }
            }
          }
        }
        return this.linksRewritten = true;
      } else {
        if (!this.locationRequested) {
          script = document.createElement('script');
          script.src = 'http://www.google.com/jsapi';
          document.getElementsByTagName('head')[0].appendChild(script);
          this.locationRequested = true;
        }
        return window.setTimeout((__bind(function() {
          return this.rewriteLinks();
        }, this)), 50);
      }
    };
    AmazonRewriter.prototype.nonComTlds = ['ca', 'co.uk', 'fr', 'de', 'it', 'jp', 'cn'];
    AmazonRewriter.prototype.codeMap = {
      gb: 'co.uk',
      ie: 'co.uk',
      at: 'de'
    };
    AmazonRewriter.prototype.fallbackAffiliateIDs = {
      com: 'httpmackecom-20',
      ca: 'mackerroncom-20',
      'co.uk': 'mackerroncom-21',
      fr: 'mackerronco00-21'
    };
    return AmazonRewriter;
  })();
}).call(this);

new AmazonRewriter();
</script>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/06/21/perfect-effortless-bread/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple PostGIS nearest neighbour function</title>
		<link>http://blog.mackerron.com/2011/03/10/postgis-nearest-neighbour/</link>
		<comments>http://blog.mackerron.com/2011/03/10/postgis-nearest-neighbour/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 11:31:59 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[GIS]]></category>
		<category><![CDATA[PostGIS]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=516</guid>
		<description><![CDATA[Here&#8217;s a less generic and slightly different nearest-neighbour function based on Regina&#8217;s generic nearest-neighbour function at Boston GIS. It follows the same basic idea of using series of enlarging search radii to restrict distance calculations to a manageable subset of things-that-might-be-near. The difference is that it uses a geometric progression of sizes (x, x * [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Here&#8217;s a less generic and slightly different nearest-neighbour function based on <a href="http://www.bostongis.com/?content_name=postgis_nearest_neighbor_generic">Regina&#8217;s generic nearest-neighbour function</a> at Boston <span class="caps">GIS.</span></strong></p>

<p>It follows the same basic idea of using series of enlarging search radii to restrict distance calculations to a manageable subset of things-that-might-be-near. The difference is that it uses a geometric progression of sizes (<code>x, x * y, x * y^2, x * y^3, ...</code>) instead of an arithmetic one (<code>x, x + y, x + 2y, x + 3y, ...</code>).</p>

<p>For some distributions of things-that-might-be-near, and tuned with the right parameters (<code>x, y</code>), this turns out substantially faster (I&#8217;ve used it to locate the nearest UK postcode to each <a href="http://mappin.es">mappiness</a> response).</p>

<p><span id="more-516"></span></p>

<p>Note that it&#8217;s a lot simpler and less generic than the Boston <span class="caps">GIS </span>alternative: it returns only one nearest neighbour, without the associated distance, and is also less flexible about what it accepts as input.</p>


<div class="wp_syntax"><div class="code"><pre class="postgresql" style="font-family:monospace;"><span style="color: #005500;">create</span> <span style="color: #005500;">or</span> <span style="color: #005500;">replace</span> <span style="color: #005500;">function</span> 
  nn<span style="color: #66cc66;">&#40;</span>nearTo                   <span style="color: #993333;">geometry</span>
   , initialDistance          <span style="color: #993333;">real</span>
   , distanceMultiplier       <span style="color: #993333;">real</span> 
   , maxPower                 <span style="color: #993333;">integer</span>
   , nearThings               <span style="color: #993333;">text</span>
   , nearThingsIdField        <span style="color: #993333;">text</span>
   , nearThingsGeometryField  <span style="color: #993333;">text</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #005500;">returns</span> <span style="color: #993333;">integer</span> <span style="color: #005500;">as</span> $$
<span style="color: #005500;">declare</span> 
  sql     <span style="color: #993333;">text</span>;
  result  <span style="color: #993333;">integer</span>;
<span style="color: #005500;">begin</span>
  sql :<span style="color: #66cc66;">=</span> <span style="color: #ff0000;">' select '</span> <span style="color: #66cc66;">||</span> <span style="color: #333399;">quote_ident</span><span style="color: #66cc66;">&#40;</span>nearThingsIdField<span style="color: #66cc66;">&#41;</span> 
      <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' from '</span>   <span style="color: #66cc66;">||</span> <span style="color: #333399;">quote_ident</span><span style="color: #66cc66;">&#40;</span>nearThings<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' where st_dwithin($1, '</span> 
      <span style="color: #66cc66;">||</span>   <span style="color: #333399;">quote_ident</span><span style="color: #66cc66;">&#40;</span>nearThingsGeometryField<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">', $2 * ($3 ^ $4))'</span>
      <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' order by st_distance($1, '</span> <span style="color: #66cc66;">||</span> <span style="color: #333399;">quote_ident</span><span style="color: #66cc66;">&#40;</span>nearThingsGeometryField<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">')'</span>
      <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' limit 1'</span>;
  <span style="color: #005500;">for</span> i <span style="color: #005500;">in</span> <span style="color: #cc66cc;">0</span>..maxPower <span style="color: #005500;">loop</span>
    <span style="color: #005500;">execute</span> sql <span style="color: #005500;">into</span> result <span style="color: #005500;">using</span> nearTo              <span style="color: #808080; font-style: italic;">-- $1</span>
                                , initialDistance     <span style="color: #808080; font-style: italic;">-- $2</span>
                                , distanceMultiplier  <span style="color: #808080; font-style: italic;">-- $3</span>
                                , i;                  <span style="color: #808080; font-style: italic;">-- $4</span>
    <span style="color: #005500;">if</span> result <span style="color: #005500;">is</span> <span style="color: #005500;">not</span> <span style="color: #005500;">null</span> <span style="color: #005500;">then</span> <span style="color: #005500;">return</span> result; <span style="color: #005500;">end</span> <span style="color: #005500;">if</span>;
  <span style="color: #005500;">end</span> <span style="color: #005500;">loop</span>;
  <span style="color: #005500;">return</span> <span style="color: #005500;">null</span>;
<span style="color: #005500;">end</span>
$$ <span style="color: #005500;">language</span> <span style="color: #ff0000;">'plpgsql'</span> <span style="color: #005500;">stable</span>;</pre></div></div>




<p><strong>Update, August 2011</strong> &#8212; Looking at this again, I realise there was an error in the function originally posted above. Because it did only a simple bounding-box check at each step, it was possible for it to return a geometry that was not in fact the nearest, but could in the worst case be up to 41% (sqrt(2) times) further away than the nearest. The code has been updated to fix this by using <code>st_dwithin</code>. I&#8217;ve also tidied it up a bit.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/03/10/postgis-nearest-neighbour/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cubic splines in JavaScript (via CoffeeScript)</title>
		<link>http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/</link>
		<comments>http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 19:36:07 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Canvas]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=466</guid>
		<description><![CDATA[For a recent study two colleagues needed to elicit a cumulative probability distribution function (CDF) from survey respondents. We decided it would be nice to allow respondents to interact with this CDF after providing some key values, and implemented this in the web browser with &#60;canvas&#62; (falling back on FlashCanvas for IE). In the process, [...]]]></description>
			<content:encoded><![CDATA[<p>For a recent study <a href="http://personal.lse.ac.uk/calel/">two</a> <a href="http://www.voxeu.com/index.php?q=node%2F5453">colleagues</a> needed to elicit a cumulative probability distribution function (CDF) from survey respondents.</p>

<p>We decided it would be nice to allow respondents to interact with this <span class="caps">CDF </span>after providing some key values, and implemented this in the web browser with <code>&lt;canvas&gt;</code> (falling back on <a href="http://flashcanvas.net/">FlashCanvas</a> for IE).</p>

<p>In the process, we implemented three kinds of <a href="http://en.wikipedia.org/wiki/Cubic_spline">cubic spline</a> calculation in the ever-wonderful <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>: natural, clamped and (what we actually needed) monotonic cubic splines.</p>

<p>You can play with some examples below: click-and-drag the round handles, or double-click to enter values directly. Feel free to borrow the code (ideally with attribution) if it&#8217;s of use to you.</p>

<p><span id="more-466"></span></p>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"></script><script type="text/javascript" src="/wp-content/uploads/2011/01/cubic_spline_min.js"></script><script type="text/javascript" src="/wp-content/uploads/2011/01/cubic_spline_chart.js"></script><div id="page">
<script type="text/javascript">
  ChartMonotonic = new SplineChart();
  ChartNatural   = new SplineChart();
  ChartClamped   = new SplineChart();
</script><!--[if lt IE 9]>
  <script type="text/javascript" src="http://c0021630.cdn1.cloudfiles.rackspacecloud.com/flashcanvas.js"></script><script type="text/javascript">
  ChartMonotonic.ie = true;
  ChartNatural.ie   = true;   
  ChartClamped.ie   = true;
</script><![endif]-->

<div style="height: 1em;"></div>

<h3>Monotonic</h3>

<div style="height: 1em;"></div>

<div id="chart_monotonic" class="cubic_spline" style="width: 575px"><canvas width="575" height="300"></canvas></div>
<script type="text/javascript">
  ChartMonotonic.init('chart_monotonic', 'X', 'Prob(Something ≤ X)', '#f00', -100, 100, function(xs, ys) {
    return new MonotonicCubicSpline(xs, ys);
  });
  ChartMonotonic.point(new Question().answer(0),  0);
  ChartMonotonic.point(new Question().answer(2),  0.25);
  ChartMonotonic.point(new Question().answer(6),  0.5);
  ChartMonotonic.point(new Question().answer(9.6),  0.75);
  ChartMonotonic.point(new Question().answer(10), 1);
</script>

<div style="height: 2em;"></div>

<h3>Natural</h3>

<div style="height: 1em;"></div>

<div id="chart_natural" class="cubic_spline" style="width: 575px;"><canvas width="575" height="300"></canvas></div>
<script type="text/javascript">
  ChartNatural.init('chart_natural', 'X', 'F(x)', '#0f0', -100, 100, function(xs, ys) {
    return new CubicSpline(xs, ys);
  });
  ChartNatural.point(new Question().answer(0),  0);
  ChartNatural.point(new Question().answer(2),  0.25);
  ChartNatural.point(new Question().answer(6),  0.5);
  ChartNatural.point(new Question().answer(9.6),  0.75);
  ChartNatural.point(new Question().answer(10), 1);
</script>

<div style="height: 2em;"></div>

<h3>Clamped (to a slope of 1 at both ends)</h3>

<div style="height: 1em;"></div>

<div id="chart_clamped" class="cubic_spline" style="width: 575px;"><canvas width="575" height="300"></canvas></div>
<script type="text/javascript">
  ChartClamped.init('chart_clamped', 'X', 'F(x)', '#00f', -100, 100, function(xs, ys) {
    return new CubicSpline(xs, ys, 1, 1);
  });
  ChartClamped.point(new Question().answer(0),  0);
  ChartClamped.point(new Question().answer(2),  0.25);
  ChartClamped.point(new Question().answer(6),  0.5);
  ChartClamped.point(new Question().answer(9.6),  0.75);
  ChartClamped.point(new Question().answer(10), 1);
</script>

<div style="height: 4em;"></div>

</div>

<h3>The spline code</h3>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MonotonicCubicSpline
&nbsp;
<span style="color:#008000; font-style:italic;"># by George MacKerron, mackerron.com</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># adapted from: </span>
<span style="color:#008000; font-style:italic;"># http://sourceforge.net/mailarchive/forum.php?thread_name=</span>
<span style="color:#008000; font-style:italic;"># EC90C5C6-C982-4F49-8D46-A64F270C5247%40gmail.com&amp;forum_name=matplotlib-users</span>
<span style="color:#008000; font-style:italic;"># (easier to read at http://old.nabble.com/%22Piecewise-Cubic-Hermite-Interpolating-</span>
<span style="color:#008000; font-style:italic;"># Polynomial%22-in-python-td25204843.html)</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># with help from:</span>
<span style="color:#008000; font-style:italic;"># F N Fritsch &amp; R E Carlson (1980) 'Monotone Piecewise Cubic Interpolation', </span>
<span style="color:#008000; font-style:italic;">#   SIAM Journal of Numerical Analysis 17(2), 238 - 246.</span>
<span style="color:#008000; font-style:italic;"># http://en.wikipedia.org/wiki/Monotone_cubic_interpolation</span>
<span style="color:#008000; font-style:italic;"># http://en.wikipedia.org/wiki/Cubic_Hermite_spline</span>
&nbsp;
  constructor: <span style="color:#006600; font-weight:bold;">&#40;</span>x, y<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    n = x.<span style="color:#9900CC;">length</span>
    delta = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; m = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; alpha = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; beta = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; dist = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; tau = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>y<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> y<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> x<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>delta<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span> <span style="color:#9966CC; font-weight:bold;">if</span> i <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span>
    m<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = delta<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    m<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = delta<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    to_fix = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      to_fix.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> to_fix
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = m<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      alpha<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      beta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>  = m<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> 
      dist<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>  = <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>alpha<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>beta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      tau<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>   = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">sqrt</span><span style="color:#006600; font-weight:bold;">&#40;</span>dist<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    to_fix = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      to_fix.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> dist<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">9</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> to_fix
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>     = tau<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> alpha<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      m<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = tau<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> beta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#006600; font-weight:bold;">*</span> delta<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@x</span> = x<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    <span style="color:#0066ff; font-weight:bold;">@y</span> = y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    <span style="color:#0066ff; font-weight:bold;">@m</span> = m
&nbsp;
  interpolate: <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>@x.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>..<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;</span>= x
    h = <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    t = <span style="color:#006600; font-weight:bold;">&#40;</span>x <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h
    t2 = <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>t, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    t3 = <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>t, <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    h00 =  <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> t3 <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> t2 <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
    h10 =      t3 <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> t2 <span style="color:#006600; font-weight:bold;">+</span> t
    h01 = <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> t3 <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> t2
    h11 =      t3  <span style="color:#006600; font-weight:bold;">-</span>    t2
    y = h00 <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@y</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        h10 <span style="color:#006600; font-weight:bold;">*</span> h <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@m</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        h01 <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@y</span><span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        h11 <span style="color:#006600; font-weight:bold;">*</span> h <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#0066ff; font-weight:bold;">@m</span><span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    y
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> CubicSpline  <span style="color:#008000; font-style:italic;"># natural or clamped</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># by George MacKerron, mackerron.com</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># adapted from:</span>
<span style="color:#008000; font-style:italic;"># http://www.michonline.com/ryan/csc/m510/splinepresent.html</span>
&nbsp;
  constructor: <span style="color:#006600; font-weight:bold;">&#40;</span>x, a, d0, dn<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">unless</span> x? <span style="color:#9966CC; font-weight:bold;">and</span> a?
    clamped = d0? <span style="color:#9966CC; font-weight:bold;">and</span> dn?
    n = x.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>
    h = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; y = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; l = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; u = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; z = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; c = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; b = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; d = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; k = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>; s = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> x<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      k<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      s<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = k<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> clamped
      y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> d0
      y<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> dn <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      y<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> clamped
      l<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> h<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      u<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0.5</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = y<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      l<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">1</span>
      u<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      l<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> x<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> u<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      u<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>y<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> z<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> clamped
      l<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = h<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">-</span> u<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>y<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> z<span style="color:#006600; font-weight:bold;">&#91;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> l<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span>
      c<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = z<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      l<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">1</span>
      z<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
      c<span style="color:#006600; font-weight:bold;">&#91;</span>n<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>n <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>..<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      c<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = z<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> u<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> c<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      b<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> a<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> c<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">3</span>
      d<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>c<span style="color:#006600; font-weight:bold;">&#91;</span>i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">-</span> c<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@x</span> = x<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>..<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    <span style="color:#0066ff; font-weight:bold;">@a</span> = a<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@b</span> = b
    <span style="color:#0066ff; font-weight:bold;">@c</span> = c<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...<span style="color:#9900CC;">n</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@d</span> = d
&nbsp;
  derivative: <span style="color:#006600; font-weight:bold;">-&gt;</span>
    s = new this.<span style="color:#9900CC;">constructor</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    s.<span style="color:#9900CC;">x</span> = <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...@x.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    s.<span style="color:#9900CC;">a</span> = <span style="color:#0066ff; font-weight:bold;">@b</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...@b.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span>  <span style="color:#008000; font-style:italic;"># copy</span>
    s.<span style="color:#9900CC;">b</span> = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> c <span style="color:#9966CC; font-weight:bold;">for</span> c <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#0066ff; font-weight:bold;">@c</span>
    s.<span style="color:#9900CC;">c</span> = <span style="color:#006666;">3</span> <span style="color:#006600; font-weight:bold;">*</span> d <span style="color:#9966CC; font-weight:bold;">for</span> d <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#0066ff; font-weight:bold;">@d</span>
    s.<span style="color:#9900CC;">d</span> = <span style="color:#006666;">0</span> <span style="color:#9966CC; font-weight:bold;">for</span> x <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>...@d.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    s
&nbsp;
  interpolate: <span style="color:#006600; font-weight:bold;">&#40;</span>x<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-&gt;</span>
    <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>@x.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>..<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&lt;</span>= x
    deltaX = x <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#0066ff; font-weight:bold;">@x</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
    y = <span style="color:#0066ff; font-weight:bold;">@a</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        <span style="color:#0066ff; font-weight:bold;">@b</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> deltaX <span style="color:#006600; font-weight:bold;">+</span> 
        <span style="color:#0066ff; font-weight:bold;">@c</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>deltaX, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> 
        <span style="color:#0066ff; font-weight:bold;">@d</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">pow</span><span style="color:#006600; font-weight:bold;">&#40;</span>deltaX, <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    y</pre></div></div>




<p>Download:</p>


<ul>
<li><a href="/wp-content/uploads/2011/01/cubic_spline.coffee.txt">the above CoffeeScript</a></li>
<li><a href="/wp-content/uploads/2011/01/cubic_spline.js">the compiled JavaScript</a></li>
<li><a href="/wp-content/uploads/2011/01/cubic_spline_min.js">the minified compiled JavaScript</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2011/01/01/javascript-cubic-splines/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Blocking the weakest passwords</title>
		<link>http://blog.mackerron.com/2010/12/14/death-to-weak-passwords/</link>
		<comments>http://blog.mackerron.com/2010/12/14/death-to-weak-passwords/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 12:24:04 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[System admin]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=429</guid>
		<description><![CDATA[The recent Gawker passwords leak once again highlights the widespread use of passwords that offer essentially no security. Some years ago, when working on a secure web app for a large organisation &#8212; let&#8217;s call them Secret Testing Ltd &#8212; I was keen that people shouldn&#8217;t choose hopelessly weak passwords. I was particularly concerned by [...]]]></description>
			<content:encoded><![CDATA[<p>The recent <a href="http://gawker.com/5712615/commenting-accounts-compromised-++-change-your-passwords">Gawker passwords leak</a> once again highlights the widespread use of passwords that offer essentially no security.</p>

<p>Some years ago, when working on a secure web app for a large organisation &#8212; let&#8217;s call them Secret Testing Ltd &#8212; I was keen that people shouldn&#8217;t choose hopelessly weak passwords. I was particularly concerned by my sysadmin colleague&#8217;s fondness for passwords of the form &#8216;p/\55w0rd&#8217; or &#8216;S3cr3t-T35t|ng&#8217;.</p>

<p><span id="more-429"></span></p>

<p>I therefore wrote some simple Ruby code to try to catch very weak passwords:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> PasswordUtils
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span>original<span style="color:#006600; font-weight:bold;">&#41;</span>
    look_or_sound_alikes = <span style="color:#006600; font-weight:bold;">&#123;</span> \
      <span style="color:#996600;">'0'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'o'</span><span style="color:#006600; font-weight:bold;">&#93;</span> ,
      <span style="color:#996600;">'1'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span>, <span style="color:#996600;">'l'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'2'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'to'</span>, <span style="color:#996600;">'too'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'3'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'e'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'4'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'a'</span>, <span style="color:#996600;">'for'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'5'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'s'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'6'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'g'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'8'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'b'</span>, <span style="color:#996600;">'ate'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'9'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'g'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'i'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'$'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'s'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'|'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span>, <span style="color:#996600;">'l'</span>, <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'!'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'i'</span>, <span style="color:#996600;">'l'</span>, <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'@'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'g'</span>, <span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'('</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'c'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'['</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'c'</span>, <span style="color:#996600;">'e'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'{'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'e'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'&amp;'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'and'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'*'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'star'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">')'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'d'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'^'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'/'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'a'</span>, <span style="color:#996600;">'v'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'<span style="color:#000099;">\\</span>'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
      <span style="color:#996600;">'&lt;'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'k'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span> 
    <span style="color:#008000; font-style:italic;"># the penultimate two substitutions catch /\ (A) and \/ (V), albeit without</span>
    <span style="color:#008000; font-style:italic;"># distinguishing them, and the last (in conjunction with the empty options </span>
    <span style="color:#008000; font-style:italic;"># for ! and |) catches !&lt; and |&lt; (K)</span>
    versions = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    original.<span style="color:#9900CC;">downcase</span>.<span style="color:#9900CC;">each_char</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span>
      versions.<span style="color:#9900CC;">collect</span>! <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>v<span style="color:#006600; font-weight:bold;">|</span>
        alikes = look_or_sound_alikes<span style="color:#006600; font-weight:bold;">&#91;</span>c<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#006600; font-weight:bold;">&#91;</span>c<span style="color:#006600; font-weight:bold;">&#93;</span>
        alikes.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>c1<span style="color:#006600; font-weight:bold;">|</span> v <span style="color:#006600; font-weight:bold;">+</span> c1 <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      versions.<span style="color:#9900CC;">flatten</span>!
    <span style="color:#9966CC; font-weight:bold;">end</span>
    versions
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>password, custom_banned_list = <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    standard_banned_list = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{RAILS_ROOT}/config/banned_password_words.txt&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    banned_words = standard_banned_list.<span style="color:#9900CC;">downcase</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>\W<span style="color:#006600; font-weight:bold;">+/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> 
      custom_banned_list.<span style="color:#9900CC;">downcase</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>\W<span style="color:#006600; font-weight:bold;">+/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">delete_if</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span> w.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">4</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    alike_words = <span style="color:#006600; font-weight:bold;">&#91;</span>password.<span style="color:#9900CC;">downcase</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span> PasswordUtils.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span>password<span style="color:#006600; font-weight:bold;">&#41;</span>
    banned_words.<span style="color:#9900CC;">any</span>? <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>banned_word<span style="color:#006600; font-weight:bold;">|</span>
      alike_words.<span style="color:#9900CC;">any</span>? <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>alike_word<span style="color:#006600; font-weight:bold;">|</span> alike_word.<span style="color:#9966CC; font-weight:bold;">include</span>? banned_word <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>




<p>The first method of the class undoes some common substitutions:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;</span> PasswordUtils.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'p/<span style="color:#000099;">\5</span>5w0rd'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;password&quot;</span>, <span style="color:#996600;">&quot;pvssword&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&gt;</span>  PasswordUtils.<span style="color:#9900CC;">look_and_sound_alikes</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'S3cr3t-T35t|ng'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;secret-testing&quot;</span>, <span style="color:#996600;">&quot;secret-testlng&quot;</span>, <span style="color:#996600;">&quot;secret-testng&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>




<p>And the second method uses this in conjunction with a list of banned words to check that an entered password isn&#8217;t hopelessly weak.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;</span> PasswordUtils.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'p/<span style="color:#000099;">\5</span>5w0rd'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&gt;</span>  PasswordUtils.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'S3cr3t-T35t|ng'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&gt;</span> PasswordUtils.<span style="color:#9900CC;">obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'gkAsd76!o'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span></pre></div></div>




<p>Obviously, you need a good banned words list &#8212; perhaps starting with some <a href="http://www.buzzfeed.com/gavon/top-25-gawker-passwords">top N passwords lists</a>, and including the name of your company, the web app, and words related to the area of business, local pubs, and so on.</p>

<p>It&#8217;s also a good idea to include custom banned words for individual users. For example:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">custom_banned_list = <span style="color:#996600;">&quot;#{first_names} #{surname} #{department} #{organisation} #{email}&quot;</span>
PasswordUtils.<span style="color:#9900CC;">password_obvious</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>password, custom_banned_list<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>




<p>Passing these tests isn&#8217;t a sufficient condition for ruling out a weak password, but it&#8217;s arguably a necessary one, and a good start.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2010/12/14/death-to-weak-passwords/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  blog.mackerron.com/feed/ ) in 1.48295 seconds, on Feb 5th, 2012 at 2:47 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 5th, 2012 at 3:47 am UTC -->
