<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Emergent Computing</title>
	<atom:link href="http://www.emergentcomputing.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.emergentcomputing.com/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 08 Sep 2011 20:58:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Removing background from icons, OR, &#8220;Hey that worked!&#8221;</title>
		<link>http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/</link>
		<comments>http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 20:58:07 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Graphics]]></category>

		<guid isPermaLink="false">http://www.emergentcomputing.com/blog/?p=266</guid>
		<description><![CDATA[What do you do if you have a flat jpeg image containing an icon against a background, and you want to create a png of the icon on its own with a transparent background? You could use an &#8220;intelligent&#8221; selection &#8230; <a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What do you do if you have a flat jpeg image containing an icon against a background, and you want to create a png of the icon on its own with a transparent background?</p>
<p>You could use an &#8220;intelligent&#8221; selection tool to select the background and delete it, but you&#8217;ll probably be left with some remains of the background stuck to the outside of the icon. You could use a &#8220;colour to alpha&#8221; tool, but if there&#8217;s any of the background colour in the icon iteself then you&#8217;ll end up with a semi-transparent icon. If you&#8217;re smart, you could combine these tools and be pretty much there. But&#8230;</p>
<p>If you&#8217;re lucky enough, as I was, to have access the same icon appearing in a two of places against different backgrounds, you can use that to your advantage. After all, the background is simply whatever differ between each occurence.</p>
<p>In GIMP, I created the icon thus:</p>
<p>I cut out each occurence of the icon (background and all) to the smallest size possible without chopping any edges off, and pasted them both into the same image as layers. At this point the icons lined up with each other nicely.<br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/attachment/1/" rel="attachment wp-att-267"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/1.png" alt="" title="1" width="200" height="107" class="alignleft size-full wp-image-267" /></a><br style="clear:both"/></p>
<p>The background is whatever differs between the two occurences, so I set the layer mode for the top layer to &#8220;difference&#8221;. Then I copied the resulting image to the clipboard and pasted it back as a new layer (on top).<br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/attachment/2/" rel="attachment wp-att-274"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/2.png" alt="" title="2" width="200" height="129" class="alignleft size-full wp-image-274" /></a><br style="clear:both"/></p>
<p>The top layer now has straight black where the icon is, and some rather middling colours where the background is. I wanted to create a version of this layer to be applied as a mask to one of the original occurences. But that means I need straight white there the icon is, straight black where the background is, and shades of grey around the edges.</p>
<p>So I invert the colours. Now I have my white where the icon is.<br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/attachment/3/" rel="attachment wp-att-275"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/3.png" alt="" title="3" width="200" height="131" class="alignleft size-full wp-image-275" /></a><br style="clear:both"/></p>
<p>Next I used curves to bring the background down to as dark as possible. I just dragged the bottom left of the line to the right, to the darkest point where data exists.<br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/attachment/4/" rel="attachment wp-att-276"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/4.png" alt="" title="4" width="358" height="287" class="alignleft size-full wp-image-276" /></a><br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/attachment/5/" rel="attachment wp-att-277"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/5.png" alt="" title="5" width="200" height="137" class="alignleft size-full wp-image-277" /></a><br style="clear:both"/></p>
<p>Ok the mask is ready. I copied it to the clipboard, and applied it as a layer mask to one of the layers holding the original occurences of the icon (it is converted to greyscal in the process). I made all other layers invisible, and made sure all layer modes were back on &#8220;normal&#8221;.<br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/6-2/" rel="attachment wp-att-292"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/61.png" alt="" title="6" width="200" height="127" class="alignleft size-full wp-image-292" /></a><br style="clear:both"/></p>
<p>The final icon<br />
<a href="http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/attachment/7/" rel="attachment wp-att-283"><img src="http://www.emergentcomputing.com/blog/uploads/2011/09/7.png" alt="" title="7" width="78" height="78" class="alignleft size-full wp-image-283" /></a><br style="clear:both"/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2011-09-09/removing-background-from-icon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Little Confidence Booster</title>
		<link>http://www.emergentcomputing.com/blog/2011-06-14/a-little-confidence-booster/</link>
		<comments>http://www.emergentcomputing.com/blog/2011-06-14/a-little-confidence-booster/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 00:00:46 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emergentcomputing.com/blog/?p=262</guid>
		<description><![CDATA[It’s nice to know that qBox does better than Facebook when it comes to accidental repeated texts! <a href="http://www.emergentcomputing.com/blog/2011-06-14/a-little-confidence-booster/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago I spent half a day shoring up qBox against a potential bug where the same text message would be sent out multiple times within a few microseconds, instead of just once as it should be. I knew that in practice this bug was unlikely to ever show up, but being the kind of programmer I am I didn&#8217;t want to leave it to chance.</p>
<p>The fix was pretty mind-bending: working with mysql locks, thinking about race conditions etc. I remember thinking I shouldn&#8217;t be struggling so much with this, and I should have this stuff down-pat by this stage in my programming career. Anyway, 3.5 hours later I had the fix.</p>
<p>Then today, I got a text from Facebook telling me a friend confirmed my request. And a split second later I got the same text. And a split second later, again, I got the same text. Then finally, one more split second later, the same text.</p>
<p>So it looks like the folks at Facebook are struggling even more than me! It&#8217;s nice to know that qBox does better than Facebook when it comes to accidental repeated texts!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2011-06-14/a-little-confidence-booster/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Interactive CLI Autoload Substitute</title>
		<link>http://www.emergentcomputing.com/blog/2011-04-19/php-interactive-cli-autoload-substitute/</link>
		<comments>http://www.emergentcomputing.com/blog/2011-04-19/php-interactive-cli-autoload-substitute/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 02:45:01 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[alternative]]></category>
		<category><![CDATA[autoload]]></category>
		<category><![CDATA[interactive]]></category>
		<category><![CDATA[php cli]]></category>
		<category><![CDATA[substitute]]></category>

		<guid isPermaLink="false">http://ocf.co.nz/?p=239</guid>
		<description><![CDATA[<img src="http://www.emergentcomputing.com/uploads/2011/04/php-cli.png" alt="PHP CLI" title="php-cli" width="60" height="60" class="alignleft size-full wp-image-240" /> Class autoloading doesn't work in PHP's interactive CLI. So you can rule out running interactive tests on your code if you are relying on your autoload function to load the necessary classes. But, here is a script that can recurse through a directory and include all the class files, in the right order! <a href="http://www.emergentcomputing.com/blog/2011-04-19/php-interactive-cli-autoload-substitute/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Class autoloading doesn&#8217;t work in PHP&#8217;s interactive CLI (the docs state: Autoloading is not available if using PHP in CLI interactive mode). So you can rule out running interactive tests on your code if you are relying on your autoload function to load the necessary classes.</p>
<p>What would be cool is a script that could recurse through a directory and include all the class files, in the right order so as to satisfy class dependencies &#8211; i.e., never include a class which extends a superclass, or implements an interface, unless that superclass or interface has already been included. Such a script would more or less obviate autoloading.</p>
<p>Luckily for me, I always keep my class file structure tidy:</p>
<ul>
<li>strictly one class per file</li>
<li>class files are stored in subdirectories to match their namespace</li>
<li>class files don&#8217;t do any actual work on being included, save to possibly initialise static variables</li>
</ul>
<p>So I gave it a crack, and the result is a loadclasses.php, a file you can auto prepend (php -d &#8220;auto_prepend_file=loadclasses.php&#8221; -a) for a working interactive shell with all your classes loaded!</p>
<p><strong>loadclasses.php:</strong></p>
<pre style="background-color: #ffa; padding: 1em; margin-bottom: 1em;">
function acin($name,$namespace) {
	if ( substr($name,0,1) == "\" )
		return $name;
	return "$namespace\$name";
}

function loadClassesInDir($dir) {
	$files = explode("n", shell_exec("find '$dir' -name '*.php'") );
	for ( $i=0; $i&lt;count($files); $i++ ) {
		$file = $files[$i];
		if ( !$file ) continue;

		//echo $file;

		$namespace = str_replace("/","\",dirname(substr($file,strlen($dir))));

		$contents = file_get_contents($file);
		$interface = $clazz = null;
		if ( preg_match("/s+implementss+([\\A-Za-z_0-9]*)/",$contents,$groups) ) {
			$interface = acin($groups[1],$namespace);
			//echo " dependent interface:$interface";
		}
		if ( preg_match("/s+extendss+([\\A-Za-z_0-9]*)/",$contents,$groups) ) {
			$clazz = acin($groups[1],$namespace);
			//echo " dependent class:$clazz";
		}
		if ( $clazz &#038;&#038; !class_exists($clazz) || $interface &#038;&#038; !interface_exists($interface) ) {
			//echo " skip";
			$files[] = $file;
		} else {
			//echo " include";
			include $file;
		}
		//echo "n";
	}

}

loadClassesInDir("/path/to/classes");
</pre>
<p>Change the last line to point to the directory where your classes are stored. Repeat this line multiple times if needed, to cover all the directories where classes live.</p>
<p>Some caveats:</p>
<ul>
<li>You will have to get the calls to <tt>loadClassesInDir</tt> in the right order if one <em>set</em> of classes depends on another</li>
<li>Hasn&#8217;t been completed for multiple interface implementations</li>
<li>I&#8217;m using the find command &#8211; should still work on windows but you&#8217;ll gnu find or similar installed, or you could write the pure php version with opendir();</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2011-04-19/php-interactive-cli-autoload-substitute/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculate Next Birthday with MySQL</title>
		<link>http://www.emergentcomputing.com/blog/2011-04-17/calculate-next-birthday-with-mysql/</link>
		<comments>http://www.emergentcomputing.com/blog/2011-04-17/calculate-next-birthday-with-mysql/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 23:25:55 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://ocf.co.nz/?p=220</guid>
		<description><![CDATA[<img src="http://www.emergentcomputing.com/blog/uploads/2011/04/mysql-150x150.gif" alt="" title="mysql" width="60" height="60" class="alignleft size-thumbnail wp-image-256" /> Today I thought I'd fire off a query to get customers next birthday, to send them a birthday reminder if it's coming up. I quickly became aware of some caveats. <a href="http://www.emergentcomputing.com/blog/2011-04-17/calculate-next-birthday-with-mysql/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="font-size:80%">
<pre><code>
select <strong>mytable</strong>.*, case
  when <strong>birthdate</strong> + interval year(current_date) - year(<strong>birthdate</strong>) year > current_date
    then <strong>birthdate</strong> + interval year(current_date) - year(<strong>birthdate</strong>) year
  else <strong>birthdate</strong> + interval year(current_date) - year(<strong>birthdate</strong>) + 1 year
  end as next_birthday
  from <strong>mytable</strong>;
</code></pre>
</div>
<p>(bold text means field and table names to be replaced)</p>
<p>Today I thought I&#8217;d fire off a query to get customers next birthday, to send them a birthday reminder if it&#8217;s coming up. I quickly became aware of some caveats.</p>
<p>Most obviously, you can&#8217;t simply compare the birth<em>date</em> timestamp with the current timestamp because every customer&#8217;s birthdate is in the past. You have to somehow ignore the years.</p>
<p>Use of MySQL functions to extract the day and month from the birthdate would have to be used with caution if the end of the month was approaching (among other assorted boundary issues). Any use of the day of the year function is also tricky because on a leap year the days are all out by one after March 1st. I didn&#8217;t want people born on February 29th to get an email every four years!</p>
<p>But after some tests, I found that if I found the correct number of years (n) to step forward from the actual birthdate, then <tt>birthdate + interval <em>n</em> year</tt> always gave the correct result. If a customer&#8217;s birthday is February 29th, you would get result like 2011-02-28 or 2012-02-29. The value of n is, or course, the current year minus the year of the birthdate, or that plus one if their birthday has already been this year (see above).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2011-04-17/calculate-next-birthday-with-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# Integer Bug: yes I went there!</title>
		<link>http://www.emergentcomputing.com/blog/2011-02-03/c-integer-bug/</link>
		<comments>http://www.emergentcomputing.com/blog/2011-02-03/c-integer-bug/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 08:18:45 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://ocf.co.nz/?p=182</guid>
		<description><![CDATA[What values could <tt>int</tt>s a and b take to make the following C# snippet throw an ImpossibleException?

<pre>
if (a > 0 &#038;& b > 0 &#038;& a + b < 0)
      throw new ImpossibleException();
</pre>
<br/>
In other words, what two positive integers add to a negative number? Of course, there is no such pair. Unless you ask C#... <a href="http://www.emergentcomputing.com/blog/2011-02-03/c-integer-bug/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>What values could <tt>int</tt>s a and b take to make the following C# snippet throw an ImpossibleException?</p>
<pre>
if (a &gt; 0 &#038;&#038; b &gt; 0 &#038;&#038; a + b &lt; 0)
      throw new ImpossibleException();
</pre>
<p><br/></p>
<p>In other words, what two positive integers add to a negative number? Of course, there is no such pair.<br/></p>
<p>Unless you ask C#, where a = 2147483647 and b = 1 will trigger the ImpossibleException (no ArithmeticOverflowException or similar) . And the sum of a and b is apparently -2147483648.<br />
<br/></p>
<p>Among many implications is the fact that in C#, this loop:</p>
<pre>for ( int i = 2147483647; i <= 2147483647; i++ )
{
    &hellip;
}</pre>
<p><br/><br />
is the same as this loop:</p>
<pre>while (true)
{
    &hellip;
}
</pre>
<p><br/><br />
This extends to the rest of .NET, plus Java, PHP, C++ - like the recent <a href="http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/">Java and PHP Bug</a> which causes a crash when converting the number 2.2250738585072012e-308.<br />
<br/><br />
What a laugh!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2011-02-03/c-integer-bug/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Programmer-Available Software Development</title>
		<link>http://www.emergentcomputing.com/blog/2010-10-30/programmer-available-software/</link>
		<comments>http://www.emergentcomputing.com/blog/2010-10-30/programmer-available-software/#comments</comments>
		<pubDate>Sat, 30 Oct 2010 04:25:39 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Development Techniques]]></category>

		<guid isPermaLink="false">http://www.emergentcomputing.com/blog/?p=6</guid>
		<description><![CDATA[As a programmer, I have the luxury of being able to create software by myself, for myself. I cash in on this a lot &#8211; I use my own accounting software, graphics software and framework for PDP networks. But when &#8230; <a href="http://www.emergentcomputing.com/blog/2010-10-30/programmer-available-software/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As a programmer, I have the luxury of being able to create software by myself, for myself. I cash in on this a lot &#8211; I use my own accounting software, graphics software and framework for PDP networks. But when I write software for myself, I do things a bit differently to when I&#8217;m writing software for a client. Just by taking a slightly different approach, I&#8217;m able to speed up development significantly and do very tricky things that, frankly, would be difficult or impossible to achieve with off-the-shelf software.</p>
<p>The basic approach is, instead of going the normal route and striving for a program which is highly configurable and flexible, I write a program which is totally <em>in</em>flexible. There are no installation options or preferences pages, no complex user database, and usually a just a basic user interface. The program does what it does and that&#8217;s it, unless I change the actual code of the program.</p>
<p>Obviously, this saves time because there is less code to write, but it goes even further than that. What I&#8217;ve come to realise is that the features of the program need to be very well defined before you can give them good configuration options. OK, sometimes it&#8217;s obvious: a feature that calculates GST would need a configuration option for the GST rate. But when it comes to a feature that calculates the PAYE for overseas employees, it&#8217;s not so immediately obvious what the right configuration options would be.</p>
<p>Also, the features can&#8217;t be too likely to change in the near future or all the work that went into making them configurable will have to be thrown away. Clarifying and finalising requirements is a big job, but as long as I&#8217;m happy with a completely unconfigurable program, I can skip this job too.</p>
<p>And without exception, when I start coding, I don&#8217;t have a crystal clear picture of where I want the software to end up. Personally, I like it this way. Having loosely defined requirements simply means I&#8217;m not ready to commit to something until I can see it working and be sure it&#8217;s the right fit. Changing my requirements often means I can always have that new feature, and get a competitive edge over people stuck on rigid software. Two big advantages, and development is sped up to boot!</p>
<p>So I asked myself, why couldn&#8217;t I pass these advantages onto my customers?</p>
<p>In other words, what if the programmer created a very inflexible program for a client, for a very reasonable price, but make his/herself available to change it whenever necessary? You could call it &#8220;Programmer-Available Software Development&#8221; (PASD), because the programmer gets involved on a fairly regular basis. Would PASD really work for the customer?</p>
<p>The first obvious problem is that whenever the program needed even the slightest change, including such trivial things as a change in the tax rate, the programmer would have to be called in. This could get costly for the customer and it would probably turn out that a configurable program would have been more economical overall.</p>
<p>Another problem is that realistically the software could only be given to one customer, and limited to single instance. If multiple copies of the software were set up, they might each evolve in different ways. If there were four instances of the software, each with its own special way of calculating tax, then that&#8217;s four different sets of source code. This creates a maintenance problem which would need to be handled carefully by the programmer, and could waste a lot of time.</p>
<p>But there are some circumstances where PASD is perfect for the customer. Namely, it&#8217;s when requirements are <em>un</em>clear, and <em>far</em> from finalised.</p>
<p>If the behavior of the program is changing faster than the mere parameters, then you might as well stick with a totally unconfigurable program and have the programmer change the parameters as part of development, since they&#8217;ll be working on the software anyway. Why go to the hassle of setting up a preferences page for the tax rate, when tomorrow the software might be automatically looking this value up on the internet or to getting it from another program? It just doesn&#8217;t make sense to go to the expense of creating a highly configurable, flexible program when the requirements are in flux.</p>
<p>So when should you clarify and finalise the requirements? The answer is above: when you start wanting to configure the software often, or you want to deploy multiple copies. And one of the great thing about PASD is that it gives you a demonstration of the software in action before this time comes, which should give you the confidence to provide clear and finalised requirements and be sure they will work for your business.</p>
<p>Of course, if you don&#8217;t need to configure the software that often, and you&#8217;re happy with a single instance, then you could stay on PASD indefinitely.</p>
<p>PASD software can be put to work from a very early stage. In fact, my advice is to make the software live and start using it as soon as possible so you and your staff can start to benefit from it, as well as thinking about additional requirements for the software. There&#8217;s nothing like using the live software for identifying those special cases which require a special behavior, or thinking of new features that could save you time in your daily routine.</p>
<p>You could characterise PASD as an even more extreme incarnation of agile software development. Whereas agile development might see programmers and customers have scheduled weekly meetings, PASD puts the programmer on call to respond to the customers request the very next day, or even on the same day. Whereas agile development might see the customer testing software in a test environment, PASD makes the software live so the customer can use it on real data. And whereas agile development says nothing about the flexibility of software, PASD dictates that the software stay very concrete, either indefinitely, or until the customer is ready to give clear and more-or-less final requirements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2010-10-30/programmer-available-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Ray Tracer</title>
		<link>http://www.emergentcomputing.com/blog/2010-09-30/ray-tracing/</link>
		<comments>http://www.emergentcomputing.com/blog/2010-09-30/ray-tracing/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 19:04:41 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Graphics]]></category>

		<guid isPermaLink="false">http://ocf.co.nz/?p=110</guid>
		<description><![CDATA[<img src="http://ocf.co.nz/uploads/2010/09/raytracinglogo-150x150.png" alt="" title="raytracinglogo" width="60" height="60" class="alignleft size-thumbnail wp-image-173" />
<p>About six years ago, I wrote some BASIC code which did the maths to rotate points in a 3D space, and the bare minimum to render them. Lately I've made some additions to the system so I've decided to report my progress as I go. But first, the history so far.</p> <a href="http://www.emergentcomputing.com/blog/2010-09-30/ray-tracing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>About six years ago, I wrote some BASIC code which did the maths to rotate points in a 3D space, and the bare minimum to render them. The points could be joined with lines and with this system I was able to produce a spinning transparent cube, a spinning random cloud of particles, and a very poorly drawn spinning 3D heart. Since then I&#8217;ve tacked bits on every once in a while, usually with a week of nights&#8217; development at a time. Lately I&#8217;ve been excited by where it&#8217;s going so I&#8217;ve decided to report my progress as I go. But first, the history so far.</p>
<p><strong>Mid 2004</strong><br />
Created the original BASIC version. Points were defined in three arrays (point_xs, point_ys, point_zs) holding coordinates, and lines in two (line_froms, line_tos) holding the indicies of points to link. Rotation was done by passing in two coordinates at a time to a rotate function. E.g., pass in the x and z coordinates to rotate around the y axis. No concept of a camera; everything was rendered around the origin (offset to the centre of the screen).</p>
<p>The rendering was very simple: just render the points based on their x and y coordinates, and ignore the z coordinate. I thought about adding perspective by pulling points with higher z values closer to the origin, but never got to it. Rendering the lines was equally simple: just use the line function to draw a straight line between the final computed coordinates of the points in question.</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/EHMmx_o4dkQ?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/EHMmx_o4dkQ?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
<b>Original spinning heart output</b></p>
<p>One very interesting bug I got in the original version had the spinning objects crumpling in on themselves. My spinning heart, for example, would start spinning fine for maybe 1/4 of a revolution, then some of the points would start to twitch, getting a little closer to the origin each time. Then all of a sudden, all the points and lines would head straight for the origin and the entire shape become a singularity at the centre of the screen.</p>
<p>The problem was (if you haven&#8217;t guessed) that I was allowing computation errors in the rotation to compound. I should have kept the original set of points around in memory, stepped forward from 0 to 360 degrees, and rotated a clone of the points by that amount each time. But instead, I was simply looping without a counter and rotating the master copy of the points by a degree each time. Each time the object was rotated, the x and y values came back a little low, so eventually all x and y values hit zero.</p>
<p><strong>Late 2006</strong><br />
Ported the code to Java, my favourite language of the time. The code remains Java-based to this day.</p>
<p><strong>November 2008</strong><br />
Added support for polygons. In the same spirit as the line support of the original version, I just called Java&#8217;s Graphics.drawPoly() method on all the connected points (which I renamed to Nodes).</p>
<p>Invented a &#8220;camera&#8221;, with position plus yaw, pitch, roll. Basically this just offers an object to store information about what offsets and rotations should be performed before rendering; the first step to rendering a frame is to bring the focus to the origin and rotate the space so we&#8217;re looking straight at it.</p>
<p>I also created a file format for the &#8220;spaces&#8221; being rendered. A simple text format to define nodes, lines, and polygons. Lines and polygons now require RGB values to define their colour. To future-proof, I also allow definitions of lights including position, colour and intensity, which remains unused for now.</p>
<p>Rendering remains the same, but with perspective added based on a perspective factor. Perspective is added by multiplying the x and y values by the perspective factor raised to zero minus the z value. A perspective factor of about 1.004 seemed to be the most agreeable, at least with the sizes of object I was working with with a width of about 100 units (pixels).</p>
<p>To create some sort of lighting effect, I dimmed polygons by the sine of their angle with the camera. This way a solid green cube rotating randomly did not just look like a square morphing into a octagon, but gave the illusion of a shaded cube.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/85qJGv6GNc8?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/85qJGv6GNc8?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br />
<b>Demo of the polygon support and lighting effect.</b></p>
<p>I got some weird results when certain assumptions were violated. My code never checked that all nodes in a polygon were in a plane. So, just for fun, I decided to define a polygon with nodes that weren&#8217;t in a plane. First I defined two parallel polygons in the shape of a 2D heart, about 100 units wide and separated by about 20 units. I confirmed that they rendered okay. The first had nodes &#8220;a, b, c, &#8230;&#8221; and the second &#8220;a2, b2, c2, &#8230;&#8221;. Then I made them a single polygon, which broke my assumption, by simple using all the nodes from both polygons: &#8220;a, b, c, &#8230;, a2, b2, c2, &#8230;&#8221;.</p>
<p>I watched the shape rotate, and the result was an optical illusion. When the angle was near enough to straight on, it looked like ribbon in a heart shape. But when rotated around you thought you might see the full width of the ribbon, suddenly you&#8217;re looking between two 2D heart-shaped polygons. Then, just as suddenly it seems to go back to the ribbon.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/IWRAR7qn0_s?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/IWRAR7qn0_s?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br />
<b>Parallel hearts optical illusion</b></p>
<p>This got me thinking about how the brain resolves unexpected light and shadows. Nothing on the screen was changing suddenly, yet my interpretation was changing very suddenly as the object rotated. Even while in one interpretation, you could see evidence that something was not quite right with the object, but it was small enough to ignore. That is, until the small flaws took over and my interpretation shifted again. It also got me thinking that, while the usual aim of graphic design is to present veridical, realistic graphics, it could also be used to present stimuli that could not possibly be created by objects in the real world.</p>
<p><strong>December 2008</strong><br />
Started on real ray tracing. At this point I did not know what the term &#8220;ray tracing&#8221; meant, but since the beginning of the whole process (2004) I thought it would be a great idea to try to render a scene by bouncing virtual photons off my virtual objects. Up until this point I was doing what I call &#8220;direct&#8221; rendering, that is, figuring out how to transform the nodes in a scene to change the angle and simply drawing lines or polygons between those points. Bouncing virtual photons around would be a whole different approach: the link between the internal model of the scene and the final rendered image would be less explicit and more natural, with the final image being less of a representation of the model and more like and &#8220;impression&#8221; of the scene on a virtual film.</p>
<p>These ideas had been incubating for a number of years by now. For example, I thought that if I used virtual photons, then perspective would take care of itself; distant object would appear smaller because the photons they reflected would hit my virtual lens at angles closer to parallel. I knew from high school science class that most objects diffuse light, so I knew I would have to assign each object such a &#8220;scatter factor&#8221;. A mirror would have a scatter factor close to zero, and a matte object like a piece of paper would have a high scatter factor. Similarly I&#8217;d need to give my objects absorption and transparency factors too. I expected to see cool lighting effects and even to encounter depth-of-focus effects associated with real lenses.</p>
<p>My plan was to take a lead from the real world (or at least my understanding of it). I&#8217;d put lights in the scene (represented by a vector for position and an intensity) , as well as a lens (represented by a vector position for the center, a vector normal for its direction, and a radius) and a film (a plane parallel to the lens and set back by a given distance). I&#8217;d create some necessary geometry utility functions to find things like the intersection of a line and plane, or to tell if a point on a polygon&#8217;s plane was actually inside the boundary of the polygon or not. I&#8217;d set up a loop where each light fired off a photon at a time, and it was bounced around the scene until it hit the lens or disappeared into the blue yonder (which was actually rendered black).</p>
<p>I started coding, reading articles on the web, writing unit tests for my geometry functions, watching debug output in both text format and as pixels on the screen. I wanted to get something up and running as soon as possible. Finally I had completed all the elements of my basic plan&#8230;but it still did not work at all how I&#8217;d hoped. The pixels were garbled. I was able to see <em>some</em> evidence that I was on the right track, but I was at a loss as to how turn a lot of noisy pixel into a pristine image. Here&#8217;s one of the better looking images I saw, of three 2D cards side by side right in front of the camera.</p>
<p><a href="http://ocf.co.nz/2010-09-30/ray-tracing/fuzzy/" rel="attachment wp-att-143"><img src="http://www.emergentcomputing.com/blog/uploads/2010/09/fuzzy.png" alt="" title="Fuzzy" width="301" height="301" class="alignleft size-full wp-image-143" /></a><a href="http://ocf.co.nz/2010-09-30/ray-tracing/not-fuzzy/" rel="attachment wp-att-146"><img src="http://www.emergentcomputing.com/blog/uploads/2010/09/not-fuzzy.png" alt="" title="not-fuzzy" width="303" height="301" class="alignleft size-full wp-image-146" /></a><br />
<br class="clear"/></p>
<p><b>Left: Garbled output from an early attempt at ray tracing. Right: the same scene rendered with the original system.</b></p>
<p>Some things to notice from these images: Firstly the ray-traced image is inverted compared to the directly rendered image, which proves the virtual lens is working at least somewhat. Even around the center of the cards there are some missing pixels, which is what you&#8217;d expect since I had (as yet) no system to ensure every pixel got a hit. The pixels are more concentrated around the center of the cards, which is promising but at this stage I wasn&#8217;t sure if I was seeing a lighting effect, a lack of focus, a bug in my maths, or a combination of all three. The edges of the cards blend into each other, which suggests faulty maths or a lack of focus, but I was sure I&#8217;d positioned the film the right distance back from the lens to achieve sharp focus so that only left faulty maths. Sure enough, that&#8217;s what I&#8217;d eventually find to be the case.</p>
<p><b>September 2010</b><br />
Had a 20-hour hackathon where I tracked down and corrected most of the faulty maths in the system. With my wife away at an executive retreat, I finally had the time focus required to review each part of the system and really make sure it was doing the right thing under all conditions. Previously I always felt like I only have a limited amount of time to fix it, which prevented me from going down paths of investigation that really needed to be explored.</p>
<p>As well as going over every part of the system, I also threw away some parts. I had the brilliant idea (which I should have had from the start) of using a simple pinhole camera approach rather than a complex lens-based system. By now I was well aware that, to guarantee each pixel gets a hit, conventional ray-tracing is done from the camera to object to light rather than the more natural light to object to camera. So, I switched to this approach.</p>
<p>I rapidly found and fixed bugs, edging forward by turning messed up images into cleaner ones. Here&#8217;s two shots of three cards again, this time viewed from an angle.</p>
<p><a href="http://ocf.co.nz/2010-09-30/ray-tracing/cards-buggy/" rel="attachment wp-att-149"><img src="http://www.emergentcomputing.com/blog/uploads/2010/09/Cards-Buggy.png" alt="" title="Cards Buggy" width="414" height="365" class="alignleft size-full wp-image-149" /></a><br />
<a href="http://ocf.co.nz/2010-09-30/ray-tracing/cards-less-buggy/" rel="attachment wp-att-150"><img src="http://www.emergentcomputing.com/blog/uploads/2010/09/Cards-Less-Buggy.png" alt="" title="Cards Less Buggy" width="414" height="365" class="alignleft size-full wp-image-150" /></a><br />
<br class="clear"/></p>
<p>The first image shows a bug in the function that checked if two points were on the same or opposite sides of a line. After I fixed the bug, I got the second image. Other things to note here: I only rendered every fourth pixel (to save time) so you do still get missing pixels in the output, the gaps are just uniform.<br />
The mixing of the colours in the first image was seemingly random, which I really didn&#8217;t expect. Even faulty maths, I thought, would result in pretty well defined errors, not random mixing like this. But I guess that&#8217;s just one of the properties of bugs: they can do anything.</p>
<p>Also, the perspective is very apparent, which proves my hunch that perspective would take care of itself. In fact, the perspective was way too extreme, but I quickly figured out what settings to change to control this (namely that the camera needs to be further away from the object, and the film set back more from the pinhole). Finally, you can&#8217;t tell by looking, but these images were a lot quicker to render than the previous ones. This is because of the backwards tracing (from camera instead of from the light source). I no longer had to wait and hope for each pixel to get hit, I could guarantee it because I looped over each pixel and tried to get a hit.</p>
<p>In this one I rendered a blue cube with the camera inside it, and I move the light source from one side to the other to watch the lighting effects. The whole movie took about half an hour to render.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/PmwUoTgJqAw?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/PmwUoTgJqAw?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>You&#8217;ll note some that some of the objects appear to have &#8220;belly buttons&#8221;. That&#8217;s a residual bug that I&#8217;m actually still working on. It has to do with a shortcut I took on calculating the directness with which a photon hits a surface. More to come on that&#8230;</p>
<p>I also added some more code to handle spheres. This turned out to be surprisingly simple in the context of ray tracing. Until now the only thing that could be rendered was a Polygon. So, I looked at how the renderer was interacting with polygons and wrote an interface, called &#8220;Thing&#8221;, to describe it. I managed to distill it down to three main functions: Polygon.getPointsOfIntersection(line), Polygon.getReflectionPlane(point) and p.getColor(). Then I changed the rendering code to work only with &#8220;Things&#8221;, and removed all mentions of the Polygon class from the rendering code and confirmed it still worked as before (which it did).</p>
<p>Now that I had the Thing interface, I could render any 3D shape just by implementing its getPointsOfIntersection and getReflectionPlane methods (and getColor of course, but that&#8217;s easy). For the sphere it was very simple.</p>
<p>Here are some demos of the spheres.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/4G_spC6EyJQ?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/4G_spC6EyJQ?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><a href="http://ocf.co.nz/2010-09-30/ray-tracing/three-spheres/" rel="attachment wp-att-157"><img src="http://www.emergentcomputing.com/blog/uploads/2010/09/Three-Spheres.jpg" alt="" title="Three Spheres" width="640" height="480" class="alignleft size-full wp-image-157" /></a></p>
<p>Again, the spheres have navels, and some are worse than others. Also, there are some obvious edge effects here: black dots appear at the joins of the walls when the camera is facing straight on. The spheres fade to black way to harshly &#8211; just shows that it&#8217;s not about all hard maths, it&#8217;s also about fine tuning settings to make something look acceptable to the human eye. (Ignore the jpeg and mpeg effects, they&#8217;re not really in the rendered images).</p>
<p>Here&#8217;s a really crazy bug I saw. This has to do with maxing out the brightness of colours when using Java&#8217;s hue, saturation, brightness (hsb) colour functions. I had code to adjust the brightness of colours by converting rgb colours to hsb, changing the brightness, then converting back to rgb. Brightness is expressed from 0~1 with 1 being the brightest, and my code was attempting to set the brightness to much higher numbers like 0~1000. I knew full well my code had this fault, but I was too excited to think about how to normalise the brightness values so I figured I&#8217;d just run it let the brightness saturate. But rather than saturation I got this:</p>
<p>I&#8217;m just guessing, but it looks like Java&#8217;s colour function wraps around at brightness 1, so instead of a really bright image, I got layered gradients. Doesn&#8217;t explain the presence of other colours in the middle of the walls though&#8230;</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/F_mU574Yz6M?fs=1&amp;hl=en_GB"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/F_mU574Yz6M?fs=1&amp;hl=en_GB" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
<b>Really hippy output resulting from a brightness bug</b></p>
<p>Well, that&#8217;s all I have for this post. My next posts on this will be a lot shorter and will probably have more images that look similar to each other as I expect to post about particular points and concepts, and subtle differences between different techniques. Keep watching!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2010-09-30/ray-tracing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtering input in a complex environment</title>
		<link>http://www.emergentcomputing.com/blog/2010-03-02/filtering-input-in-a-complex-environment/</link>
		<comments>http://www.emergentcomputing.com/blog/2010-03-02/filtering-input-in-a-complex-environment/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 02:58:33 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Artificial Intelligence]]></category>

		<guid isPermaLink="false">http://ocf.co.nz/?p=84</guid>
		<description><![CDATA[In my last post I touched on the idea that to be successful in a complex environment, any AI system would need to filter its input, essentially throwing away irrelevant information at a very early stage in order to keep &#8230; <a href="http://www.emergentcomputing.com/blog/2010-03-02/filtering-input-in-a-complex-environment/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://ocf.co.nz/2009-11-26/blink-malcolm-gladwell/">last post</a> I touched on the idea that to be successful in a complex environment, any AI system would need to filter its input, essentially throwing away irrelevant information at a very early stage in order to keep up with the rapid flow of incoming data. In this post, I will elaborate on this idea.</p>
<p>Input filtering, as I see it, is about the quick (and possibly dirty) extraction of information from incoming data. It&#8217;s about turning the rapid flow of data into a comparative trickle of high-quality information, which itself becomes a data stream for higher-level subsystems.<sup>1</sup></p>
<p>Filtering input is not about simply ignoring data; if we wanted to do this we could simply use fewer sensors. Consider an agent connected to a high resolution digital camera. It is true that, to reduce the current of the incoming data stream, the agent could discard or ignore the values of certain pixels. For example, it could ignore the outer edge of the frame and consider only the center, or ignore every second pixel to achieve a full but lower-resolution view. But, discarding input is equivalent to simply using poorer sensors, so does not gain the agent any advantage over simply being fitted with these poorer sensors in the first place.<sup>2</sup></p>
<p>What filtering input <i>is</i> about is taking what information we want from some data, and then discarding that data. With the data goes a lot of other information which we could have extracted, but which we can do without. To return to a vision example, consider my old 640&#215;480 webcam, which provides 307,200 pixels per frame. Each pixels requires 16 bits to encode, and the camera can serve 15 frames per second. That means my camera provides 70.3Mb of data per second, which is a lot.</p>
<p>Now imagine this camera connected to a hypothetical AI security system for detecting intruders, the Securicam5000. Inside the Securicam5000 is a subsystem which detects the degree of change from one frame to the next. For every frame, this subsystem provides a 4b message to whichever other subsystems need it, to say how much the frame differs from the previous one on a scale of 0 to 15. (Let&#8217;s assume for now that the designers have established that the degree of change from frame to frame is relevant to the overall goal of detecting intruders.)</p>
<p>What our subsystem achieves here is to filter the input. If the Securicam5000 was fitted with a whole array of similar input filtering subsystems, then the actual incoming data (all 70.3Mb per second of it) could be discarded once the relevant information had been extracted. Even if there were one hundred input filtering subsystems in the Securicam5000, each contributing on average, say, 10b per frame, that&#8217;s still only gives a 14.6Kb/s trickle of information to be passed to the higher-level subsystems. That&#8217;s a rate of almost 5000 times less than the raw input stream, which is much more manageable for a processor of limited speed.</p>
<p>As Sherlock Holmes gathers data about a case, he often gets to a point where he has all but solved the case and starts looking for the final evidence against his number one suspect. Meanwhile, Dr. Watson (and the reader) has no idea how Holmes can be so sure he has found the best lead. To the non-detective, ruling out some of the other suspects seems foolish and dangerous. But it is Holmes&#8217; power to identify and discard irrelevant information that frees up his mind to deduce who did it.</p>
<p>For example, say Holmes&#8217; client said he saw the servant admiring the painting late one night, but Holmes observed that the servant lacked the intelligence to successfully sell the painting. Holmes can throw away the possibility that servant stole the painting and even remove from his consciousness the distracting anecdote about the servant&#8217;s suspicious activity. Meanwhile, Watson grows more confused with every new piece of information, and suffers from information overload.</p>
<p>I believe that the visual system and other systems in the brain must do something similar to what Holmes does in his detective work, but subconsciously. To cope with a stream of data even greater that that of my old webcam, or any modern digital camera for that matter, the raw video data must be converted into a slower stream of simple information: presence of a curve here, presence of some lines there, lots of blank space. This data is more manageable by the later stages of the visual system, which in turn can produce a simple internal model of what exists in the world: a hot cup of tea to my right, and a pen and paper in front of me, and blue skies above.</p>
<p>In turn, my highest-level subsystems can take this model and play with it, and forget about the raw visual data from which it was extracted. I reach for the teacup because my internal model tells me it is there, not because I have consciously and painfully processed screeds of visual data and deduced that a teacup must be there &#8211;  no system on earth could actually process so much data so quickly.</p>
<p>As I said previously, filtering input is not about simply ignoring data. To blank-out every second pixel on a camera, or in the human case every second rod or cone on our retina, would be as foolish as Watson trying to combat information overload by ignoring every second fact of the case. Firstly, this would be harmful to Watson&#8217;s ability to solve the case. And furthermore, this butchering of the input only achieves a data reduction of 50 percent, where the kind of reduction needed is likely to be far greater than that. We cannot throw away data indiscriminately and expect to be better off.</p>
<p>The question arises then, how do we know what information to keep and what to throw away. The answer will, of course, depend on the particular problem you are trying to solve. In the domain of triaging patients complaining of chest pain, Lee Goldman was able drill down to to exactly four pieces of relevant information: whether the patients ECG is normal, whether the pain is unstable angina, whether there is fluid in the patients lungs, and whether the patients systolic blood pressure is below 100. He achieved this by applying statical methods to years worth of patient records.</p>
<p>In the case of human vision, one might argue that it is evolution which has equipped the visual system with knowledge of what information is relevant and what is not. In the hypothetical example of the Securicam5000, the designers decided, using their expert knowledge, that how much the input changes from one frame to the next is among the information relevant to the problem of detecting intruders. Judging which information is relevant is a matter of carefully thinking about and experimenting with the problem you are trying to solve.</p>
<p><sup>1</sup> It may appear I am equating data with information, but this is not exactly my intention. I am using the data/information distinction like a north/south distinction. Anywhere you stand, north is on one side of you and south on the other. For any AI subsystem you look at, data comes from one side and information goes out the other; so one subsystem&#8217;s information is another subsystem&#8217;s data.</p>
<p><sup>2</sup> However, one could imagine an optimization process where a high resolution device was used in a series of tests, ignoring different input in each test in order to find the minimal set of sensors needed for a particular agent in a particular environment to achieve a particular task.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2010-03-02/filtering-input-in-a-complex-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Blink, by Malcolm Gladwell</title>
		<link>http://www.emergentcomputing.com/blog/2009-11-26/blink-malcolm-gladwell/</link>
		<comments>http://www.emergentcomputing.com/blog/2009-11-26/blink-malcolm-gladwell/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 02:02:27 +0000</pubDate>
		<dc:creator>Oran</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[blink]]></category>
		<category><![CDATA[malcolm gladwell]]></category>

		<guid isPermaLink="false">http://ocf.co.nz/?p=65</guid>
		<description><![CDATA[<img src="http://ocf.co.nz/uploads/2009/11/blink-cover-150x150.jpg" alt="" title="Cover" width="60" height="60" class="alignleft size-thumbnail wp-image-68" /> This is a book about the first moments of any encounter. It explains the amazing ability of the subconscious mind to infer a wealth of information from even the thinest slice of experience. Experts can spot a fake statue within seconds of seeing it, predict the success of a marriage by watching a couple chat, or identify a bird after a sighting of only a few seconds at great distance. We can all tell if we like someone in the first few minutes of talking with them, and we can tell what a person is thinking by looking at their face. <a href="http://www.emergentcomputing.com/blog/2009-11-26/blink-malcolm-gladwell/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.emergentcomputing.com/blog/uploads/2009/11/blink-cover.jpg" alt="blink-cover" title="blink-cover" width="160" height="252" class="alignleft size-full wp-image-68" style="float: left; margin: 0 1em 0 0;"/></p>
<p>This is a book about the first moments of any encounter. It explains the amazing ability of the subconscious mind to infer a wealth of information from even the thinest slice of experience. Experts can spot a fake statue within seconds of seeing it, predict the success of a marriage by watching a couple chat, or identify a bird after a sighting of only a few seconds at great distance. We can all tell if we like someone in the first few minutes of talking with them, and we can tell what a person is thinking by looking at their face.</p>
<p>Gladwell explains that our snap judgments are very powerful and surprisingly accurate &#8211; often more accurate than a reasoned decision. He then gets into they ways our subconscious can get it wrong, and the danger of acting on snap judgments of the wrong kind.</p>
<p>This was a very satisfying read. A lot of research has gone into the book, and it is presented in a compelling way which interweaves talk about different studies to get the point across most effectively. Whatever profession you&#8217;re in, this book has the potential to change your way of thinking about your work, and to get you using a better combination of reason and instinct.</p>
<p>This book relates very directly to my AI research. I believe that any AI system operating in a complex environment, being that it would have limited computing power, would need a subsystem which filtered the incoming sensations (data), essentially blanking out certain information. Only in this way could the system keep up with processing the data as it came in. I have wondered if the loss of such information would be damning to the systems ability to make good decisions. But I feel the conclusions put forward in this book give hope to the possibility that it would not.</p>
<p>This book also made me think about the vast difference, and occasional similarities, between conscious and subconscious thought. Currently the most successful AI tackles problems which humans would apply conscious thought to, like diagnosing a disease or playing chess. AI has had less success with problems humans use subconscious thought to solve, like identifying an object or walking across a room. The gap between the two areas is vast, with chess AI performing at super-human level and the most expensive mars explorer having less intelligence than an insect. But, though vastly different, the two areas also seem to have something in common.</p>
<p>In the book, Gladwell talks about an algorithm devised by a doctor for triaging patients complaining of chest pain. Just as I thought he was about to conclude that no simple algorithm could take the place of a subjective examination by a nurse, he concluded the exact opposite: that the algorithm could outperform the nurses even though it took only a handful of factors into account. It turns out that the intuition of the nurses was not required, and that (by analysing years&#8217; of data) their entire decision making process could be distilled into a simple algorithm that takes four true or false inputs and produces an output of &#8220;high-risk&#8221;, &#8220;medium-risk&#8221; or &#8220;low-risk&#8221;.</p>
<p>We usually think of instinctive activities like walking and seeing as involving a very fast flow of incoming data (compared with conscious thoughts which deals with a few elements at a time). But I think the story about this algorithm reiterates that we don&#8217;t need most of this data and that we are best to carefully throw away the irrelevant information and let only the relevant information reach the &#8220;decision making machine&#8221;. This makes subconscious tasks seem a lot more like conscious ones.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.emergentcomputing.com/blog/2009-11-26/blink-malcolm-gladwell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

