<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>code-spot</title>
	
	<link>http://code-spot.co.za</link>
	<description>a programming blog</description>
	<lastBuildDate>Wed, 25 Aug 2010 10:59:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/code-spot" /><feedburner:info uri="code-spot" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Update to Functional Equations Reference</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/eQkGe5hX68o/</link>
		<comments>http://code-spot.co.za/2010/08/25/update-to-functional-equations-reference/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 10:59:04 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Snippet]]></category>
		<category><![CDATA[difference equation]]></category>
		<category><![CDATA[discrete calculus]]></category>
		<category><![CDATA[functional equation]]></category>
		<category><![CDATA[z-transform]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=1061</guid>
		<description><![CDATA[I have updated the Reference for Functional Equations. I have added several entries to the tables, updated the graphs, added some new graphs, added some explanations and additional notes on notation, corrected a few typos, and re-organised the document slightly. Get the new version here.


Related posts:Update: Reference for Functional Equations
A Reference for Functional Equations



Related posts:<ol><li><a href='http://code-spot.co.za/2009/05/27/update-reference-for-functional-equations/' rel='bookmark' title='Permanent Link: Update: Reference for Functional Equations'>Update: Reference for Functional Equations</a></li>
<li><a href='http://code-spot.co.za/2009/02/26/a-reference-for-functional-equations/' rel='bookmark' title='Permanent Link: A Reference for Functional Equations'>A Reference for Functional Equations</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-421 alignleft" title="1052727062_0ec2c67ea4_small" src="http://code-spot.co.za/blog/wp-content/uploads/2009/02/1052727062_0ec2c67ea4_small.jpg" alt="" width="142" height="142" />I have updated the <em>Reference for Functional Equations</em>. I have added several entries to the tables, updated the graphs, added some new graphs, added some explanations and additional notes on notation, corrected a few typos, and re-organised the document slightly. Get the new version <a href="http://code-spot.co.za/difference-and-functional-equations-reference/">here</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F08%2F25%2Fupdate-to-functional-equations-reference%2F&amp;linkname=Update%20to%20Functional%20Equations%20Reference"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2009/05/27/update-reference-for-functional-equations/' rel='bookmark' title='Permanent Link: Update: Reference for Functional Equations'>Update: Reference for Functional Equations</a></li>
<li><a href='http://code-spot.co.za/2009/02/26/a-reference-for-functional-equations/' rel='bookmark' title='Permanent Link: A Reference for Functional Equations'>A Reference for Functional Equations</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/zExOXIRoTOw8xP-aap1QTLBTg7o/0/da"><img src="http://feedads.g.doubleclick.net/~a/zExOXIRoTOw8xP-aap1QTLBTg7o/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/zExOXIRoTOw8xP-aap1QTLBTg7o/1/da"><img src="http://feedads.g.doubleclick.net/~a/zExOXIRoTOw8xP-aap1QTLBTg7o/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/eQkGe5hX68o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/08/25/update-to-functional-equations-reference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/08/25/update-to-functional-equations-reference/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=update-to-functional-equations-reference</feedburner:origLink></item>
		<item>
		<title>A Simple Trick for Moving Objects in a Physics Simulation</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/wTQvHWGsDpM/</link>
		<comments>http://code-spot.co.za/2010/07/27/a-simple-trick-for-moving-objects-in-a-physics-simulation/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 19:24:24 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Simulation]]></category>
		<category><![CDATA[damper]]></category>
		<category><![CDATA[force]]></category>
		<category><![CDATA[game programming]]></category>
		<category><![CDATA[physics]]></category>
		<category><![CDATA[PID controller]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=1013</guid>
		<description><![CDATA[
(Original Image by Valerie Everett)
It is sometime necessary to move an object in a physics simulation to a specific point. On the one hand, it can be difficult to analyse the exact force you have to apply; on the other hand it might not look so good if you animate the object&#8217;s position directly.
A compromise [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2009/04/09/cellular-automata-for-simulation-in-games/' rel='bookmark' title='Permanent Link: Cellular Automata for Simulation in Games'>Cellular Automata for Simulation in Games</a></li>
<li><a href='http://code-spot.co.za/2008/12/07/random-steering-7-components-for-a-toolkit/' rel='bookmark' title='Permanent Link: Random Steering &#8211; 7 Components for a Toolkit'>Random Steering &#8211; 7 Components for a Toolkit</a></li>
<li><a href='http://code-spot.co.za/2008/10/29/force-field-editor-v10/' rel='bookmark' title='Permanent Link: Force Field Editor v1.0'>Force Field Editor v1.0</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-1035" title="springs" src="http://code-spot.co.za/blog/wp-content/uploads/2010/07/springs2.png" alt="" width="488" height="257" /></p>
<p>(<a href="http://www.flickr.com/photos/valeriebb/248282508/sizes/o/">Original Image</a> by <a href="http://www.flickr.com/photos/valeriebb/">Valerie Everett</a>)</p>
<p>It is sometime necessary to move an object in a physics simulation to a specific point. On the one hand, it can be difficult to analyse the exact force you have to apply; on the other hand it might not look so good if you animate the object&#8217;s position directly.</p>
<p>A compromise that works well in many situations is to use a spring-damper system to move the object.</p>
<p>The trick is simple: we apply two forces—the one is proportional to the displacement; the other is proportional to the velocity. Tweaked correctly, they combine to give realistic movement to the desired point.</p>
<p><span id="more-1013"></span></p>
<p>The <a href="http://en.wikipedia.org/wiki/Hookes_law"><em>spring force</em></a> is proportional to the difference between the current position and the position where we want the object:</p>
<img src='http://s.wordpress.com/latex.php?latex=F_s%20%3D%20-k%28x%20-%20x_0%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='F_s = -k(x - x_0)' title='F_s = -k(x - x_0)' class='latex' />
<p>Here, <img src='http://s.wordpress.com/latex.php?latex=k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='k' title='k' class='latex' /> is a positive value called the <em>spring constant</em>.</p>
<p>As you can see, the force gets smaller as our object approaches the desired position, and becomes zero when it reaches that position. Unfortunately, in the absence of friction or drag, the <em>velocity</em> is not zero at this point, so the object overshoots the desired position, and moves past it. The force becomes bigger, but in the opposite direction. The object keeps on moving, slowing down, and finally starts moving in the opposite direction towards the desired position. This goes on indefinitely.</p>
<p>When there is friction or drag, we might be lucky enough for the system to slow down the object sufficiently so that its velocity becomes zero when the object reaches the desired position. This can be tricky to accomplish, though, and might impact the simulation environment in undesirable ways.</p>
<p>It is better to add a counteracting force explicitly. We add a <em>damper force</em> that is propostional to the velocity of the object, again opposite in direction. Here <img src='http://s.wordpress.com/latex.php?latex=c&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='c' title='c' class='latex' /> is the <em>viscous damping coefficient</em>, also a positive number.</p>
<img src='http://s.wordpress.com/latex.php?latex=F_d%20%3D%20-cv&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='F_d = -cv' title='F_d = -cv' class='latex' />
<p>We then apply the sum of the forces to our object:</p>
<img src='http://s.wordpress.com/latex.php?latex=F_t%20%3D%20F_s%20%2B%20F_d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='F_t = F_s + F_d' title='F_t = F_s + F_d' class='latex' />
<p>The trick is to choose <img src='http://s.wordpress.com/latex.php?latex=c&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='c' title='c' class='latex' /> to get the behaviour we want.</p>
<p>Fortunately, this is easy. The following table summarizes how the damping constant affects behaviour. Here, <img src='http://s.wordpress.com/latex.php?latex=m&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='m' title='m' class='latex' /> is the mass of the object.</p>
<table>
<tbody>
<tr>
<td><img src='http://s.wordpress.com/latex.php?latex=c%20%3D%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='c = 0' title='c = 0' class='latex' /></td>
<td>The object oscillates.</td>
</tr>
<tr>
<td><img src='http://s.wordpress.com/latex.php?latex=0%20%3C%20c%20%3C%202%5Csqrt%7Bmk%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='0 &lt; c &lt; 2\sqrt{mk}' title='0 &lt; c &lt; 2\sqrt{mk}' class='latex' /></td>
<td>The object oscillates, but the oscillations die down.</td>
</tr>
<tr>
<td><img src='http://s.wordpress.com/latex.php?latex=c%20%3D%202%5Csqrt%7Bmk%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='c = 2\sqrt{mk}' title='c = 2\sqrt{mk}' class='latex' /></td>
<td>The object moves to the desired position without oscillating in minimum time.</td>
</tr>
<tr>
<td><img src='http://s.wordpress.com/latex.php?latex=c%20%3E%202%5Csqrt%7Bmk%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='c &gt; 2\sqrt{mk}' title='c &gt; 2\sqrt{mk}' class='latex' /></td>
<td>The object moves to the desired position without oscillating, and takes longer as c increases.</td>
</tr>
</tbody>
</table>
<p>If you want to see an explanation of how this works, see the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Damping">damping</a>.</p>
<p>By choosing <img src='http://s.wordpress.com/latex.php?latex=c%20%3D%202%5Csqrt%7Bmk%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='c = 2\sqrt{mk}' title='c = 2\sqrt{mk}' class='latex' />, we are left with only one parameter to tweak (the spring constant), with which we can adjust the time it will take for the object to reach the desired spot.</p>
<p>A simple implementation of this idea is given by the following function. The function should be called for every simulation frame, until we are satisfied that the object reached its spot:</p>
<pre>private void MoveTo(Rigidbody rigidbody, Vector3 newPosition,
      float springConstant)
{
  Vector3 desiredDisplacement = rigidbody.position - newPosition;
  Vector3 springForce = -springConstant * desiredDisplacement;

  float viscousDampingCoefficient
    = 2 * sqrt(rigidbody.mass * springConstant);

  Vector3 dampingForce
    = -viscousDampingCoefficient * rigidbody.velocity;

  Vector3 totalForce = springForce + dampingForce;
  rigidbody.AddForce(totalForce);
}</pre>
<p>This will work even when there is drag or friction, except that the object will move slower (in this case we can decrease the artificial damping, although it is a bit risky). When there is an external force applied to the object, the object will come to rest at some point away from the desired position. By increasing the spring constant, the distance between this point and the desired point can be made smaller. Thus, we can also use this scheme to maintain objects at a certain height, for example, which can give a rather realistic simulation of a hovercraft or even a drifting object.</p>
<p><strong>Update: </strong>This is an example of a <a href="http://en.wikipedia.org/wiki/PID_controller">PID controller</a> (proportional–integral–derivative controller), for which there is a C++ implementation in my <a href="http://code.google.com/p/specialnumbers/">Special Numbers Library</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F07%2F27%2Fa-simple-trick-for-moving-objects-in-a-physics-simulation%2F&amp;linkname=A%20Simple%20Trick%20for%20Moving%20Objects%20in%20a%20Physics%20Simulation"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2009/04/09/cellular-automata-for-simulation-in-games/' rel='bookmark' title='Permanent Link: Cellular Automata for Simulation in Games'>Cellular Automata for Simulation in Games</a></li>
<li><a href='http://code-spot.co.za/2008/12/07/random-steering-7-components-for-a-toolkit/' rel='bookmark' title='Permanent Link: Random Steering &#8211; 7 Components for a Toolkit'>Random Steering &#8211; 7 Components for a Toolkit</a></li>
<li><a href='http://code-spot.co.za/2008/10/29/force-field-editor-v10/' rel='bookmark' title='Permanent Link: Force Field Editor v1.0'>Force Field Editor v1.0</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/YkMrtnmFmrQQW6IfJD5cq7bXDn4/0/da"><img src="http://feedads.g.doubleclick.net/~a/YkMrtnmFmrQQW6IfJD5cq7bXDn4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/YkMrtnmFmrQQW6IfJD5cq7bXDn4/1/da"><img src="http://feedads.g.doubleclick.net/~a/YkMrtnmFmrQQW6IfJD5cq7bXDn4/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/wTQvHWGsDpM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/07/27/a-simple-trick-for-moving-objects-in-a-physics-simulation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/07/27/a-simple-trick-for-moving-objects-in-a-physics-simulation/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-simple-trick-for-moving-objects-in-a-physics-simulation</feedburner:origLink></item>
		<item>
		<title>Region Quadtrees in C++</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/Bzlhpe_OXrU/</link>
		<comments>http://code-spot.co.za/2010/06/15/region-quadtrees-in-c/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 11:14:14 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Downloads]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Image Processing]]></category>
		<category><![CDATA[image partitioning]]></category>
		<category><![CDATA[quadtree]]></category>
		<category><![CDATA[spatial partitioning]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=983</guid>
		<description><![CDATA[
(Original image by GoAwayStupidAI).
Below are four C++ implementations of the region quadtree (the kind used for image compression, for example). The different implementations were made in an attempt to optimise construction of quadtrees. (For a tutorial on implementing region quadtrees, see Issue 26 [6.39 MB zip] of Dev.Mag).

NaiveQuadtree is the straightforward implementation.
AreaSumTableQuadtree uses a summed [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2008/10/06/quadtrees/' rel='bookmark' title='Permanent Link: Quadtrees'>Quadtrees</a></li>
<li><a href='http://code-spot.co.za/2008/11/15/quadtrees-2/' rel='bookmark' title='Permanent Link: Quadtrees'>Quadtrees</a></li>
<li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="display: inline; border: 0px;" title="quadtree" src="http://code-spot.co.za/blog/wp-content/uploads/2010/06/quadtree.png" border="0" alt="quadtree" width="491" height="375" /></p>
<p>(<a href="http://www.flickr.com/photos/goawaystupidai/3106598088/">Original image</a> by <a href="http://www.flickr.com/photos/goawaystupidai/">GoAwayStupidAI</a>).</p>
<p>Below are four C++ implementations of the <a href="http://www.voronoi.com/wiki/index.php?title=Quadtree">region quadtree</a> (the kind used for image compression, for example). The different implementations were made in an attempt to optimise <em>construction </em>of quadtrees. (For a tutorial on implementing region quadtrees, see <a href="http://www.devmag.org.za/uploads/DevMag_Issue26.zip">Issue 26</a> [6.39 MB zip] of <a href="http://www.devmag.org.za/">Dev.Mag</a>).</p>
<ul>
<li><strong>NaiveQuadtree </strong>is the straightforward implementation.</li>
<li><strong>AreaSumTableQuadtree </strong>uses a <a href="http://en.wikipedia.org/wiki/Summed_area_table">summed area table</a> to perform fast calculations of the mean and variance of regions in the data grid.</li>
<li><strong>AugmentedAreaSumTableQuadtree </strong>is the same, except that the area sum table has an extra row and column of zeros to prevents if-then logic that slows it down and makes it tricky to understand.</li>
<li><strong>SimpleQuadtree </strong>is the same as AugmentedAreaSumTableQuadtree , except that no distinction is made (at a class level) between different node types.</li>
</ul>
<p><span id="more-983"></span>The interfaces of all quadtrees are the same, but I did not want to extend from a base class. (Instead, a compile time check is performed on the classes, using <a href="http://www.boost.org/doc/libs/1_43_0/libs/concept_check/concept_check.htm">boost concepts</a>).</p>
<p>The results of the performance (on my machine!) of the trees are as follows:</p>
<table border="0" cellspacing="0" cellpadding="2" width="500">
<tbody>
<tr>
<td style="text-align: left;" width="100" valign="top">(milliseconds)</td>
<td style="text-align: right;" width="100" valign="top"><strong>N</strong></td>
<td style="text-align: right;" width="100" valign="top"><strong>S</strong></td>
<td style="text-align: right;" width="100" valign="top"><strong>AST</strong></td>
<td style="text-align: right;" width="100" valign="top"><strong>AAST</strong></td>
</tr>
<tr>
<td style="text-align: right;" width="100" valign="top"></td>
<td style="text-align: right;" width="100" valign="top">3</td>
<td style="text-align: right;" width="100" valign="top">4</td>
<td style="text-align: right;" width="100" valign="top">4</td>
<td style="text-align: right;" width="100" valign="top">3</td>
</tr>
<tr>
<td width="100" valign="top"><strong>64×64</strong></td>
<td style="text-align: right;" width="100" valign="top">14</td>
<td style="text-align: right;" width="100" valign="top">14</td>
<td style="text-align: right;" width="100" valign="top">14</td>
<td style="text-align: right;" width="100" valign="top">13</td>
</tr>
<tr>
<td width="100" valign="top"><strong>128×128</strong></td>
<td style="text-align: right;" width="100" valign="top">55</td>
<td style="text-align: right;" width="100" valign="top">52</td>
<td style="text-align: right;" width="100" valign="top">55</td>
<td style="text-align: right;" width="100" valign="top">52</td>
</tr>
<tr>
<td width="100" valign="top"><strong>256×256</strong></td>
<td style="text-align: right;" width="100" valign="top">229</td>
<td style="text-align: right;" width="100" valign="top">233</td>
<td style="text-align: right;" width="100" valign="top">218</td>
<td style="text-align: right;" width="100" valign="top">214</td>
</tr>
<tr>
<td width="100" valign="top"><strong>512×512</strong></td>
<td style="text-align: right;" width="100" valign="top">950</td>
<td style="text-align: right;" width="100" valign="top">1036</td>
<td style="text-align: right;" width="100" valign="top">937</td>
<td style="text-align: right;" width="100" valign="top">922</td>
</tr>
<tr>
<td width="100" valign="top"><strong>1024×1024</strong></td>
<td style="text-align: right;" width="100" valign="top">4064</td>
<td style="text-align: right;" width="100" valign="top">4459</td>
<td style="text-align: right;" width="100" valign="top">5396</td>
<td style="text-align: right;" width="100" valign="top">3891</td>
</tr>
</tbody>
</table>
<p>As it turns out, the different implementations do not differ significantly. Constructing the nodes takes long, and not so much the calculations necessary to determine whether a node should split or not, and what data should be in the node. Had I profiled properly before I started I would not have gone through this exercise…</p>
<p>Between these four implementations, the NaiveQuadtree is the one I recommend; I left in the other implementations for anyone interested.</p>
<p>The one good thing that came from this experiment is that I found out that using a zero-augmented summed area table can increase performance quite a bit. This is useful for <a href="http://code-spot.co.za/2010/04/16/simple-fast-approximate-minimum-maximum-filters/">max-filters</a> and other algorithms that use these tables.</p>
<p>You can download the source code:</p>
<p><a href="http://www.code-spot.co.za/downloads/cpp/Quadtree.zip">Quadtree.zip</a> (44 KB, Visual Studio).</p>
<p>(It requires the <a href="http://www.boost.org/users/download/">boost library</a> for concept checking, but nothing else. Everything will still work if you remove all references to the boost library. If you already have boost, just hook up to the include path in Visual Studio).</p>
<p>&#8230;or read the <a href="http://www.code-spot.co.za/downloads/cpp/quadtrees/html/index.html">online documentation</a>.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F06%2F15%2Fregion-quadtrees-in-c%2F&amp;linkname=Region%20Quadtrees%20in%20C%2B%2B"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2008/10/06/quadtrees/' rel='bookmark' title='Permanent Link: Quadtrees'>Quadtrees</a></li>
<li><a href='http://code-spot.co.za/2008/11/15/quadtrees-2/' rel='bookmark' title='Permanent Link: Quadtrees'>Quadtrees</a></li>
<li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/yLAee5Z6mYytdjviMPxrU8mok8A/0/da"><img src="http://feedads.g.doubleclick.net/~a/yLAee5Z6mYytdjviMPxrU8mok8A/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/yLAee5Z6mYytdjviMPxrU8mok8A/1/da"><img src="http://feedads.g.doubleclick.net/~a/yLAee5Z6mYytdjviMPxrU8mok8A/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/Bzlhpe_OXrU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/06/15/region-quadtrees-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/06/15/region-quadtrees-in-c/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=region-quadtrees-in-c</feedburner:origLink></item>
		<item>
		<title>Catching Common Image Processing Programming Errors with Generic Unit Tests</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/hvirum8spkk/</link>
		<comments>http://code-spot.co.za/2010/05/12/catching-common-image-processing-programming-errors-with-generic-unit-tests/#comments</comments>
		<pubDate>Wed, 12 May 2010 13:40:30 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Image Processing]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=936</guid>
		<description><![CDATA[
When implementing image algorithms, I am prone to make these mistakes:

swapping x and y;
working on the wrong channel;
making off-by-one errors, especially in window algorithms;
making division-by-zero errors;
handling borders incorrectly; and
handling non-power-of-two sized images incorrectly.

Since these types of errors are prevalent in many image-processing algorithms, it would be useful to develop, once and for all, general tests [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2008/11/15/quadtrees-2/' rel='bookmark' title='Permanent Link: Quadtrees'>Quadtrees</a></li>
<li><a href='http://code-spot.co.za/2010/04/16/simple-fast-approximate-minimum-maximum-filters/' rel='bookmark' title='Permanent Link: Simple, Fast* Approximate Minimum / Maximum Filters'>Simple, Fast* Approximate Minimum / Maximum Filters</a></li>
<li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-947" title="crash test dummy" src="http://code-spot.co.za/blog/wp-content/uploads/2010/05/dummy1.png" alt="crash test dummy" width="491" height="321" /></p>
<p>When implementing image algorithms, I am prone to make these mistakes:</p>
<ul>
<li>swapping x and y;</li>
<li>working on the wrong channel;</li>
<li>making off-by-one errors, especially in window algorithms;</li>
<li>making division-by-zero errors;</li>
<li>handling borders incorrectly; and</li>
<li>handling non-power-of-two sized images incorrectly.</li>
</ul>
<p>Since these types of errors are prevalent in many image-processing algorithms, it would be useful to develop, once and for all, general tests that will catch these errors quickly for <em>any</em> algorithm.</p>
<p>This post is about such tests.</p>
<p><span id="more-936"></span></p>
<h2>The General Idea</h2>
<p>The general idea is to exploit the fact that many algorithms satisfy invariants such as these:</p>
<pre>some_transform(algorithm(image))
  == algorithm(some_transform(image))</pre>
<p>For example: a 3-by-3 box blur is invariant under a vertical flip:</p>
<pre>box_blur3x3(flip_vertical(image))
  == flip_vertical(box_blur3x3 (image))</pre>
<p>It does not matter whether we apply the flip before or after applying the box filter—the result should be the same.</p>
<p>What kind of errors can the above test expose? Since it checks whether the algorithm (not the image) is vertically symmetric, the test can catch certain off-by-one errors along the vertical axis. Here is an example of a faulty implementation of the blur algorithm. Here the function <code>sum</code> adds all the pixel values in the rectangle x0..x1 – 1 and y0..y1 – 1.</p>
<pre>//C-like pseudo-code
Image &amp; box_filter3x3(Image &amp; image)
{
  forXY(image, x, y)
  {
    x0, y0 = max(0, x – 1), max(0, y – 1)
    x1, y1 = min(x + 1, image.width), min(y + 1, image.height)
    result = sum(image, x0, x1, y0, y1) / ((x1 – x0) * (y1 – y0));
  }

  image = result;
  return image;
}</pre>
<p>Can you spot the error? The actual window used is only 2 by 2. But how does the test catch this error? To see why the test will fail, notice the difference in windows for the top-left and bottom-left pixels:</p>
<p>Top Left:</p>
<pre>x0, y0 == 0, 0
x1, y1 == 1, 1</pre>
<p>Bottom Left</p>
<pre>x0, y0 == width – 2, height – 2
x1, y1 == width , height</pre>
<p>As you can see, the two windows have different sizes! The bottom-left pixel window is 1 by 1, but the top left pixel is 2 by 2. Thus flipping the image before and after applying the box-blur gives different results.</p>
<p>The correct algorithm is</p>
<pre>//C-like pseudo-code
Image &amp; box_filter3x3(Image &amp; image)
{
  forXY(image, x, y)
  {
    x0, y0 = max(0, x – 1), max(0, y – 1)
    x1, y1 = min(x + 2, image.width), min(y + 2, image.height)
    result = sum(image, x0, x1, y0, y1) /
      ((x1 – x0) * (y1 – y0));
  }

  image = result;

  return Image;
}</pre>
<p>Now the windows for the top and bottom left pixels are:</p>
<pre>x0, y0 == 0, 0
x1, y1 == 2, 2</pre>
<p>Bottom Left</p>
<pre>x0, y0 == width – 2, height – 2
x1, y1 == width , height</pre>
<p>We can see the window sizes are now the same.</p>
<h2>Transforms</h2>
<p>Here is a list of suggested transforms and the types of errors they can catch:</p>
<table border="0" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td width="140" valign="top"><code>flipVertical<br />
</code><code>flipHorizontal</code></td>
<td width="340" valign="top">Off-by-one errors.</td>
</tr>
<tr>
<td width="140" valign="top"><code>flipDiagonal</code></td>
<td width="340" valign="top">Swapping x and y.</td>
</tr>
<tr>
<td width="140" valign="top"><code>rotateChannels</code></td>
<td width="340" valign="top">Working on the wrong channel.</td>
</tr>
<tr>
<td width="140" valign="top"><code>invert</code></td>
<td width="340" valign="top">Calculation mistakes, certain kinds of division-by-zero. errors.</td>
</tr>
<tr>
<td width="140" valign="top"><code>scaleIntensity</code></td>
<td width="340" valign="top">Calculation mistakes.</td>
</tr>
<tr>
<td width="140" valign="top"><code>adjustGamma</code></td>
<td width="340" valign="top">Certain kinds of statistical ordering errors.</td>
</tr>
<tr>
<td width="140" valign="top"><code>crop</code></td>
<td width="340" valign="top">Certain kind of incorrect border calculations, certain power-of-two errors.</td>
</tr>
<tr>
<td width="140" valign="top"><code>translateVertival<br />
</code><code>translateHorizontal</code></td>
<td width="340" valign="top">Certain kinds of incorrect border calculations, off-by-one errors.</td>
</tr>
<tr>
<td width="140" valign="top"><code>desaturate</code></td>
<td width="340" valign="top">Certain channel processing errors.</td>
</tr>
</tbody>
</table>
<p>Many algorithms should (in theory) also be invariant under scaling. However, because of the complexity involved in interpolation and sampling, I do not recommend using scaling for testing. It is quite difficult to determine under some interpolation or sampling scheme whether an algorithm should in fact be (exactly) invariant or not under scaling. This of course also applies to other transforms that rely on sampling or interpolation.</p>
<p>You will probably also select transforms that are more specific to the algorithms you are implementing. Keep these as simple as possible—not only to avoid implementation errors, but also to avoid subtle misconceptions: it must be easy to see (or well established) that a certain algorithm is invariant under a transform. Test your own transform functions aggressively.</p>
<h2>Generic Solutions</h2>
<p>Writing test code for each transform is easy, but tedious (and hence error prone). Here I show how a generic test can be implemented using C++ macros or functional programming. The generic test can be used to test whether any algorithm is invariant under a given transform.</p>
<h3>Macros Implementation</h3>
<p>Probably the easiest way to implement a general test-function in C++ is to implement it as a macro. Here is how this looks:</p>
<pre>//C++
#define TEST_TRANSFORM_INVARIANCE(image, transform, command) \
  do { \
    Image image; \
    make_test_image(image); \
    \
    Image original_image(image); \
    command; \
    \
    Image image1(image); \
    transform(image1); \
    \
    image = original_image; \
    transform(image); \
    command; \
    \
    if (image != image1) \
      report_useful_failure_message(...); \
  } while(0)</pre>
<p>We can now use this macro like this:</p>
<pre>TEST_TRANSFORM_INVARIANCE (image, flipVertical, my_algorithm(image));</pre>
<p>The nice thing about the macro approach is how easy functions that take any number of parameters can be tested:</p>
<pre>TEST_TRANSFORM_INVARIANCE (image, flipVertical, my_algorithm(image, 10, 20));</pre>
<p>Notice that the first parameter is a <em>variable name</em>. The macro declares this variable, and the user can use it in the command parameter to pass the image to the algorithm.</p>
<h3>Functional Programming Implementation</h3>
<p>If macros are not available, or using them is not desirable, you can still use a generic approach. Unfortunately, we need to define functions with a consistent argument list for each test we want to perform, which means we might need to write more code in some languages.</p>
<p>The general test function can be defined as follows in C++:</p>
<pre>//C++
test_transform_inavriance(
  Image &amp; (* function)(Image &amp;),
  Image &amp; (* transform)(Image &amp;))
{
  Image image;
  make_test_image(image);

  Image original_image(image);
  function(image);

  Image image1(image);
  transform(image1);

  image = original_image;
  transform(image);
  function(image);

  if (image != image1)
    report_useful_failure_message(...);
}</pre>
<p>To use it with a single argument function, we simply call it like this:</p>
<pre>test_transform_inavriance(flip_vertical, my_algorithm);</pre>
<p>To use it with a function that takes more than one parameter, we need to define a function to call the extra parameters:</p>
<pre>// C++
Image &amp; test_my_algorithm_wrapper(Image &amp; image)
{
  my_algorithm(image, 10, 20);
}
...
test_transform_inavriance(flip_vertical, my_algorithm_wrapper);</pre>
<p>In languages that support closures, you can wrap functions more cleanly so that you do not need to define a function for each test command. For example, in Python:</p>
<pre># Python
def wrap(fn, args):
  def wrapper(image):
    fn(image, *args)
  return fn
...
test_transform_inavriance(flip_vertical, wrap(my_algorithm, 10, 20));</pre>
<h2>Test Bundles</h2>
<p>Both the macro and functional programming approaches allow you to combine tests of different transforms in convenient functions:</p>
<pre>// C++
#define TEST_ALL(image, command)\
  do { \
    TEST_TRANSFORM_INVARIANCE (image, flip_vertical, command); \
    TEST_TRANSFORM_INVARIANCE (image, flip_horizontal, command); \
    ...
  } while(0)</pre>
<pre>// C++
void test_all(Image &amp; (* fn)(Image &amp;))
{
  test_transform_inavriance(flip_vertical, function);
  test_transform_inavriance(flip_ horizontal, function);
  ...
}</pre>
<h2>Test Images</h2>
<p>It is important that your images do not destroy the very asymmetry that you are trying to expose. For instance, if we ran the test at the very beginning of this post with an all-zero image, the test will have passed. The image should be asymmetric under the transform we are using, that is, the following must hold:</p>
<pre>transform(image) != image</pre>
<p>For different transforms, this means different things. For example, for flip_diagonal, the image must not be square, for inverse, the image must not be the constant grayscale image 0.5.</p>
<p>It is useful to build an extra test into our test macro or function, to make sure that we do not inadvertently break this requirement. Here is the modified macro:</p>
<pre>// C++
#define TEST_TRANSFORM_INVARIANCE(image, transform, command)\
  do { \
    Image image; \
    make_test_image(image); \
    \
    Image original_image(image); \
    transform(image); \
    \
    if(image == original_image) \
      report_unsuitable_test_image(...); \
    \
    image = original_image; \
    command; \
    \
    Image image1(image); \
    transform(image1); \
    \
    image = original_image; \
    transform(image); \
    command; \
    \
    if (image != image1) \
      report_useful_failure_message(...); \
  } while(0)</pre>
<p>For many algorithms, using an image of noise (independent for each channel) works well. Make sure the image have unequal dimensions that are prime numbers (for example, 11 and 13). Using prime numbers ensures that the two dimensions will not have any common divisors, which makes certain kind of tests for recursive algorithms (such as quad-tree compression) more robust.</p>
<h2>Reporting Failures</h2>
<p>In the example implementation, we have the line</p>
<pre>if (image != image1) report_useful_failure_message(...);</pre>
<p>This is a somewhat simplistic scheme. What is a useful failure message? Of course, the message must report the test that failed. But it should also give information about how the test failed:</p>
<ul>
<li>whether it was a mismatch of the number of channels, image dimensions, or pixel values;</li>
<li>the number of channels and image dimensions;</li>
<li>the number of pixels for which the test failed; and</li>
<li>the first pixel location where the test failed, and the expected and actual pixel values.</li>
</ul>
<p>These bits of information can help us hunt down the cause. For example, if the test data is an 11-by-13 image, and the test fails for 13 pixels, the error is most likely a border problem caused by an off-by-one error. If the first pixels that fails is 0, 0, and the test fails for (almost) all pixels, and the pixel values differ only by sign, we can guess that there is some sign error made that affects the entire image.</p>
<p>The actual test will thus be a bit more complicated, delegating to a function such as this:</p>
<pre>test_image_equality(
  Image &amp; image1,
  Image image 2,
  FailureInfo &amp; info)
{
  info.has_failed = false;
  info.failed_pixels_count = 0;
  info.dimensions_image1 = image1.dimensions;
  info.dimensions_image2 = image2.dimensions;
  info.channels_image1 = image1.channels
  info.channels_image2 = image2.channels

  if(image1.channels != image2.channels)
  {
     info.has_failed = true;
     info.failure_type = CHANNEL_MISMATCH;
     return;
  }

  if(image1.dimensions != image2.dimensions)
  {
    info.has_failed = true;
    info.failure_type = DIMENSION_MISMATCH;
    return;
  }

  forXY(image, x, y)
  {
    if(abs(image1(x, y) - image2(x, y)) &lt; THRESHOLD)
    {
      if (!info.has_failed)
      {
        info.has_failed = true;
        info.failure_type = VALUE_MISMATCH;
        info.first_failed_x = x;
        info.first_failed_y = y;
        info_first_failed_image1 = image1(x,y);
        info_first_failed_image2 = image2(x,y);
      }

      info.failed_pixels_count++;
    }
  }
}</pre>
<p>In the test macro or function, we call the function like this:</p>
<pre>...
FailureInfo info; \
test_image_equality(image, image1, info); \
if (info.has_failed) report_failure(info); \
...</pre>
<h2>Using Third-Party Image Libraries</h2>
<p>It is important that you understand the transforms you use for testing very well. It is therefore a good idea to use you own transforms, and not those of a library. This way, unknown design choices in the library cannot bite you. Many image libraries do not for example specify how they handle borders, division by zero, rounding, etc. These details are often not important when using the algorithms in a task—but they can make a test fail (or succeed) when it should not.</p>
<p>The same danger exists when you use third party algorithms as building blocks for your own. In this case testing your code will be harder. As a starting point, consider testing whether third party algorithms satisfy the invariants you expect to hold. If they do not, you may need to modify your test code to accommodate for the discrepancy. If they do, you can be a little more confident that your tests will be reliable.</p>
<p>(Yes, it is not normally recommended to test other people&#8217;s code with unit tests. However, this is a once-off test to make sure that your own tests are reliable, and since it is so easy to implement (since you already have the test macro / function and transforms), I do not see the harm. Just keep the third-party library test separate from your own.)</p>
<h2>Defining Correctness—When are two images equal?</h2>
<p>Correctness of an image algorithm is a subtle issue, mostly because the discrete, quantized, finite model of image computation is inherently an approximation of the “real” thing. The question is too broad to tackle here (and frankly, I do not have enough knowledge to do it), so I will focus on aspects that are specifically relevant to this kind of testing.</p>
<p>Let us start with an example of an essentially correct algorithm that fails a test that we expect that it should not:</p>
<pre>// C++
Image &amp; threshold(Image &amp; image)
{
  forXY(image, x, y)
    image(x, y) = (image(x, y) &lt;= 0.5f) ? 0 : 1;

  return image;
}</pre>
<p>We expect this simple algorithm to be invariant under the inverse transform. However, it is not. Consider a pixel value of 0.5: the inverse of this is 0.5. So both the pixel and its inverse will map to zero, and hence the following will not be true:</p>
<pre>inverse(threshold(image)) == threshold(inverse(image)) //not true
inverse(threshold(0.5f)) == inverse(0) == 1 //left side
threshold(inverse(0.5f)) == threshold(0.5f) == 0 //right side</pre>
<p>It looks like the problem is easily solved by changing the algorithm:</p>
<pre>// C++
Image &amp; threshold(Image ℑ)
{
  forXY(image, x, y)
    image(x, y) = (image(x, y) &lt; 0.5f) ? 0 : 1;

  return image;
}</pre>
<p>But, for floating point numbers on a machine, there is another number 0.5 – epsilon such that the following algorithm is equivalent to the one above:</p>
<pre>// C++
Image &amp; threshold(Image &amp; image)
{
  forXY(image, x, y)
    image(x, y) = (image(x, y) &lt;= 0.5f - epsilon) ? 0 : 1;

  return image;
}</pre>
<p>But for this algorithm our invariant does not hold for a pixel with the value 0.5 – epsilon! Since the last two algorithms are equivalent, it means the modified algorithm is also not correct in this strict sense. In fact, it is not possible to implement an algorithm that is correct in this sense (using floating-point numbers).</p>
<p>But we feel that any of the above implementation <em>is</em> correct, and hence our test is wrong. So how do we change it, and should we?</p>
<p>We can change one (or more) of three things:</p>
<ul>
<li>the test data</li>
<li>the test transform</li>
<li>how we test for equality in images</li>
</ul>
<p>Because of the simplicity and general usefulness of both the transform and the test data, I feel it is best to leave these as is. That means we have to change the measure of equality. Since we use random data, we might want to use the “is probably equal” measure—that is, two images are equal if a certain percentage of pixels are equal (within some threshold). Since the likelihood of generating 0.5 is low, our test should pass. I do not like this idea for two reasons:</p>
<p>First, it is not generally useful. For example, another test might fail when the borders are not equal (a much larger number of pixels), even though we feel that it must not for some specific algorithm. We then need another equality measure to handle that case.</p>
<p>Second, it is bound to hide a class of errors where a small number of pixels are incorrectly processed, and we do not want that.</p>
<p>Instead, we would like some measure that is generally useful, but can be tweaked for the specific algorithm to overcome those cases where we expect the algorithm to fail.</p>
<p>One way to do this is to use equality masks: a simple bit array that says whether we are interested in that pixel or not. In this case, we need the mask to be constructed from the test data; here is how we do it:</p>
<pre>//C++
BitImage &amp; make_ignore_value_mask(
  BitImage &amp; mask,
  Image &amp; image,
  float value)
{
  forXY(image, x, y)
    mask = image(x, y) == 0.5f;
}</pre>
<p>We then change our macro to this:</p>
<pre>#define TEST_TRANSFORM_INVARIANCE (image, mask, transform, command, mask_command) \
  do { \
    Image image; \
    make_test_image(image); \
    \
    Image original_image(image); \
    transform(image); \
    \
    if(image == original_image)
      report_unsuitable_test_image(...); \
    \
    image = original_image; \
    command; \
    \
    Image image1(image); \
    transform(image1); \
    \
    image = original_image; \
    transform(image); \
    command; \
    \
    BitImage mask(image.width, image.height); \
    mask_command; \
    \
    if (mask * image != mask * image1)
      report_useful_failure_message(...); \
  } while(0)</pre>
<p>We call the macro like this:</p>
<p>TEST_TRANSFORM_INVARIANCE (image, mask, inverse, threshold(image), make_ignore_value_mask(mask, image, value));</p>
<p>The functional programming solutions are similarly modified:</p>
<pre>// C++
test_transform_inavriance(
  Image &amp; (* function)(Image &amp;),
  BitImage &amp; (*mask_creation_function) (BitImage &amp; mask, Image &amp; image),
  Image &amp; (* transform)(Image &amp;))
{
  Image image;
  make_test_image(image);

  Image original_image(image);

  if(image == original_image)
      report_unsuitable_test_image(...); 

  image = original_image;
  function(image);

  Image image1(image);
  transform(image1);

  image = original_image;
  transform(image);
  function(image);

  BitImage mask;
  mask_creation_function(mask, image);

  if (mask * image != mask * image1)
    report_useful_failure_message(...);
}</pre>
<p>We need a wrapping function to call our extra argument:</p>
<pre>BitImage &amp; void wrapped_ make_ignore_value_mask(
  BitImage &amp; mask,
  Image &amp; image)
{
  return make_ignore_value_mask(mask, image, 0,5f);
}</pre>
<p>Now we can call our test function like this:</p>
<pre>test_transform_inavriance(image, mask, inverse, threshold,
  wrapped_make_ignore mask(mask, image));</pre>
<p>In languages that support closures such as Python, we can again use the wrapping technique as before:</p>
<pre>test_transform_inavriance(image, mask, inverse, threshold,
  wrap(make_ignore mask(mask, image), 0.5))</pre>
<p>Here are a few suggestions for useful mask types:</p>
<table border="0" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td width="158" valign="top"><code>ignore_none</code></td>
<td width="340" valign="top">A constant array of 1s. Probably the one to be used with most algorithms.</td>
</tr>
<tr>
<td width="158" valign="top"><code>ignore_value</code><br />
<code>ignore_values</code></td>
<td width="340" valign="top">Ignores all the pixels in the test data that equal a given value or list of values.</td>
</tr>
<tr>
<td width="158" valign="top"><code>ignore_range</code></td>
<td width="340" valign="top">Ignores all the pixels in the test data that fall in the given range.</td>
</tr>
<tr>
<td width="158" valign="top"><code>ignore_out_of_range</code></td>
<td width="340" valign="top">Ignores all the pixels in the test data that fall outside a given range.</td>
</tr>
<tr>
<td width="158" valign="top"><code>ignore_rect</code></td>
<td width="340" valign="top">Ignores all the pixels inside a specified rectangle.</td>
</tr>
<tr>
<td width="158" valign="top"><code>ignore_border</code></td>
<td width="340" valign="top">Ignore all pixels in a boarder of specified width.</td>
</tr>
</tbody>
</table>
<p>Be careful for inadvertent ignore_all masks. For example, the ignore_border mask might be all zero when the border is thicker than half the smallest image dimension. It is a good idea to build in a test to check that the mask is not all-zero in the test macro or function.</p>
<p>Also watch out when transforms or algorithms change image dimensions—make sure the mask is constructed correctly.</p>
<p>We have now answered how we can change the test to pass for the thresholding example (and more generally); it remains to answer whether we should. My feeling is: only when you <em>have </em>to. Generally, I test without regard for such subtle issues. When a test fails, I carefully try to understand whether it is because the algorithm is fundamentally wrong, or whether it is just an obscure instance that makes the test fail. In the latter case, I will amend the test with the necessary masks.</p>
<p><b>Update</b>: Here is another example of how an invariance test can fail even when the algorithm is fundamentally correct. Consider a region quadtree compression scheme. Suppose we want to compress a 5&#038;times 5 image, and suppose the algorithm divides the image in four rectangles. Because 5 is odd, the rectangles will differ in size. The biggest rectangle should always be in the same spot, regardless of the reflection; thus the algorithm should fail when testing pixels along the center. We cannot really address this issue with masks. To me it is unclear how to handle this at all (and clearly, we do not want to limit our tests to powers-of-two images only).</p>
<h2>Warning: A False sense of Security</h2>
<p>When you have a large group of transforms to construct invariance checks from, you can easily test for a whole bunch of errors with just a few lines of code. If the tests pass, it is easy to think that the algorithm is correct. It may not be:</p>
<ul>
<li>Perhaps the test image is unsuitable. This may be by coincidence if the test image is random.</li>
<li>Any particular test does not catch all errors of a certain type.</li>
<li>All transforms do not cover the entire set of possible errors.</li>
</ul>
<p>A set of invariance tests does in general not prove the <em>correctness</em> of a particular algorithm. It merely exposes <em>certain kinds of errors</em>. Therefore, additional tests for correctness are necessary.</p>
<h2>Invariance Test Checklist / Summary</h2>
<p>The basic structure of the test macro / function is as follows:</p>
<ol>
<li>Create test data.</li>
<li>Calculate transform(algorithm(test_image)).</li>
<li>Calculate algorithm(transform(test_image)).</li>
<li>Compare these results and report any failures.</li>
</ol>
<p>Remember:</p>
<ul>
<li>Check that the test data is changed by the transform.</li>
<li>Use masks to cater for peripheral special cases where certain pixels, values, or regions in an image should be ignored for comparisons.</li>
<li>Check that your masks are not all zero (sanity check).</li>
<li>Report useful information when a test fails:
<ul>
<li>what kind of failure (dimension mismatch, channel mismatch, value mismatch);</li>
<li>in the case of value mismatch, the number of pixels that are mismatched and the values of the first pixels from each image that fail to match.</li>
</ul>
</li>
</ul>
<h2>More on Unit Testing for Image Processing</h2>
<ul>
<li><a href="http://blogs.mathworks.com/steve/2009/02/03/mtest-a-unit-test-harness-for-matlab-code/">MTEST &#8211; A unit test harness for MATLAB code</a></li>
<li><a href="http://aras-p.info/blog/2007/07/31/testing-graphics-code/">Testing Graphics Code</a></li>
</ul>
<h2>How do <em>You </em>Test Your Image Algorithms?</h2>
<p>Let me know in the comments <img src='http://code-spot.co.za/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F05%2F12%2Fcatching-common-image-processing-programming-errors-with-generic-unit-tests%2F&amp;linkname=Catching%20Common%20Image%20Processing%20Programming%20Errors%20with%20Generic%20Unit%20Tests"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2008/11/15/quadtrees-2/' rel='bookmark' title='Permanent Link: Quadtrees'>Quadtrees</a></li>
<li><a href='http://code-spot.co.za/2010/04/16/simple-fast-approximate-minimum-maximum-filters/' rel='bookmark' title='Permanent Link: Simple, Fast* Approximate Minimum / Maximum Filters'>Simple, Fast* Approximate Minimum / Maximum Filters</a></li>
<li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/Sq29AnYc2RnXBdw7qlx472JuIcs/0/da"><img src="http://feedads.g.doubleclick.net/~a/Sq29AnYc2RnXBdw7qlx472JuIcs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Sq29AnYc2RnXBdw7qlx472JuIcs/1/da"><img src="http://feedads.g.doubleclick.net/~a/Sq29AnYc2RnXBdw7qlx472JuIcs/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/hvirum8spkk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/05/12/catching-common-image-processing-programming-errors-with-generic-unit-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/05/12/catching-common-image-processing-programming-errors-with-generic-unit-tests/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=catching-common-image-processing-programming-errors-with-generic-unit-tests</feedburner:origLink></item>
		<item>
		<title>Simple, Fast* Approximate Minimum / Maximum Filters</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/o2P0m_8ZCnc/</link>
		<comments>http://code-spot.co.za/2010/04/16/simple-fast-approximate-minimum-maximum-filters/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 14:13:05 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Image Processing]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[dilation]]></category>
		<category><![CDATA[erosion]]></category>
		<category><![CDATA[filtering]]></category>
		<category><![CDATA[maximum filter]]></category>
		<category><![CDATA[minimum filter]]></category>
		<category><![CDATA[morphology]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=881</guid>
		<description><![CDATA[
*Fast = not toooo slow…
For the image restoration tool I had to implement min and max filters (also erosion and dilation—in this case with a square structuring element). Implementing these efficiently is not so easy. The naive approach is to simply check all the pixels in the window, and select the maximum or minimum value. This algorithm&#8217;s [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2010/06/15/region-quadtrees-in-c/' rel='bookmark' title='Permanent Link: Region Quadtrees in C++'>Region Quadtrees in C++</a></li>
<li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
<li><a href='http://code-spot.co.za/2010/07/27/a-simple-trick-for-moving-objects-in-a-physics-simulation/' rel='bookmark' title='Permanent Link: A Simple Trick for Moving Objects in a Physics Simulation'>A Simple Trick for Moving Objects in a Physics Simulation</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="display: inline; border: 0px initial initial;" title="minmax" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/minmax.png" border="0" alt="minmax" width="491" height="321" /></p>
<p><em>*Fast = not toooo slow…</em></p>
<p>For the <a href="http://code-spot.co.za/2010/04/15/experimental-tool-for-removing-unwanted-artefacts-in-textures/">image restoration tool</a> I had to implement <a href="http://livedocs.adobe.com/en_US/Photoshop/10.0/help.html?content=WSfd1234e1c4b69f30ea53e41001031ab64-795d.html">min and max filters</a> (also <a href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/erode.htm">erosion</a> and <a href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/dilate.htm">dilation</a>—in this case with a square <a href="http://en.wikipedia.org/wiki/Structuring_element">structuring element</a>). Implementing these efficiently is not so easy. The naive approach is to simply check all the pixels in the window, and select the maximum or minimum value. This algorithm&#8217;s run time is quadratic in the window width, which can be a bit slow for the bigger windows that I am interested in. There are some very efficient algorithms available, but they are quite complicated to implement properly (some require esoteric data structures, for example <a href="http://www.archipel.uqam.ca/309/1/webmaximinalgo.pdf">monotonic wedges</a> (PDF)), and many are not suitable for floating point images.</p>
<p>So I came up with this approximation scheme. It uses some expensive floating point operations, but its run time is <em>constant</em> in the window width.</p>
<p><span id="more-881"></span></p>
<p>The crux of the algorithm is the following approximation, which works well for <img src='http://s.wordpress.com/latex.php?latex=0%20%3C%20x_i%20%3C%201&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='0 &lt; x_i &lt; 1' title='0 &lt; x_i &lt; 1' class='latex' />, <img src='http://s.wordpress.com/latex.php?latex=p%20%5Cgg%201&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p \gg 1' title='p \gg 1' class='latex' />.</p>
<img src='http://s.wordpress.com/latex.php?latex=%20%5Cmax_%7Bi%3D1%7D%5ENx_i%5Capprox%20%28%5Cfrac%7B1%7D%7BN%7D%5Csum_%7Bi%3D1%7D%5ENx_i%5Ep%29%5E%7B1%2Fp%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' \max_{i=1}^Nx_i\approx (\frac{1}{N}\sum_{i=1}^Nx_i^p)^{1/p} ' title=' \max_{i=1}^Nx_i\approx (\frac{1}{N}\sum_{i=1}^Nx_i^p)^{1/p} ' class='latex' />
<p>I am not going into the mathematical details of why this a fair approximation.</p>
<p>To turn this into a max filter is straightforward:</p>
<h3>1. Calculate the power image</h3>
<p>Raise each pixel to the power <em>p</em>.</p>
<img src='http://s.wordpress.com/latex.php?latex=P%28x%2C%20y%29%20%3D%20%5BI%28x%2C%20y%29%5D%5Ep&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P(x, y) = [I(x, y)]^p' title='P(x, y) = [I(x, y)]^p' class='latex' />
<h3>2. Calculate a summed area table</h3>
<p>The <a href="http://en.wikipedia.org/wiki/Summed_area_table">summed area table</a> (or integral) of an image is a table containing in each cell (x, y), the sum of all the pixels top and left of (x, y); for the power image <img src='http://s.wordpress.com/latex.php?latex=P%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='P ' title='P ' class='latex' /> it is given by:</p>
<img src='http://s.wordpress.com/latex.php?latex=S%28x%2Cy%29%20%3D%20%5Csum_%7Bu%3D0%7D%5E%7Bx%7D%5Csum_%7Bv%3D0%7D%5E%7By%7DP%28u%2Cv%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='S(x,y) = \sum_{u=0}^{x}\sum_{v=0}^{y}P(u,v)' title='S(x,y) = \sum_{u=0}^{x}\sum_{v=0}^{y}P(u,v)' class='latex' />
<p><strong>Update:</strong> This can be efficiently be calculated using the following recurrence:</p>
<img src='http://s.wordpress.com/latex.php?latex=S%28x%2C%20y%29%20%3D%20S%28x%2C%20y%20-%201%29%20%2B%20S%28x%20-%201%2C%20y%29%20-%20S%28x%2C%20y%29%20%2B%20P%28x%2C%20y%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='S(x, y) = S(x, y - 1) + S(x - 1, y) - S(x, y) + P(x, y)' title='S(x, y) = S(x, y - 1) + S(x - 1, y) - S(x, y) + P(x, y)' class='latex' />
<p>and <img src='http://s.wordpress.com/latex.php?latex=S%28x%2C%20y%29%20%3D%200%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='S(x, y) = 0 ' title='S(x, y) = 0 ' class='latex' /> if <img src='http://s.wordpress.com/latex.php?latex=x%20%3C%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x &lt; 0' title='x &lt; 0' class='latex' /> or <img src='http://s.wordpress.com/latex.php?latex=y%20%3C%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y &lt; 0' title='y &lt; 0' class='latex' />.</p>
<h3>3. Calculate the window mean</h3>
<p>Use the cumulative image sum to calculate the mean in the window. Here, <img src='http://s.wordpress.com/latex.php?latex=r&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='r' title='r' class='latex' /> is the window radius, <em>A</em> stands for average:</p>
<img src='http://s.wordpress.com/latex.php?latex=A%28x%2C%20y%29%20%3D%20%5Cfrac%7B1%7D%7B%282r%20%2B%201%29%5E2%7D%5BS%28x-r-1%2C%20y-r-1%29%20%2B%20S%28x%20%2B%20r%2C%20y%20%2B%20r%29-S%28x-r-1%2C%20y%20%2B%20r%29-S%28x%20%2B%20r%2C%20y-r-1%29%5D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A(x, y) = \frac{1}{(2r + 1)^2}[S(x-r-1, y-r-1) + S(x + r, y + r)-S(x-r-1, y + r)-S(x + r, y-r-1)]' title='A(x, y) = \frac{1}{(2r + 1)^2}[S(x-r-1, y-r-1) + S(x + r, y + r)-S(x-r-1, y + r)-S(x + r, y-r-1)]' class='latex' />
<h3>4. Calculate the approximate maximum</h3>
<img src='http://s.wordpress.com/latex.php?latex=M%28x%2C%20y%29%20%3D%20%5BA%28x%2C%20y%29%5D%5E%7B1%2Fp%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='M(x, y) = [A(x, y)]^{1/p}' title='M(x, y) = [A(x, y)]^{1/p}' class='latex' />
<p>That’s it!</p>
<p>The minimum filter is implemented by finding the maximum of the inverse image and then inverting the result. This approach uses two more passes through the image; so far I could not find a direct approximation for the minimum value. (<strong>Update:</strong> It seems using <img src='http://s.wordpress.com/latex.php?latex=p%5Cll%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p\ll 0' title='p\ll 0' class='latex' /> gives an approximation for finding the minimum of a set of values.)</p>
<h2>Notes</h2>
<ul>
<li>For very large images, you might run into floating point issues when calculating the cumulative sum image. You can reduce this effect somewhat by subtracting the (total image) mean of the power image from each pixel before calculating the image sum.</li>
<li>For the image sizes I worked on, the value <img src='http://s.wordpress.com/latex.php?latex=p%3D8&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p=8' title='p=8' class='latex' /> was suitable. The higher <img src='http://s.wordpress.com/latex.php?latex=p&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p' title='p' class='latex' />, the more accurate results, as long as you have no underflow.</li>
<li>Raising powers is a slow operation. By choosing a suitable value of <img src='http://s.wordpress.com/latex.php?latex=p&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p' title='p' class='latex' />, you can use a suitable, faster approximation for calculating the power.</li>
<li><strong>Update:</strong> It is possible to implement this as a two-pass algorithm, first working on columns, then on rows. This requires constructing two tables, which makes the algorithm slower. However, using this approach allows bigger images to be processed before overflow in the summed are tables becomes a problem.</li>
</ul>
<p>Initially I thought that once the maximum can be found, we can also find the second maximum, and so on, so that any statistical order filter can be constructed.</p>
<p>The basic idea was that if <img src='http://s.wordpress.com/latex.php?latex=m_1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='m_1' title='m_1' class='latex' /> is the maximum, we could find the second largest value like this:</p>
<img src='http://s.wordpress.com/latex.php?latex=m_2%20%5Capprox%20%5Cfrac%7B1%7D%7BN-1%7D%5B%28%5Csum_%7Bi%3D1%7D%5EN%20x_i%5Ep%29%20-%20m_1%5Ep%5D%29%5E%7B1%2Fp%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='m_2 \approx \frac{1}{N-1}[(\sum_{i=1}^N x_i^p) - m_1^p])^{1/p}' title='m_2 \approx \frac{1}{N-1}[(\sum_{i=1}^N x_i^p) - m_1^p])^{1/p}' class='latex' />
<p>The idea is that we remove the maximum value from the sum, so that the result must yield the second largest element. Of course, we do not use the actual maximum, but the approximation—and this is where the formula fails. When we use the approximate maximum, it is easy to show that the formula above will yield the exact same approximate maximum, and not the <em>second</em> largest element.</p>
<p>I should have know it seemed too good to be true!</p>
<p><strong>Update:</strong> while looking for links for this post, I found this article: <a href="http://www.ph.tn.tudelft.nl/People/albert/papers/ICPR17VlietV13_5_13.pdf" class="broken_link">Robust Local Max-Min Filters by Normalized Power-Weighted Filtering</a> (PDF) which initially looked like it was essentially the same thing. Although it is very similar, it is in fact different. The approximate maximum is given by the value:</p>
<img src='http://s.wordpress.com/latex.php?latex=%20%5Cmax_%7Bi%3D1%7D%5ENx_i%5Capprox%20%5Cfrac%7B%5Csum_%7Bi%3D1%7D%5ENx_i%5E%7Bp%20%2B%201%7D%7D%7B%5Csum_%7Bi%3D1%7D%5ENx_i%5Ep%7D%20&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' \max_{i=1}^Nx_i\approx \frac{\sum_{i=1}^Nx_i^{p + 1}}{\sum_{i=1}^Nx_i^p} ' title=' \max_{i=1}^Nx_i\approx \frac{\sum_{i=1}^Nx_i^{p + 1}}{\sum_{i=1}^Nx_i^p} ' class='latex' />
<p>for <img src='http://s.wordpress.com/latex.php?latex=p%20%5Cgg%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p \gg 0' title='p \gg 0' class='latex' />.</p>
<p>Using <img src='http://s.wordpress.com/latex.php?latex=p%20%5Cll%200&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p \ll 0' title='p \ll 0' class='latex' /> gives an approximation to the minimum.</p>
<p>The nice thing about this approximation is that it seems to work well for all real <img src='http://s.wordpress.com/latex.php?latex=x_i&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x_i' title='x_i' class='latex' />, not just for <img src='http://s.wordpress.com/latex.php?latex=0%20%5Cleq%20x_i%20%5Cleq%201&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='0 \leq x_i \leq 1' title='0 \leq x_i \leq 1' class='latex' />.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F04%2F16%2Fsimple-fast-approximate-minimum-maximum-filters%2F&amp;linkname=Simple%2C%20Fast%2A%20Approximate%20Minimum%20%2F%20Maximum%20Filters"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2010/06/15/region-quadtrees-in-c/' rel='bookmark' title='Permanent Link: Region Quadtrees in C++'>Region Quadtrees in C++</a></li>
<li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
<li><a href='http://code-spot.co.za/2010/07/27/a-simple-trick-for-moving-objects-in-a-physics-simulation/' rel='bookmark' title='Permanent Link: A Simple Trick for Moving Objects in a Physics Simulation'>A Simple Trick for Moving Objects in a Physics Simulation</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/vz-MsQnH6KRvQtu8H7-r8iUHyzo/0/da"><img src="http://feedads.g.doubleclick.net/~a/vz-MsQnH6KRvQtu8H7-r8iUHyzo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/vz-MsQnH6KRvQtu8H7-r8iUHyzo/1/da"><img src="http://feedads.g.doubleclick.net/~a/vz-MsQnH6KRvQtu8H7-r8iUHyzo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/o2P0m_8ZCnc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/04/16/simple-fast-approximate-minimum-maximum-filters/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/04/16/simple-fast-approximate-minimum-maximum-filters/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=simple-fast-approximate-minimum-maximum-filters</feedburner:origLink></item>
		<item>
		<title>Experimental Tool for Removing Unwanted Artefacts in Textures</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/IiXhceo6miQ/</link>
		<comments>http://code-spot.co.za/2010/04/15/experimental-tool-for-removing-unwanted-artefacts-in-textures/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 13:36:40 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Downloads]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Image Processing]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[filtering]]></category>
		<category><![CDATA[game tools]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=849</guid>
		<description><![CDATA[
Many textures used for 3D art start from photographs. Ideally, such textures should be uniformly lit so that the texture does not interfere with the lighting applied by the 3D software. Often, lighting artefacts must be removed by hand. This can be tedious and time consuming.
The tool provided here aims to automate this process. It [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2009/05/27/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-example-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.</a></li>
<li><a href='http://code-spot.co.za/2009/10/24/guerrilla-tool-development/' rel='bookmark' title='Permanent Link: Guerrilla Tool Development'>Guerrilla Tool Development</a></li>
<li><a href='http://code-spot.co.za/2009/04/08/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="texture" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/texture.png" border="0" alt="texture" width="491" height="321" /></p>
<p>Many textures used for 3D art start from photographs. Ideally, such textures should be uniformly lit so that the texture does not interfere with the lighting applied by the 3D software. Often, lighting artefacts must be removed by hand. This can be tedious and time consuming.</p>
<p>The tool provided here aims to automate this process. It is still in an experimental phase, so it is very crude. Below you can see some of the before and after pictures.</p>
<p><span id="more-849"></span></p>
<p>I will say more about how these work in a later post.</p>
<p>If you want to give it a try, go <a href="http://code-spot.co.za/image-restoration-tool/" class="broken_link">here</a> to download (caveats: command-line only; Windows only; requires ImageMagick.)</p>
<table border="0" cellspacing="0" cellpadding="2" width="500">
<tbody>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="hair" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/hair.jpg" border="0" alt="hair" width="240" height="240" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="hair_std_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/hair_std_.png" border="0" alt="hair_std_" width="240" height="240" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="pebbles" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/pebbles.jpg" border="0" alt="pebbles" width="240" height="209" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="pebbles_minmax" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/pebbles_minmax.png" border="0" alt="pebbles_minmax" width="240" height="209" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="paper" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/paper.jpg" border="0" alt="paper" width="240" height="320" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="paper_mean_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/paper_mean_.png" border="0" alt="paper_mean_" width="240" height="320" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="metal" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/metal.jpg" border="0" alt="metal" width="240" height="117" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="metal_mean_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/metal_mean_.png" border="0" alt="metal_mean_" width="240" height="117" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="metal2" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/metal2.jpg" border="0" alt="metal2" width="240" height="109" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="metal2_mean_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/metal2_mean_.png" border="0" alt="metal2_mean_" width="240" height="109" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="machinery" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/machinery.jpg" border="0" alt="machinery" width="240" height="240" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="machinery_minmax" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/machinery_minmax.png" border="0" alt="machinery_minmax" width="240" height="240" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="paint" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/paint.jpg" border="0" alt="paint" width="240" height="180" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="paint_mean_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/paint_mean_.png" border="0" alt="paint_mean_" width="240" height="180" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="wood" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/wood.jpg" border="0" alt="wood" width="240" height="320" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="wood_std_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/wood_std_.png" border="0" alt="wood_std_" width="240" height="320" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="color" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/color.jpg" border="0" alt="color" width="240" height="213" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="color_mean_2" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/color_mean_2.png" border="0" alt="color_mean_2" width="240" height="213" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="color" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/color.jpg" border="0" alt="color" width="240" height="213" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="color_mean_value_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/color_mean_value_.png" border="0" alt="color_mean_value_" width="240" height="213" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="scene" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/scene.jpg" border="0" alt="scene" width="240" height="240" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="scene_mean" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/scene_mean.png" border="0" alt="scene_mean" width="240" height="240" /></td>
</tr>
<tr>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="grass" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/grass.jpg" border="0" alt="grass" width="240" height="160" /></td>
<td width="250" valign="top"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="grass_mean_" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/grass_mean_.png" border="0" alt="grass_mean_" width="240" height="160" /></td>
</tr>
</tbody>
</table>
<p>The tool can also improve artefacts in tileable textures:</p>
<p><strong>BEFORE </strong>(distracting horizontal striping)</p>
<p><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="texture1" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/texture1.png" border="0" alt="texture1" width="500" height="375" /></p>
<p><strong>AFTER</strong> (reduced striping)</p>
<p><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" title="texture2" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/texture2.png" border="0" alt="texture2" width="500" height="375" /></p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F04%2F15%2Fexperimental-tool-for-removing-unwanted-artefacts-in-textures%2F&amp;linkname=Experimental%20Tool%20for%20Removing%20Unwanted%20Artefacts%20in%20Textures"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2009/05/27/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-example-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.</a></li>
<li><a href='http://code-spot.co.za/2009/10/24/guerrilla-tool-development/' rel='bookmark' title='Permanent Link: Guerrilla Tool Development'>Guerrilla Tool Development</a></li>
<li><a href='http://code-spot.co.za/2009/04/08/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/vc2SagwKjNsJGmtWksDWBEmJ7eo/0/da"><img src="http://feedads.g.doubleclick.net/~a/vc2SagwKjNsJGmtWksDWBEmJ7eo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/vc2SagwKjNsJGmtWksDWBEmJ7eo/1/da"><img src="http://feedads.g.doubleclick.net/~a/vc2SagwKjNsJGmtWksDWBEmJ7eo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/IiXhceo6miQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/04/15/experimental-tool-for-removing-unwanted-artefacts-in-textures/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/04/15/experimental-tool-for-removing-unwanted-artefacts-in-textures/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=experimental-tool-for-removing-unwanted-artefacts-in-textures</feedburner:origLink></item>
		<item>
		<title>Poisson Disk Sampling Example Code</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/52L03TPrKjg/</link>
		<comments>http://code-spot.co.za/2010/04/07/poisson-disk-sampling-example-code/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 08:57:27 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Downloads]]></category>
		<category><![CDATA[Image Processing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[poisson disk]]></category>
		<category><![CDATA[procedural texture]]></category>
		<category><![CDATA[sampling]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=806</guid>
		<description><![CDATA[I decided to put the Poisson disk sampling code here for download since the site that hosted it is down. The code accompanies the tutorial on Dev.Mag: Poisson Disk Sampling.
Download



poisson_disk_java.zip (184 KB)
 poisson_disk_python.zip (912 KB)
 poisson_disk_ruby.zip (59 KB)





Related posts:A simple texture algorithm – faster code and more results
A Simple Procedural Texture Algorithm &#8211; More Results [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
<li><a href='http://code-spot.co.za/2008/11/14/a-simple-procedural-texture-algorithm-more-results-and-code/' rel='bookmark' title='Permanent Link: A Simple Procedural Texture Algorithm &#8211; More Results and Code'>A Simple Procedural Texture Algorithm &#8211; More Results and Code</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-817" title="poisson" src="http://code-spot.co.za/blog/wp-content/uploads/2010/04/poisson3.png" alt="poisson" width="142" height="142" />I decided to put the Poisson disk sampling code here for download since the site that hosted it is down. The code accompanies the tutorial on Dev.Mag: <a href="http://www.devmag.org.za/articles/55-POISSON-DISK-SAMPLING/">Poisson Disk Sampling</a>.</p>
<h2>Download</h2>
<table border="0">
<tbody>
<tr>
<td><a href="http://www.code-spot.co.za/downloads/poisson/poisson_disk_java.zip">poisson_disk_java.zip</a> (184 KB)<br />
<a href="http://www.code-spot.co.za/downloads/poisson/poisson_disk_python.zip"> poisson_disk_python.zip</a> (912 KB)<br />
<a href="http://www.code-spot.co.za/downloads/poisson/poisson_disk_ruby.zip"> poisson_disk_ruby.zip</a> (59 KB)</td>
</tr>
</tbody>
</table>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2010%2F04%2F07%2Fpoisson-disk-sampling-example-code%2F&amp;linkname=Poisson%20Disk%20Sampling%20Example%20Code"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2008/12/15/a-simple-texture-algorithm-faster-code-and-more-results/' rel='bookmark' title='Permanent Link: A simple texture algorithm – faster code and more results'>A simple texture algorithm – faster code and more results</a></li>
<li><a href='http://code-spot.co.za/2008/11/14/a-simple-procedural-texture-algorithm-more-results-and-code/' rel='bookmark' title='Permanent Link: A Simple Procedural Texture Algorithm &#8211; More Results and Code'>A Simple Procedural Texture Algorithm &#8211; More Results and Code</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/oGR4qMFYv3WPfePxQv5mbnihQbI/0/da"><img src="http://feedads.g.doubleclick.net/~a/oGR4qMFYv3WPfePxQv5mbnihQbI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/oGR4qMFYv3WPfePxQv5mbnihQbI/1/da"><img src="http://feedads.g.doubleclick.net/~a/oGR4qMFYv3WPfePxQv5mbnihQbI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/52L03TPrKjg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2010/04/07/poisson-disk-sampling-example-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2010/04/07/poisson-disk-sampling-example-code/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=poisson-disk-sampling-example-code</feedburner:origLink></item>
		<item>
		<title>Tips for Designing and Implementing a Stimulus Response Agent</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/G9oUzj2Wfi0/</link>
		<comments>http://code-spot.co.za/2009/10/25/tips-for-designing-and-implementing-a-stimulus-response-agent/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 20:35:41 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[convolution]]></category>
		<category><![CDATA[filtering]]></category>
		<category><![CDATA[Kalman filter]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[PID controller]]></category>
		<category><![CDATA[racing game ai]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[random steering]]></category>
		<category><![CDATA[response curve]]></category>
		<category><![CDATA[Special Numbers Library]]></category>
		<category><![CDATA[stimilus response agent]]></category>
		<category><![CDATA[system design]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=776</guid>
		<description><![CDATA[
(Original Image by everyone’s idle.)
This post was a originally published on Luma Labs, now dead.
As old as stimulus-response techniques are, they still form an important part of many AI systems, even if it is a thin layer underneath a sophisticated decision, planning, or learning system. In this tutorial I give some advice to their design [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2008/12/07/random-steering-7-components-for-a-toolkit/' rel='bookmark' title='Permanent Link: Random Steering &#8211; 7 Components for a Toolkit'>Random Steering &#8211; 7 Components for a Toolkit</a></li>
<li><a href='http://code-spot.co.za/2008/11/11/5-tips-for-prototyping-slow-algorithms/' rel='bookmark' title='Permanent Link: 5 Tips for Prototyping Slow Algorithms'>5 Tips for Prototyping Slow Algorithms</a></li>
<li><a href='http://code-spot.co.za/2009/04/09/cellular-automata-for-simulation-in-games/' rel='bookmark' title='Permanent Link: Cellular Automata for Simulation in Games'>Cellular Automata for Simulation in Games</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="display: inline; border-width: 0px;" title="brain" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/brain.png" border="0" alt="brain" width="500" height="366" /><br />
(<a href="http://www.flickr.com/photos/mgdtgd/3507973704/">Original Image</a> by <a href="http://www.flickr.com/photos/mgdtgd/">everyone’s idle</a>.)</p>
<p><em>This post was a originally published on Luma Labs, now dead.</em></p>
<p>As old as stimulus-response techniques are, they still form an important part of many AI systems, even if it is a thin layer underneath a sophisticated decision, planning, or learning system. In this tutorial I give some advice to their design and implementation, mostly out of experience gained from implementing the AI for some racing games.</p>
<p>A <em>stimulus response agent</em> (or a <em>reactive agent</em>) is an agent that takes inputs from its world through sensors, and then takes action based on those inputs through actuators. Between the stimulus and response, there is a processing unit that can be arbitrarily complex. An example of such an agent is one that controls a vehicle in a racing game: the agent “looks” at the road and nearby vehicles, and then decides how much to turn and break.</p>
<p><span id="more-776"></span></p>
<p>This definition is so broad that it is hard to think of agents that are <em>not</em> stimulus response agents. Some agents base their actions not on inputs, but on their internal state alone. See for example how <a href="http://code-spot.co.za/2008/12/07/random-steering-7-components-for-a-toolkit/">random steering algorithms</a> can lead to interesting behaviour.</p>
<p>Some agents don&#8217;t act. They just digest. The only way they can be useful if we look at what they are “thinking”. In fact, they are often designed with the sole purpose of “telling” us what they think, and they are not usually called <em>agents</em>, but rather decision systems. A face recognition system is an example of this. Of course, if we consider “telling” or “deciding” an action, these decision system become stimulus response agents too – but since we do not think of them as agents, the distinction is useful.</p>
<h2>Design</h2>
<h3>1. Do not design your system around an overly simplistic view</h3>
<p>The typical presentation of a stimulus response agent looks like this:</p>
<p><img style="display: inline; border-width: 0px;" title="SRA_simple" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/SRA_simple.png" border="0" alt="SRA_simple" width="303" height="52" /></p>
<p>This presentation, while technically correct, is suitable only for flowers blowing in the wind. A real-world stimulus-response agent might look more like this:</p>
<p><img style="display: inline; border-width: 0px;" title="sra_complex" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/sra_complex.png" border="0" alt="sra_complex" width="436" height="332" /></p>
<p>Note that there are five factors that influence decisions:</p>
<ul>
<li><strong>Game state</strong> is the mode of the game. For example, when an agent can be in a PLAY state (actively competing against the player) or a CHILL state (after taking over from the player at the end of the game.</li>
<li><strong>Global world state </strong>is the current conditions of the world, such as the weather or time of day.</li>
<li><strong>Local world</strong> <strong>state</strong> is what is normally thought of as the “stimulus”. It is the properties of the world around the agent that changes as the agents moves or otherwise acts in the world. For example, the shape of the path near a path following agent is part of the local world state.</li>
<li><strong>Agent parameters</strong> constitute the fixed limits of the agent&#8217;s sensory processing, and reactionary systems. For example, how far can the AI see, how quickly will it react, and how high can it jump. These parameters often describe the bounds for a state variable.</li>
<li><strong>Agent state</strong> is the changing parameters of the agent&#8217;s behaviour.</li>
</ul>
<p>Note that all these can be mapped to the simplistic view of our agent. However, it is important to recognise the differences in these groups of variables, because the agent is made aware of them (connected to them) in different ways.</p>
<p>The world state is not sensed, but communicated through passed parameters, or a query to the world state object.</p>
<p>The game state is enforced by the game system, and typically the agent does not query or sense the game state – it is communicated from the outside.</p>
<p>The local world state is sensed by the agent through its sensors. Typically this means the agent must have hooks into the world. This data can be noisy or incomplete, so the agent might use filtering, and hence will store its own processed copy of the data.</p>
<p>The agent parameters are partially hard-coded, and partially generated on construction, or read from a file. These do not change over the agent&#8217;s life time.</p>
<p><img style="display: inline; border-width: 0px;" title="agent_state" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/agent_state.png" border="0" alt="agent_state" width="171" height="105" /></p>
<p>The agent state is calculated on updates. It has two parts:</p>
<ul>
<li>The <strong>discrete state</strong> is usually implemented as a state machine. In a vehicle driving agent, the discrete states can be PULL_AWAY, NORMAL, WRONG_WAY, and so on.</li>
<li>The <strong>continuous state</strong> of an agent is the state determined by a set of parameters. For a vehicle driving agent, these can include “deviation_from_path”, “distance_from_closest_player”, “aggressiveness” and so on. Note that the continuous state for every discrete state can be described by a different set of parameters, possibly overlapping.In general, a different set of response equations will be used for every discrete state. In fact, the sole purpose of the state machine is to select the correct set of response equations for every situation.</li>
</ul>
<p>The table below summarises the factors that influence a stimulus response agent&#8217;s decisions.</p>
<table border="0" cellspacing="0" cellpadding="2" width="492">
<tbody>
<tr>
<td width="145" valign="top"><strong>Factor</strong></td>
<td width="345" valign="top"><strong>Source</strong></td>
</tr>
<tr>
<td width="145" valign="top">Game state</td>
<td width="345" valign="top">Game system</td>
</tr>
<tr>
<td width="145" valign="top">Global world state</td>
<td width="345" valign="top">World</td>
</tr>
<tr>
<td width="145" valign="top">Local world state</td>
<td width="345" valign="top">Sensors</td>
</tr>
<tr>
<td width="145" valign="top">Physical parameters</td>
<td width="345" valign="top">Hard-coded / File / Generated</td>
</tr>
<tr>
<td width="145" valign="top">Agent state</td>
<td width="345" valign="top">Calculated</td>
</tr>
<tr>
<td width="145" valign="top">
<ul>
<li><span style="font-size: 10.8333px;">Discrete State</span></li>
<li><span style="font-size: 10.8333px;">Continuous State</span></li>
</ul>
</td>
<td width="345" valign="top">State machine transitions<br />
Equations</td>
</tr>
</tbody>
</table>
<h3>2. Clearly distinguish between objects that have state, and those that do not (or should not)</h3>
<p>It is easy to build objects that have states when they should not. It is, for example, reasonable to design a path-following object so that it keeps track of an agent&#8217;s progress along the path (such as the last node reached), to simplify communication between the agent and the path. In this scenario, the communication looks like this:</p>
<p><img style="display: inline; border-width: 0px;" title="state_wrong1" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/state_wrong1.png" border="0" alt="state_wrong1" width="285" height="114" /></p>
<p>There are at least two problems with this set-up:</p>
<ul>
<li>every agent must have its own copy of the path; and</li>
<li>the agent can&#8217;t ask any path information that violates the path object&#8217;s assumption about where the agent is.</li>
</ul>
<p>To illustrate the last point, consider the situation where the path keeps track of the last node reached by the agent, and updates that node as the agent reports its position to the path object. It uses this node and the next node to interpolate a suitable position for the agent to move to. All is fine, until the agent needs information about the future, for example, it&#8217;s projection one second from now on the path. One second from now, the agent may have reached another node, something this simple system cannot handle properly.</p>
<p>Another way to do this, is for the agent to store the last node reached and pass it along its position in queries:</p>
<p><img style="display: inline; border-width: 0px;" title="state_wrong2" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/state_wrong2.png" border="0" alt="state_wrong2" width="288" height="150" /></p>
<p>This does not solve the problem really – must the agent now store a separate node for queries into the future?</p>
<p>The best solution is to have a path manager. It has two responsibilities:</p>
<ul>
<li>to store any agent state information relating to the path – the last node reached, in our example; and</li>
<li>to handle calculations for queries (based only on data from the path).</li>
</ul>
<p><img style="display: inline; border-width: 0px;" title="states_correct" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/states_correct.png" border="0" alt="states_correct" width="511" height="131" /></p>
<p>Now, when the agent asks the path manager about its projection 1 second from now, the path manager can check against the path whether a node will be reached, and perform the correct calculation. [In practise, the agent will transform time into distance travelled in time at its current velocity, so that the path manager only needs to know about distance, not time].</p>
<p>Every agent must have its own path manager, but the path managers can share the same path.</p>
<p>Consider another, slightly different, example. A certain agent has a “angriness” factor, which is randomised every 10 updates between two fixed extremes. Every type of agent has a different set of extremes (a monster will have higher extremes than a cow, for example), which helps determine the agent&#8217;s “personality”. It is easy to dump the extremes and the current value in one object (typically, the agent object). This is a poor design for two reasons:</p>
<ul>
<li>There is unnecessary duplicated data, with the associated disadvantages (such as making network packets bulkier, making save files of the game state bigger, and so on).</li>
<li>The distinction between of agent state and agent parameters gets muddy. This makes it easier to make mistakes, overcomplicate the design, and introduce unnecessary inefficiencies.</li>
</ul>
<p>A better design is to put the extremes into an “angriness profile” object, which can be shared by agents of the same type; in the example there will be two instances, one for cows and one for monsters.</p>
<p>Note that this issue goes hand-in-hand with preferring composition over inheritance hierarchies.</p>
<h3>3. Draw pictures to show the ideal response to a given stimulus situation</h3>
<p>It is very important to define clearly what you want the agent to do given some stimulus. The following graphs shows a few examples for a vehicle steering agent.</p>
<table border="0" cellspacing="0" cellpadding="2" width="500">
<tbody>
<tr>
<td width="166" valign="top"><img style="display: inline; border-width: 0px;" title="steering_graph" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/steering_graph.png" border="0" alt="steering_graph" width="160" height="159" /></td>
<td width="166" valign="top"><img style="display: inline; border-width: 0px;" title="nitro_graph" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/nitro_graph.png" border="0" alt="nitro_graph" width="160" height="159" /></td>
<td width="166" valign="top"><img style="display: inline; border-width: 0px;" title="nitro_graph2" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/nitro_graph2.png" border="0" alt="nitro_graph2" width="160" height="159" /></td>
</tr>
<tr>
<td width="166" valign="top"><span style="color: #408080;">Steering as a function of angular deviation from path.</span></td>
<td width="166" valign="top"><span style="color: #408080;">Nitrous usage as a function of angular deviation from path (reckless driver).</span></td>
<td width="166" valign="top"><span style="color: #408080;">Nitrous usage as a function of angular deviation from path (conservative driver).</span></td>
</tr>
</tbody>
</table>
<p>Most variables will depend on more than one other variable. Do not worry too much about that when drawing these diagrams. Focus on typical cases, and jot down any requirements or assumptions.</p>
<p>Also, do not try to write down any equations for your graphs. Any relationship can always be represented by a <em>response curve</em>, something that is much quicker to set up and easy to implement. A response curve is essentially a look-up table with linear interpolation. It can be used to approximate arbitrary functions by specifying the input range, and a number of output samples. The idea is discussed more thoroughly in <a href="http://introgamedev.com/resource_aiwisdom.html">AI Programming Wisdom 1</a> (<em>The beauty of Response Curves </em>by Bob Alexander).</p>
<h3>4. Draw System Diagrams to show how variables relate</h3>
<p>In a complicated system, it is easy to lose track of how variables relate. A forgotten relationship can often lead to behaviour that is hard to understand. Having an easy-to-reference diagram will be a great help in debugging faulty behaviour.</p>
<p><img style="display: inline; border-width: 0px;" title="flow_diagram" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/flow_diagram.png" border="0" alt="flow_diagram" width="537" height="486" /></p>
<p>The diagram above distinguishes between relationships under AI control, and relationships that are under physics control – i.e. Relationships that cannot be changed by the agent. The diagram also indicates whether a relationship is positive (i.e. more of the one will result in more of the other), or negative (i.e. more of one will result in less of the other).</p>
<h3>5. Use a spreadsheet to graph response curves to typical situations</h3>
<p>Once you have your equations, you have to make sure that they actually describe the curves you intend. Also, in complicated formulas, it is important to check how these curves behave on typical data sets – <em>especially if you employ filtering </em>(see below).</p>
<p><img style="display: inline; border-width: 0px;" title="spread_sheet_graph" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/spread_sheet_graph.png" border="0" alt="spread_sheet_graph" width="479" height="358" /></p>
<h3>6. Eliminate unimportant feedback loops.</h3>
<p>Feedback is important for proper control in most systems. However, every loop makes it more difficult to analyse and understand the system – something that becomes apparent when things go wrong. If your system is complex, try to remove some of the loops (by removing some of the dependencies). You can always complicate your system <em>once you have it working</em>.</p>
<h3>7. Prototype your agent on a computer algebra system</h3>
<p>A computer algebra system (CAS) is the perfect environment to prototype a stimulus response agent:</p>
<ul>
<li>The high-level syntax, dynamic variables, and fat libraries allows you develop designs quickly, so that you can try out more designs.</li>
<li>The built-in graph plotting capabilities are useful for debugging (see below) and understanding complex designs.</li>
<li>You can simulate scenarios that are hard to obtain in the actual game, leading to a design that is much more robust.</li>
</ul>
<h2>Filtering</h2>
<h3>8. Filtering input, output, and intermediate values can drastically improve behaviour</h3>
<p>There are several reasons to use filtering in your agent:</p>
<ul>
<li>To reduce noise that might confuse your agent about the state the world (or it) is in.</li>
<li>To smooth out (and hence fill in) incomplete data. For example, a path made of line segments can be “filtered” so that it appears smooth to the agent.</li>
<li>To make the actions of the agent seem more determined. An agent that changes it&#8217;s mind 10 times a second is not very believable.</li>
<li>To prevent abrupt reactions to changes in the world that will make the agent less believable.</li>
</ul>
<p>There are several approaches to filtering. One approach that works well in many cases is to change a variable only by some maximum amount, like this:</p>
<pre>updateFilteredX(x)
{
   filteredX += clamp(x – filteredX, -maxIncX, maxIncX);
}</pre>
<p>Here maxIncX is much smaller than typical values of x (using a tenth is a good starting point).</p>
<p>When you have many filtered variables, it becomes unmanageable to filter them all in this way – for every variable you want to filter, you need three extra variables, and you need to remember to use the right updating technique whenever the variable changes. It is better to encapsulate the filtering in a special class (as has been done in the <em>Special Numbers Library </em>– see <a href="http://code.google.com/p/specialnumbers/">http://code.google.com/p/specialnumbers/</a>).</p>
<p>Other approaches to filtering include:</p>
<ul>
<li>statistical filtering techniques, such as <a href="http://en.wikipedia.org/wiki/Recursive_least_squares_filter">least squares</a> and <a href="http://en.wikipedia.org/wiki/Kalman_filter">Kalman</a> filtering;</li>
<li><a href="http://en.wikipedia.org/wiki/Digital_filter">convolutional filters</a>; and</li>
<li><a href="http://en.wikipedia.org/wiki/PID_controller">PID controllers</a>.</li>
</ul>
<h3>9. Make your filtering technique frame-rate independent, and do it from the start</h3>
<p>The rate of updates of filters can have a dramatic effect on resulting behaviour. This rate can either fluctuate naturally (as it goes with frame rate), or be the difference between a Debug and Release versions of your application.</p>
<p>The resulting changes in behaviour makes it hard to:</p>
<ul>
<li>debug faulty behaviour; and</li>
<li>spot problems to begin with (because it always works fine on <em>your</em> machine!).</li>
</ul>
<p>How you make your filtering frame-rate independent depends on the method of filtering used. For the system explained above, it merely means updating with an amount proportional to the elapsed time (between updates).</p>
<pre>updateFilteredX(x, elapsedTime)
{
   filteredX += clamp(x – filteredX,
                -maxIncX*elapsedTime, maxIncX*elapsedTime);
}</pre>
<p>The updateFilteredX function above will use a smaller value for maxIncX than the one that does not compensate for time. It is for this reason that you should implement frame-rate independence <em>from the start</em>. Otherwise you will need to re-tweak all your values increment values <em>again</em>.</p>
<h3>10. Do not filter the channels of n-dimensional data separately</h3>
<p>If you filter a position, for example, by the method described above, you might be tempted to do something like the following:</p>
<pre>updateFilteredXYZ(point)
{
   filteredPoint.x += clamp(point.x – filteredPoint.x,
                               -maxInc, maxInc);
   filteredPoint.y += clamp(point.y – filteredPoint.y,
                               -maxInc, maxInc);
   filteredPoint.z += clamp(point.z – filteredPoint.z,
                               -maxInc, maxInc);
}</pre>
<p>The above code will lead to strange behaviour. Consider for example,</p>
<ul>
<li>filteredPoint = (0, 0, 0),</li>
<li>point = (2, 1, 0) (for the next 4 updates)</li>
<li>maxInc = 0.5</li>
</ul>
<p>The variable filteredPoint will now go through these values on the next four updates:</p>
<p>(0.5, 0.5, 0)</p>
<p>(1.0, 1.0, 0)</p>
<p>(1.5, 1.0, 0)</p>
<p>(2.0, 1.0, 0)</p>
<p>If this filteredPoint represents an agent trying to reach (2, 1, 0). Notice that the points do not lie in a straight line, the agent will first move to point (1, 1, 0), and then <em>turn</em> before moving further. An onlooker will not understand this strange behaviour.</p>
<p>The correct way to implement filtering for multi-dimensional data is to add a clamped amount of difference between the value and the filteredValue to the filtered value.</p>
<pre>updateFilteredXYZ(point)
{
   updateAmount = clamp((filteredPoint – point).len(),
                        0, maxInc)
   filteredPoint += (point – filteredPoint) * updateAmount;
}</pre>
<p>Now the next four values of filteredPoint lie in a straight line:</p>
<p>(0.316, 0.632, 0)</p>
<p>(0.632, 1.265, 0)</p>
<p>(0.948, 1.897, 0)</p>
<p>(1, 2, 0)</p>
<h3>11. Beware of filtering that reduces the range of a variable</h3>
<p>Some kinds of filtering can reduce the range of a variable – for example, instead of reaching zero, a variable may merely come <em>close</em> to zero. This is important in checks that assumes variables will come to a have certain value <em>eventually – </em>these checks must be modified to compensate for the range discrepancies.</p>
<h3>12. Beware of accumulated latency when filtering variables through various layers of logic</h3>
<p>Filtering usually results in some latency. Where filtering is used in a layered system, these latencies can add up, and produce a system that is slow to respond. In many situations these latencies can be reduced or eliminated if you can make accurate predictions about the future.</p>
<p>You can reduce the filtering by using it only where it is really important – not everywhere. You can also exchange smoothness for a quicker response. How you accomplish this depends on the method of filtering you use; in the filtering described above you can increase the value of the increment.</p>
<p>If you feel adventurous, you can try out a system that filters only after it becomes aware that it is necessary. For example, the amount of filtering you apply can depend on the amount of noise measured over the last number of frames. In many situations you can approximate the amount of noise by the amount energy of the measured signal. Systems like these can be hard to make robust without resorting to difficult mathematics or special software.</p>
<p>You can also switch to a more sophisticated filtering approach, such as a Kalman filter or PID controller. PID controllers uses prediction to reduce latency; Kalman filtering uses a system model that makes it more effective in complicated scenarios.</p>
<h3>13. Be Careful When filtering combined signals</h3>
<p>You might want to add (or combine otherwise) several signals, filter this combination, and work on this filtered combined signal. This is a mistake when the signals have typical data transitions at different frequencies: one signal&#8217;<span style="font-size: 13.3333px;">s noise is another&#8217;s data.</span></p>
<p>To illustrate the problem, look at the two signals below. Signal 1 is a low frequency signal, with a spike of noise. Signal 2 is a pure high frequency signal. The noise is clearly visible in the combined signal. Also shown are several filtered versions of the combined signal. Notice that the more we filter, the more we reduce the high frequency signal. And if we do not filter enough, the noise is still very present.</p>
<p>The solution is to filter the signals separately – the low frequency signal can be filtered much more than the high frequency signal – and only then combine the filtered sequences. The result is shown in the last figure.</p>
<table border="0" cellspacing="0" cellpadding="2" width="500">
<tbody>
<tr>
<td width="166" valign="top"><span style="color: #408080;"> <img style="display: inline; border-width: 0px;" title="signal1" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/signal1.png" border="0" alt="signal1" width="160" height="140" /> </span></td>
<td width="166" valign="top"><span style="color: #408080;"><img style="display: inline; border-width: 0px;" title="signal2" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/signal2.png" border="0" alt="signal2" width="160" height="140" /> </span></td>
<td width="166" valign="top"><span style="color: #408080;"><img style="display: inline; border-width: 0px;" title="combined_signal" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/combined_signal.png" border="0" alt="combined_signal" width="160" height="140" /> </span></td>
</tr>
<tr>
<td width="166" valign="top"><span style="color: #408080;">Signal 1</span></td>
<td width="166" valign="top"><span style="color: #408080;">Signal 2</span></td>
<td width="166" valign="top"><span style="color: #408080;">Combined signal</span></td>
</tr>
<tr>
<td width="166" valign="top"><span style="color: #408080;"><img style="display: inline; border-width: 0px;" title="filtered_0_1" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/filtered_0_1.png" border="0" alt="filtered_0_1" width="160" height="140" /></span></td>
<td width="166" valign="top"><span style="color: #408080;"><img style="display: inline; border-width: 0px;" title="filtered_0_5" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/filtered_0_5.png" border="0" alt="filtered_0_5" width="160" height="140" /> </span></td>
<td width="166" valign="top"><span style="color: #408080;"><img style="display: inline; border-width: 0px;" title="combined_signal" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/combined_signal1.png" border="0" alt="combined_signal" width="160" height="140" /> </span></td>
</tr>
<tr>
<td width="166" valign="top"><span style="color: #408080;">Combined signal filtered (0.1)</span></td>
<td width="166" valign="top"><span style="color: #408080;">Combined signal filtered (0.5)</span></td>
<td width="166" valign="top"><span style="color: #408080;">Combined signal filtered (1.0)</span></td>
</tr>
<tr>
<td width="166" valign="top"><span style="color: #408080;"><img style="display: inline; border-width: 0px;" title="filtered_separately" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/filtered_separately.png" border="0" alt="filtered_separately" width="160" height="140" /> </span></td>
<td width="166" valign="top"><span style="color: #408080;"> </span></td>
<td width="166" valign="top"><span style="color: #408080;"> </span></td>
</tr>
<tr>
<td width="166" valign="top"><span style="color: #408080;">Signals filtered before combined.</span></td>
<td width="166" valign="top"></td>
<td width="166" valign="top"></td>
</tr>
</tbody>
</table>
<h3>14. Avoid if-then logic in response calculations.</h3>
<p>If-then logic signifies one of two things:</p>
<ul>
<li>a state difference that should be implemented as proper discrete state of the state machine; or</li>
<li>the need for a step function.</li>
</ul>
<p>In the first case, your state should be broken up into two states, with proper transitions. A stimulus response agent is complex enough with you having to track trough various conditions to understand behaviour. Every state should have one response that depends continuously on the stimulus. Because state machines scale so badly, introducing more states is not very desirable either. There are of course several ways to organise states properly to alleviate the scaling problem, but this is the topic of another tutorial.</p>
<p>If your if-then logic is against the value of a variable (for example &#8216;if x &gt; 0&#8242;), you can replace it with an appropriately chosen step function. Using step functions instead of if-then logic simplifies the design, and can be replaced with drop-in “smooth” versions when it becomes evident that it is necessary.</p>
<h2>Testing and Debugging</h2>
<h3>15. Rendering the current state-machine state on screen.</h3>
<p>It is a small point, but often strange behaviour results not from incorrect response to stimulus, but from incorrect state transitions. When implementing your agent inside the game, having state transitions visible on screen will make that kind of bug that much easier to spot.</p>
<h3>16. Graph variables and their internal states on screen.</h3>
<p>Graphing variables (filtered and unfiltered) over time on screen will save you hours of debugging time. Whenever your agent does something funny, you can see at a glance if there are variables with unexpected values that could explain the agent&#8217;s actions, perhaps using the CAS prototype as a reference.</p>
<p>Unfortunately, this tip becomes less useful as the system gets more complex. Having twenty plots on your screen will do little to spot problems.</p>
<h3>17. Use unit tests to ensure correct implementation of formulas.</h3>
<p>Stimulus response agents are perfect candidates for unit testing, especially when using the CAS prototype as a reference implementation. Unit testing your assumptions about the system will ensure correctness, and will help to make you aware of changes that break the system early. It will also make it easier to change and optimise formulas, or change them with smoother or sharper versions. Having a constant reference against which you can tweak parameters also allows you to be daring and make aggressive changes.</p>
<h3>18. Use generators to mock the agent&#8217;s environment.</h3>
<p>A generator is a object that generates a sequence of values. Typically it has a getValue() method, which returns a different value every time it is called. Generators are very similar to iterators, except that they usually generate values on the fly, rather than pointing to members of a container (although reading values from a container is one valid way to generate values). Generators are often used to implement iterators.</p>
<p>To implement unit tests and a CAS prototype, you need to mock various aspects of the game, the game world, and other agents. Using generators for this purpose makes mocking unbelievably easy and quick. Use generators to generate streams of</p>
<ul>
<li>elapsed times;</li>
<li>path angle deviations;</li>
</ul>
<ul>
<li>positions and velocities of other agents; and</li>
<li>state transitions.</li>
</ul>
<p>You can even mock parts of your agent to test sections in isolation. It helps if you build a library of generators and functions (response curves) that can be stacked together. You will do good to implement at least the following functions:</p>
<ul>
<li>step, line, and ramp;</li>
<li>clamped line and sigmoid (or atan);</li>
<li>cos, square, and saw tooth;</li>
<li>exponential and exponential decay;</li>
</ul>
<p>You should implement the following generators:</p>
<ul>
<li>a general generator that generates values from a function;</li>
<li>a constant generator;</li>
<li>a sum and product generator (generates the sum or product of two generators); and</li>
<li>generators that generate random values of various distributions.</li>
</ul>
<h2>Conclusion</h2>
<p>A complex stimulus response agent can be a challenge to design and implement properly; every approach has its set of headaches, and every solution brings other considerations to the table. Solving problems is just half the fun – <em>not</em> solving them is the other half!</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2009%2F10%2F25%2Ftips-for-designing-and-implementing-a-stimulus-response-agent%2F&amp;linkname=Tips%20for%20Designing%20and%20Implementing%20a%20Stimulus%20Response%20Agent"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2008/12/07/random-steering-7-components-for-a-toolkit/' rel='bookmark' title='Permanent Link: Random Steering &#8211; 7 Components for a Toolkit'>Random Steering &#8211; 7 Components for a Toolkit</a></li>
<li><a href='http://code-spot.co.za/2008/11/11/5-tips-for-prototyping-slow-algorithms/' rel='bookmark' title='Permanent Link: 5 Tips for Prototyping Slow Algorithms'>5 Tips for Prototyping Slow Algorithms</a></li>
<li><a href='http://code-spot.co.za/2009/04/09/cellular-automata-for-simulation-in-games/' rel='bookmark' title='Permanent Link: Cellular Automata for Simulation in Games'>Cellular Automata for Simulation in Games</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/wLq9lwMUepGmCNNqj4qF_culKdo/0/da"><img src="http://feedads.g.doubleclick.net/~a/wLq9lwMUepGmCNNqj4qF_culKdo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/wLq9lwMUepGmCNNqj4qF_culKdo/1/da"><img src="http://feedads.g.doubleclick.net/~a/wLq9lwMUepGmCNNqj4qF_culKdo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/G9oUzj2Wfi0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2009/10/25/tips-for-designing-and-implementing-a-stimulus-response-agent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2009/10/25/tips-for-designing-and-implementing-a-stimulus-response-agent/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tips-for-designing-and-implementing-a-stimulus-response-agent</feedburner:origLink></item>
		<item>
		<title>Guerrilla Tool Development</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/qpaNqoDXw78/</link>
		<comments>http://code-spot.co.za/2009/10/24/guerrilla-tool-development/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 16:18:45 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ai editor]]></category>
		<category><![CDATA[Dev.Mag]]></category>
		<category><![CDATA[level editor]]></category>
		<category><![CDATA[tool development]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=750</guid>
		<description><![CDATA[ Tools for editing game levels and AI for your own games are nice to have, but it is not always practical to implement these for small projects, nor is it affordable to buy them off-the-shelf or bundled with expensive middleware.
In the Dev.Mag article Guerrilla Tool Development, I give some ideas for getting some useful [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2009/04/08/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.</a></li>
<li><a href='http://code-spot.co.za/2009/05/27/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-example-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; display: inline; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" title="guerrilla_tools" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/guerrilla_tools1.png" border="0" alt="guerrilla_tools" width="142" height="142" align="left" /> Tools for editing game levels and AI for your own games are nice to have, but it is not always practical to implement these for small projects, nor is it affordable to buy them off-the-shelf or bundled with expensive middleware.</p>
<p>In the Dev.Mag article <a href="http://www.devmag.org.za/articles/294-GUERRILLA-TOOL-DEVELOPMENT/">Guerrilla Tool Development</a>, I give some ideas for getting some useful tools on a tight budget. Check it out!</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2009%2F10%2F24%2Fguerrilla-tool-development%2F&amp;linkname=Guerrilla%20Tool%20Development"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2009/04/08/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a  Level Editor for your XNA Games: Updated for XNA 3.0.</a></li>
<li><a href='http://code-spot.co.za/2009/05/27/how-to-turn-xsi-mod-tool-into-a-level-editor-for-your-xna-games-example-updated-for-xna-30/' rel='bookmark' title='Permanent Link: How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.'>How to Turn XSI Mod Tool into a Level Editor for your XNA Games: Example Updated for XNA 3.0.</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/3q73WONRKdi-8ArTWfoT7w81AaI/0/da"><img src="http://feedads.g.doubleclick.net/~a/3q73WONRKdi-8ArTWfoT7w81AaI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/3q73WONRKdi-8ArTWfoT7w81AaI/1/da"><img src="http://feedads.g.doubleclick.net/~a/3q73WONRKdi-8ArTWfoT7w81AaI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/qpaNqoDXw78" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2009/10/24/guerrilla-tool-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2009/10/24/guerrilla-tool-development/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=guerrilla-tool-development</feedburner:origLink></item>
		<item>
		<title>15 Steps to Implement a Neural Net</title>
		<link>http://feedproxy.google.com/~r/code-spot/~3/r2o4OvbYBvU/</link>
		<comments>http://code-spot.co.za/2009/10/08/15-steps-to-implemented-a-neural-net/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 15:02:26 +0000</pubDate>
		<dc:creator>herman.tulleken</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Downloads]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[artificial intelligence]]></category>
		<category><![CDATA[Matlab]]></category>
		<category><![CDATA[neural network]]></category>
		<category><![CDATA[Octave]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[pattern recognition]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[sampling]]></category>

		<guid isPermaLink="false">http://code-spot.co.za/?p=655</guid>
		<description><![CDATA[
(Original image by Hljod.Huskona / CC BY-SA 2.0).
I used to hate neural nets. Mostly, I realise now, because I struggled to implement them correctly. Texts explaining the working of neural nets focus heavily on the mathematical mechanics, and this is good for theoretical understanding and correct usage. However, this approach is terrible for the poor implementer, neglecting [...]


Related posts:<ol><li><a href='http://code-spot.co.za/2008/09/21/generating-random-numbers-with-arbitrary-distributions/' rel='bookmark' title='Permanent Link: Generating Random Numbers with Arbitrary Distributions'>Generating Random Numbers with Arbitrary Distributions</a></li>
<li><a href='http://code-spot.co.za/2009/04/09/cellular-automata-for-simulation-in-games/' rel='bookmark' title='Permanent Link: Cellular Automata for Simulation in Games'>Cellular Automata for Simulation in Games</a></li>
<li><a href='http://code-spot.co.za/2008/11/11/5-tips-for-prototyping-slow-algorithms/' rel='bookmark' title='Permanent Link: 5 Tips for Prototyping Slow Algorithms'>5 Tips for Prototyping Slow Algorithms</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="neuron" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/neuron1.jpg" border="0" alt="neuron" width="500" height="332" /></p>
<p>(<a href="http://www.flickr.com/photos/lorelei-ranveig/2294885420/">Original image</a> by <a rel="cc:attributionURL" href="http://www.flickr.com/photos/lorelei-ranveig/">Hljod.Huskona</a> / <a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a>).</p>
<p>I used to hate neural nets. Mostly, I realise now, because I struggled to implement them correctly. Texts explaining the working of neural nets focus heavily on the mathematical mechanics, and this is good for theoretical understanding and correct usage. However, this approach is terrible for the poor implementer, neglecting many of the details that concern him or her.</p>
<p>This tutorial is an implementation guide. It is not an explanation of how or why neural nets work, or when they should or should not be used. This tutorial will tell you step by step how to implement a very basic neural network. It comes with a simple example problem, and I include several results that you can compare with those that you find.</p>
<p><span id="more-655"></span></p>
<p>I tried to make the design as straightforward as possible. The training algorithm is simple backpropagation. There are no hidden layers (I will treat that in an upcoming tutorial), no momentum, no adaptive learning rates, and no sophisticated stopping conditions. Those are, in a sense, easy to add once you have a working neural net against which you can benchmark more elaborate designs.</p>
<p>To keep the implementation simple, I did not bother with optimisation. This too can easily be addressed once a working neural net is in place against which you can verify correctness and measure performance improvements.</p>
<p>The brief introduction below is a very superficial explanation of a neural net; it is included mostly to establish terminology and help you map it to the concepts that are explained in more detail in other texts.</p>
<h2>Preliminary remarks and overview</h2>
<h3>What we are doing</h3>
<p>The problem we are trying to solve is this: we have some measurements (features of an object), and we have a good idea that these features might tell us in which class the object belongs. For example, if we are dealing with fruit, knowing the size, colour, and “roughness” of the skin, we might deduce which type the fruit is. Of course, we want a <em>program </em>for this.</p>
<p>Now in heaven, there is a function for exactly that task – we give the function the features, and it spits out the class.</p>
<p>Down here on earth, we are not so lucky (well, not for most problems anyway). So instead, we have to do with some approximation. A neural net is one possibility – there are also others. A neural net (one without any hidden layers) is parameterised by a weight matrix. Different problems in general have different weight matrices. To solve our problem, we need to find a suitable matrix.</p>
<p>If both our set of known samples and the problem itself are reasonable, we might expect to find such a matrix. But not directly – we have to use some kind of iterative scheme – we have to “train” our neural net. We use some of the known samples for this.</p>
<p>Behind the scenes, the weight matrix and the feature vector are combined using some matrix operations to give the output vector, which is converted to a class. The mathematical details of this can be found <a href="http://www.mth.kcl.ac.uk/courses/guide.pdf" class="broken_link">elsewhere</a> (<a href="http://www.learnartificialneuralnetworks.com/backpropagation.html">more</a>).</p>
<p>After we have trained the neural net, we can use it in an application to classify objects that we may or may not have encountered before. Generally, the training and application programs are separate. The training program is the difficult part; most of the tutorial deals with training.</p>
<p>It is common to divide the known samples in three sets, called the training set, validation set, and test set, typically divided in the ratio 50%, 25%, and 25%. The training set is used to update the weights iteratively; the validation set is used to stop the training algorithm, and the test set is used to estimate how well our trained neural net will do in the wild.</p>
<p>Each iteration of the training algorithm is called, quite poetically, an <em>epoch</em>. Many different things affect the number of epochs we will need to train the neural net: the problem complexity, how we scale our updates, and how the weight matrix has been initialised.</p>
<p>We can control the speed with a parameter called the learning rate. In general, higher learning rate means faster learning (although, when it is set too high, the network might become unstable and not learn at all).</p>
<h3>Representation</h3>
<p>We usually represent the features (our measurements) as a vector of numbers, like this:</p>
<p>[0.01, 1.07, 3.60]</p>
<p>In cases of non-numeric values, we convert whatever we have to numbers with some scheme. For instance, when dealing with colours, we might want to use RGB values, or we might want to make a list of colours (red, yellow, green, etc.), assign a number to each of these labels, and use the corresponding number.</p>
<p>Classes, usually not being numbers, are similarly treated: we assign a number (often arbitrarily) to each class, and use that in our computations. For the actual training, however, we use an output vector. The output vector has a 1 in the position of the class number, and 0 everywhere else.</p>
<p>Thus, if we are dealing with three classes of fruit (apple, pear, banana), and number the classes 1, 2, and 3 respectively, we will have the following output vectors:</p>
<table border="0" cellspacing="0" cellpadding="2" width="400">
<tbody>
<tr>
<td width="135" valign="top"><strong>Class</strong></td>
<td width="142" valign="top"><strong>Class Number</strong></td>
<td width="121" valign="top"><strong>Output Vector</strong></td>
</tr>
<tr>
<td width="135" valign="top">Apple</td>
<td width="142" valign="top">1</td>
<td width="121" valign="top">1 0 0</td>
</tr>
<tr>
<td width="135" valign="top">Pear</td>
<td width="142" valign="top">2</td>
<td width="121" valign="top">0 1 0</td>
</tr>
<tr>
<td width="135" valign="top">Banana</td>
<td width="155" valign="top">3</td>
<td width="153" valign="top">0 0 1</td>
</tr>
</tbody>
</table>
<p>It is convenient to put all the inputs of a set together in a single matrix, where each row is a sample. Similarly, outputs and classes are also put into matrices, with input sample in a row (say row number <em>n</em>) corresponds to output sample in row <em>n</em>, and also the class in row <em>n</em>.</p>
<p>The implementation below makes use of high-level matrix operations. This avoids many of the errors that can creep in loop-dense code. The following table will give dimensions of all the matrixes involved; this will be helpful during implementation (especially for assert statements). The numbers are given in terms of the number of inputs (features) of the problem, the number of outputs.</p>
<table border="0" cellspacing="0" cellpadding="2" width="490">
<tbody>
<tr>
<td width="263" valign="top"><strong>Matrix</strong></td>
<td width="113" valign="top"><strong>Rows</strong></td>
<td width="112" valign="top"><strong>Columns</strong></td>
</tr>
<tr>
<td width="256" valign="top">input vector of a single sample</td>
<td width="117" valign="top">1</td>
<td width="115" valign="top">input_count</td>
</tr>
<tr>
<td width="251" valign="top">output vector of a single sample</td>
<td width="120" valign="top">1</td>
<td width="117" valign="top">output_count</td>
</tr>
<tr>
<td width="248" valign="top">class vector of a single sample</td>
<td width="122" valign="top">1</td>
<td width="119" valign="top">1</td>
</tr>
<tr>
<td width="245" valign="top">input matrix of training set</td>
<td width="124" valign="top">training_count</td>
<td width="120" valign="top">input_count</td>
</tr>
<tr>
<td width="243" valign="top">output matrix of training set</td>
<td width="125" valign="top">training_count</td>
<td width="121" valign="top">output_count</td>
</tr>
<tr>
<td width="242" valign="top">class vector of training set</td>
<td width="126" valign="top">training_count</td>
<td width="121" valign="top">1</td>
</tr>
<tr>
<td width="242" valign="top">bias vector of training set</td>
<td width="126" valign="top">training_count</td>
<td width="121" valign="top">1</td>
</tr>
<tr>
<td width="242" valign="top">net vector of single sample</td>
<td width="126" valign="top">1</td>
<td width="121" valign="top">output_count</td>
</tr>
<tr>
<td width="242" valign="top">weights matrix</td>
<td width="126" valign="top">input_count + 1</td>
<td width="121" valign="top">output_count</td>
</tr>
<tr>
<td width="242" valign="top">weights delta matrix</td>
<td width="126" valign="top">input_count + 1</td>
<td width="121" valign="top">output_count</td>
</tr>
<tr>
<td width="242" valign="top">error vector</td>
<td width="126" valign="top">1</td>
<td width="121" valign="top">output_count</td>
</tr>
<tr>
<td width="242" valign="top">delta (sensitivity vector)</td>
<td width="126" valign="top">1</td>
<td width="121" valign="top">output_count</td>
</tr>
</tbody>
</table>
<h3>Overview</h3>
<p>The basic idea of the training algorithm is the following:</p>
<p>First we load in the data: the training samples, the validation samples, and the test samples.</p>
<p>Then we start to train: we run the backpropagation algorithm on random samples. After each iteration, we see how our network is doing so far (on the validation set), and then we decide whether to keep training or not.</p>
<p>After we stopped, we do a final evaluation of our network on the test set – this gives us an indication of whether the neural net will generalise well to samples not originally in the training set.</p>
<p>After we have found a weight matrix that we can live with, we cfan incorporate this in the application were we need the functionality.</p>
<p>The training program has x functions:</p>
<ul>
<li>train</li>
<li>load data</li>
<li>feed-forward</li>
<li>evaluate network</li>
<li>backpropagation</li>
<li>output to class</li>
<li>class to output</li>
<li>activation</li>
<li>activation derivative</li>
</ul>
<p>The application program uses these functions:</p>
<ul>
<li>feed-forward</li>
<li>output vector to class</li>
</ul>
<h2>Implementation</h2>
<h3>1. Gather the necessary libraries (or write them)</h3>
<p>You will need the following libraries:</p>
<ul>
<li>A library that supports matrix algebra; and</li>
<li>A library that plots graphs (x versus y).</li>
</ul>
<p>If you can’t find a matrix library for your implementation language, then you can write a simple library yourself. Since neural nets do not require matrix inverses or long chains of matrix products, you need not worry (much) about numerical stability, thus the implementation is straightforward.</p>
<p>The implementation needs to support the following matrix operations:</p>
<ul>
<li>matrix transposition;</li>
<li>matrix addition;</li>
<li>matrix multiplication with a scalar;</li>
<li>ordinary matrix multiplication;</li>
<li>Hadamard multiplication (component-wise multiplication);</li>
<li>Kronecker multiplication (only necessary for between row and column vectors); and</li>
<li>horizontal matrix concatenation.</li>
</ul>
<p>The first few operations are standard matrix operations, but you might be less familiar with the last three. (Also check out the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Matrix_multiplication">matrix multiplication</a> – it covers all the types of multiplication mentioned here.)</p>
<p>Hadamard multiplication of matrices is defined for two matrices of equal dimensions. Each component of the new matrix is the product of corresponding components in the two multiplicands, that is:</p>
<pre>Z[i][j] = X[i][j] * Y[i][j]</pre>
<p>The Kronecker product of a row vector and column vector is defined as a matrix whose components are given by:</p>
<pre>Z[i][j] = X[0][i] * Y[j][0]</pre>
<p>It is possible to define the product for arbitrary matrices, but we don’t need it.</p>
<p>The horizontal concatenation combines two matrices with the same number of rows. For example, the matrices A and B below will be concatenated to form the new matrix C:<br />
<img src='http://s.wordpress.com/latex.php?latex=A%3D%5Cbegin%7Bpmatrix%7D10%20%26%203%5C%5C4%20%26%205%5Cend%7Bpmatrix%7D%2C%5C%3AB%3D%5Cbegin%7Bpmatrix%7D6%20%26%208%20%26%202%5C%5C3%261%2610%5Cend%7Bpmatrix%7D%2C%5C%3AC%3D%5Cbegin%7Bpmatrix%7D10%20%26%203%266%20%26%208%20%26%202%5C%5C4%20%26%205%26%203%20%261%2610%5Cend%7Bpmatrix%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A=\begin{pmatrix}10 &amp; 3\\4 &amp; 5\end{pmatrix},\:B=\begin{pmatrix}6 &amp; 8 &amp; 2\\3&amp;1&amp;10\end{pmatrix},\:C=\begin{pmatrix}10 &amp; 3&amp;6 &amp; 8 &amp; 2\\4 &amp; 5&amp; 3 &amp;1&amp;10\end{pmatrix}' title='A=\begin{pmatrix}10 &amp; 3\\4 &amp; 5\end{pmatrix},\:B=\begin{pmatrix}6 &amp; 8 &amp; 2\\3&amp;1&amp;10\end{pmatrix},\:C=\begin{pmatrix}10 &amp; 3&amp;6 &amp; 8 &amp; 2\\4 &amp; 5&amp; 3 &amp;1&amp;10\end{pmatrix}' class='latex' /></p>
<p>A simple implementation simply constructs a new matrix whose components are given by</p>
<pre>if j &lt; X_width
  Z[i][j] = X[i][j]
else
   Z[i][j] = Y[i, j – X_width]</pre>
<p>If no graph libraries are available, simply write a function that will output a tab-separated list of the input and output sequences to plot. You can then load or paste this into your favourite spreadsheet program to make the necessary plots.</p>
<h3>2. Implement Output and Class conversion functions</h3>
<p>This is very simple: implement a function that converts an output matrix to a class number vector, and another that converts a class number to an output vector.</p>
<p>For example, the output_to_class function will take the following matrix</p>
<p>1 0 0</p>
<p>0 1 0</p>
<p>0 0 1</p>
<p>1 0 0</p>
<p>0 0 1</p>
<p>and convert it to:</p>
<p>1</p>
<p>2</p>
<p>3</p>
<p>1</p>
<p>3</p>
<p>(The second function will convert the second matrix back to the first matrix).</p>
<h3>3. Implement a function to read in data files</h3>
<p>For this tutorial you can use the following three files:</p>
<ul>
<li>iris_training.dat</li>
<li>iris_validation.dat</li>
<li>iris_test.dat</li>
</ul>
<p>These three files contain samples from the <a href="http://en.wikipedia.org/wiki/Iris_flower_data_set">ICU iris dataset</a>, a simple and quite famous dataset. In each file, samples or contained in rows. Each row has seven entries, separated by tabs. The first four entries are features of irises (sepal length, sepal width, petal length, and petal width); the last three is the outputs denoting the species of iris (setosa, versicolor, and virginica). I have preprocessed the values a bit to get them in the appropriate ranges.</p>
<p>You must read in the data so that you can treat the inputs of each set as a single matrix; similarly for the outputs.</p>
<p>I find it useful to store all the data in a structure, like this:</p>
<ul>
<li>data_set
<ul>
<li>input_count</li>
<li>output_count</li>
<li>training_set
<ul>
<li>inputs</li>
<li>outputs</li>
<li>classes</li>
<li>count</li>
<li>bias</li>
</ul>
</li>
<li>validation_set
<ul>
<li>inputs</li>
<li>outputs</li>
<li>classes</li>
<li>count</li>
<li>bias</li>
</ul>
</li>
<li>test_set
<ul>
<li>inputs</li>
<li>outputs</li>
<li>classes</li>
<li>count</li>
<li>bias</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>This makes it more useful to send the data as parameters.</p>
<h3>4. Implement an activation function and its derivative</h3>
<p>The activation function must take in a matrix X, and return a matrix Y. Y is computed by applying a function component-wise to X. For now, use the hyperbolic tangent function:</p>
<img src='http://s.wordpress.com/latex.php?latex=%20f%28x%29%20%3D%20%5Cdfrac%7B%5Ctanh%28x%29%20%2B%201%7D%7B2%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt=' f(x) = \dfrac{\tanh(x) + 1}{2}' title=' f(x) = \dfrac{\tanh(x) + 1}{2}' class='latex' /><br />
The activation function derivative must similarly take in a matrix X, and return a matrix Y. Y is computed by applying the derivative of the activation componentwise to X. The derivative of the function above is:<br />
<img src='http://s.wordpress.com/latex.php?latex=f%27%28x%29%20%3D%20%5Cdfrac%7B1%20-%20%5Ctanh%5E2%28x%29%7D%7B2%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='f&#039;(x) = \dfrac{1 - \tanh^2(x)}{2}' title='f&#039;(x) = \dfrac{1 - \tanh^2(x)}{2}' class='latex' /></p>
<h3>5. Implement the feed-forward function</h3>
<p>The function must take as arguments an input matrix, weight matrix, and a bias node matrix.</p>
<p>The function should return an output matrix, and a net matrix</p>
<p>These are computed as follows:</p>
<pre>net = mul(weights, horcat(inputs, bias))
output = activate(net)</pre>
<p>The bias matrix is a constant column vector of 1s with as many rows as the input matrix. This vector corresponds to the bias nodes. The implementation here is a bit clumsy, but for now, the approach used here minimises the potential for error.</p>
<h3>6. Implement a weight initialisation function</h3>
<p>This function must take in a maximum weight, a width and height, and return a matrix of the given width and height, randomly initialised in the range [-max_weight max_weight].</p>
<h3>7. Implement a function that evaluates the network error.</h3>
<p>The function must take in:</p>
<ul>
<li>an input matrix,</li>
<li>a weight matrix,</li>
<li>a target output matrix,</li>
<li>a target class matrix,</li>
<li>a bias matrix.</li>
</ul>
<p>The function must return the error e, and the classification error c.</p>
<p>To compute these, first compute the output matrix Z using the feed-forward function (you can ignore the net matrix).</p>
<pre>[output net] = feedforward(inputs, weights, bias)</pre>
<p>Now subtract the target output matrix from the output matrix, square the components, add together, and normalise:</p>
<pre>error = sum_all_components((target_outputs – outputs)^2) ...</pre>
<pre>   / (sample_count * output_count)</pre>
<p>From the output matrix, calculate the classes:</p>
<pre>classes = classes_from_output_vectors(outputs)</pre>
<p>Count the number of classes that corresponds with the target classes, and divide by the number of samples to normalise:</p>
<pre>c = sum_all_components(classes != target_classes)/sample_count</pre>
<p>(Here, our inequality returns a matrix of 0s and 1s, with 1s in positions where the corresponding components in classes and target_classes are not equal.)</p>
<h3>8. Implement a dummy backpropagation function</h3>
<p>The function should take in:</p>
<ul>
<li>An input matrix</li>
<li>A weight matrix</li>
<li>a learning rate (eta, as in the Greek letter)</li>
<li>a bias vector</li>
</ul>
<p>The function must return an updated weight matrix. For now, return W as is.</p>
<h3>9. Implement the train function</h3>
<p>The training function should take in three sets, the training_set, validation_set, and test_set. Implement a way to limit the maximum number of samples that will actually be used for training (you can also do his in the main program described in the next section). This is very helpful for debugging purposes (especially if you plan to later replace the backpropagation algorithm with something a little faster – and more complicated).</p>
<p>The function should return a weight matrix, and error values as floats.</p>
<p>Initialise a value plot_graphs to true. This is a debug flag, so it is appropriate to implement this as a macro if it is supported by the implementation language.</p>
<p>The function should initialise a weight matrix using initialise weights. For now, use a max_weight of 1/2.</p>
<p>The function should also construct three bias vectors bias_training, bias_validate, and bias_test. Each must contain only 1s, with as many rows as there are inputs in the training, validation and test sets respectively.</p>
<p>Implement a while loop that stops after 500 iterations. (We will change the while condition later to something else, so do not use a for loop).</p>
<p>Inside the loop, call the backpropagation algorithm. Use the training set inputs, the weights, (for now) a fixed learning rate of 0.1, and bias vector bias_train. Assign the result to weights.</p>
<p>Still inside the loop, call the network error function three times: one time for each of the training, validation, and test sets. Use the weight matrix, and the appropriate bias vector. Wrap these calls in an if-statement that tests for a value plot_graphs. (If your language supports it, you can use conditional compilation on the value of plot_graphs).</p>
<p>Store the errors in six arrays (error_train, classification_error_train, etc.), with the current epoch number as index.</p>
<p>After the loop, plot the six error arrays as a function of epoch number. Wrap this in an if-statement (or conditional compilation statement) that tests for the value plot_graphs.</p>
<p>Call the network error function again, on all three sets as before.</p>
<p>Return the weights, and the six errors.</p>
<h3>10. Implement the main training program</h3>
<p>The program should load in the sets (using the load_sets function), and pass these to the training algorithm.</p>
<h3>11. Run the program</h3>
<p>The important thing is that everything should run. You should see your error plots; at this stage they should be straight, horizontal lines. Because of the random weight initialisation, we cannot predict where these lines will lie (so do not be alarmed if they do not look exactly the same as below – as long as they are straight and horizontal).</p>
<p><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="backprop" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/backprop.png" border="0" alt="backprop" width="486" height="399" /></p>
<h3>12. Implement the backpropagation function</h3>
<p>You have already created the dummy function; now you can put in the actual calculations.</p>
<p>First, select a random sample.</p>
<p>Now, calculate the net matrix and output matrix using the feed-forward function.</p>
<pre>[output, net] = feedforward(random_sample, weights, bias)</pre>
<p>Calculate the error vector</p>
<pre>error_vector = target_outputs - outputs</pre>
<p>Calculate the sensitivity.</p>
<pre>delta = hammard(error_vector, activation_diff(net))</pre>
<p>The corresponding mathematical expression in the textbook might look like this:<br />
<img src='http://s.wordpress.com/latex.php?latex=%5Cdelta_k%20%3D%20%28t_k%20-%20z_k%29%20f%27%28y_k%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\delta_k = (t_k - z_k) f&#039;(y_k)' title='\delta_k = (t_k - z_k) f&#039;(y_k)' class='latex' />
<p>Calculate the weights delta:</p>
<pre>weights_delta = scalar_mul(eta, kronecker(transpose(outputs), delta))</pre>
<p>The corresponding mathematical expression in the textbook might look like this:<br />
<img src='http://s.wordpress.com/latex.php?latex=w_%7Bkj%7D%20%3D%20%5Ceta%20%28t_k%20-%20z_k%29%20f%27%28y_k%29y_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='w_{kj} = \eta (t_k - z_k) f&#039;(y_k)y_j' title='w_{kj} = \eta (t_k - z_k) f&#039;(y_k)y_j' class='latex' /></p>
<p>Update the weights:</p>
<pre>weights = add(weights, weights_delta)</pre>
<p>and return the matrix.</p>
<h3>13 Run the program (AGAIN)</h3>
<p>First, set the debug option to train on only one sample. The curve should like like this:</p>
<p><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="backprop3" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/backprop3.png" border="0" alt="backprop3" width="486" height="398" /></p>
<p>Notice that the error curves are smooth, the training error rate goes to 0, and the other error rates go to 0.4, plus or minus – this depends on the initial weights. It will also be different if you use a sample other than the first.</p>
<p>If your curve looks right, change the debug option to train on all samples. Your error curves should now look something like this:</p>
<p><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="backprop2" src="http://code-spot.co.za/blog/wp-content/uploads/2009/10/backprop2.png" border="0" alt="backprop2" width="486" height="398" /></p>
<p>The important feature of the error curves is that they should steadily descent on average. If your curve does not resemble the one shown here; there is a mistake in your implementation. It is often helpful to limit the training set to a single sample (thereby eliminating the randomisation of sampling during training) to see what is going on.</p>
<p>Although the errors often follow the relationship training &lt; validation &lt; test, this is not always the case, so do not be alarmed if this is not true on a run (You can see it is not always true in the run above).</p>
<h3>14 Implement a proper stopping condition</h3>
<p>Change the while loop to stop when the validation error drops below a threshold. Note that this threshold usually depends on the problem. There are better stopping conditions that are less sensitive to the problem at hand, but this one will do for now.</p>
<h3>15 Implement a statistical analysis</h3>
<p>This part is important for you to get an idea of the robustness of the neural net. In practice, a very simple analysis will suffice.</p>
<p>This part need to train the algorithm 30 times, and then report the mean, standard deviation and maximum of the</p>
<ul>
<li>training time,</li>
<li>regression error, and</li>
<li>classification error (on the test sets).</li>
</ul>
<p>In general, you would like all these values to be “low”. Here are some experiments for the iris data set with different learning rates. For each, 30 runs were made; other parameters are as described earlier (max_weight = 1/2, validation_stop_threshold = 0.1).</p>
<table border="0" cellspacing="0" cellpadding="2" width="486">
<tbody>
<tr>
<td width="171" valign="top"></td>
<td width="107" valign="top"><strong>Mean</strong></td>
<td width="100" valign="top"><strong>Standard Deviation</strong></td>
<td width="106" valign="top"><strong>Maximum</strong></td>
</tr>
<tr>
<td width="171" valign="top"><strong>eta = 0.05</strong></td>
<td width="107" valign="top"></td>
<td width="100" valign="top"></td>
<td width="106" valign="top"></td>
</tr>
<tr>
<td width="171" valign="top">Training time</td>
<td width="107" valign="top">1200</td>
<td width="100" valign="top">124.681</td>
<td width="106" valign="top">1489</td>
</tr>
<tr>
<td width="171" valign="top">Regression error</td>
<td width="107" valign="top">0.115343</td>
<td width="100" valign="top">0.0017233</td>
<td width="106" valign="top">0.11894</td>
</tr>
<tr>
<td width="171" valign="top">Classification Error</td>
<td width="107" valign="top">0.17807</td>
<td width="100" valign="top">0.0456762</td>
<td width="106" valign="top">0.263158</td>
</tr>
<tr>
<td width="171" valign="top"><strong>eta = 0.1</strong></td>
<td width="107" valign="top"></td>
<td width="100" valign="top"></td>
<td width="106" valign="top"></td>
</tr>
<tr>
<td width="171" valign="top">Training time</td>
<td width="107" valign="top">582.533</td>
<td width="100" valign="top">65.3076</td>
<td width="106" valign="top">719</td>
</tr>
<tr>
<td width="171" valign="top">Regression error</td>
<td width="107" valign="top">0.114626</td>
<td width="100" valign="top">0.00180851</td>
<td width="106" valign="top">0.118697</td>
</tr>
<tr>
<td width="171" valign="top">Classification Error</td>
<td width="107" valign="top">0.214912</td>
<td width="100" valign="top">0.0317323</td>
<td width="106" valign="top">0.263158</td>
</tr>
<tr>
<td width="171" valign="top"><strong>eta = 0.5</strong></td>
<td width="107" valign="top"></td>
<td width="100" valign="top"></td>
<td width="106" valign="top"></td>
</tr>
<tr>
<td width="171" valign="top">Training time</td>
<td width="107" valign="top">120.967</td>
<td width="100" valign="top">16.7095</td>
<td width="106" valign="top">169</td>
</tr>
<tr>
<td width="171" valign="top">Regression error</td>
<td width="107" valign="top">0.115711</td>
<td width="100" valign="top">0.0038786</td>
<td width="106" valign="top">0.123573</td>
</tr>
<tr>
<td width="171" valign="top">Classification Error</td>
<td width="107" valign="top">0.245614</td>
<td width="100" valign="top">0.0242702</td>
<td width="106" valign="top">0.263158</td>
</tr>
<tr>
<td width="171" valign="top"><strong>eta = 1</strong></td>
<td width="107" valign="top"></td>
<td width="100" valign="top"></td>
<td width="106" valign="top"></td>
</tr>
<tr>
<td width="171" valign="top">Training time</td>
<td width="107" valign="top">67.1667</td>
<td width="100" valign="top">12.2477</td>
<td width="106" valign="top">99</td>
</tr>
<tr>
<td width="171" valign="top">Regression error</td>
<td width="107" valign="top">0.114755</td>
<td width="100" valign="top">0.00488566</td>
<td width="106" valign="top">0.124468</td>
</tr>
<tr>
<td width="171" valign="top">Classification Error</td>
<td width="107" valign="top">0.253509</td>
<td width="100" valign="top">0.0201287</td>
<td width="106" valign="top">0.263158</td>
</tr>
</tbody>
</table>
<h2>Using the neural net in a program</h2>
<p>To use the neural net in a program after you have trained it, you need to save the weights found by the training program to a file. Your application must then read in this weights, and use it with the feedforward function to calculate the class.</p>
<p>Here is pseudo-code for the program. Note that the training program and classification program needn’t be implemented in the same language. This allows you to take advantage of speed and interface components that might not be available in your target platform. It is a very good idea to implement your training algorithm on a computer algebra system (such as <a href="http://www.mathworks.com/">Matlab</a> or <a href="http://www.gnu.org/software/octave/">Octave</a>) where you can take advantage of both matrix and graphing capabilities (the code provided below works in both).</p>
<h2>Using the training algorithm on other problems</h2>
<p>When using your neural net for other algorithms, you might need to change the learning rate, stopping threshold, and weight_max for weight the initialisation. The error plots are indispensible for this purpose.</p>
<p>As long as the learning rate is not too high, it should not affect the quality of the solution, only the number of iterations necessary to obtain it. The stopping threshold, however, has does affect the quality of the solution: if it is tool low, the problem might not be solved, or the neural net might train very long; if it is too high, you will get poor performance. There are better stopping conditions available; once you have everything working, you should investigate these.</p>
<p>Remember that you should not base your decisions on a single run, as runs can differ quite drastically from one another. Perform a few runs, and base decisions on these.</p>
<p>The value weight_max can usually be chosen as 1/sqrt(input_count) with good results, but here too it depends on the problem.</p>
<p>For further benchmarking, check out the <a href="ftp://ftp.ira.uka.de/pub/neuron/">Proben1 datasets</a>, described <a href="http://page.mi.fu-berlin.de/prechelt/Biblio/1994-21.pdf">here</a>. (Also check out the erratum note on <a href="http://page.mi.fu-berlin.de/prechelt/Biblio/">this site</a> – search for proben on the page.)</p>
<h2>Download</h2>
<p>The following code works in Matlab and Octave. (Included is a randint function; if you are using Matlab you can remove it, because it is already implemented in Matlab).</p>
<p><a href="http://www.code-spot.co.za/downloads/neural_net/iris_data_files.zip">iris_data_files.zip</a> (3 KB)</p>
<p><a href="http://www.code-spot.co.za/downloads/neural_net/basic_neural_net_0_1.zip">basic_neural_net_0_1.zip</a> (10 KB)</p>
<p>The program provided cheats a little – instead of reading in the raw .dat files, it reads in the .mat file that already has the data in the right structure.</p>
<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fcode-spot.co.za%2F2009%2F10%2F08%2F15-steps-to-implemented-a-neural-net%2F&amp;linkname=15%20Steps%20to%20Implement%20a%20Neural%20Net"><img src="http://code-spot.co.za/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>

<p>Related posts:<ol><li><a href='http://code-spot.co.za/2008/09/21/generating-random-numbers-with-arbitrary-distributions/' rel='bookmark' title='Permanent Link: Generating Random Numbers with Arbitrary Distributions'>Generating Random Numbers with Arbitrary Distributions</a></li>
<li><a href='http://code-spot.co.za/2009/04/09/cellular-automata-for-simulation-in-games/' rel='bookmark' title='Permanent Link: Cellular Automata for Simulation in Games'>Cellular Automata for Simulation in Games</a></li>
<li><a href='http://code-spot.co.za/2008/11/11/5-tips-for-prototyping-slow-algorithms/' rel='bookmark' title='Permanent Link: 5 Tips for Prototyping Slow Algorithms'>5 Tips for Prototyping Slow Algorithms</a></li>
</ol></p>
<p><a href="http://feedads.g.doubleclick.net/~a/zo5NqGoO7bvXoTwVm9RfgSm1sPI/0/da"><img src="http://feedads.g.doubleclick.net/~a/zo5NqGoO7bvXoTwVm9RfgSm1sPI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/zo5NqGoO7bvXoTwVm9RfgSm1sPI/1/da"><img src="http://feedads.g.doubleclick.net/~a/zo5NqGoO7bvXoTwVm9RfgSm1sPI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/code-spot/~4/r2o4OvbYBvU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://code-spot.co.za/2009/10/08/15-steps-to-implemented-a-neural-net/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://code-spot.co.za/2009/10/08/15-steps-to-implemented-a-neural-net/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=15-steps-to-implemented-a-neural-net</feedburner:origLink></item>
	</channel>
</rss>
