<?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>Manfredas Zabarauskas&#039; Blog &#187; Development</title>
	<atom:link href="http://blog.zabarauskas.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zabarauskas.com</link>
	<description>We are what we repeatedly do; excellence, then, is not an act but a habit. -- Aristotle</description>
	<lastBuildDate>Fri, 04 Jun 2010 12:26:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Conway&#8217;s Game of Life</title>
		<link>http://blog.zabarauskas.com/conways-game-of-life/</link>
		<comments>http://blog.zabarauskas.com/conways-game-of-life/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 11:20:34 +0000</pubDate>
		<dc:creator>Manfredas Zabarauskas</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[conway]]></category>
		<category><![CDATA[game of life]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.zabarauskas.com/?p=454</guid>
		<description><![CDATA[// 
Description
In 1970s John Horton Conway (British mathematician and University of Cambridge graduate) opened a whole new field of mathematical research by publishing a revolutionary paper on the cellular automaton called the Game of Life. Suffice it to say that the game which he has described with four simple rules has the power of a [...]]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript">// <![CDATA[
 function show_applet() { var html_element, body_element, p_element, text_node; html_element = document.documentElement; body_element = html_element.lastChild; applet_element = document.createElement("applet"); text_node = document.createTextNode("Cannot start the applet! Please install the Java Runtime Environment."); applet_element.appendChild(text_node); applet_element.setAttribute("code", "uk.ac.cam.mz297.tick6star.GuiLifeApplet"); applet_element.setAttribute("archive", "http://www.zabarauskas.com/downloads/Game%20of%20Life/GameOfLife.jar"); applet_element.setAttribute("height", "0"); applet_element.setAttribute("width", "0"); body_element.appendChild(applet_element); }
// ]]&gt;</script></p>
<h3>Description</h3>
<p>In 1970s <a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Horton Conway</a> (British mathematician and University of Cambridge graduate) opened a whole new field of mathematical research by publishing a revolutionary paper on the <a href="http://en.wikipedia.org/wiki/Cellular_automaton">cellular automaton</a> called the <em>Game of Life</em>. Suffice it to say that the game which he has described with four simple rules has the power of a <a href="http://en.wikipedia.org/wiki/Universal_Turing_machine">universal Turing machine</a>, i.e. anything that can be computed algorithmically can be computed within Conway&#8217;s Game of Life (outlines of a proof for given by Berlekamp et al; implemented by Chapman as a universal register machine within the Game of Life in 2002).<br />
<small><div class="wp-caption alignright" style="width: 81px"><a href="javascript:show_applet();"><img title="Launch the Game of Life..." src="http://blog.zabarauskas.com/img/gol_thumb.jpg" alt="Launch the Game of Life..." width="71" height="71" /></a><p class="wp-caption-text">Glider in the Game of Life</p></div></small><br />
The Game of Life is a zero-player game, i.e. the player interacts only by creating an initial configuration on a two-dimensional grid of square cells and then observing how it evolves. Every new generation of cells (which can be either live or dead) is a pure function of the previous generation and is described by this set of rules:</p>
<ol>
<li>Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.</li>
<li>Any live cell with more than three live neighbours dies, as if by overcrowding.</li>
<li>Any live cell with two or three live neighbours lives on to the next generation.</li>
<li>Any dead cell with exactly three live neighbours becomes a live cell.</li>
</ol>
<p>For more information, patterns and current news about the research involving Game of Life check out the brilliant <a href="http://conwaylife.com/wiki/index.php?title=Main_Page">LifeWiki at conwaylife.com</a>.<br />
&nbsp;</p>
<h3>Implementation</h3>
<p>The following applet visualising the Game of Life has been developed as part of the coursework for Object-Oriented Programming at the University of Cambridge, all code was written and compiled in Sun&#8217;s Java SE 1.6. </p>
<p>Click on any of the screenshots or the button below to launch the Game of Life (and if nothing shows up, make sure that you have the <a href="http://www.java.com/en/download/index.jsp">Java Runtime Environment (JRE)</a> installed).</p>
<form name="gol" action="javascript:show_applet()" method="get">
<input type="submit" name="sub_button" onClick="this.disabled=true; this.value='The Game of Life is loading, please wait...';" style="width: 600px;" value="Launch the Game of Life!" width="600">
</form>
<p><small><div class="wp-caption alignleft" style="width: 610px"><a href="javascript:show_applet();"><img title="Spacefiller in the Game of Life" src="http://blog.zabarauskas.com/img/gol.jpg" alt="Game of Life Implementation by Manfredas Zabarauskas" width="600" height="419" /></a><p class="wp-caption-text">Spacefiller (Game of Life applet)</p></div></small><br />
<span id="more-454"></span><br />
<small><div class="wp-caption alignleft" style="width: 610px"><a href="javascript:show_applet();"><img title="Game of Life Implementation by Manfredas Zabarauskas" src="http://blog.zabarauskas.com/img/gol2.jpg" alt="Traffic circle in the Game of Life" width="600" height="419" /></a><p class="wp-caption-text">Traffic circle (Game of Life applet)</p></div></small></p>
<p><small><div class="wp-caption alignleft" style="width: 610px"><a href="javascript:show_applet();"><img title="Game of Life intial pattern editor" src="http://blog.zabarauskas.com/img/gol3.jpg" alt="Game of Life Implementation by Manfredas Zabarauskas" width="600" height="419" /></a><p class="wp-caption-text">Pattern editor (Game of Life applet)</p></div></small><br />
&nbsp;</p>
<h3>References</h3>
<p>1. Berlekamp, E. R.; Conway, J. H.; and Guy, R. K. &#8220;What Is Life?&#8221; Ch. 25 in Winning Ways for Your Mathematical Plays, Vol. 2: Games in Particular. London: Academic Press, 1982.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zabarauskas.com/conways-game-of-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It Literally Pays Off to Do Homework in Cambridge</title>
		<link>http://blog.zabarauskas.com/it-literally-pays-off-to-do-homework-in-cambridge/</link>
		<comments>http://blog.zabarauskas.com/it-literally-pays-off-to-do-homework-in-cambridge/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 21:18:07 +0000</pubDate>
		<dc:creator>Manfredas Zabarauskas</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[cambridge university]]></category>
		<category><![CDATA[mips]]></category>
		<category><![CDATA[prize]]></category>
		<category><![CDATA[sort]]></category>

		<guid isPermaLink="false">http://blog.zabarauskas.com/?p=377</guid>
		<description><![CDATA[
&#160;
45 minutes, 28 MIPS instructions and £25.
Computer Science FTW.
&#160;
# Copyright Manfredas Zabarauskas, 2009.
# MIPS routine that reads an array of ten integers
# and prints the sorted array to console.
.text
main:   sub $t7, $sp, 40
l_read: li $v0, 5
        syscall
        sw $v0, [...]]]></description>
			<content:encoded><![CDATA[<p><small><div class="wp-caption alignleft" style="width: 590px"><img title="Well done! - joint shortest traditional (and practical :-) sort for the OS1a prize tick." src="http://blog.zabarauskas.com/img/sort.jpg" alt="Well done! - joint shortest traditional (and practical :-) sort for the OS1a prize tick." width="580" height="258" /><p class="wp-caption-text">&quot;Well done! - joint shortest traditional (and practical :<b></b>-) sort for the OS1a prize tick&quot;. Cambridge, 2009.</p></div></small></p>
<div style="clear: both;">&nbsp;<br />
45 minutes, 28 MIPS instructions and £25.<br />
Computer Science FTW.<br />
&nbsp;</div>
<pre># Copyright Manfredas Zabarauskas, 2009.
# MIPS routine that reads an array of ten integers
# and prints the sorted array to console.
.text
main:   sub $t7, $sp, 40
l_read: li $v0, 5
        syscall
        sw $v0, 0($t7)
        add $t7, $t7, 4
        bne $t7, $sp, l_read
l_out:  sub $t8, $sp, 36
        sub $t7, 40
l_inn:  add $t8, $t8, 4
        lw $t2, -8($t8)
        lw $t3, -4($t8)
        ble $t2, $t3, no_swp
        sw $t2, -4($t8)
        sw $t3, -8($t8)
        move $t7, $sp
no_swp: bne $t8, $sp, l_inn
        beq $t7, $sp, l_out
l_prnt: li $v0, 11
        li $a0, 10
        syscall
        li $v0, 1
        lw $a0, 0($t7)
        syscall
        add $t7, $t7, 4
        bne $t7, $sp, l_prnt
        li $v0, 10
        syscall
</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zabarauskas.com/it-literally-pays-off-to-do-homework-in-cambridge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eigenfaces Tutorial</title>
		<link>http://blog.zabarauskas.com/eigenfaces-tutorial/</link>
		<comments>http://blog.zabarauskas.com/eigenfaces-tutorial/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 16:43:22 +0000</pubDate>
		<dc:creator>Manfredas Zabarauskas</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[eigenface]]></category>
		<category><![CDATA[eigenfaces]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.zabarauskas.com/?p=286</guid>
		<description><![CDATA[The main purpose behind writing this tutorial was to provide a more detailed set of instructions for someone who is trying to implement an eigenface based face detection or recognition systems. It is assumed that the reader is familiar (at least to some extent) with the eigenface technique as described in the original M. Turk [...]]]></description>
			<content:encoded><![CDATA[<p><i>The main purpose behind writing this tutorial was to provide a more detailed set of instructions for someone who is trying to implement an eigenface based face detection or recognition systems. It is assumed that the reader is familiar (at least to some extent) with the eigenface technique as described in the original M. Turk and A. Pentland papers (see &#8220;References&#8221; for more details). </i></p>
<h3>Introduction</h3>
<p>The idea behind eigenfaces is similar (to a certain extent) to the one behind the periodic signal representation as a sum of simple oscillating functions in a <a href="http://en.wikipedia.org/wiki/Fourier_series" target="_blank">Fourier decomposition</a>. The technique described in this tutorial, as well as in the original papers, also aims to represent a face as a linear composition of the base images (called the eigenfaces).</p>
<p>The recognition/detection process consists of initialization, during which the eigenface basis is established and face classification, during which a new image is projected onto the &#8220;face space&#8221; and the resulting image is categorized by the weight patterns as a known-face, an unknown-face or a non-face image.</p>
<h3>Demonstration</h3>
<p>To <a href="http://www.zabarauskas.com/downloads/Eigenfaces.zip">download</a> the software shown in video for 32-bit x86 platform, click <a href="http://www.zabarauskas.com/downloads/Eigenfaces.zip">here</a>. It was compiled using Microsoft Visual C++ 2008 and uses <a href="http://www.gnu.org/software/gsl/" target="_blank">GSL</a> for Windows.</p>
<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/YWRiF7FAuKE&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/YWRiF7FAuKE&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<h3>Establishing the Eigenface Basis</h3>
<p>First of all, we have to obtain a training set of <img src="http://blog.zabarauskas.com/wp-content/cache/tex_69691c7bdcc3ce6d5d8a1361f22d04ac.png" align="absmiddle" class="tex" alt="M" /> grayscale face images  <img src="http://blog.zabarauskas.com/wp-content/cache/tex_89a934fc176ed09fa49252cf10f8957c.png" align="absmiddle" class="tex" alt="I_1, I_2, ..., I_M" />. They should be:</p>
<ol>
<li> face-wise aligned, with eyes in the same level and faces of the same scale,</li>
<li> normalized so that every pixel has a value between 0 and 255 (i.e. one byte per pixel encoding), and</li>
<li>of the same <img src="http://blog.zabarauskas.com/wp-content/cache/tex_cd94a3641bb6ba72c90dd0d8f4d2e199.png" align="absmiddle" class="tex" alt="N \times N" /> size.</li>
</ol>
<p>So just capturing everything formally, we want to obtain a set:</p>
<p><center><img src="http://blog.zabarauskas.com/wp-content/cache/tex_d1b806dc65ca4bcb76dfc062ae060be5.png" align="absmiddle" class="tex" alt="\{ I_1, I_2, ..., I_M \}" />, where <img src="http://blog.zabarauskas.com/wp-content/cache/tex_f08f417ca9693bf48ed20d5708b6f9c7.png" align="absmiddle" class="tex" alt="I_k = \begin{bmatrix} p_{1,1}^k &amp; p_{1,2}^k &amp; ... &amp; p_{1,N}^k \\ p_{2,1}^k &amp; p_{2,2}^k &amp; ... &amp; p_{2,N}^k \\ \vdots \\ p_{N,1}^k &amp; p_{N,2}^k &amp; ... &amp; p_{N,N}^k \end{bmatrix}_{N \times N}" /> and <img src="http://blog.zabarauskas.com/wp-content/cache/tex_f025d7635bbe720a4b66adccea31ddd3.png" align="absmiddle" class="tex" alt="0 \leq p_{i,j}^k \leq 255." /></center></p>
<p>Once we have that, we should change the representation of a face image <img src="http://blog.zabarauskas.com/wp-content/cache/tex_bc6d0de85e84afdaf232791d9aafa398.png" align="absmiddle" class="tex" alt="I_k" /> from a <img src="http://blog.zabarauskas.com/wp-content/cache/tex_cd94a3641bb6ba72c90dd0d8f4d2e199.png" align="absmiddle" class="tex" alt="N \times N" /> matrix, to a <img src="http://blog.zabarauskas.com/wp-content/cache/tex_067beafbfe4c5e47df74c436264c5493.png" align="absmiddle" class="tex" alt="\Gamma_k" /> point in <img src="http://blog.zabarauskas.com/wp-content/cache/tex_ec4ad94a9be87109217fcd9d10ebcd52.png" align="absmiddle" class="tex" alt="N^2" />-dimensional space. Now here is how we do it: <span id="more-286"></span>we concatenate all the rows of the matrix <img src="http://blog.zabarauskas.com/wp-content/cache/tex_bc6d0de85e84afdaf232791d9aafa398.png" align="absmiddle" class="tex" alt="I_k" /> into one big vector of dimension <img src="http://blog.zabarauskas.com/wp-content/cache/tex_ec4ad94a9be87109217fcd9d10ebcd52.png" align="absmiddle" class="tex" alt="N^2" />. Can it get any more simpler than that?</p>
<p>This is how it looks formally:</p>
<p><center><img src="http://blog.zabarauskas.com/wp-content/cache/tex_39c24b1755e3c06f42b365c62a282ccb.png" align="absmiddle" class="tex" alt="\Gamma_k = \begin{bmatrix} p_{1,1}^k \\ p_{1,2}^k \\ \vdots \\ p_{1,N}^k \\ p_{2,1}^k \\ p_{2,2}^k \\ \vdots \\ p_{2,N}^k \\ \vdots \\ p_{N,1}^k \\ p_{N,2}^k \\ \vdots \\ p_{N,N}^k \end{bmatrix}_{N \times 1}" />, where  <img src="http://blog.zabarauskas.com/wp-content/cache/tex_0d577846ec877dc57a43942af2f5919f.png" align="absmiddle" class="tex" alt="k = 1, ..., M" /> and <img src="http://blog.zabarauskas.com/wp-content/cache/tex_7810a75f664cc78102b11f42972062e3.png" align="absmiddle" class="tex" alt="p_{i,j}^k \in I_k" /></center></p>
<p>Since we are much more interested in the characteristic features of those faces, let&#8217;s subtract everything what is common between them, i.e. the <strong>average face</strong>.<br />
The average face of the previous mean-adjusted images can be defined as <img src="http://blog.zabarauskas.com/wp-content/cache/tex_2ee5b10fa3153fc3dfe076869222c7d8.png" align="absmiddle" class="tex" alt="\Psi = {{1}\over{M}} \sum_{i=1}^{M} \Gamma_i" />, then each face differs from the average by the vector <img src="http://blog.zabarauskas.com/wp-content/cache/tex_e6b4043d66e1baf4d6839f0bc51c4107.png" align="absmiddle" class="tex" alt="\Phi_i = \Gamma_i - \Psi" />.</p>
<p>Now we should attempt to find a set of orthonormal vectors which best describe the distribution of our data. The necessary steps in this at a first glance daunting task would seem to be:</p>
<ol>
<li>Obtain a <a href="http://en.wikipedia.org/wiki/Covariance_matrix" target="_blank">covariance matrix</a><br />
<img src="http://blog.zabarauskas.com/wp-content/cache/tex_cc75d8834aff897124eaf1ef8e60fa1d.png" align="absmiddle" class="tex" alt="C = {{1}\over{M}} \sum_{i=1}^{M} \Phi_i \Phi_i^T = AA^T" />, where <img src="http://blog.zabarauskas.com/wp-content/cache/tex_95e05c29c4d2ed0d862144b734d1200b.png" align="absmiddle" class="tex" alt="A = \left[ \Phi_1 \Phi_2 ... \Phi_M \right]" />.</li>
<li>Find the eigenvectors <img src="http://blog.zabarauskas.com/wp-content/cache/tex_c96b59279af8b06034c43473c16ab01d.png" align="absmiddle" class="tex" alt="u_k" /> and eigenvalues <img src="http://blog.zabarauskas.com/wp-content/cache/tex_8ff9c1b69b4201fec1b23780372d5cdf.png" align="absmiddle" class="tex" alt="\lambda_k" /> of <img src="http://blog.zabarauskas.com/wp-content/cache/tex_0d61f8370cad1d412f80b84d143e1257.png" align="absmiddle" class="tex" alt="C" />.</li>
</ol>
<p>However, note two things here: <img src="http://blog.zabarauskas.com/wp-content/cache/tex_7fc56270e7a70fa81a5935b72eacbe29.png" align="absmiddle" class="tex" alt="A" /> is of the size <img src="http://blog.zabarauskas.com/wp-content/cache/tex_f538d8e85c63fd7582add2d8672562b2.png" align="absmiddle" class="tex" alt="N^2 \times M" /> and hence the matrix <img src="http://blog.zabarauskas.com/wp-content/cache/tex_0d61f8370cad1d412f80b84d143e1257.png" align="absmiddle" class="tex" alt="C" /> is of the size <img src="http://blog.zabarauskas.com/wp-content/cache/tex_72af584bfe05bf85e4d69e506a3b4675.png" align="absmiddle" class="tex" alt="N^2 \times N^2" />. To put things into perspective &#8211; if your image size is <img src="http://blog.zabarauskas.com/wp-content/cache/tex_7967136cf815c43bf428b85d8f990a4b.png" align="absmiddle" class="tex" alt="128 \times 128" />, then the size of the matrix <img src="http://blog.zabarauskas.com/wp-content/cache/tex_0d61f8370cad1d412f80b84d143e1257.png" align="absmiddle" class="tex" alt="C" /> would be <img src="http://blog.zabarauskas.com/wp-content/cache/tex_782e66b36998bb9fadf2b50c5ae2d775.png" align="absmiddle" class="tex" alt="16384 \times 16384" />. Determining eigenvectors and eigenvalues for a matrix this size would be an absolutely intractable task!</p>
<p>So how do we go about it? A simple mathematical trick: first let&#8217;s calculate the inner product matrix <img src="http://blog.zabarauskas.com/wp-content/cache/tex_9779c443501e95b557b4661bba870560.png" align="absmiddle" class="tex" alt="L = A^T A" />, of the size <img src="http://blog.zabarauskas.com/wp-content/cache/tex_93ff99aa85b95038b1d2748d250caf4d.png" align="absmiddle" class="tex" alt="M \times M" />. Then let&#8217;s find it&#8217;s eigenvectors <img src="http://blog.zabarauskas.com/wp-content/cache/tex_4f430d84ae7eb54df6bfe4a906af6638.png" align="absmiddle" class="tex" alt="v_i, i = 1, ..., M" /> of <img src="http://blog.zabarauskas.com/wp-content/cache/tex_d20caec3b48a1eef164cb4ca81ba2587.png" align="absmiddle" class="tex" alt="L" /> (of the <img src="http://blog.zabarauskas.com/wp-content/cache/tex_69691c7bdcc3ce6d5d8a1361f22d04ac.png" align="absmiddle" class="tex" alt="M" />-th dimension). Now observe, that if <img src="http://blog.zabarauskas.com/wp-content/cache/tex_d3c618cc46f1a82db89606012cd75043.png" align="absmiddle" class="tex" alt="L v_i = \lambda_i v_i" />, then</p>
<p><center><img src="http://blog.zabarauskas.com/wp-content/cache/tex_c1882247ef593606f0485b400c87bcf4.png" align="absmiddle" class="tex" alt="\begin{array} {rcl} A L v_i &amp;=&amp; \lambda_i A v_i \Rightarrow \\ A A^T A v_i &amp;=&amp; \lambda_i A v_i \Rightarrow \\ C A v_i &amp;=&amp; \lambda_i A v_i \end{array}" />,</center></p>
<p>and hence <img src="http://blog.zabarauskas.com/wp-content/cache/tex_ce45a4315a74df24a9d46ff33119fd69.png" align="absmiddle" class="tex" alt="u_i = A v_i" /> and <img src="http://blog.zabarauskas.com/wp-content/cache/tex_5614371f803f8a78b18b27391549a107.png" align="absmiddle" class="tex" alt="\lambda_i" /> are respectively the <img src="http://blog.zabarauskas.com/wp-content/cache/tex_69691c7bdcc3ce6d5d8a1361f22d04ac.png" align="absmiddle" class="tex" alt="M" /> eigenvectors (of <img src="http://blog.zabarauskas.com/wp-content/cache/tex_ec4ad94a9be87109217fcd9d10ebcd52.png" align="absmiddle" class="tex" alt="N^2" />-th dimension) and eigenvalues of <img src="http://blog.zabarauskas.com/wp-content/cache/tex_0d61f8370cad1d412f80b84d143e1257.png" align="absmiddle" class="tex" alt="C" />. Make sure to normalize <img src="http://blog.zabarauskas.com/wp-content/cache/tex_eb00a04135562ae6f74786f084f54327.png" align="absmiddle" class="tex" alt="u_i" />, such that <img src="http://blog.zabarauskas.com/wp-content/cache/tex_11ab4920d9be82d30e3c4c1fa3fbea30.png" align="absmiddle" class="tex" alt="\left\| u_i \right\| = 1" />.</p>
<p>We will call these eigenvectors <img src="http://blog.zabarauskas.com/wp-content/cache/tex_eb00a04135562ae6f74786f084f54327.png" align="absmiddle" class="tex" alt="u_i" /> the <strong>eigenfaces</strong>. Scale them to 255 and render on the screen, to see why.</p>
<p>It turns out that quite a few eigenfaces with the smallest eigenvalues can be discarded, so leave only the <img src="http://blog.zabarauskas.com/wp-content/cache/tex_3fe4ce6c661e7015ff4e5c3054260ab8.png" align="absmiddle" class="tex" alt="R \leq M" /> ones with the largest eigenvalues (i.e. only the ones making the greatest contribution to the variance of the original image set) and chuck them into the matrix <img src="http://blog.zabarauskas.com/wp-content/cache/tex_1f1a76aa21ad1b9ba4e2bf48d2879611.png" align="absmiddle" class="tex" alt="U = \left[ u_1 u_2 ... u_R \right]_{N \times R}" /></p>
<p>After you have done that &#8211; congratulations! We won&#8217;t need anything else, but the matrix <img src="http://blog.zabarauskas.com/wp-content/cache/tex_4c614360da93c0a041b22e537de151eb.png" align="absmiddle" class="tex" alt="U" /> for the next steps &#8211; face detection and classification.</p>
<h3>Face Classification Using Eigenfaces</h3>
<p>Once the eigenfaces are created, a new face image <img src="http://blog.zabarauskas.com/wp-content/cache/tex_07710b5c43702a8bb7b9104eacc6ba71.png" align="absmiddle" class="tex" alt="\Gamma" /> can be transformed into it&#8217;s eigenface components by a simple operation:</p>
<p><center><img src="http://blog.zabarauskas.com/wp-content/cache/tex_1358890c107de0ec0ab7637e1d6a01a4.png" align="absmiddle" class="tex" alt="\Omega = U^T (\Gamma - \Psi) =  \begin{bmatrix} \omega_1 \\ \omega_2 \\ \vdots \\ \omega_R \end{bmatrix}_{R \times 1}" />.</center></p>
<p>The weights <img src="http://blog.zabarauskas.com/wp-content/cache/tex_eb948b1c50831e30722aa00670819bc4.png" align="absmiddle" class="tex" alt="\omega_i \in \Omega" /> describe the contribution of each eigenface in representing the input face image. We can use this vector for <strong>face recognition</strong> by finding the smallest <a href="http://en.wikipedia.org/wiki/Euclidean_distance">Euclidean distance</a> <img src="http://blog.zabarauskas.com/wp-content/cache/tex_c64243adb5cde4ced701f126265899d5.png" align="absmiddle" class="tex" alt="\epsilon_{rec}" /> between the input face and training faces weight vectors, i.e. by calculating <img src="http://blog.zabarauskas.com/wp-content/cache/tex_3bb3e0a287a6f7f61935fcea0b7a7b94.png" align="absmiddle" class="tex" alt="\epsilon_{rec} = min \left\| \Omega - \Omega_i \right\|" />. If <img src="http://blog.zabarauskas.com/wp-content/cache/tex_8b19a3eb9d689b6f139f6cfb61c9d98a.png" align="absmiddle" class="tex" alt="\epsilon_{rec} &lt; \Theta_{rec}" />, where <img src="http://blog.zabarauskas.com/wp-content/cache/tex_8d7bfd80a860b12ebb430bc051573049.png" align="absmiddle" class="tex" alt="\Theta_{rec}" /> is a treshold chosen heuristically, then we can say that the input image is recognized as the image with which it gives the lowest score.</p>
<p>The weights vector can also be used for an unknown <strong>face detection</strong>, exploiting the fact that the images of faces do not change radically when projected into the face space, while the projection of non-face images appear quite different. To do so, we can calculate the distance <img src="http://blog.zabarauskas.com/wp-content/cache/tex_2283e0ad240100f5a6953e6efd2cc06f.png" align="absmiddle" class="tex" alt="\epsilon_{det}" /> from the mean-adjusted input image <img src="http://blog.zabarauskas.com/wp-content/cache/tex_f1833047ad4f5ada395df8a2903b641c.png" align="absmiddle" class="tex" alt="\Phi = \Gamma - \Psi" /> and its projection onto face space <img src="http://blog.zabarauskas.com/wp-content/cache/tex_79041fdea0a0f2e4a7c83d2d9c63b38a.png" align="absmiddle" class="tex" alt="\Phi_f = \sum_{i=1}^R \omega_i u_i " />, i.e. <img src="http://blog.zabarauskas.com/wp-content/cache/tex_d3bfb48a60d5ec7f9ad1a45312aeb636.png" align="absmiddle" class="tex" alt="\epsilon_{det} = \left\| \Phi - \Phi_f \right\|" />. Again, if <img src="http://blog.zabarauskas.com/wp-content/cache/tex_484af1868e0f0a277c80f62f06d6b4b2.png" align="absmiddle" class="tex" alt="\epsilon_{det} &lt; \Theta_{det}" /> for some treshold <img src="http://blog.zabarauskas.com/wp-content/cache/tex_94ade02ef424d4e009df3fe9720e1992.png" align="absmiddle" class="tex" alt="\Theta_{det}" /> (also obtained heuristically, for example, by observing <img src="http://blog.zabarauskas.com/wp-content/cache/tex_2283e0ad240100f5a6953e6efd2cc06f.png" align="absmiddle" class="tex" alt="\epsilon_{det}" /> for an input set consisting only of face images and a set of non-face images) we can conclude that the input image is a face.</p>
<h3>References</h3>
<p>1. Face Recognition Using Eigenfaces, Matthew A. Turk and Alex P. Pentland, MIT Vision and Modeling Lab, CVPR ‘91.<br />
2. Eigenfaces for Recognition, Matthew A. Turk and Alex P. Pentland, Journal of Cognitive Neuroscience ‘91.<br />
3. <a href="http://www.scholarpedia.org/article/Eigenfaces" target="_blank">Eigenfaces</a>. Sheng Zhang and Matthew Turk (2008), Scholarpedia, 3(9):4244. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zabarauskas.com/eigenfaces-tutorial/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>SMRP6400/SMDK64X0 IIC synchronization problems</title>
		<link>http://blog.zabarauskas.com/smrp6400smdk6410-iic-synchronization-problems/</link>
		<comments>http://blog.zabarauskas.com/smrp6400smdk6410-iic-synchronization-problems/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 21:45:12 +0000</pubDate>
		<dc:creator>Manfredas Zabarauskas</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drivers]]></category>
		<category><![CDATA[iic]]></category>
		<category><![CDATA[samsung]]></category>
		<category><![CDATA[smdk6400]]></category>
		<category><![CDATA[smdk6410]]></category>
		<category><![CDATA[smrp6400]]></category>
		<category><![CDATA[windows ce]]></category>

		<guid isPermaLink="false">http://blog.zabarauskas.com/?p=116</guid>
		<description><![CDATA[
Since last week we have spent quite some time debugging Samsung SMRP6400/SMDK64X0 IIC drivers, I thought I might share with one particular example here. It is both a good showcase of the hardware/software synchronization issues and since the bugs are in the latest version of the drivers shipped together with the development platforms, it might [...]]]></description>
			<content:encoded><![CDATA[<p><small><div class="wp-caption alignright" style="width: 191px"><img title="Debugging Samsung SMRP6400" src="http://blog.zabarauskas.com/img/100_0139_small.jpg" alt="Debugging Samsung SMRP6400" width="181" height="150" /><p class="wp-caption-text">Debugging Samsung SMRP6400</p></div></small></p>
<p>Since last week we have spent quite some time debugging Samsung SMRP6400/SMDK64X0 IIC drivers, I thought I might share with one particular example here. It is both a good showcase of the hardware/software synchronization issues and since the bugs are in the latest version of the drivers shipped together with the development platforms, it might save someone from additional headaches.</p>
<p>So, while working on the drivers for IIC one of our automated tests to make sure that IIC still works was to write some data on the bus, do an immediate read-back and verify that both data written and read back matches; something similar to this:</p>
<pre>UCHAR outData[3] = { REGISTER, DATA_BYTE_1, DATA_BYTE2 };
UCHAR inData[2] = { 0, 0 };

IIC_Write(SLAVE_ADDRESS, outData, 3);
IIC_Read(SLAVE_ADDRESS, REGISTER, inData, 2);

if ((inData[0] != DATA_BYTE_1) || (inData[1] != DATA_BYTE_2))
{
    DEBUGMSG(ERROR_MSG,
             (TEXT("Immediate write/read data mismatch: data sent [0x%X " \
                   "0x%X] differs from the data received [0x%X, 0x%X]."),
                   DATA_BYTE_1, DATA_BYTE_2, inData[0], inData[1]));
}</pre>
<p>However, after we added some IIC read calls from another hardware driver it started spitting fire throwing the following error message:</p>
<pre>Immediate write/read data mismatch: data sent <strong>[0xCA, 0xFE]</strong>
differs from the data received <strong>[0xCA, 0xFE]</strong>.</pre>
<p>Now this clearly meant we had a serious problem: the error message was saying that the data does not match, which obviously was not the case as shown by the message text!</p>
<p>Since we were pretty confident about our side of things, as well as the readings from the scope, it seemed like a good time to start looking at the Samsung IIC drivers (and especially s3c64X0_iic_lib.cpp). The driver structure there is pretty straightforward: the first read/write byte on the bus triggers the hardware IRQ, which is mapped to SysIntr triggering a transfer event; then any subsequent call to a read/write function blocks waiting for a <code>transfer-done</code> event, which is triggered when the last byte is read/written in the IST.</p>
<p>Everything looks sane up to the point where a <code>transfer-done</code> event is signalled from the IST (pseudocode, not the original code below, due to the legal issues):</p>
<pre>static HANDLE ghTransferEvent;
static HANDLE ghTransferDone;
static DWORD IICSysIntr;

...

static DWORD IST(LPVOID lpContext)
{
    BOOL bTransferDone = FALSE;

    while (TRUE) {
        WaitForSingleObject(ghTransferEvent, INFINITE);

        switch (IIC_BUS_STATUS) {
            case MASTER_RECEIVE:
                // receive bytes and store them in the buffer
            break;

            case MASTER_TRANSMIT:
                // transmit bytes from the buffer in memory
                if (LAST_BYTE) bTransferDone = TRUE;
            break;

            InterruptDone(IICSysIntr);

            if (bTransferDone) {
                SetEvent(ghTransferDone);
            }
        }
    }
}</pre>
<p>Two major problems with this code are:</p>
<ol>
<li>The <code>bTransferDone</code> variable is never set from the IIC read, and hence the <code>transfer-done</code> event for bus reads is never triggered,</li>
<li>After the <code>bTransferDone</code> is set from the IIC write, it is never reset, hence the <code>transfer-done</code> event is triggered after reading/writing single byte on the bus in all subsequent transactions.</li>
</ol>
<p>That explains the initial test case failure: during the write/immediate read data comparison the data arrives exactly between the <code>if</code> statement and the following printout, thus triggering the error message, but printing the correct data to the output due to the early signal of the event.</p>
<p>The way to solve this is also straightforward: make sure that the <code>bTransferDone</code> variable is cleared after the <code>transfer-done</code> event is triggered, and make sure that master-receive mode sets the <code>bTransferDone</code> variable after reading the last byte of the transaction from the IIC bus.</p>
<p>In pseudocode it would look similar to:</p>
<pre>static DWORD IST(LPVOID context)
{
    BOOL bTransferDone = FALSE;

    while (TRUE) {
        WaitForSingleObject(ghTransferEvent, INFINITE);

        switch (IIC_BUS_STATUS) {
            case MASTER_RECEIVE:
                // receive bytes and store them in the buffer
                if (LAST_BYTE) bTransferDone = TRUE;
            break;

            case MASTER_TRANSMIT:
                // transmit bytes from the buffer in memory
                if (LAST_BYTE) bTransferDone = TRUE;
            break;

            InterruptDone(IICSysIntr);

            if (bTransferDone) {
                bTransferDone = FALSE;
                SetEvent(ghTransferDone);
            }
        }
    }
}</pre>
<p>The lesson of the day (quoting my colleague) is: &#8220;<em>The first rule about multithreading &#8211; you&#8217;re wrong</em>&#8220;.</p>
<div class="wp-caption alignleft" style="width: 652px"><img title="At work. Wolfson Microelectronics PLC, 2009" src="http://blog.zabarauskas.com/img/100_0138_small.jpg" alt="At work. Wolfson Microelectronics PLC, 2009" width="642" height="496" /><p class="wp-caption-text">At work. Wolfson Microelectronics PLC, 2009</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.zabarauskas.com/smrp6400smdk6410-iic-synchronization-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://analytics.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://analytics.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->
