<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-14061308</id><updated>2012-02-16T11:53:23.485-03:00</updated><category term='Image Processing'/><category term='Scala'/><category term='Compilers'/><category term='Miscellaneous'/><category term='Performance'/><category term='Microposts'/><category term='Java'/><category term='Quality'/><title type='text'>Codng.com</title><subtitle type='html'>Trying to change the world one post at a time</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.codng.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.codng.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-14061308.post-4755162040084511111</id><published>2011-09-07T18:28:00.001-03:00</published><updated>2011-09-08T11:03:29.335-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Parallelism &amp; Performance: Why O-notation matters</title><content type='html'>&lt;blockquote&gt;&lt;b&gt;UPDATE:&lt;/b&gt; There was a bug in the way the suffix map was built in the original post that &lt;a href="http://www.reddit.com/user/lolplz"&gt;lolplz&lt;/a&gt; found. I updated this post with that bug fixed, however, the content of the post has not changed significantly.&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;Aleksandar Prokopec presented a &lt;a href="http://days2011.scala-lang.org/node/138/272"&gt;very interesting talk about Scala Parallel Collections&lt;/a&gt; in &lt;a href="http://days2011.scala-lang.org/"&gt;Scala Days 2011&lt;/a&gt;. I saw it today and gave me some food for thought,&lt;br /&gt;&lt;p&gt;He opens his talk with an intriguing code snippet:&lt;br /&gt;&lt;pre class="brush: scala"&gt;for {&lt;br /&gt;  s &amp;lt;- surnames&lt;br /&gt;  n &amp;lt;- names&lt;br /&gt;  if s endsWith n&lt;br /&gt;} yield (n , s)&lt;br /&gt;&lt;/pre&gt;What this code does, given what presumably are two sequences of strings, it builds all pairs (name, surname) where the surname ends with the name.&lt;br /&gt;&lt;p&gt;The algorithm used is very brute force, it's order is roughly O(N^2) (it's basically a &lt;a href="http://en.wikipedia.org/wiki/Cartesian_product"&gt;Cartesian Product&lt;/a&gt; being filtered). He then goes on to show that by just using parallel collections:&lt;br /&gt;&lt;pre class="brush: scala"&gt;for {&lt;br /&gt;  s &amp;lt;- surnames.par&lt;br /&gt;  n &amp;lt;- names.par&lt;br /&gt;  if s endsWith n&lt;br /&gt;} yield (n , s)&lt;br /&gt;&lt;/pre&gt;He can leverage all the cores and reduce the runtime by two or four, depending on the number of cores available in the machine where it's running. For example, the non-parallel version runs in &lt;b&gt;1040ms&lt;/b&gt;, the parallel one runs in &lt;b&gt;575ms&lt;/b&gt; with two cores, and in &lt;b&gt;305ms&lt;/b&gt; with four. Which is indeed very impressive for such a minor change.&lt;br /&gt;&lt;p&gt;What concerns me is that, no matter how many cores you add, the problem as presented is still O(N^2). It is true that many useful problems can only be speeded up by throwing more hardware at it, but most of the times, using the right data representation can yield even bigger gains.&lt;br /&gt;&lt;p&gt;If we use this problem as an example, we can build a slightly more complex implementation, but that hopefully is a lot faster. The approach I'm taking is that of building a suffix map for surnames. There are &lt;a href="http://en.wikipedia.org/wiki/Suffix_tree"&gt;more efficient data structures (memory wise)&lt;/a&gt; to do this, but for simplicity I'll use a Map:&lt;br /&gt;&lt;pre class="brush: scala"&gt;val suffixMap = collection.mutable.Map[String, List[String]]().withDefaultValue(Nil)&lt;br /&gt;for (s &amp;lt;- surnames; i &amp;lt;- 0 until s.length; suffix = s.substring(i)) &lt;br /&gt;    suffixMap(suffix) = s :: suffixMap(suffix)&lt;br /&gt;&lt;/pre&gt;Having built the prefix map, we can naively rewrite the loop to use it (instead of the Cartesian Product):&lt;br /&gt;&lt;pre class="brush: scala"&gt;for {&lt;br /&gt;  n &amp;lt;- names&lt;br /&gt;  s &amp;lt;- suffixMap(n)&lt;br /&gt;} yield (n , s)&lt;br /&gt;&lt;/pre&gt;In theory, this loop is roughly O(N) (assuming the map is a HashMap), since it now does a constant number of operations on each name it processes, rather than processing all the names for each surname (I'm ignoring the fact that the map returns lists). &lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;Note:&lt;/b&gt; The algorithmic order does not change much if we take into account the suffix map construction. Let's assume that we have S surnames and N names, the order of building the suffix map is O(S) and the order building the pairs is O(N), the total order of the algorithm is O(N+S). If we assume that N is approximately equal to S, then the order is O(N+N) which is the same than O(2N), which can be simplified to O(N).&lt;br /&gt;&lt;/blockquote&gt;So, let's see if this holds up in real life. For this I wrote the following scala script that runs a few passes of several different implementations:&lt;br /&gt;&lt;pre class="brush: scala"&gt;#!/bin/sh&lt;br /&gt;exec scala -deprecation -savecompiled &amp;quot;$0&amp;quot; &amp;quot;$@&amp;quot;&lt;br /&gt;!#&lt;br /&gt;def benchmark[T](name: String)(body: =&amp;gt;T) {&lt;br /&gt;    val start = System.currentTimeMillis()&lt;br /&gt;    val result = body&lt;br /&gt;    val end = System.currentTimeMillis()&lt;br /&gt;    println(name + &amp;quot;: &amp;quot; + (end - start))&lt;br /&gt;    result&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val surnames = (1 to 10000).map(&amp;quot;Name&amp;quot; + _)&lt;br /&gt;val names    = (1 to 10000).map(&amp;quot;Name&amp;quot; + _)&lt;br /&gt;&lt;br /&gt;val suffixMap = collection.mutable.Map[String, List[String]]().withDefaultValue(Nil)&lt;br /&gt;for (s &amp;lt;- surnames; i &amp;lt;- 0 until s.length; suffix = s.substring(i)) &lt;br /&gt;    suffixMap(suffix) = s :: suffixMap(suffix)&lt;br /&gt;&lt;br /&gt;for( i &amp;lt;- 1 to 5 ) {&lt;br /&gt;    println(&amp;quot;Run #&amp;quot; + i)&lt;br /&gt;    benchmark(&amp;quot;Brute force&amp;quot;) {&lt;br /&gt;        for {&lt;br /&gt;            s &amp;lt;- surnames&lt;br /&gt;            n &amp;lt;- names&lt;br /&gt;            if s endsWith n&lt;br /&gt;        } yield (n , s)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    benchmark(&amp;quot;Parallel&amp;quot;) {&lt;br /&gt;        for {&lt;br /&gt;            s &amp;lt;- surnames.par&lt;br /&gt;            n &amp;lt;- names.par&lt;br /&gt;            if s endsWith n&lt;br /&gt;        } yield (n , s)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    benchmark(&amp;quot;Smart&amp;quot;) {&lt;br /&gt;        val suffixMap = collection.mutable.Map[String, List[String]]().withDefaultValue(Nil)&lt;br /&gt;        for (s &amp;lt;- surnames; i &amp;lt;- 0 until s.length; suffix = s.substring(i)) &lt;br /&gt;            suffixMap(suffix) = s :: suffixMap(suffix)&lt;br /&gt;        for {&lt;br /&gt;            n &amp;lt;- names&lt;br /&gt;            s &amp;lt;- suffixMap(n)&lt;br /&gt;        } yield (n , s)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    benchmark(&amp;quot;Smart (amortized)&amp;quot;) {&lt;br /&gt;        for {&lt;br /&gt;            n &amp;lt;- names&lt;br /&gt;            s &amp;lt;- suffixMap(n)&lt;br /&gt;        } yield (n , s)&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;There are four implementations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Brute Force: the original implementation&lt;br /&gt;&lt;li&gt;Parallel: same as before, but using parallel collections.&lt;br /&gt;&lt;li&gt;Smart: Using the prefix map (and measuring the map construction)&lt;br /&gt;&lt;li&gt;Smart (amortized): same as before, but with the prefix map cost amortized.&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;&lt;h2&gt;Benchmark Results&lt;/h2&gt;Running this script in a four core machine, I get the following results: &lt;pre&gt;Run #1&lt;br /&gt;Brute force: 2158&lt;br /&gt;Parallel: 1355&lt;br /&gt;Smart: 153&lt;br /&gt;Smart (amortized): 27&lt;br /&gt;Run #2&lt;br /&gt;Brute force: 1985&lt;br /&gt;Parallel: 899&lt;br /&gt;Smart: 82&lt;br /&gt;Smart (amortized): 7&lt;br /&gt;Run #3&lt;br /&gt;Brute force: 1947&lt;br /&gt;Parallel: 716&lt;br /&gt;Smart: 69&lt;br /&gt;Smart (amortized): 5&lt;br /&gt;Run #4&lt;br /&gt;Brute force: 1932&lt;br /&gt;Parallel: 714&lt;br /&gt;Smart: 67&lt;br /&gt;Smart (amortized): 6&lt;br /&gt;Run #5&lt;br /&gt;Brute force: 1933&lt;br /&gt;Parallel: 713&lt;br /&gt;Smart: 68&lt;br /&gt;Smart (amortized): 5&lt;br /&gt;&lt;/pre&gt;As expected, the parallel version runs 3.5 times as fast as the naive one, but the implementation using the "Smart" approach runs more than &lt;b&gt;30 times faster&lt;/b&gt; than the naive one. If we were able to amortize the cost of building the suffix map, the speed-up is even more staggering, at a whooping 380 times faster (although this is not always possible)! &lt;p&gt;What we can conclude from this, paraphrasing Fred Brooks&lt;sup&gt;&lt;a href="#foot1"&gt;1&lt;/a&gt;&lt;/sup&gt;, is that regarding performance there is &lt;a href="http://en.wikipedia.org/wiki/No_Silver_Bullet"&gt;no silver bullet&lt;/a&gt;. The basics matter, maybe now they even matter more than ever. &lt;p&gt;Analyzing algorithmic order, in its most basic form (making huge approximations) is a very practical tool to solving hard performance problems. Still, the simple approach used here to optimize the problem is also parallelizable, which for a large enough problem, it might gain some speedup using parallel collections. &lt;p&gt;Don't get me wrong, I love Scala parallel collections and parallel algorithms are increasingly important, but they are by no means a magical solution that can be used for any problem (and I think Aleksandar is with me in this one).&lt;h2&gt;Footnotes&lt;/h2&gt;&lt;p id="foot1"&gt;&lt;sup&gt;1&lt;/sup&gt; misquoting is probably more accurate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-4755162040084511111?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/4755162040084511111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/09/parallelism-performance-why-o-notation.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/4755162040084511111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/4755162040084511111'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/09/parallelism-performance-why-o-notation.html' title='Parallelism &amp; Performance: Why O-notation matters'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-6853092264314736663</id><published>2011-05-17T18:06:00.000-03:00</published><updated>2011-05-17T18:06:33.929-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microposts'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>File locks in bash</title><content type='html'>For quite a while I've been looking for a portable utility that mimics &lt;a href="http://www.linuxmanpages.com/man1/lockfile.1.php"&gt;Procmail's "lockfile" &lt;/a&gt;command. I didn't need all the functionality, just for it to lock a single file and support a retry limit and sleep parameters.&lt;br /&gt;&lt;p&gt;I finally implemented one using Bash's "noclobber" option. I don't know if it will work correctly on NFS, but it should work fine on most filesystems. Hopefully it will be useful to some of you.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: bash"&gt;#!/bin/bash&lt;br /&gt;set -e&lt;br /&gt;declare SCRIPT_NAME=&amp;quot;$(basename $0)&amp;quot;&lt;br /&gt;&lt;br /&gt;function usage {&lt;br /&gt; echo &amp;quot;Usage: $SCRIPT_NAME [options] &amp;lt;lock file&amp;gt;&amp;quot;&lt;br /&gt; echo &amp;quot;Options&amp;quot;&lt;br /&gt; echo &amp;quot;       -r, --retries&amp;quot;&lt;br /&gt; echo &amp;quot;           limit the number of retries before giving up the lock.&amp;quot;&lt;br /&gt; echo &amp;quot;       -s, --sleeptime, -&amp;lt;seconds&amp;gt;&amp;quot;&lt;br /&gt; echo &amp;quot;           number of seconds between each attempt. Defaults to 8 seconds.&amp;quot;&lt;br /&gt; exit 1&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#Check that at least one argument is provided&lt;br /&gt;if [ $# -lt 1 ]; then usage; fi&lt;br /&gt;&lt;br /&gt;declare RETRIES=-1&lt;br /&gt;declare SLEEPTIME=8 #in seconds&lt;br /&gt;#Parse options&lt;br /&gt;for arg; do&lt;br /&gt; case &amp;quot;$arg&amp;quot; in&lt;br /&gt;  -r|--retries) shift; &lt;br /&gt;   if [ $# -lt 2 ]; then usage; fi; &lt;br /&gt;   RETRIES=&amp;quot;$1&amp;quot;; shift &lt;br /&gt;   echo &amp;quot;$RETRIES&amp;quot; | egrep -q &amp;#x27;^-?[0-9]+$&amp;#x27; || usage #check that it&amp;#x27;s a number&lt;br /&gt;   ;;&lt;br /&gt;  -s|--sleeptime) shift; &lt;br /&gt;   if [ $# -lt 2 ]; then usage; fi; &lt;br /&gt;   SLEEPTIME=&amp;quot;$1&amp;quot;; shift &lt;br /&gt;   echo &amp;quot;$SLEEPTIME&amp;quot; | egrep -q &amp;#x27;^[0-9]+$&amp;#x27; || usage #check that it&amp;#x27;s a number&lt;br /&gt;   ;;&lt;br /&gt;  --) shift ; break ;;&lt;br /&gt;  -[[:digit:]]*) &lt;br /&gt;   if [ $# -lt 1 ]; then usage; fi; &lt;br /&gt;   SLEEPTIME=${1:1}; shift&lt;br /&gt;   echo &amp;quot;$SLEEPTIME&amp;quot; | egrep -q &amp;#x27;^[0-9]+$&amp;#x27; || usage #check that it&amp;#x27;s a number&lt;br /&gt;   ;;&lt;br /&gt;  --*) usage;; #fail on other options&lt;br /&gt; esac&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;#Check that only one argument is left&lt;br /&gt;if [ $# -ne 1 ]; then usage; fi&lt;br /&gt;&lt;br /&gt;declare lockfile=&amp;quot;$1&amp;quot;&lt;br /&gt;for (( i=0; $RETRIES &amp;lt; 0 || i &amp;lt; $RETRIES; i++ )); do&lt;br /&gt; if ( set -o noclobber; echo &amp;quot;$$&amp;quot; &amp;gt; &amp;quot;$lockfile&amp;quot;) 2&amp;gt; /dev/null; &lt;br /&gt; then&lt;br /&gt;  exit 0&lt;br /&gt; fi&lt;br /&gt; #Wait a bit&lt;br /&gt; sleep $SLEEPTIME&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;#Failed&lt;br /&gt;cat $lockfile&lt;br /&gt;exit 1&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-6853092264314736663?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/6853092264314736663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/05/file-locks-in-bash.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/6853092264314736663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/6853092264314736663'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/05/file-locks-in-bash.html' title='File locks in bash'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-8211418369300198095</id><published>2011-04-14T17:20:00.001-03:00</published><updated>2011-04-14T17:22:31.053-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Image Processing'/><title type='text'>Content-aware image resizing</title><content type='html'>Today I'm going to discuss a technique called &lt;a href="http://www.faculty.idc.ac.il/arik/SCWeb/imret/index.html"&gt;Seam Carving&lt;/a&gt;, originally presented in Siggraph 2007. This algorithm at it's core it's fairly simple but produces impressive results.&lt;br /&gt;&lt;br /&gt;We will start from this image:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-GldHWvth9Is/TacRxhZwaHI/AAAAAAAACAY/kpimCCmPrHk/s1600/seam1.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="426" width="640" src="http://4.bp.blogspot.com/-GldHWvth9Is/TacRxhZwaHI/AAAAAAAACAY/kpimCCmPrHk/s640/seam1.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And take 200 pixels from its width, and turn it into this one:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-2CX1kXlsM04/TacSEZnmjJI/AAAAAAAACAg/OTXceFZxeM4/s1600/seam1-out.png" imageanchor="1" style=""&gt;&lt;img border="0" height="426" width="480" src="http://1.bp.blogspot.com/-2CX1kXlsM04/TacSEZnmjJI/AAAAAAAACAg/OTXceFZxeM4/s480/seam1-out.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Note that the image wasn't just resized, but most of the detail is still there. The size reduction is rather aggressive so there are some artifacts. But the results are quite good.&lt;br /&gt;&lt;br /&gt;This algorithm works by repeatedly finding vertical &lt;i&gt;seams&lt;/i&gt; of pixels and removing them. It chooses which one to remove by finding the seam with the minimal amount of energy. &lt;br /&gt;&lt;br /&gt;The whole algorithm revolves around an energy function. In this case, I'm using a function suggested in the original paper which is based on the luminance of the image. What we do is compute the vertical and horizontal derivatives of the image, take the absolute value of each, and add both. The derivative is approximated by a simple subtraction.&lt;br /&gt;&lt;br /&gt;The following code computes the energy of the image. The &lt;code&gt;intensities&lt;/code&gt; image is basically the grayscale version of the image, normalized between 0 and 1.&lt;br /&gt;&lt;pre class="brush: java"&gt;private static FloatImage computeEnergy(FloatImage intensities) {&lt;br /&gt;        int w = intensities.getWidth(), h = intensities.getHeight();&lt;br /&gt;        final FloatImage energy = FloatImage.createSameSize(intensities);&lt;br /&gt;        for(int x = 0; x &amp;lt; w-1; x++) {&lt;br /&gt;            for(int y = 0; y &amp;lt; h-1; y++) {&lt;br /&gt;                //I'm aproximating the derivatives by subtraction&lt;br /&gt;                float e = abs(intensities.get(x,y)-intensities.get(x+1,y))&lt;br /&gt;                        + abs(intensities.get(x,y)-intensities.get(x,y+1));&lt;br /&gt;                energy.set(x,y, e);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return energy;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After applying this function to our image, we get the following:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-LkmSrc7z6ds/Tac2bGpl5CI/AAAAAAAACAo/A2-bAVveD4g/s1600/seam1-energy.png" imageanchor="1" style=""&gt;&lt;img border="0" height="426" width="640" src="http://3.bp.blogspot.com/-LkmSrc7z6ds/Tac2bGpl5CI/AAAAAAAACAo/A2-bAVveD4g/s640/seam1-energy.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You can observe that the edges are highlighted (i.e. have more energy). That is caused by our choice of an energy function. Since we're taking the derivatives and adding its absolute value, abrupt changes in luminance are highlighted (i.e. edges).&lt;br /&gt;&lt;p&gt;The next step is where things start to get interesting. To find the minimal energy seam, we build an image with the accumulated minimal energy. We do so by computing an image where the value of each pixel is the value of the minimum of the three above it, plus the energy of that pixel:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-PfiDoaIQgBo/TadPMN3I2yI/AAAAAAAACAw/JdSp674Jx-0/s1600/seam%2Bminimal.png" imageanchor="1" style=""&gt;&lt;img border="0" height="320" width="320" src="http://2.bp.blogspot.com/-PfiDoaIQgBo/TadPMN3I2yI/AAAAAAAACAw/JdSp674Jx-0/s320/seam%2Bminimal.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We do so with the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;final FloatImage energy = computeEnergy(intensities);&lt;br /&gt;&lt;br /&gt;    final FloatImage minima = FloatImage.createSameSize(energy);&lt;br /&gt;    //First row is equal to the energy&lt;br /&gt;    for(int x = 0; x &amp;lt; w; x++) {&lt;br /&gt;        minima.set(x,0, energy.get(x,0));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    //I assume that the rightmost pixel column in the energy image is garbage&lt;br /&gt;    for(int y = 1; y &amp;lt; h; y++) {&lt;br /&gt;        minima.set(0,y, energy.get(0,y) + min(minima.get(0, y - 1),&lt;br /&gt;                minima.get(1, y - 1)));&lt;br /&gt;&lt;br /&gt;        for(int x = 1; x &amp;lt; w-2; x++) {&lt;br /&gt;            final float sum = energy.get(x,y) + min(min(minima.get(x - 1, y - 1),&lt;br /&gt;                    minima.get(x, y - 1)),minima.get(x + 1, y - 1));&lt;br /&gt;            minima.set(x,y, sum);&lt;br /&gt;        }&lt;br /&gt;        minima.set(w-2,y, energy.get(w-2,y) + min(minima.get(w-2, y - 1),&lt;br /&gt;                minima.get(w-3, y - 1)));&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once we do this, the last row contains the sum of all the potential minimal seams. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-6Qsyo3QBNBQ/TadRDVQMTZI/AAAAAAAACA4/z6wflsKJycI/s1600/seam1-minima.png" imageanchor="1" style=""&gt;&lt;img border="0" height="426" width="640" src="http://3.bp.blogspot.com/-6Qsyo3QBNBQ/TadRDVQMTZI/AAAAAAAACA4/z6wflsKJycI/s640/seam1-minima.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;With this, we search the last row for the one with the minimum total value: &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;//We find the minimum seam&lt;br /&gt;    float minSum = Float.MAX_VALUE;&lt;br /&gt;    int seamTip = -1;&lt;br /&gt;    for(int x = 1; x &amp;lt; w-1; x++) {&lt;br /&gt;        final float v = minima.get(x, h-1);&lt;br /&gt;        if(v &amp;lt; minSum) {&lt;br /&gt;            minSum=v;&lt;br /&gt;            seamTip=x;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And backtrace the seam:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;//Backtrace the seam&lt;br /&gt;    final int[] seam = new int[h];&lt;br /&gt;    seam[h-1]=seamTip;&lt;br /&gt;    for(int x = seamTip, y = h-1; y &amp;gt; 0; y--) {&lt;br /&gt;        float left = x&amp;gt;0?minima.get(x-1, y-1):Float.MAX_VALUE;&lt;br /&gt;        float up = minima.get(x, y-1);&lt;br /&gt;        float right = x+1&amp;lt;w?minima.get(x+1, y-1):Float.MAX_VALUE;&lt;br /&gt;        if(left &amp;lt; up &amp;amp;&amp;amp; left &amp;lt; right) x=x-1;&lt;br /&gt;        else if(right &amp;lt; up &amp;amp;&amp;amp; right &amp;lt; left) x= x+1;&lt;br /&gt;        seam[y-1]=x;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Having the minimum energy seam, all is left to do is remove it.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-LaRoSd1qKCk/TadR9H2fYxI/AAAAAAAACBA/M3_b4T3eEb0/s1600/seam1-minseam.png" imageanchor="1" style=""&gt;&lt;img border="0" height="426" width="640" src="http://1.bp.blogspot.com/-LaRoSd1qKCk/TadR9H2fYxI/AAAAAAAACBA/M3_b4T3eEb0/s640/seam1-minseam.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If we repeat this process several times, removing one seam at a time, we end up with a smaller image. Check the following video to see this algorithm in action:&lt;br /&gt;&lt;br /&gt;&lt;iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/Elpdgxi1Ytw" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;If you want to reduce an image vertically, you have to find horizontal seams. If you want to do it vertically and horizontally you have to find which seam has the least energy (either the vertical or the horizontal one) and remove that one.&lt;br /&gt;&lt;p&gt;This implementation is quick &amp; dirty and very simplistic. Many optimization can be done to make it work faster. It is also quite incomplete. By priming the energy image, you can influence the algorithm to avoid distorting certain objects in the image or to particularly pick one.&lt;br /&gt;&lt;p&gt;It is also possible to use it to enlarge an image (although I haven't implemented it), and by a combination of both methods one can selectively remove objects from an image.&lt;br /&gt;&lt;p&gt;The full source code for this demo follows. Have fun!&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java; collapse: true"&gt;import javax.imageio.ImageIO;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.awt.image.BufferedImage;&lt;br /&gt;import java.awt.*;&lt;br /&gt;import static java.lang.Math.abs;&lt;br /&gt;import static java.lang.Math.min;&lt;br /&gt;&lt;br /&gt;public class SeamCarving&lt;br /&gt;{&lt;br /&gt;    public static void main(String[] args) throws IOException {&lt;br /&gt;        final BufferedImage input = ImageIO.read(new File(args[0]));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        final BufferedImage[] toPaint = new BufferedImage[]{input};&lt;br /&gt;        final Frame frame = new Frame(&amp;quot;Seams&amp;quot;) {&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public void update(Graphics g) {&lt;br /&gt;                final BufferedImage im = toPaint[0];&lt;br /&gt;                if (im != null) {&lt;br /&gt;                    g.clearRect(0,0,getWidth(), getHeight());&lt;br /&gt;                    g.drawImage(im,0,0,this);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;        frame.setSize(input.getWidth(), input.getHeight());&lt;br /&gt;        frame.setVisible(true);&lt;br /&gt;&lt;br /&gt;        BufferedImage out = input;&lt;br /&gt;        for(int i = 0; i &amp;lt; 200; i++) {&lt;br /&gt;            out = deleteVerticalSeam(out);&lt;br /&gt;            toPaint[0]=out;&lt;br /&gt;            frame.repaint();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static BufferedImage deleteVerticalSeam(BufferedImage input) {&lt;br /&gt;        return deleteVerticalSeam(input, findVerticalSeam(input));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static BufferedImage deleteVerticalSeam(final BufferedImage input, final int[] seam) {&lt;br /&gt;        int w = input.getWidth(), h = input.getHeight();&lt;br /&gt;        final BufferedImage out = new BufferedImage(w-1,h, BufferedImage.TYPE_INT_ARGB);&lt;br /&gt;&lt;br /&gt;        for(int y = 0; y &amp;lt; h; y++) {&lt;br /&gt;            for(int x = 0; x &amp;lt; seam[y]; x++) {&lt;br /&gt;                    out.setRGB(x,y,input.getRGB(x, y));&lt;br /&gt;            }&lt;br /&gt;            for(int x = seam[y]+1; x &amp;lt; w; x++) {&lt;br /&gt;                    out.setRGB(x-1,y,input.getRGB(x, y));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return out;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static int[] findVerticalSeam(BufferedImage input) {&lt;br /&gt;        final int w = input.getWidth(), h = input.getHeight();&lt;br /&gt;        final FloatImage intensities = FloatImage.fromBufferedImage(input);&lt;br /&gt;        final FloatImage energy = computeEnergy(intensities);&lt;br /&gt;&lt;br /&gt;        final FloatImage minima = FloatImage.createSameSize(energy);&lt;br /&gt;        //First row is equal to the energy&lt;br /&gt;        for(int x = 0; x &amp;lt; w; x++) {&lt;br /&gt;            minima.set(x,0, energy.get(x,0));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //I assume that the rightmost pixel column in the energy image is garbage&lt;br /&gt;        for(int y = 1; y &amp;lt; h; y++) {&lt;br /&gt;            minima.set(0,y, energy.get(0,y) + min(minima.get(0, y - 1),&lt;br /&gt;                    minima.get(1, y - 1)));&lt;br /&gt;&lt;br /&gt;            for(int x = 1; x &amp;lt; w-2; x++) {&lt;br /&gt;                final float sum = energy.get(x,y) + min(min(minima.get(x - 1, y - 1),&lt;br /&gt;                        minima.get(x, y - 1)),minima.get(x + 1, y - 1));&lt;br /&gt;                minima.set(x,y, sum);&lt;br /&gt;            }&lt;br /&gt;            minima.set(w-2,y, energy.get(w-2,y) + min(minima.get(w-2, y - 1),minima.get(w-3, y - 1)));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //We find the minimum seam&lt;br /&gt;        float minSum = Float.MAX_VALUE;&lt;br /&gt;        int seamTip = -1;&lt;br /&gt;        for(int x = 1; x &amp;lt; w-1; x++) {&lt;br /&gt;            final float v = minima.get(x, h-1);&lt;br /&gt;            if(v &amp;lt; minSum) {&lt;br /&gt;                minSum=v;&lt;br /&gt;                seamTip=x;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //Backtrace the seam&lt;br /&gt;        final int[] seam = new int[h];&lt;br /&gt;        seam[h-1]=seamTip;&lt;br /&gt;        for(int x = seamTip, y = h-1; y &amp;gt; 0; y--) {&lt;br /&gt;            float left = x&amp;gt;0?minima.get(x-1, y-1):Float.MAX_VALUE;&lt;br /&gt;            float up = minima.get(x, y-1);&lt;br /&gt;            float right = x+1&amp;lt;w?minima.get(x+1, y-1):Float.MAX_VALUE;&lt;br /&gt;            if(left &amp;lt; up &amp;amp;&amp;amp; left &amp;lt; right) x=x-1;&lt;br /&gt;            else if(right &amp;lt; up &amp;amp;&amp;amp; right &amp;lt; left) x= x+1;&lt;br /&gt;            seam[y-1]=x;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return seam;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static FloatImage computeEnergy(FloatImage intensities) {&lt;br /&gt;        int w = intensities.getWidth(), h = intensities.getHeight();&lt;br /&gt;        final FloatImage energy = FloatImage.createSameSize(intensities);&lt;br /&gt;        for(int x = 0; x &amp;lt; w-1; x++) {&lt;br /&gt;            for(int y = 0; y &amp;lt; h-1; y++) {&lt;br /&gt;                //I&amp;#x27;m approximating the derivatives by subtraction&lt;br /&gt;                float e = abs(intensities.get(x,y)-intensities.get(x+1,y))&lt;br /&gt;                        + abs(intensities.get(x,y)-intensities.get(x,y+1));&lt;br /&gt;                energy.set(x,y, e);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return energy;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: java; collapse: true"&gt;import java.awt.image.BufferedImage;&lt;br /&gt;&lt;br /&gt;public final class FloatImage {&lt;br /&gt;    private final int width;&lt;br /&gt;    private final int height;&lt;br /&gt;    private final float[] data;&lt;br /&gt;&lt;br /&gt;    public FloatImage(int width, int height) {&lt;br /&gt;        this.width = width;&lt;br /&gt;        this.height = height;&lt;br /&gt;        this.data = new float[width*height];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getWidth() {&lt;br /&gt;        return width;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getHeight() {&lt;br /&gt;        return height;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public float get(final int x, final int y) {&lt;br /&gt;        if(x &amp;lt; 0 || x &amp;gt;= width) throw new IllegalArgumentException(&amp;quot;x: &amp;quot; + x);&lt;br /&gt;        if(y &amp;lt; 0 || y &amp;gt;= height) throw new IllegalArgumentException(&amp;quot;y: &amp;quot; + y);&lt;br /&gt;        return data[x+y*width];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void set(final int x, final int y, float value) {&lt;br /&gt;        if(x &amp;lt; 0 || x &amp;gt;= width) throw new IllegalArgumentException(&amp;quot;x: &amp;quot; + x);&lt;br /&gt;        if(y &amp;lt; 0 || y &amp;gt;= height) throw new IllegalArgumentException(&amp;quot;y: &amp;quot; + y);&lt;br /&gt;        data[x+y*width] = value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static FloatImage createSameSize(final BufferedImage sample) {&lt;br /&gt;        return new FloatImage(sample.getWidth(), sample.getHeight());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static FloatImage createSameSize(final FloatImage sample) {&lt;br /&gt;        return new FloatImage(sample.getWidth(), sample.getHeight());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static FloatImage fromBufferedImage(final BufferedImage src) {&lt;br /&gt;        final int width = src.getWidth();&lt;br /&gt;        final int height = src.getHeight();&lt;br /&gt;        final FloatImage result = new FloatImage(width, height);&lt;br /&gt;        for(int x = 0; x &amp;lt; width; x++) {&lt;br /&gt;            for(int y = 0; y &amp;lt; height; y++) {&lt;br /&gt;                final int argb = src.getRGB(x, y);&lt;br /&gt;                int r = (argb &amp;gt;&amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&lt;br /&gt;                int g = (argb &amp;gt;&amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&lt;br /&gt;                int b = argb &amp;amp; 0xFF;&lt;br /&gt;                result.set(x,y, (r*0.3f+g*0.59f+b*0.11f)/255);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;    public BufferedImage toBufferedImage(float scale) {&lt;br /&gt;        final BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);&lt;br /&gt;        for(int x = 0; x &amp;lt; width; x++) {&lt;br /&gt;            for(int y = 0; y &amp;lt; height; y++) {&lt;br /&gt;                final int intensity = ((int) (get(x, y) * scale)) &amp;amp; 0xFF;&lt;br /&gt;                result.setRGB(x,y,0xFF000000 | intensity | intensity &amp;lt;&amp;lt; 8 | intensity &amp;lt;&amp;lt; 16);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-8211418369300198095?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/8211418369300198095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/04/content-aware-image-resizing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/8211418369300198095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/8211418369300198095'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/04/content-aware-image-resizing.html' title='Content-aware image resizing'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-GldHWvth9Is/TacRxhZwaHI/AAAAAAAACAY/kpimCCmPrHk/s72-c/seam1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-7109699805814199863</id><published>2011-04-08T16:51:00.000-03:00</published><updated>2011-04-08T16:51:36.637-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microposts'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Nerding with the Y-combinator</title><content type='html'>What follows is a pointless exercise. Hereby I present you the &lt;a href="http://kestas.kuliukas.com/YCombinatorExplained/"&gt;Y-combinator&lt;/a&gt; in Java with generics:&lt;br /&gt;&lt;pre class="brush: java"&gt;public class Combinators {&lt;br /&gt;    interface F&amp;lt;A,B&amp;gt; {&lt;br /&gt;        B apply(A x);&lt;br /&gt;    }&lt;br /&gt;    //Used for proper type checking&lt;br /&gt;    private static interface FF&amp;lt;A, B&amp;gt; extends F&amp;lt;FF&amp;lt;A, B&amp;gt;, F&amp;lt;A, B&amp;gt;&amp;gt; {}&lt;br /&gt;&lt;br /&gt;    //The Y-combinator&lt;br /&gt;    public static &amp;lt;A, B&amp;gt; F&amp;lt;A, B&amp;gt; Y(final F&amp;lt;F&amp;lt;A, B&amp;gt;,F&amp;lt;A, B&amp;gt;&amp;gt; f) {&lt;br /&gt;        return U(new FF&amp;lt;A, B&amp;gt;() {&lt;br /&gt;            public F&amp;lt;A, B&amp;gt; apply(final FF&amp;lt;A, B&amp;gt; x) {&lt;br /&gt;                return f.apply(new F&amp;lt;A, B&amp;gt;() {&lt;br /&gt;                    public B apply(A y) {&lt;br /&gt;                        return U(x).apply(y);&lt;br /&gt;                    }&lt;br /&gt;                });&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    //The U-combinator&lt;br /&gt;    private static &amp;lt;A,B&amp;gt; F&amp;lt;A, B&amp;gt; U(FF&amp;lt;A, B&amp;gt; a) {&lt;br /&gt;        return a.apply(a);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static F&amp;lt;F&amp;lt;Integer, Integer&amp;gt;, F&amp;lt;Integer, Integer&amp;gt;&amp;gt; factorialGenerator() {&lt;br /&gt;        return new F&amp;lt;F&amp;lt;Integer, Integer&amp;gt;, F&amp;lt;Integer, Integer&amp;gt;&amp;gt;() {&lt;br /&gt;            public F&amp;lt;Integer, Integer&amp;gt; apply(final F&amp;lt;Integer, Integer&amp;gt; fact) {&lt;br /&gt;                return new F&amp;lt;Integer, Integer&amp;gt;() {&lt;br /&gt;                    public Integer apply(Integer n) {&lt;br /&gt;                        return n == 0 ? 1 : n * fact.apply(n-1);&lt;br /&gt;                    }&lt;br /&gt;                };&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        F&amp;lt;Integer, Integer&amp;gt; fact = Y(factorialGenerator());&lt;br /&gt;        System.out.println(fact.apply(6));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Having the Y-combinator implemented in Java, actually serves no purpose (Java supports recursion) but it was interesting to see if it could be done with proper generics.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-7109699805814199863?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/7109699805814199863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/04/nerding-with-y-combinator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7109699805814199863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7109699805814199863'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/04/nerding-with-y-combinator.html' title='Nerding with the Y-combinator'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-110410728783402323</id><published>2011-04-04T12:46:00.001-03:00</published><updated>2011-04-04T14:31:11.089-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Paper programming</title><content type='html'>When I was a kid, all I wanted was a computer. Finally when I was twelve I made a bargain with my dad. I would give up the graduation trip in exchange for a Commodore 64 (graduation trips are customary in Argentina when you finish primary and secondary school).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ah59U45RMss/TZneS4tb6aI/AAAAAAAAB_s/wa7M18V7BAE/s1600/c64.jpg" imageanchor="1" style=""&gt;&lt;img border="0" height="180" width="320" src="http://2.bp.blogspot.com/-ah59U45RMss/TZneS4tb6aI/AAAAAAAAB_s/wa7M18V7BAE/s320/c64.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We bought a "Segundamano" (lit. second hand) magazine and found a used one for U$S 200. My dad contacted the seller and we went to pick it up.&lt;br /&gt;&lt;br /&gt;You have to keep in mind that this was 1989 and the social and economic landscape in &lt;a href="http://en.wikipedia.org/wiki/1989_riots_in_Argentina"&gt;Argentina was a mess&lt;/a&gt;. That year the &lt;a href="http://www.wolframalpha.com/input/?i=argentina+inflation+1989"&gt;inflation rate was over 3000%&lt;/a&gt; (it is not a typo) and those 200 dollars was a lot of money, so my dad really made an effort.&lt;br /&gt;&lt;br /&gt;If you are still paying attention, you might have noticed that I never mentioned a &lt;a href="http://en.wikipedia.org/wiki/Commodore_Datasette"&gt;Datasette&lt;/a&gt; nor a disk drive. All I got was a Commodore 64, plain and simple. But this was not going to stop me.&lt;br /&gt;&lt;br /&gt;After we got it, my dad was concerned that I might get too obsessed with the computer, so he placed some additional constraints on when I could use it (the fact that we had only one TV might have also been a factor in his decision). I was allowed to use it only on Saturday mornings before noon.&lt;br /&gt;&lt;br /&gt;In retrospective, I think that this two factors made me a better programmer. &lt;br /&gt;&lt;br /&gt;At that time I had some experience programming in Logo mostly. It was a Logo dialect in spanish that we used at school. We had a Commodore-128 laboratory at school (about eight machines with disk drives and monitors). I started learning Logo when I was 8, by the time I was twelve I could program a bit of BASIC also, but not much since literature was scarce.&lt;br /&gt;&lt;br /&gt;One great thing about the Commodore 64 was that it came with BASIC, but most importantly, it came with a manual! The Commodore's Basic manual was my first programming book.&lt;br /&gt;&lt;br /&gt;What happened was that I was forced to work as if I had punched cards. I would spend most of my spare time during the week writing programs in a notebook I had. Thinking about ways to solve problems and reading and re-reading the C64 manual.&lt;br /&gt;&lt;br /&gt;On saturday mornings I would wake up at 6 am and hook-up the computer to the TV and start typing whatever program I was working on that week. Run it and debug it, improve it and around noon my mom would start reminding me that time was up. So at that point I began listing the BASIC source code and copying it back to my notebook.&lt;br /&gt;&lt;br /&gt;It was during this time that I rediscovered things like an optimized Bubble-sort, although I didn't know its name then (and I wouldn't learn it for many more years). I still vividly remember the moment. It was one afternoon that I was trying to figure out a way to sort an array, so I started playing with a &lt;a href="http://en.wikipedia.org/wiki/Baraja_(playing_cards)"&gt;deck of cards&lt;/a&gt;. I finally figured out that I could do several passes of comparison and exchanges on adjacent cards. And if I did exactly as many passes as the number of elements the array would be sorted. I also noticed that the largest element would be at the end of the array after the first pass, and the second largest would be in place after the second pass and so on. This allowed me to save about half the number of comparisons.&lt;br /&gt;&lt;br /&gt;The most valuable thing that I learned during this time is that when it comes to programming, thinking hard about the problem at hand before doing anything pays off, big time!&lt;br /&gt;&lt;br /&gt;I eventually was able to save enough for a Datasette (it costed 40 dollars, my dad payed half of it) and I was able to build much larger programs.&lt;br /&gt;&lt;br /&gt;The biggest one I wrote was an interpreter with a multitasking runtime. It was very basic. I had no notion of a lexer, let alone a parser. Commands were composed of a single letter (the first one of the line) and several arguments. You could declare procedures with names and call them. It was like pidgin-basic (since my exposure was to basic) but the procedure structure resembled Logo.&lt;br /&gt;&lt;br /&gt;Programs were stored in memory in several arrays. There was a main one that contained statements, and couple to hold procedure names and offsets into the main array.&lt;br /&gt;&lt;br /&gt;The runtime divided the screen in 4 areas (this was a 40x25 text screen, so not much room was left for each), and each window could run a separate program. The runtime would do a round robin on each running program, executing a single statement of each on each pass. For this it had to keep keeping a separate program counter and variables for each. I even planned to add windowing calls to create custom windows but I never got to finish it.&lt;br /&gt;&lt;br /&gt;It was at this time that I also got interested in electronics, so I built a a few contraptions controlled by the C64, but that's a tale for another post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-110410728783402323?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/110410728783402323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/04/paper-programming.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/110410728783402323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/110410728783402323'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/04/paper-programming.html' title='Paper programming'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-ah59U45RMss/TZneS4tb6aI/AAAAAAAAB_s/wa7M18V7BAE/s72-c/c64.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-6884922434155236620</id><published>2011-03-30T20:42:00.000-03:00</published><updated>2011-03-30T20:42:29.507-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Compilers'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Matching Regular Expressions using its Derivatives</title><content type='html'>&lt;h3&gt;Introduction&lt;/h3&gt;Regular expressions are expressions that describe a set of strings over a particular alphabet. We will begin with a crash course on simple regular expressions. You can assume that we're talking about text and characters but in fact this can be generalized to any (finite) alphabet.&lt;br /&gt;&lt;br /&gt;The definition of regular expressions is quite simple&lt;sup&gt;&lt;a href="#footnotes"&gt;1&lt;/a&gt;&lt;/sup&gt;, there are three basic (i.e. terminal) regular expressions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The null expression (denoted as: &lt;b&gt;&amp;empty;&lt;/b&gt;) which never matches anything&lt;/li&gt;&lt;li&gt;The empty expression, that only matches the empty string (I will use &lt;b&gt;&amp;epsilon;&lt;/b&gt; to represent this expression since it's customary&lt;sup&gt;&lt;a href="#footnotes"&gt;2&lt;/a&gt;&lt;/sup&gt;)&lt;/li&gt;&lt;li&gt;The character literal expression (usually called 'c'), that matches a single character&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;These three basic building blocks can be combined using some operators to form more complex expressions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sequencing of regular expressions matches two regular expressions in sequence&lt;/li&gt;&lt;li&gt;alternation matches one of the two sub-expressions (usually represented by a '|' symbol)&lt;/li&gt;&lt;li&gt;the repetition operator (aka. Kleene's star) matches zero or more repetitions of the specified subexpression&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Some examples will make this clearer:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The expression &lt;b&gt;'a'&lt;/b&gt; will only match the character 'a'. Similarly &lt;b&gt;'b'&lt;/b&gt; will only match 'b'. If we combine them by sequencing &lt;b&gt;'ab'&lt;/b&gt; will match 'ab'.&lt;/li&gt;&lt;li&gt;The expression &lt;b&gt;'a|b'&lt;/b&gt; will match either 'a' or 'b'.&lt;/li&gt;&lt;li&gt;If we combine sequencing with alternation as in &lt;b&gt;'(a|b)(a|b)'&lt;/b&gt; (the parenthesis are clarifying), it will match: 'aa', 'ab', 'ba' or 'bb'.&lt;/li&gt;&lt;li&gt;Kleene's star as mentioned before matches zero or more of the preceding subexpression. So the expression 'a*' will match: '', 'a', 'aa', 'aaa', 'aaaa', ...&lt;/li&gt;&lt;li&gt;We can do more complex combinations, such as &lt;b&gt;'ab*(c|&amp;epsilon;)'&lt;/b&gt; that will match things like: 'a', 'ab', 'ac', 'abc', 'abb', 'abbc', ... that is any string starting with an 'a' followed by zero or more 'b''s and optionally ending in a 'c'.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Typical implementations of regular expression matchers convert the regular expression to an NFA or a DFA (which are a kind of &lt;a href="http://en.wikipedia.org/wiki/Finite_state_machine"&gt;finite state machine&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Anyway, a few weeks ago I ran into &lt;a href="http://matt.might.net/articles/implementation-of-regular-expression-matching-in-scheme-with-derivatives/"&gt;a post about using the derivative of a regular expression for matching&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is a quite intriguing concept and worth exploring. The original post gives an implementation in Scheme&lt;sup&gt;&lt;a href="#footnotes"&gt;3&lt;/a&gt;&lt;/sup&gt;. But leaves out some details that make it a bit tricky to implement. I'll try to walk you through the concept, up to a working implementation in Java.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Derivative of a Regular Expression&lt;/h3&gt;So, first question: What's the derivative of a regular expression?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The derivative of a regular expression with respect to a character 'c' computes a new regular expression that matches what the original expression would match, assuming it had just matched the character 'c'.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;As usual, some examples will (hopefully) help clarify things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The expression &lt;b&gt;'foo'&lt;/b&gt; derived with respect to 'f' yields the expression: 'oo' (which is what's left to match).&lt;br /&gt;&lt;li&gt;The expression &lt;b&gt;'ab|ba'&lt;/b&gt; derived with respect to 'a', yields the expression: 'b'&lt;br /&gt;Similarly, the expression &lt;b&gt;'ab|ba'&lt;/b&gt; derived with respect to 'b', yields the expression: 'a'&lt;br /&gt;&lt;li&gt;The expression &lt;b&gt;'(ab|ba)*'&lt;/b&gt; derived with respect to 'a', yields the expression: 'b(ab|ba)*'&lt;br /&gt;&lt;/ul&gt;As we explore this notion, we will work a &lt;code&gt;RegEx&lt;/code&gt; class. The skeleton of this class looks like this:&lt;pre class="brush: java"&gt;public abstract class RegEx {&lt;br /&gt;    public abstract RegEx derive(char c);&lt;br /&gt;    public abstract RegEx simplify();&lt;br /&gt;//...&lt;br /&gt;    public static final RegEx unmatchable = new RegEx() { /* ... */ }&lt;br /&gt;    public static final RegEx empty = new RegEx() { /* ... */ }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;It includes constants for the unmatchable (null) and empty expressions, and a derive and simplify methods wich we will cover in detail (but not just now).&lt;br/&gt;&lt;br/&gt;Before we go in detail about the rules of regular expression derivation, let's take a small -but necessary- detour and cover some details that will help us get a working implementation. &lt;br/&gt;&lt;br/&gt;The formalization of the derivative of a regular expression depends on a set of simplifying constructors that are necessary for a correct implementation. These will be defined a bit more formally and we will build the skeleton of its implementation at this point.&lt;br/&gt;&lt;br/&gt;Let's begin with the sequencing operation, we define the following constructor (ignore spaces): &lt;pre class="brush: java"&gt;seq( &amp;empty;, _ ) = &amp;empty;&lt;br /&gt;seq( _, &amp;empty; ) = &amp;empty;&lt;br /&gt;seq( &amp;epsilon;, r2 ) = r2&lt;br /&gt;seq( r1, &amp;epsilon; ) = r1&lt;br /&gt;seq( r1, r2 ) = r1 r2&lt;br /&gt;&lt;/pre&gt;The first two definitions state that if you have a sequence with the null expression (&amp;empty;, which is unmatchable) and any other expression, it's the same than having the null expression (i.e. it will not match anything).  &lt;br/&gt;&lt;br/&gt;The third and fourth definitions state that if you have a sequence of the empty expression (&amp;epsilon;, matches only the empty string) and any other expression, is the same than just having the other expression (the empty expression is the identity with respect to the sequence operator).  &lt;br/&gt;&lt;br/&gt;The fifth and last definition just builds a regular sequence.   &lt;br/&gt;&lt;br/&gt;With this, we can draft a first implementation of a sequence constructor (in the gang-of-four's parlance it's a factory method):&lt;pre class="brush: java"&gt;    public RegEx seq(final RegEx r2) {&lt;br /&gt;        final RegEx r1 = this;&lt;br /&gt;        if(r1 == unmatchable || r2 == unmatchable) return unmatchable;&lt;br /&gt;        if(r1 == empty) return r2;&lt;br /&gt;        if(r2 == empty) return r1;&lt;br /&gt;        return new RegEx() {&lt;br /&gt;             // ....&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;I'm leaving out the details of the RegEx for the time being, we will come back to them soon enough.&lt;br/&gt;&lt;br/&gt;The alternation operator also has simplifying constructor that is analogous to the sequence operator:&lt;pre class="brush: java"&gt;alt( &amp;epsilon;, _  ) = &amp;epsilon;&lt;br /&gt;alt(  _, &amp;epsilon; ) = &amp;epsilon;&lt;br /&gt;alt( &amp;empty;, r2 ) = r2&lt;br /&gt;alt( r1, &amp;empty; ) = r1&lt;br /&gt;alt( r1, r2 ) = r1 | r2&lt;br /&gt;&lt;/pre&gt;If you look closely, the first two definitions are rather odd. They basically reduce an alternation with the empty expression to the empty expression (&amp;epsilon;). This is because the simplifying constructors are used as part of a simplification function that reduces a regular expression to the empty expression if it matches the empty expression. We'll see how this works with the rest of it in a while.&lt;br/&gt;&lt;br/&gt;The third and fourth definitions are fairly logical, an alternation with an unmatchable expression is the same than the alternative (the unmatchable expression is the identity with respect to the alternation operator).&lt;br/&gt;&lt;br/&gt;The last one is the constructor.&lt;br/&gt;&lt;br/&gt;Taking these details into account, we can build two factory methods, one internal and one external:&lt;pre class="brush: java"&gt;    private RegEx alt0(final RegEx r2) {&lt;br /&gt;        final RegEx r1 = this;&lt;br /&gt;        if(r1 == empty || r2 == empty) return empty;&lt;br /&gt;        return alt(r2);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public RegEx alt(final RegEx r2) {&lt;br /&gt;        final RegEx r1 = this;&lt;br /&gt;        if(r1 == unmatchable) return r2;&lt;br /&gt;        if(r2 == unmatchable) return r1;&lt;br /&gt;        return new RegEx() {&lt;br /&gt;             //.....&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;The internal one &lt;code&gt;alt0&lt;/code&gt; includes the first two simplification rules, the public one is user-facing. That is, it has to let you build something like: &lt;b&gt;'ab*(c|&amp;epsilon;)'&lt;/b&gt;.&lt;br/&gt;&lt;br/&gt;Finally, the repetition operator (Kleene's star) has the following simplification rules:&lt;pre class="brush: java"&gt;rep( &amp;empty; ) = &amp;epsilon;&lt;br /&gt;rep( &amp;epsilon; ) = &amp;epsilon;&lt;br /&gt;rep( re ) = re*&lt;br /&gt;&lt;/pre&gt;The first definition states that a repetition of the unmatchable expression, matches at least the empty string.&lt;br/&gt;&lt;br/&gt;The second definition states that a repetition of the empty expression is the same than matching the empty expression.&lt;br/&gt;&lt;br/&gt;And as usual, the last one is the constructor for all other cases.&lt;br/&gt;&lt;br/&gt;A skeleton for the &lt;code&gt;rep&lt;/code&gt; constructor is rather simple:&lt;pre class="brush: java"&gt;    public RegEx rep() {&lt;br /&gt;        final RegEx re = this;&lt;br /&gt;        if(re == unmatchable || re == empty) return empty;&lt;br /&gt;        return new RegEx() {&lt;br /&gt;             // ....&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Simplify &amp; Derive&lt;/h3&gt;As hinted earlier on, derivation is based on a simplification function. This simplification function reduces a regular expression to the empty regular expression (&amp;epsilon; epsilon) if it matches the empty string or the unmatchable expression (&amp;empty;) if it does not.&lt;p/&gt;The simplification function is defined as follows:&lt;pre class="brush: java"&gt;s(&amp;empty;) = &amp;empty;&lt;br /&gt;s(&amp;epsilon;) = &amp;epsilon;&lt;br /&gt;s(c) = &amp;empty;&lt;br /&gt;s(re1 re2) = seq(s(re1), s(re2))&lt;br /&gt;s(re1 | re2) = alt(s(re1), s(re2))&lt;br /&gt;s(re*) = &amp;epsilon;&lt;br /&gt;&lt;/pre&gt;Note that this function depends on the simplifying constructors we described earlier on.&lt;p/&gt;Suppose that we want to check if the expression &lt;b&gt;'ab*(c|&amp;epsilon;)'&lt;/b&gt; matches the empty expression, if we do all the substitutions:&lt;ol&gt;&lt;li&gt;seq(s(ab*),s(c|&amp;epsilon;))&lt;br /&gt;&lt;li&gt;seq(s(seq(s(a), s(b*))),s(alt(s(c), s(&amp;epsilon;))))&lt;br /&gt;&lt;li&gt;seq(s(seq(&amp;empty;, s(&amp;epsilon;))),s(alt(&amp;empty;, &amp;epsilon;)))&lt;br /&gt;&lt;li&gt;seq(s(seq(&amp;empty;, &amp;epsilon;)),s(&amp;epsilon;))&lt;br /&gt;&lt;li&gt;seq(s(&amp;empty;),&amp;epsilon;)&lt;br /&gt;&lt;li&gt;seq(&amp;empty;,&amp;epsilon;)&lt;br /&gt;&lt;li&gt;&amp;empty;&lt;br /&gt;&lt;/ol&gt;We get the null/unmatchable expression as a result. This means that the expression &lt;b&gt;'ab*(c|&amp;epsilon;)'&lt;/b&gt; does not match the empty string.&lt;p/&gt;If on the other hand we apply the reduction on &lt;b&gt;'a*|b'&lt;/b&gt;:&lt;ol&gt;&lt;li&gt;alt(s(a*), s(b))&lt;br /&gt;&lt;li&gt;alt(&amp;epsilon;, &amp;empty;)&lt;br /&gt;&lt;li&gt;&amp;epsilon;&lt;br /&gt;&lt;/ol&gt;We get the empty expression, hence the regular expression &lt;b&gt;'a*|b'&lt;/b&gt; will match the empty string.&lt;p/&gt;The derivation function given a regular expression and a character 'x' &lt;i&gt;derives&lt;/i&gt; a new regular expression as if having matched 'x'.&lt;p/&gt;Derivation is defined by the following set of rules:&lt;pre class="brush: java"&gt;D( &amp;empty;, _ ) = &amp;empty;&lt;br /&gt;D( &amp;epsilon;, _ ) = &amp;empty;&lt;br /&gt;D( c, x ) = if c == x then &amp;epsilon; else &amp;empty;&lt;br /&gt;D(re1 re2, x) = alt(&lt;br /&gt;                     seq( s(re1) , D(re2, x) ),&lt;br /&gt;                     seq( D(re1, x), re2 )&lt;br /&gt;                )&lt;br /&gt;D(re1 | re2, x)  = alt( D(re1, x) , D(re2, x) )&lt;br /&gt;D(re*, x)        = seq( D(re, x)  , rep(re) )&lt;br /&gt;&lt;/pre&gt;The first two definition define the derivative of the unmatchable and empty expressions regarding any character, wich yields the unmatchable expression.&lt;p/&gt;The third definition states that if a character matcher (for example 'a') is derived with respect to the same character yields the empty expression otherwise yields the unmatchable expression. &lt;p/&gt;The fourth rule is a bit more involved, but trust me, it works.&lt;p/&gt;The fifth rule states that the derivative of an alternation is the alternation of the derivatives (suitably simplified).&lt;p/&gt;And the last one, describes how to derive a repetition. For example &lt;b&gt;D('(ba)*', 'b')&lt;/b&gt; yields &lt;b&gt;'a(ba)*'&lt;/b&gt;.&lt;p/&gt;We now have enough information to implement the simplify and &lt;h3&gt;Matching&lt;/h3&gt;If you haven't figured it out by now, matching works by walking the string we're checking character by character and successively deriving the regular expression until we either run out of characters, at wich point we simplify the derived expression and see if it matches the empty string. Or we end up getting the unmatchable expression, at wich point it is impossible that the rest of the string will match.&lt;p/&gt;A iterative implementation of a match method is as follows:&lt;pre class="brush: java"&gt;    public boolean matches(final String text) {&lt;br /&gt;        RegEx d = this;&lt;br /&gt;        String s = text;&lt;br /&gt;        //The 'unmatchable' test is not strictly necessary, but avoids unnecessary derivations&lt;br /&gt;        while(!s.isEmpty() &amp;&amp; d != unmatchable) {&lt;br /&gt;            d = d.derive(s.charAt(0));&lt;br /&gt;            s = s.substring(1);&lt;br /&gt;        }&lt;br /&gt;        return d.simplify() == empty;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;If we match &lt;b&gt;'ab*(c|&amp;epsilon;)'&lt;/b&gt; against the text "abbc", we get the following derivatives:&lt;ol&gt;&lt;li&gt;D(re, a) = ab*(c|&amp;epsilon;) , rest: "bbc"&lt;br /&gt;&lt;li&gt;D(re, b) = b*(c|&amp;epsilon;) , rest: "bc"&lt;br /&gt;&lt;li&gt;D(re, b) = b*(c|&amp;epsilon;) , rest: "c"&lt;br /&gt;&lt;li&gt;D(re, c) = b*(c|&amp;epsilon;) , rest: ""&lt;br /&gt;&lt;/ol&gt;And if we simplify the last derivative we get the empty expression, therefore we have a match.&lt;p/&gt;One interesting fact of this matching strategy is that it is fairly easy to implement a non-blocking matcher. That is, doing incremental matching as we receive characters.&lt;h3&gt;Implementation&lt;/h3&gt;The following is the complete class with all methods implemented. I provide a basic implementation of the &lt;code&gt;toString&lt;/code&gt; method (which is nice for debugging), and a helper &lt;code&gt;text&lt;/code&gt; method which is a shortcut to build an expression for a sequence of characters. This class is fairly easy to modify to match over a different alphabet, such as arbitrary objects and Iterables instead of Strings (it can be easily generified).&lt;pre class="brush: java"&gt;public abstract class RegEx {&lt;br /&gt;    public abstract RegEx derive(char c);&lt;br /&gt;    public abstract RegEx simplify();&lt;br /&gt;&lt;br /&gt;    public RegEx seq(final RegEx r2) {&lt;br /&gt;        final RegEx r1 = this;&lt;br /&gt;        if(r1 == unmatchable || r2 == unmatchable) return unmatchable;&lt;br /&gt;        if(r1 == empty) return r2;&lt;br /&gt;        if(r2 == empty) return r1;&lt;br /&gt;        return new RegEx() {&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx derive(char c) {&lt;br /&gt;                return r1.simplify().seq(r2.derive(c))&lt;br /&gt;                        .alt0(r1.derive(c).seq(r2));&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx simplify() {&lt;br /&gt;                return r1.simplify().seq(r2.simplify());&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public String toString() {&lt;br /&gt;                return r1 + &amp;quot;&amp;quot; + r2;&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private RegEx alt0(final RegEx r2) {&lt;br /&gt;        final RegEx r1 = this;&lt;br /&gt;        if(r1 == empty || r2 == empty) return empty;&lt;br /&gt;        return alt(r2);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public RegEx alt(final RegEx r2) {&lt;br /&gt;        final RegEx r1 = this;&lt;br /&gt;        if(r1 == unmatchable) return r2;&lt;br /&gt;        if(r2 == unmatchable) return r1;&lt;br /&gt;        return new RegEx() {&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx derive(char c) {&lt;br /&gt;                return r1.derive(c).alt0(r2.derive(c));&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx simplify() {&lt;br /&gt;                return r1.simplify().alt0(r2.simplify());&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public String toString() {&lt;br /&gt;                return &amp;quot;(&amp;quot; + r1 + &amp;quot;|&amp;quot; + r2 + &amp;quot;)&amp;quot;;&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public RegEx rep() {&lt;br /&gt;        final RegEx re = this;&lt;br /&gt;        if(re == unmatchable || re == empty) return empty;&lt;br /&gt;        return new RegEx() {&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx derive(char c) {&lt;br /&gt;                return re.derive(c).seq(re.rep());&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx simplify() {&lt;br /&gt;                return empty;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public String toString() {&lt;br /&gt;                String s = re.toString();&lt;br /&gt;                return s.startsWith(&amp;quot;(&amp;quot;)&lt;br /&gt;                        ? s + &amp;quot;*&amp;quot;&lt;br /&gt;                        :&amp;quot;(&amp;quot; + s + &amp;quot;)*&amp;quot;;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public static RegEx character(final char exp) {&lt;br /&gt;        return new RegEx() {&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx derive(char c) {&lt;br /&gt;                return exp == c?empty:unmatchable;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public RegEx simplify() {&lt;br /&gt;                return unmatchable;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            @Override&lt;br /&gt;            public String toString() {&lt;br /&gt;                return &amp;quot;&amp;quot;+ exp;&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static RegEx text(final String text) {&lt;br /&gt;        RegEx result;&lt;br /&gt;        if(text.isEmpty()) {&lt;br /&gt;            result = empty;&lt;br /&gt;        } else {&lt;br /&gt;            result = character(text.charAt(0));&lt;br /&gt;            for (int i = 1; i &amp;lt; text.length(); i++) {&lt;br /&gt;                result = result.seq(character(text.charAt(i)));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    public boolean matches(final String text) {&lt;br /&gt;        RegEx d = this;&lt;br /&gt;        String s = text;&lt;br /&gt;        //The &amp;#x27;unmatchable&amp;#x27; test is not strictly necessary, but avoids unnecessary derivations&lt;br /&gt;        while(!s.isEmpty() &amp;amp;&amp;amp; d != unmatchable) {&lt;br /&gt;            d = d.derive(s.charAt(0));&lt;br /&gt;            s = s.substring(1);&lt;br /&gt;        }&lt;br /&gt;        return d.simplify() == empty;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static class ConstantRegEx extends RegEx {&lt;br /&gt;        private final String name;&lt;br /&gt;        ConstantRegEx(String name) {&lt;br /&gt;            this.name = name;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        @Override&lt;br /&gt;        public RegEx derive(char c) {&lt;br /&gt;            return unmatchable;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        @Override&lt;br /&gt;        public RegEx simplify() {&lt;br /&gt;            return this;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        @Override&lt;br /&gt;        public String toString() {&lt;br /&gt;            return name;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static final RegEx unmatchable = new ConstantRegEx(&amp;quot;&amp;lt;null&amp;gt;&amp;quot;);&lt;br /&gt;    public static final RegEx empty = new ConstantRegEx(&amp;quot;&amp;lt;empty&amp;gt;&amp;quot;);&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        final RegEx regEx = character(&amp;#x27;a&amp;#x27;)&lt;br /&gt;                             .seq(character(&amp;#x27;b&amp;#x27;).rep())&lt;br /&gt;                             .seq(character(&amp;#x27;c&amp;#x27;).alt(empty));&lt;br /&gt;        if(regEx.matches(&amp;quot;abbc&amp;quot;)) {&lt;br /&gt;            System.out.println(&amp;quot;Matches!!!&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p/&gt;Disclaimer: Any bugs/misconceptions regarding this are my errors, so take everything with a grain of salt. Feel free to use the code portrayed here for any purpose whatsoever, if you do something cool with it I'd like to know, but no pressure.&lt;p/&gt;&lt;a name="footnotes"&gt;Footnotes&lt;/a&gt; &lt;ol&gt;&lt;li&gt;Sometimes the simpler something is, the harder it is to understand. See lambda calculus for example.&lt;br /&gt;&lt;li&gt;I will not use &amp;epsilon; (epsilon) to also represent the empty string since I think it is confusing, even though it is also customary.&lt;br /&gt;&lt;li&gt;I think that the Scheme implementation in that article won't work if you use the repetition operator, but I haven't tested it. It might just as well be that my Scheme-foo is a bit rusty.&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-6884922434155236620?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/6884922434155236620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/03/matching-regular-expressions-using-its.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/6884922434155236620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/6884922434155236620'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/03/matching-regular-expressions-using-its.html' title='Matching Regular Expressions using its Derivatives'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-7647190857161348634</id><published>2011-03-14T19:10:00.000-03:00</published><updated>2011-03-14T19:10:56.854-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Compilers'/><title type='text'>Pratt Parsers</title><content type='html'>Some time ago I came across &lt;a href="http://javascript.crockford.com/tdop/tdop.html"&gt;Pratt parsers&lt;/a&gt;. I had never seen them before, and I found them quite elegant.&lt;br /&gt;&lt;br /&gt;They were first described by Vaughan Pratt in the 1973 paper "Top down operator precedence". From a theoretical perspective they are not particularly interesting, but from an engineering point of view they are fantastic.&lt;br /&gt;&lt;br /&gt;Let's start with a real-world example. This is the grammar from the expression language for my &lt;a href="https://github.com/juancn/performance"&gt;Performance Invariants agent&lt;/a&gt;:&lt;br /&gt;&lt;pre class="brush: java"&gt;/* omitted */&lt;br /&gt;import static performance.compiler.TokenType.*;&lt;br /&gt;&lt;br /&gt;public final class SimpleGrammar&lt;br /&gt;    extends Grammar&amp;lt;TokenType&amp;gt; {&lt;br /&gt;    private SimpleGrammar() {&lt;br /&gt;        infix(LAND, 30);&lt;br /&gt;        infix(LOR, 30);&lt;br /&gt;&lt;br /&gt;        infix(LT, 40);&lt;br /&gt;        infix(GT, 40);&lt;br /&gt;        infix(LE, 40);&lt;br /&gt;        infix(GE, 40);&lt;br /&gt;        infix(EQ, 40);&lt;br /&gt;        infix(NEQ, 40);&lt;br /&gt;&lt;br /&gt;        infix(PLUS, 50);&lt;br /&gt;        infix(MINUS, 50);&lt;br /&gt;&lt;br /&gt;        infix(MUL, 60);&lt;br /&gt;        infix(DIV, 60);&lt;br /&gt;&lt;br /&gt;        unary(MINUS, 70);&lt;br /&gt;        unary(NOT, 70);&lt;br /&gt;&lt;br /&gt;        infix(DOT, 80);&lt;br /&gt;&lt;br /&gt;        clarifying(LPAREN, RPAREN, 0);&lt;br /&gt;        delimited(DOLLAR_LCURLY, RCURLY, 70);&lt;br /&gt;&lt;br /&gt;        literal(INT_LITERAL);&lt;br /&gt;        literal(LONG_LITERAL);&lt;br /&gt;        literal(FLOAT_LITERAL);&lt;br /&gt;        literal(DOUBLE_LITERAL);&lt;br /&gt;        literal(ID);&lt;br /&gt;        literal(THIS);&lt;br /&gt;        literal(STATIC);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static Expr&amp;lt;TokenType&amp;gt; parse(final String text) throws ParseException {&lt;br /&gt;        final Lexer&amp;lt;TokenType&amp;gt; lexer = new JavaLexer(text, 0 , text.length());&lt;br /&gt;        final PrattParser&amp;lt;TokenType&amp;gt; prattParser = new PrattParser&amp;lt;TokenType&amp;gt;(INSTANCE, lexer);&lt;br /&gt;        final Expr&amp;lt;TokenType&amp;gt; expr = prattParser.parseExpression(0);&lt;br /&gt;        if(prattParser.current().getType() != EOF) {&lt;br /&gt;            throw new ParseException(&amp;quot;Unexpected token: &amp;quot; + prattParser.current());&lt;br /&gt;        }&lt;br /&gt;        return expr;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static final SimpleGrammar INSTANCE = new SimpleGrammar();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty, isn't it?&lt;br /&gt;&lt;br /&gt;The number represents a precedence, for infix operators is quite obvious (it's basically a precedence table), but for clarifying and delimited expressions it sets the lower bound for the subexpression. In the grammar above, the delimited expression only accepts dot expressions and literals, parenthesis on the other hand, accept anything.&lt;br /&gt;&lt;br /&gt;So, how does the parser work? The PrattParser itself is rather elegant also:&lt;br /&gt;&lt;pre class="brush: java"&gt;/* omitted */&lt;br /&gt;public final class PrattParser&amp;lt;T&amp;gt; {&lt;br /&gt;    private final Grammar&amp;lt;T&amp;gt; grammar;&lt;br /&gt;    private final Lexer&amp;lt;T&amp;gt; lexer;&lt;br /&gt;    private Token&amp;lt;T&amp;gt; current;&lt;br /&gt;&lt;br /&gt;    public PrattParser(Grammar&amp;lt;T&amp;gt; grammar, Lexer&amp;lt;T&amp;gt; lexer)&lt;br /&gt;            throws ParseException&lt;br /&gt;    {&lt;br /&gt;        this.grammar = grammar;&lt;br /&gt;        this.lexer = lexer;&lt;br /&gt;        current = lexer.next();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Expr&amp;lt;T&amp;gt; parseExpression(int stickiness) throws ParseException {&lt;br /&gt;        Token&amp;lt;T&amp;gt; token = consume();&lt;br /&gt;        final PrefixParser&amp;lt;T&amp;gt; prefix = grammar.getPrefixParser(token);&lt;br /&gt;        if(prefix == null) {&lt;br /&gt;            throw new ParseException(&amp;quot;Unexpected token: &amp;quot; + token);&lt;br /&gt;        }&lt;br /&gt;        Expr&amp;lt;T&amp;gt; left = prefix.parse(this, token);&lt;br /&gt;&lt;br /&gt;        while (stickiness &amp;lt; grammar.getStickiness(current())) {&lt;br /&gt;            token = consume();&lt;br /&gt;&lt;br /&gt;            final InfixParser&amp;lt;T&amp;gt; infix = grammar.getInfixParser(token);&lt;br /&gt;            left = infix.parse(this, left, token);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return left;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Token&amp;lt;T&amp;gt; current() {&lt;br /&gt;        return current;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Token&amp;lt;T&amp;gt; consume() throws ParseException {&lt;br /&gt;        Token&amp;lt;T&amp;gt; result = current;&lt;br /&gt;        current = lexer.next();&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;All the magic happens in the &lt;code&gt;parseExpression&lt;/code&gt; method.&lt;br /&gt;&lt;br /&gt;Given the current token, it fetches an appropriate prefix parser. Prefix parsers recognize simple expressions (such as literals, unary operators, delimited expressions, etc.). Then it goes to process infix parsers according to precedence (&lt;i&gt;stickiness&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;Pratt parsers are a variation of &lt;a href="http://en.wikipedia.org/wiki/Recursive_descent_parser"&gt;recursive descent parsers&lt;/a&gt;. The &lt;code&gt;parseExpression&lt;/code&gt; methods represents a generalized rule in the grammar.&lt;br /&gt;&lt;br /&gt;At this point you're thinking there must be more to this. The trick must be in the Grammar class:&lt;br /&gt;&lt;pre class="brush: java"&gt;/* omitted */&lt;br /&gt;public class Grammar&amp;lt;T&amp;gt; {&lt;br /&gt;    private Map&amp;lt;T, PrefixParser&amp;lt;T&amp;gt;&amp;gt; prefixParsers = new HashMap&amp;lt;T, PrefixParser&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;    private Map&amp;lt;T, InfixParser&amp;lt;T&amp;gt;&amp;gt;  infixParsers = new HashMap&amp;lt;T, InfixParser&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;    PrefixParser&amp;lt;T&amp;gt; getPrefixParser(Token&amp;lt;T&amp;gt; token) {&lt;br /&gt;        return prefixParsers.get(token.getType());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    int getStickiness(Token&amp;lt;T&amp;gt; token) {&lt;br /&gt;        final InfixParser infixParser = getInfixParser(token);&lt;br /&gt;        return infixParser == null?Integer.MIN_VALUE:infixParser.getStickiness();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    InfixParser&amp;lt;T&amp;gt; getInfixParser(Token&amp;lt;T&amp;gt; token) {&lt;br /&gt;        return infixParsers.get(token.getType());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void infix(T ttype, int stickiness)&lt;br /&gt;    {&lt;br /&gt;        infix(ttype, new InfixParser&amp;lt;T&amp;gt;(stickiness));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void infix(T ttype, InfixParser&amp;lt;T&amp;gt; value) {&lt;br /&gt;        infixParsers.put(ttype, value);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void unary(T ttype, int stickiness)&lt;br /&gt;    {&lt;br /&gt;        prefixParsers.put(ttype, new UnaryParser&amp;lt;T&amp;gt;(stickiness));&lt;br /&gt;    }&lt;br /&gt;    protected void literal(T ttype)&lt;br /&gt;    {&lt;br /&gt;        prefix(ttype, new LiteralParser&amp;lt;T&amp;gt;());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void prefix(T ttype, PrefixParser&amp;lt;T&amp;gt; value) {&lt;br /&gt;        prefixParsers.put(ttype, value);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void delimited(T left, T right, int subExpStickiness) {&lt;br /&gt;        prefixParsers.put(left, new DelimitedParser&amp;lt;T&amp;gt;(right, subExpStickiness, true));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void clarifying(T left, T right, int subExpStickiness) {&lt;br /&gt;        prefixParsers.put(left, new DelimitedParser&amp;lt;T&amp;gt;(right, subExpStickiness, false));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nope. Just a couple of maps and some factory methods.&lt;br /&gt;&lt;br /&gt;Even the infix and prefix parsers are rather simple:&lt;br /&gt;&lt;pre class="brush: java"&gt;public class InfixParser&amp;lt;T&amp;gt; {&lt;br /&gt;    private final int stickiness;&lt;br /&gt;    protected InfixParser(int stickiness) {&lt;br /&gt;        this.stickiness = stickiness;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Expr&amp;lt;T&amp;gt; parse(PrattParser&amp;lt;T&amp;gt; prattParser, Expr&amp;lt;T&amp;gt; left, Token&amp;lt;T&amp;gt; token)&lt;br /&gt;            throws ParseException {&lt;br /&gt;        return new BinaryExpr&amp;lt;T&amp;gt;(token, left, prattParser.parseExpression(getStickiness()));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected int getStickiness() {&lt;br /&gt;        return stickiness;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class LiteralParser&amp;lt;T&amp;gt;&lt;br /&gt;        extends PrefixParser&amp;lt;T&amp;gt; {&lt;br /&gt;    public Expr&amp;lt;T&amp;gt; parse(PrattParser&amp;lt;T&amp;gt; prattParser, Token&amp;lt;T&amp;gt; token)&lt;br /&gt;            throws ParseException {&lt;br /&gt;        return new ConstantExpr&amp;lt;T&amp;gt;(token);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class UnaryParser&amp;lt;T&amp;gt;&lt;br /&gt;    extends PrefixParser&amp;lt;T&amp;gt; {&lt;br /&gt;    private final int stickiness;&lt;br /&gt;&lt;br /&gt;    public UnaryParser(int stickiness) {&lt;br /&gt;        this.stickiness = stickiness;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Expr&amp;lt;T&amp;gt; parse(PrattParser&amp;lt;T&amp;gt; prattParser, Token&amp;lt;T&amp;gt; token)&lt;br /&gt;            throws ParseException {&lt;br /&gt;        return new UnaryExpr&amp;lt;T&amp;gt;(token, prattParser.parseExpression(stickiness));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The infix and prefix parsers, just build an AST node. They recursively parse sub-expressions if necessary. If you want to check how delimited expressions work, you can &lt;a href="https://github.com/juancn/performance"&gt;browse the code in github&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;These parsers have several interesting characteristics. One one of them is that the grammar can be modified at runtime (even though it's not shown here) by adding/removing parsers, even while parsing. You can also easily add conditional grammars for sub-languages (think embedded SQL for example).&lt;br /&gt;&lt;br /&gt;The code shown here only supports an LL(1) grammar (if I'm not mistaken), but adding additional lookahead should allow for LL(k) grammars. &lt;br /&gt;&lt;br /&gt;Another interesting fact is that they way the parser is extended (by adding infix/prefix parsers) naturally yields grammars without left recursion. &lt;br /&gt;&lt;br /&gt;One thing to note is that in my simple expression language, I'm not syntactically restricting the types of sub-expressions that infix operators receive, so that has to be checked in a later stage.&lt;br /&gt;&lt;br /&gt;The only downside I can think of (besides the LL(k)-ness), is that these parsers are heavily geared towards expressions (everything is an expressions), but with some creativity statements could be added. For example, you could treat the semicolon in Java/C/C++/etc. as an infix operator.&lt;br /&gt;&lt;br /&gt;Feel free to take all this code as yours for any purpose whatsoever. Happy hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-7647190857161348634?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/7647190857161348634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/03/pratt-parsers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7647190857161348634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7647190857161348634'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/03/pratt-parsers.html' title='Pratt Parsers'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-945322804959350032</id><published>2011-02-25T20:04:00.001-03:00</published><updated>2011-02-27T00:50:51.112-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Performance Invariants (Part II)</title><content type='html'>A few days ago I wrote &lt;a href="http://www.codng.com/2011/02/performance-invariants.html"&gt;a post about performance invariants&lt;/a&gt;. The basic idea behind them, is that there should be an easy way to declare performance constraints at the source code level, and that you should be able to check them every time you run your unit tests. To make a long story short, I have been a busy little bee for the last few days and managed to build &lt;a href="http://github.com/juancn/performance"&gt;a reasonable proof-of-concept&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Let's start with simple example:&lt;br /&gt;&lt;pre class="brush: java"&gt;import performance.annotation.Expect;&lt;br /&gt;...&lt;br /&gt;class Test {&lt;br /&gt;    @Expect("InputStream.read == 0")&lt;br /&gt;    static void process(List&amp;lt;String&amp;gt; list) {&lt;br /&gt;        //...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;What we're asserting here is that we want to make sure that the number of calls to methods called &lt;code&gt;read&lt;/code&gt; defined in classes named &lt;code&gt;InputStream&lt;/code&gt; should be exactly zero.&lt;br /&gt;&lt;br /&gt;If we want to exclude basically all IO, we can change the expectation to:&lt;br /&gt;&lt;pre class="brush: java"&gt;import performance.annotation.Expect;&lt;br /&gt;...&lt;br /&gt;class Test {&lt;br /&gt;    @Expect("InputStream.read == 0 &amp;&amp; OutputStream.write == 0")&lt;br /&gt;    static void process(List&amp;lt;String&amp;gt; list) {&lt;br /&gt;        //...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Note that these are checked even for code that is called indirectly by the method &lt;code&gt;process&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;If we add an innocent looking &lt;code&gt;println&lt;/code&gt;:&lt;br /&gt;&lt;pre class="brush: java"&gt;    @Expect("InputStream.read == 0 &amp;&amp; OutputStream.write == 0")&lt;br /&gt;    static void process(List&amp;lt;String&amp;gt; list) {&lt;br /&gt;        System.out.println("Hi!");&lt;br /&gt;        //...&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And run it with the agent enabled by using:&lt;br /&gt;&lt;pre&gt;~&gt;java -javaagent:./performance-1.0-SNAPSHOT-jar-with-dependencies.jar \&lt;br /&gt;       -Xbootclasspath/a:./performance-1.0-SNAPSHOT-jar-with-dependencies.jar Test&lt;br /&gt;&lt;/pre&gt;You should get something like the following output:&lt;br /&gt;&lt;pre class="brush: java"&gt;Hi!&lt;br /&gt;Exception in thread "main" java.lang.AssertionError: Method 'Test.process' did not fulfil: InputStream.read == 0 &amp;&amp; OutputStream.write == 0&lt;br /&gt;         Matched: [#OutputStream.write=7, #InputStream.read=0]&lt;br /&gt;         Dynamic: []&lt;br /&gt;        at performance.runtime.PerformanceExpectation.validate(PerformanceExpectation.java:69)&lt;br /&gt;        at performance.runtime.ThreadHelper.endExpectation(ThreadHelper.java:52)&lt;br /&gt;        at performance.runtime.Helper.endExpectation(Helper.java:61)&lt;br /&gt;        at Test.process(Test.java:17)&lt;br /&gt;        at Test.main(Test.java:39)&lt;br /&gt;&lt;/pre&gt;This is witchraft, I say! ... well kind of.&lt;br /&gt;&lt;br /&gt;Let's stop a moment and consider what's going on here. Notice the first line of the output. It contains the text "Hi!" that we printed. This happens because the check is performed after the method &lt;code&gt;process&lt;/code&gt; finishes. In the fourth line, you can see how many times each method matched during the execution of the &lt;code&gt;process&lt;/code&gt; method. Ignore the "Dynamic" list for just a second.&lt;br /&gt;&lt;br /&gt;Let's try something a bit more interesting:&lt;br /&gt;&lt;pre class="brush: java"&gt;    class Customer { /*... */}&lt;br /&gt;    //...&lt;br /&gt;    @Expect("Statement.executeUpdate &lt; ${customers.size}")&lt;br /&gt;    void storeCustomers(List&amp;lt;Customer&amp;gt; customers) {&lt;br /&gt;        //...&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;Note the &lt;code&gt;${customers.size}&lt;/code&gt; in the expression, what this intuitively mean is that we want to take the size of the list as an upper bound. It's like the poor programmer's big-O notation.If we were to run this, but assuming that we execute two updates for each customer (instead of one as asserted), we would get:&lt;pre class="brush: java"&gt;Exception in thread "main" java.lang.AssertionError: Method 'Test.storeCustomers' did not fulfil: Statement.executeUpdate &lt; ${customers.size}&lt;br /&gt;         Matched: [#Statement.executeUpdate=50]&lt;br /&gt;         Dynamic: [customers.size=25.0]&lt;br /&gt;        at performance.runtime.PerformanceExpectation.validate(PerformanceExpectation.java:69)&lt;br /&gt;        at performance.runtime.ThreadHelper.endExpectation(ThreadHelper.java:52)&lt;br /&gt;        at performance.runtime.Helper.endExpectation(Helper.java:61)&lt;br /&gt;        at Test.storeCustomers(Test.java:19)&lt;br /&gt;        at Test.main(Test.java:42)&lt;br /&gt;&lt;/pre&gt;Check the third line, this time, the "Dynamic" list contains the length of the list.In general, expressions of the form ${a.b.c.d} are called dynamic values. They refer to arguments, instance variables or static variables.For example: &lt;ul&gt;&lt;li&gt;&lt;code&gt;${static.CONSTANT}&lt;/code&gt; refers to a variable named CONSTANT in the current class.&lt;/li&gt;&lt;li&gt;&lt;code&gt;${this.instance}&lt;/code&gt; refers to a variable named 'instance' in the current object (only valid for instance methods).&lt;/li&gt;&lt;li&gt;&lt;code&gt;${n}&lt;/code&gt; refers to an argument named 'n' (this only works if the class has debug information)&lt;/li&gt;&lt;li&gt;&lt;code&gt;${3}&lt;/code&gt; refers to the fourth argument from the left (zero based indexing)&lt;/li&gt;&lt;/ul&gt;All dynamic values &lt;b&gt;MUST&lt;/b&gt; yield a numeric value, otherwise a failure will be reported at runtime. Currently the library will complain if any dynamic value is &lt;code&gt;null&lt;/code&gt;.&lt;br/&gt;&lt;br/&gt;Although this is an early implementation, it is enough to start implementing performance invariants that can be checked every time you run your unit tests.&lt;br/&gt;Enough for today, in a followup post I'll go into the internals of the agent. If you want to browse the source code or try it out, &lt;a href="http://github.com/juancn/performance"&gt;go and grab a copy from github&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-945322804959350032?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/945322804959350032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/02/performance-invariants-part-ii.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/945322804959350032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/945322804959350032'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/02/performance-invariants-part-ii.html' title='Performance Invariants (Part II)'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-4462203045860048500</id><published>2011-02-22T12:30:00.001-03:00</published><updated>2011-02-27T00:50:55.818-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Performance Invariants</title><content type='html'>&lt;b&gt;UPDATE&lt;/b&gt; A newer post on this subject &lt;a href="http://www.codng.com/2011/02/performance-invariants-part-ii.html"&gt;can be found here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's start with a problem: How do you make unit tests that test for performance?&lt;br /&gt;&lt;br /&gt;It might seem simple, but consider that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Test must be stable across hardware/software configurations&lt;/li&gt;&lt;li&gt;Machine workload should not affect results (at least on &lt;i&gt;normal&lt;/i&gt; situations)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A friend of mine (Fernando Rodriguez-Olivera if you must know) thought of the following (among many other things):&lt;br /&gt;For each test run, record interesting metrics, such as:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;specific method calls&lt;/li&gt;&lt;li&gt;number of queries executed&lt;/li&gt;&lt;li&gt;number of I/O operations&lt;/li&gt;&lt;li&gt;etc.&lt;/li&gt;&lt;/ul&gt;And after the test run, assert that these values are under a certain threshold. If they're not, fail the test.&lt;br /&gt;He even implemented a proof-of-concept using &lt;a href="http://www.beanshell.org/"&gt;BeanShell&lt;/a&gt; to record these stats to a file during the test run, and it would check the constraints after the fact.&lt;br /&gt;&lt;br /&gt;Yesterday I was going over these ideas while preparing a presentation on code quality and something just clicked: annotate methods with performance invariants.&lt;br /&gt;The concept is similar to pre/post conditions. Each annotation is basically a post condition on the method call that states which performance "promises" the method makes.&lt;br /&gt;&lt;br /&gt;For example you should be able to do something like:&lt;br /&gt;&lt;pre class="brush: java"&gt;@Ensure("queryCount &lt;= 1")&lt;br /&gt;public CustomerInfo loadCustomerInfo() {...}&lt;br /&gt;&lt;/pre&gt;Or maybe something like this:&lt;pre class="brush: java"&gt;@Ensure("count(java.lang.Comparable.compareTo) &lt; ceil(log(this.customers.size()))")&lt;br /&gt;public CustomerInfo findById(String id) {...}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These promises are enabled only during testing since checking for them might be a bit expensive for a production system.&lt;br /&gt;&lt;br /&gt;As this is quite recent I don't have anything working (yet), but I think it's worth exploring.&lt;br /&gt;If I manage to find some time to try and build it, I'll post some updates here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-4462203045860048500?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/4462203045860048500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/02/performance-invariants.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/4462203045860048500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/4462203045860048500'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/02/performance-invariants.html' title='Performance Invariants'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-469751218797970404</id><published>2011-02-21T16:53:00.000-03:00</published><updated>2011-02-21T18:30:35.026-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>gluUnProject for iPhone/iOS</title><content type='html'>I had a hard time finding a suitable implementation of gluUnProject for an iPhone project I was working on, so I decided to port the original implementation by SGI.&lt;br /&gt;&lt;br /&gt;This is the header file (I called it "project.h"):&lt;br /&gt;&lt;pre class="brush: cpp"&gt;#ifndef __GLU_PROJECT_IOS&lt;br /&gt;#define __GLU_PROJECT_IOS&lt;br /&gt;&lt;br /&gt;#include &amp;lt;OpenGLES/ES1/gl.h&amp;gt;&lt;br /&gt;#include &amp;lt;OpenGLES/ES1/glext.h&amp;gt;&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,&lt;br /&gt;    GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,&lt;br /&gt;    GLfloat upz);&lt;br /&gt;&lt;br /&gt;GLint&lt;br /&gt;gluProject(GLfloat objx, GLfloat objy, GLfloat objz, &lt;br /&gt;     const GLfloat modelMatrix[16], &lt;br /&gt;     const GLfloat projMatrix[16],&lt;br /&gt;     const GLint viewport[4],&lt;br /&gt;     GLfloat *winx, GLfloat *winy, GLfloat *winz);&lt;br /&gt;&lt;br /&gt;GLint&lt;br /&gt;gluUnProject(GLfloat winx, GLfloat winy, GLfloat winz,&lt;br /&gt;    const GLfloat modelMatrix[16], &lt;br /&gt;    const GLfloat projMatrix[16],&lt;br /&gt;    const GLint viewport[4],&lt;br /&gt;    GLfloat *objx, GLfloat *objy, GLfloat *objz);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;GLint&lt;br /&gt;gluUnProject4(GLfloat winx, GLfloat winy, GLfloat winz, GLfloat clipw,&lt;br /&gt;     const GLfloat modelMatrix[16], &lt;br /&gt;     const GLfloat projMatrix[16],&lt;br /&gt;     const GLint viewport[4],&lt;br /&gt;     GLclampf nearVal, GLclampf farVal,      &lt;br /&gt;     GLfloat *objx, GLfloat *objy, GLfloat *objz,&lt;br /&gt;     GLfloat *objw);&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;gluPickMatrix(GLfloat x, GLfloat y, GLfloat deltax, GLfloat deltay,&lt;br /&gt;     GLint viewport[4]);&lt;br /&gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;And the source code:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;#include &amp;quot;project.h&amp;quot;&lt;br /&gt;#include &amp;lt;math.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;** Make m an identity matrix&lt;br /&gt;*/&lt;br /&gt;static void __gluMakeIdentityf(GLfloat m[16])&lt;br /&gt;{&lt;br /&gt;    m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;&lt;br /&gt;    m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;&lt;br /&gt;    m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;&lt;br /&gt;    m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#define __glPi 3.14159265358979323846&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)&lt;br /&gt;{&lt;br /&gt;    GLfloat m[4][4];&lt;br /&gt;    float sine, cotangent, deltaZ;&lt;br /&gt;    float radians = fovy / 2 * __glPi / 180;&lt;br /&gt;&lt;br /&gt;    deltaZ = zFar - zNear;&lt;br /&gt;    sine = sin(radians);&lt;br /&gt;    if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {&lt;br /&gt; return;&lt;br /&gt;    }&lt;br /&gt;    cotangent = cos(radians) / sine;&lt;br /&gt;&lt;br /&gt;    __gluMakeIdentityf(&amp;amp;m[0][0]);&lt;br /&gt;    m[0][0] = cotangent / aspect;&lt;br /&gt;    m[1][1] = cotangent;&lt;br /&gt;    m[2][2] = -(zFar + zNear) / deltaZ;&lt;br /&gt;    m[2][3] = -1;&lt;br /&gt;    m[3][2] = -2 * zNear * zFar / deltaZ;&lt;br /&gt;    m[3][3] = 0;&lt;br /&gt;    glMultMatrixf(&amp;amp;m[0][0]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void normalize(float v[3])&lt;br /&gt;{&lt;br /&gt;    float r;&lt;br /&gt;&lt;br /&gt;    r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );&lt;br /&gt;    if (r == 0.0) return;&lt;br /&gt;&lt;br /&gt;    v[0] /= r;&lt;br /&gt;    v[1] /= r;&lt;br /&gt;    v[2] /= r;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void cross(float v1[3], float v2[3], float result[3])&lt;br /&gt;{&lt;br /&gt;    result[0] = v1[1]*v2[2] - v1[2]*v2[1];&lt;br /&gt;    result[1] = v1[2]*v2[0] - v1[0]*v2[2];&lt;br /&gt;    result[2] = v1[0]*v2[1] - v1[1]*v2[0];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,&lt;br /&gt;   GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,&lt;br /&gt;   GLfloat upz)&lt;br /&gt;{&lt;br /&gt;    float forward[3], side[3], up[3];&lt;br /&gt;    GLfloat m[4][4];&lt;br /&gt;&lt;br /&gt;    forward[0] = centerx - eyex;&lt;br /&gt;    forward[1] = centery - eyey;&lt;br /&gt;    forward[2] = centerz - eyez;&lt;br /&gt;&lt;br /&gt;    up[0] = upx;&lt;br /&gt;    up[1] = upy;&lt;br /&gt;    up[2] = upz;&lt;br /&gt;&lt;br /&gt;    normalize(forward);&lt;br /&gt;&lt;br /&gt;    /* Side = forward x up */&lt;br /&gt;    cross(forward, up, side);&lt;br /&gt;    normalize(side);&lt;br /&gt;&lt;br /&gt;    /* Recompute up as: up = side x forward */&lt;br /&gt;    cross(side, forward, up);&lt;br /&gt;&lt;br /&gt;    __gluMakeIdentityf(&amp;amp;m[0][0]);&lt;br /&gt;    m[0][0] = side[0];&lt;br /&gt;    m[1][0] = side[1];&lt;br /&gt;    m[2][0] = side[2];&lt;br /&gt;&lt;br /&gt;    m[0][1] = up[0];&lt;br /&gt;    m[1][1] = up[1];&lt;br /&gt;    m[2][1] = up[2];&lt;br /&gt;&lt;br /&gt;    m[0][2] = -forward[0];&lt;br /&gt;    m[1][2] = -forward[1];&lt;br /&gt;    m[2][2] = -forward[2];&lt;br /&gt;&lt;br /&gt;    glMultMatrixf(&amp;amp;m[0][0]);&lt;br /&gt;    glTranslatef(-eyex, -eyey, -eyez);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void __gluMultMatrixVecf(const GLfloat matrix[16], const GLfloat in[4],&lt;br /&gt;        GLfloat out[4])&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    for (i=0; i&amp;lt;4; i++) {&lt;br /&gt; out[i] = &lt;br /&gt;     in[0] * matrix[0*4+i] +&lt;br /&gt;     in[1] * matrix[1*4+i] +&lt;br /&gt;     in[2] * matrix[2*4+i] +&lt;br /&gt;     in[3] * matrix[3*4+i];&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;** Invert 4x4 matrix.&lt;br /&gt;** Contributed by David Moore (See Mesa bug #6748)&lt;br /&gt;*/&lt;br /&gt;static int __gluInvertMatrixf(const GLfloat m[16], GLfloat invOut[16])&lt;br /&gt;{&lt;br /&gt;    float inv[16], det;&lt;br /&gt;    int i;&lt;br /&gt;&lt;br /&gt;    inv[0] =   m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]&lt;br /&gt;             + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];&lt;br /&gt;    inv[4] =  -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]&lt;br /&gt;             - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];&lt;br /&gt;    inv[8] =   m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]&lt;br /&gt;             + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];&lt;br /&gt;    inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]&lt;br /&gt;             - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];&lt;br /&gt;    inv[1] =  -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]&lt;br /&gt;             - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];&lt;br /&gt;    inv[5] =   m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]&lt;br /&gt;             + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];&lt;br /&gt;    inv[9] =  -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]&lt;br /&gt;             - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];&lt;br /&gt;    inv[13] =  m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]&lt;br /&gt;             + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];&lt;br /&gt;    inv[2] =   m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]&lt;br /&gt;             + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];&lt;br /&gt;    inv[6] =  -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]&lt;br /&gt;             - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];&lt;br /&gt;    inv[10] =  m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]&lt;br /&gt;             + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];&lt;br /&gt;    inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]&lt;br /&gt;             - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];&lt;br /&gt;    inv[3] =  -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]&lt;br /&gt;             - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];&lt;br /&gt;    inv[7] =   m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]&lt;br /&gt;             + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];&lt;br /&gt;    inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]&lt;br /&gt;             - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];&lt;br /&gt;    inv[15] =  m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]&lt;br /&gt;             + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];&lt;br /&gt;&lt;br /&gt;    det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];&lt;br /&gt;    if (det == 0)&lt;br /&gt;        return GL_FALSE;&lt;br /&gt;&lt;br /&gt;    det = 1.0 / det;&lt;br /&gt;&lt;br /&gt;    for (i = 0; i &amp;lt; 16; i++)&lt;br /&gt;        invOut[i] = inv[i] * det;&lt;br /&gt;&lt;br /&gt;    return GL_TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void __gluMultMatricesf(const GLfloat a[16], const GLfloat b[16],&lt;br /&gt;    GLfloat r[16])&lt;br /&gt;{&lt;br /&gt;    int i, j;&lt;br /&gt;&lt;br /&gt;    for (i = 0; i &amp;lt; 4; i++) {&lt;br /&gt; for (j = 0; j &amp;lt; 4; j++) {&lt;br /&gt;     r[i*4+j] = &lt;br /&gt;  a[i*4+0]*b[0*4+j] +&lt;br /&gt;  a[i*4+1]*b[1*4+j] +&lt;br /&gt;  a[i*4+2]*b[2*4+j] +&lt;br /&gt;  a[i*4+3]*b[3*4+j];&lt;br /&gt; }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;GLint&lt;br /&gt;gluProject(GLfloat objx, GLfloat objy, GLfloat objz, &lt;br /&gt;       const GLfloat modelMatrix[16], &lt;br /&gt;       const GLfloat projMatrix[16],&lt;br /&gt;              const GLint viewport[4],&lt;br /&gt;       GLfloat *winx, GLfloat *winy, GLfloat *winz)&lt;br /&gt;{&lt;br /&gt;    float in[4];&lt;br /&gt;    float out[4];&lt;br /&gt;&lt;br /&gt;    in[0]=objx;&lt;br /&gt;    in[1]=objy;&lt;br /&gt;    in[2]=objz;&lt;br /&gt;    in[3]=1.0;&lt;br /&gt;    __gluMultMatrixVecf(modelMatrix, in, out);&lt;br /&gt;    __gluMultMatrixVecf(projMatrix, out, in);&lt;br /&gt;    if (in[3] == 0.0) return(GL_FALSE);&lt;br /&gt;    in[0] /= in[3];&lt;br /&gt;    in[1] /= in[3];&lt;br /&gt;    in[2] /= in[3];&lt;br /&gt;    /* Map x, y and z to range 0-1 */&lt;br /&gt;    in[0] = in[0] * 0.5 + 0.5;&lt;br /&gt;    in[1] = in[1] * 0.5 + 0.5;&lt;br /&gt;    in[2] = in[2] * 0.5 + 0.5;&lt;br /&gt;&lt;br /&gt;    /* Map x,y to viewport */&lt;br /&gt;    in[0] = in[0] * viewport[2] + viewport[0];&lt;br /&gt;    in[1] = in[1] * viewport[3] + viewport[1];&lt;br /&gt;&lt;br /&gt;    *winx=in[0];&lt;br /&gt;    *winy=in[1];&lt;br /&gt;    *winz=in[2];&lt;br /&gt;    return(GL_TRUE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;GLint&lt;br /&gt;gluUnProject(GLfloat winx, GLfloat winy, GLfloat winz,&lt;br /&gt;  const GLfloat modelMatrix[16], &lt;br /&gt;  const GLfloat projMatrix[16],&lt;br /&gt;                const GLint viewport[4],&lt;br /&gt;         GLfloat *objx, GLfloat *objy, GLfloat *objz)&lt;br /&gt;{&lt;br /&gt;    float finalMatrix[16];&lt;br /&gt;    float in[4];&lt;br /&gt;    float out[4];&lt;br /&gt;&lt;br /&gt;    __gluMultMatricesf(modelMatrix, projMatrix, finalMatrix);&lt;br /&gt;    if (!__gluInvertMatrixf(finalMatrix, finalMatrix)) return(GL_FALSE);&lt;br /&gt;&lt;br /&gt;    in[0]=winx;&lt;br /&gt;    in[1]=winy;&lt;br /&gt;    in[2]=winz;&lt;br /&gt;    in[3]=1.0;&lt;br /&gt;&lt;br /&gt;    /* Map x and y from window coordinates */&lt;br /&gt;    in[0] = (in[0] - viewport[0]) / viewport[2];&lt;br /&gt;    in[1] = (in[1] - viewport[1]) / viewport[3];&lt;br /&gt;&lt;br /&gt;    /* Map to range -1 to 1 */&lt;br /&gt;    in[0] = in[0] * 2 - 1;&lt;br /&gt;    in[1] = in[1] * 2 - 1;&lt;br /&gt;    in[2] = in[2] * 2 - 1;&lt;br /&gt;&lt;br /&gt;    __gluMultMatrixVecf(finalMatrix, in, out);&lt;br /&gt;    if (out[3] == 0.0) return(GL_FALSE);&lt;br /&gt;    out[0] /= out[3];&lt;br /&gt;    out[1] /= out[3];&lt;br /&gt;    out[2] /= out[3];&lt;br /&gt;    *objx = out[0];&lt;br /&gt;    *objy = out[1];&lt;br /&gt;    *objz = out[2];&lt;br /&gt;    return(GL_TRUE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;GLint&lt;br /&gt;gluUnProject4(GLfloat winx, GLfloat winy, GLfloat winz, GLfloat clipw,&lt;br /&gt;       const GLfloat modelMatrix[16], &lt;br /&gt;       const GLfloat projMatrix[16],&lt;br /&gt;       const GLint viewport[4],&lt;br /&gt;       GLclampf nearVal, GLclampf farVal,      &lt;br /&gt;       GLfloat *objx, GLfloat *objy, GLfloat *objz,&lt;br /&gt;       GLfloat *objw)&lt;br /&gt;{&lt;br /&gt;    float finalMatrix[16];&lt;br /&gt;    float in[4];&lt;br /&gt;    float out[4];&lt;br /&gt;&lt;br /&gt;    __gluMultMatricesf(modelMatrix, projMatrix, finalMatrix);&lt;br /&gt;    if (!__gluInvertMatrixf(finalMatrix, finalMatrix)) return(GL_FALSE);&lt;br /&gt;&lt;br /&gt;    in[0]=winx;&lt;br /&gt;    in[1]=winy;&lt;br /&gt;    in[2]=winz;&lt;br /&gt;    in[3]=clipw;&lt;br /&gt;&lt;br /&gt;    /* Map x and y from window coordinates */&lt;br /&gt;    in[0] = (in[0] - viewport[0]) / viewport[2];&lt;br /&gt;    in[1] = (in[1] - viewport[1]) / viewport[3];&lt;br /&gt;    in[2] = (in[2] - nearVal) / (farVal - nearVal);&lt;br /&gt;&lt;br /&gt;    /* Map to range -1 to 1 */&lt;br /&gt;    in[0] = in[0] * 2 - 1;&lt;br /&gt;    in[1] = in[1] * 2 - 1;&lt;br /&gt;    in[2] = in[2] * 2 - 1;&lt;br /&gt;&lt;br /&gt;    __gluMultMatrixVecf(finalMatrix, in, out);&lt;br /&gt;    if (out[3] == 0.0) return(GL_FALSE);&lt;br /&gt;    *objx = out[0];&lt;br /&gt;    *objy = out[1];&lt;br /&gt;    *objz = out[2];&lt;br /&gt;    *objw = out[3];&lt;br /&gt;    return(GL_TRUE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;gluPickMatrix(GLfloat x, GLfloat y, GLfloat deltax, GLfloat deltay,&lt;br /&gt;    GLint viewport[4])&lt;br /&gt;{&lt;br /&gt;    if (deltax &amp;lt;= 0 || deltay &amp;lt;= 0) { &lt;br /&gt; return;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /* Translate and scale the picked region to the entire window */&lt;br /&gt;    glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax,&lt;br /&gt;     (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);&lt;br /&gt;    glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'm thinking on porting the entire GLUT library to the iPhone and sharing it on github. Anyone interested?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-469751218797970404?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/469751218797970404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2011/02/gluunproject-for-iphoneios.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/469751218797970404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/469751218797970404'/><link rel='alternate' type='text/html' href='http://www.codng.com/2011/02/gluunproject-for-iphoneios.html' title='gluUnProject for iPhone/iOS'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-7663702377023578885</id><published>2009-12-02T14:02:00.001-03:00</published><updated>2011-02-21T14:34:27.254-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Compilers'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Naive Brainf**k to Java compiler</title><content type='html'>Some time ago the &lt;a href="http://en.wikipedia.org/wiki/Brainfuck"&gt;brainf**k&lt;/a&gt; language caught my eye (I still don't feel comfortable spelling it right).&lt;br /&gt;&lt;br /&gt;It's a &lt;a href="http://en.wikipedia.org/wiki/Turing_tarpit"&gt;turing tarpit&lt;/a&gt;, but one not very complicated at that (for something more esoteric see &lt;a href="http://en.wikipedia.org/wiki/Malbolge"&gt;Malbolge&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Whitespace_(programming_language)"&gt;Whitespace&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;The language is very simple, it has eight instructions. So I had to write a compiler for it. It turns out to be quite easy to do:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;import static java.lang.System.out;&lt;br /&gt;&lt;br /&gt;public class BrainFk&lt;br /&gt;{&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt; out.println("public class " + args[0] + "{");&lt;br /&gt; out.println("public static void main(String args[]) throws Throwable {");&lt;br /&gt; out.println("int[] memory = new int[30000];");&lt;br /&gt; out.println("int data = 0;");&lt;br /&gt; final String code = args[1];&lt;br /&gt; for(int i = 0; i &amp;lt; code.length(); i++) {&lt;br /&gt;  char c = code.charAt(i);&lt;br /&gt;  switch(c) {&lt;br /&gt;   case '&amp;gt;':&lt;br /&gt;    out.println("++data;");&lt;br /&gt;    break;&lt;br /&gt;   case '&amp;lt;':&lt;br /&gt;    out.println("--data;");&lt;br /&gt;    break;&lt;br /&gt;   case '+':&lt;br /&gt;    out.println("++memory[data];");&lt;br /&gt;    break;&lt;br /&gt;   case '-':&lt;br /&gt;    out.println("--memory[data];");&lt;br /&gt;    break;&lt;br /&gt;   case '.':&lt;br /&gt;    out.println("System.out.print((char)(0xFF &amp;amp; memory[data]));");&lt;br /&gt;    break;&lt;br /&gt;   case ',':&lt;br /&gt;    out.println("memory[data] = System.in.read();");&lt;br /&gt;    break;&lt;br /&gt;   case '[':&lt;br /&gt;    out.println("while(memory[data] != 0) {");&lt;br /&gt;    break;&lt;br /&gt;   case ']':&lt;br /&gt;    out.println("}");&lt;br /&gt;    break;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  out.println("}}");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can use it to compile the hello world sample from the Wikipedia page:&lt;br /&gt;&lt;pre&gt;~&amp;gt;java BrainFk Hello "++++++++++[&amp;gt;+++++++&amp;gt;++++++++++&amp;gt;+++&amp;gt;+&amp;lt;&amp;lt;&amp;lt;&amp;lt;-]&amp;gt;++.&amp;gt;+.+++++++..+++.&amp;gt;++.&amp;lt;&amp;lt;+++++++++++++++.&amp;gt;.+++.------.--------.&amp;gt;+.&amp;gt;." &amp;gt; Hello.java&lt;br /&gt;~&amp;gt;javac Hello.java&lt;br /&gt;~&amp;gt;java Hello&lt;br /&gt;Hello World!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sometime I'll have to post the Forth interpreter in Java I wrote (I know some might consider sacrilege to use both languages in the same sentence, but you can't please everyone!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-7663702377023578885?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/7663702377023578885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2009/12/naive-brainfk-to-java-compiler.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7663702377023578885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7663702377023578885'/><link rel='alternate' type='text/html' href='http://www.codng.com/2009/12/naive-brainfk-to-java-compiler.html' title='Naive Brainf**k to Java compiler'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-1378034996884219704</id><published>2009-11-25T13:17:00.000-03:00</published><updated>2011-02-21T14:22:52.101-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microposts'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><category scheme='http://www.blogger.com/atom/ns#' term='Image Processing'/><title type='text'>Building 3D models using a Web Cam</title><content type='html'>Incredible technology to build a 3D model from a video of the desired object. Just watch the video:&lt;br/&gt;&lt;br/&gt;&lt;object width="480" height="295"&gt;&lt;param name="movie" value="http://www.youtube.com/v/vEOmzjImsVc&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/vEOmzjImsVc&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br/&gt;&lt;br/&gt;You can go to the &lt;a href="http://mi.eng.cam.ac.uk/~qp202/my_papers/BMVC09/"&gt;project site&lt;/a&gt; for more details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-1378034996884219704?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/1378034996884219704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2009/11/building-3d-models-using-web-cam.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/1378034996884219704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/1378034996884219704'/><link rel='alternate' type='text/html' href='http://www.codng.com/2009/11/building-3d-models-using-web-cam.html' title='Building 3D models using a Web Cam'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-1716568941127949316</id><published>2009-10-02T09:59:00.001-03:00</published><updated>2011-02-21T14:49:07.404-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Image Processing'/><title type='text'>Image Downscaling</title><content type='html'>A few days ago, a friend contacted me because he needed good image downscaling for a project he's working on.&lt;br /&gt;I remebered reading &lt;a href="http://www.xs4all.nl/~bvdwolf/main/foto/down_sample/down_sample.htm"&gt;an article&lt;/a&gt; about the types of issues when downsampling an image (and specifically a difficult one). After a few tests, I settled for a gaussian pre-blur.&lt;br /&gt;I think I got pretty good results:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-2P8SZNArFIM/TWKlQ0a2RdI/AAAAAAAAB7s/NXdpO4x-0yg/s1600/downsampled.png" imageanchor="1" style=""&gt;&lt;img border="0" height="200" width="200" src="http://2.bp.blogspot.com/-2P8SZNArFIM/TWKlQ0a2RdI/AAAAAAAAB7s/NXdpO4x-0yg/s320/downsampled.png" /&gt;&lt;/a&gt;&lt;/div&gt;Go to the &lt;a href="http://www.xs4all.nl/~bvdwolf/main/foto/down_sample/down_sample.htm"&gt;original article&lt;/a&gt; to get the source image.&lt;br /&gt;The code also tries to fit and center the image in the target. That means it will return an image with the exact size you request. It will center and rescale the source image and leav transparent background for filler space.&lt;br /&gt;&lt;pre class="brush: java"&gt;import javax.imageio.ImageIO;&lt;br /&gt;import java.awt.*;&lt;br /&gt;import java.awt.geom.AffineTransform;&lt;br /&gt;import java.awt.image.*;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;public class FitImage {&lt;br /&gt;&lt;br /&gt; public static BufferedImage fitImage(final BufferedImage input, final int width, final int height) {&lt;br /&gt;  final int inputWidth = input.getWidth();&lt;br /&gt;  final int inputHeight = input.getHeight();&lt;br /&gt;&lt;br /&gt;  final double hScale = width/(double)inputWidth;&lt;br /&gt;  final double vScale = height/(double)inputHeight;&lt;br /&gt;&lt;br /&gt;  final double scaleFactor = Math.min(hScale, vScale);&lt;br /&gt;&lt;br /&gt;  //Create a temp image&lt;br /&gt;  final BufferedImage temp = new BufferedImage(inputWidth,inputHeight, BufferedImage.TYPE_INT_ARGB);&lt;br /&gt;&lt;br /&gt;  if(scaleFactor &amp;lt; 1) {&lt;br /&gt;   //Create a gaussian kernel with a raduis proportional to the scale factor and convolve it with the image&lt;br /&gt;   final Kernel kernel = make2DKernel((float) (1 / scaleFactor));&lt;br /&gt;   final BufferedImageOp op = new ConvolveOp(kernel);&lt;br /&gt;   op.filter(input, temp);&lt;br /&gt;  } else {&lt;br /&gt;   temp.createGraphics().drawImage(input, null, 0,0);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  final BufferedImage output = new BufferedImage(width,height, BufferedImage.TYPE_INT_ARGB);&lt;br /&gt;  final Graphics2D g = output.createGraphics();&lt;br /&gt;  g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);&lt;br /&gt;  g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);&lt;br /&gt;  g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);&lt;br /&gt;  g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);&lt;br /&gt;  g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);&lt;br /&gt;&lt;br /&gt;  final int xOffset = (int) Math.max(0, (width - inputWidth * scaleFactor) / 2);&lt;br /&gt;  final int yOffset = (int) Math.max(0, (height - inputHeight * scaleFactor) / 2);&lt;br /&gt;  final AffineTransform scaleInstance = AffineTransform.getScaleInstance(scaleFactor, scaleFactor);&lt;br /&gt;  final AffineTransformOp transformOp = new AffineTransformOp(scaleInstance, AffineTransformOp.TYPE_BICUBIC);&lt;br /&gt;  g.drawImage(temp, transformOp, xOffset, yOffset);&lt;br /&gt;  return output;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static Kernel make2DKernel(float radius) {&lt;br /&gt;  final int r = (int)Math.ceil(radius);&lt;br /&gt;  final int size = r*2+1;&lt;br /&gt;  float standardDeviation = radius/3; //Guess a standard dev from the radius&lt;br /&gt;&lt;br /&gt;  final float center = (float) (size/2);&lt;br /&gt;  float sigmaSquared = standardDeviation * standardDeviation;&lt;br /&gt;&lt;br /&gt;  final float[] coeffs = new float[size*size];&lt;br /&gt;&lt;br /&gt;  for(int x = 0; x &amp;lt; size; x++ ) {&lt;br /&gt;   for(int y = 0; y &amp;lt; size; y++ ) {&lt;br /&gt;   double distFromCenterSquared = ( x - center ) * (x - center ) + ( y - center ) * ( y - center );&lt;br /&gt;   double baseEexponential = Math.pow( Math.E, -distFromCenterSquared / ( 2.0f * sigmaSquared ) );&lt;br /&gt;   coeffs[y*size+x]= (float) (baseEexponential / (2.0f*Math.PI*sigmaSquared ));&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return new Kernel(size, size, coeffs);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static void main(String[] args)&lt;br /&gt;  throws IOException&lt;br /&gt; {&lt;br /&gt;  BufferedImage out = fitImage(ImageIO.read(new File(&amp;quot;Rings1.gif&amp;quot;)), 200, 200);&lt;br /&gt;  ImageIO.write(out, &amp;quot;png&amp;quot;, new File(&amp;quot;test.png&amp;quot;));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-1716568941127949316?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/1716568941127949316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2009/10/image-downscaling.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/1716568941127949316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/1716568941127949316'/><link rel='alternate' type='text/html' href='http://www.codng.com/2009/10/image-downscaling.html' title='Image Downscaling'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-2P8SZNArFIM/TWKlQ0a2RdI/AAAAAAAAB7s/NXdpO4x-0yg/s72-c/downsampled.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-1569514589341981439</id><published>2009-02-03T09:01:00.000-02:00</published><updated>2011-02-21T14:22:51.310-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Great Quotes</title><content type='html'>&lt;blockquote&gt;"My definition of an expert in any field is a person who knows enough about what's really going on to be scared." &lt;strong&gt;- P. J. Plauger, Computer Language, March 1983&lt;/strong&gt;&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;From &lt;a href="http://stackoverflow.com/questions/58640/great-programming-quotes/58796"&gt;Stackoverflow&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-1569514589341981439?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/1569514589341981439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2009/02/great-quotes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/1569514589341981439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/1569514589341981439'/><link rel='alternate' type='text/html' href='http://www.codng.com/2009/02/great-quotes.html' title='Great Quotes'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-7835197793492624685</id><published>2008-08-12T13:03:00.000-03:00</published><updated>2011-02-21T14:22:51.283-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microposts'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Phrase of the Day</title><content type='html'>&lt;blockquote&gt;"The devil is in the details, but exorcism is in implementation, not theory." - (author unknown)&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-7835197793492624685?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/7835197793492624685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2008/08/phrase-of-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7835197793492624685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/7835197793492624685'/><link rel='alternate' type='text/html' href='http://www.codng.com/2008/08/phrase-of-day.html' title='Phrase of the Day'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-524848681224137085</id><published>2008-02-06T18:34:00.000-02:00</published><updated>2011-02-21T14:22:51.058-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>Juggling Chainsaws</title><content type='html'>&lt;a HREF="http://thecodist.com/fiche/thecodist/article/writing-multithreaded-code-is-like-juggling-chainsaws"&gt;Andrew writes&lt;/a&gt; probably one of the funniest and most elocuent articles I've read about thread programming. His opening line:&lt;br/&gt;&lt;blockquote&gt; &lt;em&gt;Writing multithreaded code is like juggling chainsaws; amazing when it works and truly sucky when it doesn't.&lt;/em&gt;&lt;/blockquote&gt;&lt;br/&gt;Truly summarizes the feeling when you've had to deal with a multithreaded system. He argues that probably one of the most difficult thing to achieve is "avoiding doing nothing". I agree with his thoughts in the sense that if you are even considering multithreading something, you are trying to achieve maximum utilization (i.e. not wasting resources). But I'm not sure that getting maximum utilization is the hardest part by itself.&lt;br/&gt;&lt;br/&gt;Besides the usual problems, like avoiding deadlocks or protecting shared data, I always found that the hardest part was, to paraphrase &lt;a HREF="http://thecodist.com/fiche/thecodist/article/writing-multithreaded-code-is-like-juggling-chainsaws"&gt;Andrew&lt;/a&gt;, "avoid doing something".&lt;br/&gt;&lt;br/&gt;What I mean is that in multithreaded applications (it also applies to distributed applications), probably the hardest part is coming up with ways to avoid needing synchronization.&lt;br/&gt;&lt;br/&gt;At least in my experience, figuring out ways to make the system exhibit consistent and predictable behavior without relying on atomicity, has always been the part that most of the design effort is invested in, and if done properly, where the greatest gains in scalability is achieved.&lt;br/&gt;&lt;br/&gt;Take for example the &lt;a HREF="http://labs.google.com/papers/gfs.html"&gt;Google File System&lt;/a&gt;, a massive, multi-petabyte storage filesystem. It is designed to work on clusters of several thousand machines, distibuted across several datacenters (even on different countries).&lt;br/&gt;&lt;br/&gt;To achieve the expected performance, they had to throw away the usual file semantics, and think completely out-of-the box. But don't take my word for it, go, &lt;a HREF="http://labs.google.com/papers/gfs-sosp2003.pdf"&gt;fetch the paper&lt;/a&gt; (if you haven't already done so), and read it yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-524848681224137085?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/524848681224137085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2008/02/juggling-chainsaws.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/524848681224137085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/524848681224137085'/><link rel='alternate' type='text/html' href='http://www.codng.com/2008/02/juggling-chainsaws.html' title='Juggling Chainsaws'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-6912697722857564416</id><published>2007-11-05T16:44:00.000-03:00</published><updated>2011-02-21T14:22:51.043-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Miscellaneous'/><title type='text'>A better way to do concurrent programming (Part 1)</title><content type='html'>A while ago (I think round 2005), some guys from Microsoft Research &lt;a HREF="http://research.microsoft.com/~simonpj/papers/stm/"&gt;published a paper&lt;/a&gt; about Composable Memory Transactions.&lt;br/&gt;&lt;br/&gt;After reading it, I began doing a small implementation in Java (quite ugly, btw), and I was astonished by the possibilities. So quite naturally (being the geek I am), I started toying with the idea of implementing a set of extensions for Java.&lt;br/&gt;&lt;br/&gt;In this and other posts, I'll try to make an introduction to the basic idea. Note that I will probably change existing posts quite often to correct mistakes or ommissions. In this post I'll focus on an overview of the basic idea, in a future post I'll address composition of transactions (the &lt;em&gt;C&lt;/em&gt; in &lt;em&gt;CMT&lt;/em&gt;), static checking for side effects, and alternatives to implement the runtime part of this. If you're really curious, I recommend reading the original paper.&lt;br/&gt;&lt;br/&gt;The gist of the idea is to replace common locking based semantics with in-memory transactions, so instead of writing complex locking semantics, you rely on optimistic locking handled by the runtime.&lt;br/&gt;&lt;br/&gt;The following example shows how a producer-consumer problem can be solved with a queue of fixed size using Java with CMT:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;strong&gt;public&lt;/strong&gt; class BufferedQueue { &lt;br/&gt;    &lt;strong&gt;private&lt;/strong&gt; LinkedList list; &lt;br/&gt;    &lt;strong&gt;public&lt;/strong&gt; BufferedQueue() { &lt;br/&gt;        list = new LinkedList(); &lt;br/&gt;    } &lt;br/&gt;    &lt;strong&gt;public&lt;/strong&gt; Object consume() { &lt;br/&gt;        Object value; &lt;br/&gt;        &lt;strong&gt;atomic&lt;/strong&gt; { &lt;br/&gt;            &lt;strong&gt;if&lt;/strong&gt;(list.isEmpty()) { &lt;br/&gt;                &lt;strong&gt;retry&lt;/strong&gt;; &lt;br/&gt;            } &lt;br/&gt;            value = list.removeFirst(); &lt;br/&gt;        } &lt;br/&gt;        &lt;strong&gt;return&lt;/strong&gt; value; &lt;br/&gt;    } &lt;br/&gt;    &lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;void&lt;/strong&gt; produce(Object value) { &lt;br/&gt;        &lt;strong&gt;atomic&lt;/strong&gt; { &lt;br/&gt;            &lt;strong&gt;if&lt;/strong&gt;(list.size() &amp;gt; 10) { &lt;br/&gt;                &lt;strong&gt;retry&lt;/strong&gt;; &lt;br/&gt;            } &lt;br/&gt;            list.add(value); &lt;br/&gt;        } &lt;br/&gt;    } &lt;br/&gt;    &lt;strong&gt;public&lt;/strong&gt; Object peek() { &lt;br/&gt;        Object value; &lt;br/&gt;        &lt;strong&gt;atomic&lt;/strong&gt; { &lt;br/&gt;            &lt;strong&gt;if&lt;/strong&gt;(list.isEmpty()) { &lt;br/&gt;                &lt;strong&gt;retry&lt;/strong&gt;; &lt;br/&gt;            } &lt;br/&gt;            value = list.getFirst(); &lt;br/&gt;        } &lt;strong&gt;else&lt;/strong&gt; { &lt;br/&gt;            value = null; &lt;br/&gt;        } &lt;br/&gt;        &lt;strong&gt;return&lt;/strong&gt; value; &lt;br/&gt;    } &lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Take a look at two keywords: &lt;strong&gt;atomic&lt;/strong&gt; and &lt;strong&gt;retry&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;The &lt;strong&gt;atomic&lt;/strong&gt; keyword demarcates a transaction. That means that this block is all-or-nothing (well get to the &lt;strong&gt;else&lt;/strong&gt; later). For example let's take a closer look at the &lt;code&gt;consume&lt;/code&gt; method.&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;strong&gt;public&lt;/strong&gt; Object consume() { &lt;br/&gt;    Object value; &lt;br/&gt;    &lt;strong&gt;atomic&lt;/strong&gt; { &lt;br/&gt;        if(list.isEmpty()) { &lt;br/&gt;            &lt;strong&gt;retry&lt;/strong&gt;; &lt;br/&gt;        } &lt;br/&gt;        value = list.removeFirst(); &lt;br/&gt;    } &lt;br/&gt;    &lt;strong&gt;return&lt;/strong&gt; value; &lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;The &lt;strong&gt;atomic&lt;/strong&gt; statement starts a transaction. In this transaction we first check to see if the list is empty. If it is, we issue a &lt;strong&gt;retry&lt;/strong&gt; statement.&lt;br/&gt;The &lt;strong&gt;retry&lt;/strong&gt; statement, rolls-back all changes and suspends the transaction until at least one of the fields used in the block (either directly or indirectly) is modified by another transaction committing. When this happens, the execution is restarted in a new transaction at the beginning of the enclosing atomic block.&lt;br/&gt;If this time the list is not empty, the first element is removed from the list, and the transaction is committed. If at the time of the commit there is a conflict with another transaction, the execution is rolled back and retried.&lt;br/&gt;&lt;br/&gt;Note that it is very important that the atomic blocks do not have side-effects (such as creating files, etc.) outside of the control of the transaction manager.&lt;br/&gt;&lt;br/&gt;(to be continued...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-6912697722857564416?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/6912697722857564416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2007/11/better-way-to-do-concurrent-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/6912697722857564416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/6912697722857564416'/><link rel='alternate' type='text/html' href='http://www.codng.com/2007/11/better-way-to-do-concurrent-programming.html' title='A better way to do concurrent programming (Part 1)'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-4954101210106993322</id><published>2007-11-05T15:26:00.000-03:00</published><updated>2011-02-21T14:22:51.013-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>13949712720901ForOSX - Java for OSX</title><content type='html'>In a &lt;a HREF="http://blogs.sun.com/bblfish/entry/vote_for_java6_on_leopard"&gt;blog post&lt;/a&gt; henry resumes the sad state of affairs of Java in OSX.&lt;br/&gt;&lt;br/&gt;So here I am, joining this campaign by posting this entry in protest! Apple, please don't let us down!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-4954101210106993322?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/4954101210106993322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2007/11/13949712720901forosx-java-for-osx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/4954101210106993322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/4954101210106993322'/><link rel='alternate' type='text/html' href='http://www.codng.com/2007/11/13949712720901forosx-java-for-osx.html' title='13949712720901ForOSX - Java for OSX'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-115040175252102736</id><published>2006-06-15T16:45:00.000-03:00</published><updated>2006-06-15T17:23:53.856-03:00</updated><title type='text'>How the Wii-mote works</title><content type='html'>I know this is pure speculation, but I've been following the Revolution/Wii for a while, and one thing that kept me intrigued is how would Nintendo build such a fantastic controller in a cost effective manner.&lt;br /&gt;&lt;br /&gt;After much thought I think I get it.&lt;br /&gt;&lt;br /&gt;There are two distinct control schemes in the Wii-mote:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Orientation and acceleration&lt;/li&gt;&lt;li&gt;Pointing&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;strong&gt;Orientation and Acceleration&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The orientation and acceleration is quite easy, it only needs an accelerometer. This only tells you the orientation relative to the ground (if you're swinging, the 'perceived' ground shifts). &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Pointing&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This is the hard part.&lt;br /&gt;&lt;br /&gt;There are some observations I (and several others) made:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The Wii-mote has a dark plastic window in the front&lt;/li&gt;&lt;li&gt;You have to place a 'Sensor Bar' under or over the TV&lt;/li&gt;&lt;li&gt;The Wii can track multiple remotes with high acuracy&lt;/li&gt;&lt;li&gt;There is an image sensor in the remote&lt;/li&gt;&lt;li&gt;It has been mentioned of a problem with halogen lights&lt;/li&gt;&lt;li&gt;The remote has to be pointed to the sensor bar for precision aiming&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Keeping those in mind, let me explain how it all makes sense:&lt;/p&gt;&lt;p&gt;First of all, the dark window in the wii-mote, is a visible-light filter. Very similar to the window in front of most remote controls. But instead of having a IR led behind it, it has an image sensor.&lt;/p&gt;&lt;p&gt;This image sensor only 'sees' infrared images, probably in fairly low resolution. It uses this to see the sensor bar, which is basically a row of IR leds.&lt;/p&gt;&lt;p&gt;The wii-mote captures an image of what's in front of it (basically a bright line on a dark background), and looks for the sensor bar (which should be the brightest IR thing in the image). &lt;/p&gt;&lt;p&gt;Since the size of the sensor bar is fixed, you can acurately calculate the distance of the wii-mote from the sensor bar, the rotation (the image sensor sees a line rotated), and the angle of the wii-mote in relation to the center of the sensor bar (the line is off-center in the image).&lt;/p&gt;&lt;p&gt;This approach is quite easy to implement, but it has several drawbacks:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If you are too close to the bar, you cannot acurately estimate the angle or position&lt;/li&gt;&lt;li&gt;If you are too far, the precision also suffers, since the resolution of the image sensor limits how far you can be&lt;/li&gt;&lt;li&gt;Halogen lights (or any other light source with lots of IR light, such as direct sunlight) can effectively blind the image sensor&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It also is very cost effective since low resolution image sensors are quite cheap in bulk, and image tracking is also very well understood for this scenario (think of optical mice, for example).&lt;/p&gt;&lt;p&gt;Hope you enjoyed this.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-115040175252102736?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/115040175252102736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2006/06/how-wii-mote-works.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/115040175252102736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/115040175252102736'/><link rel='alternate' type='text/html' href='http://www.codng.com/2006/06/how-wii-mote-works.html' title='How the Wii-mote works'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112560461137097423</id><published>2005-09-01T16:54:00.000-03:00</published><updated>2005-09-01T16:56:51.376-03:00</updated><title type='text'>Quote of the day</title><content type='html'>&lt;em&gt;"Puctuality is the virtue of the bored"&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://www.quotationspage.com/quotes/Evelyn_Waugh"&gt;- Evelyn Waugh&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;(given that I seem to be unable to blog about something more interesting, I'll keep it simple)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112560461137097423?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112560461137097423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/09/quote-of-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112560461137097423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112560461137097423'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/09/quote-of-day.html' title='Quote of the day'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112499756059028756</id><published>2005-08-25T16:15:00.000-03:00</published><updated>2005-08-25T16:19:20.596-03:00</updated><title type='text'>Quote of the day</title><content type='html'>&lt;em&gt;"... You are free to fold, spindle or mutilate for the betterment of your proprietary closed-source product that makes you zillions of dollars, without penalty ..."&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;from &lt;/strong&gt;&lt;a href="http://www.drools.org/Licensing"&gt;&lt;strong&gt;Drools Licensing&lt;/strong&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Talking about Drools' liberal open source license. LOL!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112499756059028756?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112499756059028756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/08/quote-of-day_25.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112499756059028756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112499756059028756'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/08/quote-of-day_25.html' title='Quote of the day'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112446277962614135</id><published>2005-08-19T11:30:00.000-03:00</published><updated>2005-08-19T11:46:19.630-03:00</updated><title type='text'>Fixed and Floating point for J2ME</title><content type='html'>As you probably know, J2ME in its most basic form doesn't support floating point operations. This can be a problem if you are trying to develop games for it.&lt;br /&gt;&lt;br /&gt;I've been looking around for alternatives, and found that most sites reference you to MathFP (the link I had seems to be broken, google for it), which is a fast library to do fixed point math. The problem with it is that for certain types of calculations, fixed point can be complicated, given that it is hard to represent numbers that are too small or too large, and mix those in the same calculation.&lt;br /&gt;&lt;br /&gt;Browsing around I found &lt;a href="http://www.dclausen.net/projects/microfloat/"&gt;MicroFloat&lt;/a&gt;, which is a very nice floating point library written entirely in Java. The only gotcha is that it requires &lt;strong&gt;long&lt;/strong&gt; support from the KVM.&lt;br /&gt;&lt;br /&gt;There are other libraries around (which I havent tested) such as &lt;a href="http://sourceforge.net/projects/real-java"&gt;Real Java&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Well, now to start that doom clone for my cell phone...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112446277962614135?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112446277962614135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/08/fixed-and-floating-point-for-j2me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112446277962614135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112446277962614135'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/08/fixed-and-floating-point-for-j2me.html' title='Fixed and Floating point for J2ME'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112352752632481881</id><published>2005-08-08T15:48:00.000-03:00</published><updated>2005-08-08T15:58:46.330-03:00</updated><title type='text'>Impressive DOM scripting</title><content type='html'>If you happen to have a few minutes of spare time, check out &lt;a href="http://www.dhteumeuleu.com"&gt;"Interactive DOM Scripting"&lt;/a&gt; which is simply awesome.&lt;br /&gt;&lt;br /&gt;The most impressive pages are IE only (don't blame me). This site has the spirit of the old demos built for machines such as the &lt;a href="http://www.obsoletecomputermuseum.org/amiga500/"&gt;Commodore Amiga 500&lt;/a&gt;. A bit of nostalgia is unavoidable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112352752632481881?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112352752632481881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/08/impressive-dom-scripting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112352752632481881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112352752632481881'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/08/impressive-dom-scripting.html' title='Impressive DOM scripting'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112317698256003163</id><published>2005-08-04T14:34:00.000-03:00</published><updated>2005-08-04T17:49:22.853-03:00</updated><title type='text'>Quote of the day</title><content type='html'>&lt;em&gt;"In a perfect world, reading code would be like reading a book. Unfortunately, code is written for computers to execute, not for humans to read. You can’t just read code from start to finish—they’re like those choose-your-own-ending books, forcing you to go all over the place to figure out how not to kill your main character. "&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;From &lt;a href="http://particletree.com/features/successful-strategies-for-commenting-your-code"&gt;Successful Strategies for Commenting Code&lt;/a&gt; - By Ryan Campbell&lt;br /&gt;&lt;br /&gt;The quote is great, but I disagree with some of the statements in the article. I'm more of the idea that code comments should explain &lt;strong&gt;why&lt;/strong&gt; you are doing something, not &lt;strong&gt;how&lt;/strong&gt;. Anyway, as with any imperative guidelines, it is more important the spirit of the law, than the law itself.&lt;br /&gt;&lt;br /&gt;In spirit, I think the idea of code comments is to make code more understandable for other people or for a future version of yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112317698256003163?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112317698256003163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/08/quote-of-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112317698256003163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112317698256003163'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/08/quote-of-day.html' title='Quote of the day'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112300028560443416</id><published>2005-08-02T13:28:00.000-03:00</published><updated>2005-08-02T13:31:25.610-03:00</updated><title type='text'>Not much time left</title><content type='html'>It has been a while since my last post, I've been really busy lately because a new version of our product is in the pipeline, and development is picking up speed.&lt;br /&gt;&lt;br /&gt;I'll continue the regular posts soon (hopefully!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112300028560443416?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112300028560443416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/08/not-much-time-left.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112300028560443416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112300028560443416'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/08/not-much-time-left.html' title='Not much time left'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112186771320939666</id><published>2005-07-20T10:52:00.005-03:00</published><updated>2011-06-08T15:55:52.476-03:00</updated><title type='text'>Intersecting a QuadCurve2D (Part II)</title><content type='html'>(continued from &lt;a href="http://www.codng.com/2005/07/intersecting-quadcurve2d-part-i.html"&gt;part one&lt;/a&gt;)&lt;br /&gt;So far we have the parametric equation of quadratic bezier curve:&lt;br /&gt;&lt;br /&gt;Q(t) = P1 (1 - t)^2 + P2 (2t(1-t)) + P3 (t^2)&lt;br /&gt;&lt;br /&gt;All we have to do now is devise an efficient way to check the intersection with a rectangle. We have three cases of intersection:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If one of the endpoints of the curve is contained in the rectangle, the curve intersects the rectangle&lt;/li&gt;&lt;li&gt;If the curve intersects one of the line segments that delimit the rectangle, the curve intersects the rectangle&lt;/li&gt;&lt;li&gt;If neither of these is true, there is no intersection.&lt;/li&gt;&lt;/ul&gt;The first case is the easiest to check, we just have to check if the rectangle contains either one of the endpoints (P1 and P3).&lt;br /&gt;The second one is a bit trickier. First, let me make one observation: the sides of a rectangle are always parallel to one of the coordinate axis (I know this sounds obvious in this context, but bear with me).&lt;br /&gt;What this means is that the top and bottom edges of the rectangle are contained by a line of the form:&lt;br /&gt;&lt;br /&gt;y = c&lt;br /&gt;&lt;br /&gt;with c = rect.getY() for the top edge and c = rect.getY() + rect.getHeight() for the bottom edge.&lt;br /&gt;Analogously, the left and right edges:&lt;br /&gt;&lt;br /&gt;x = c&lt;br /&gt;&lt;br /&gt;with c = rect.getX() for the left edge and c = rect.getX()+rect.getWidth() for the right edge.&lt;br /&gt;Let's use the top edge as an example, to check if the curve &lt;em&gt;cuts&lt;/em&gt; that edge, we must do two checks:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;That exists a value of t, such as 0 &amp;lt;= t &amp;lt;= 1 and c = Qy(t)&lt;/li&gt;&lt;li&gt;And that rect.getX() &lt;= Qx(t) &amp;lt;= rect.getX() + rect.getWidth() is true for that value of t&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;Where Qx(t) and Qy(t) are the parametric ecuations of the curve for each coordinate:&lt;/p&gt;&lt;p&gt;Qx(t) = Px1 (1 - t)^2 + Px2 (2t(1-t)) + Px3 (t^2) &lt;p&gt;Qy(t) = Py1 (1 - t)^2 + Py2 (2t(1-t)) + Py3 (t^2) &lt;p&gt;To perform the aforementioned checks, we must solve t for:  &lt;p&gt;c = Q(t) &lt;p&gt;(since Qx(t) and Qy(t) are analogous, I won't specify which one I'm referring , since the result is the same). &lt;p&gt;That yields (after some more mathemagic passes): &lt;p&gt;(P1 - 2 P2 + P3)t^2 + (2 P2-2 P1) t + (P1 - c) = 0 &lt;p&gt;Which is a simple quadratic equation. As you know, quadratic equations have (potentially) two roots. So we must check both values (if present) to see if any of those yields the expected result. &lt;p&gt;To solve it in code, we can use the handy QuadCurve2D.solveQuadratic() method.   &lt;pre class="brush: java"&gt;public boolean curveIntersects(QuadCurve2D curve, double rx, double ry, double rw, double rh)&lt;br /&gt;  {&lt;br /&gt;      /**&lt;br /&gt;       * A quadratic bezier curve has the following parametric equation:&lt;br /&gt;       *&lt;br /&gt;       * Q(t) = P0(1-t)^2 + P1(2t(1-t)) + P2(t^2)&lt;br /&gt;       *&lt;br /&gt;       * Where 0 &amp;lt;= t &amp;lt;= 1 and P0 is the starting point, P1 is the control point and&lt;br /&gt;       * P2 is the end point.&lt;br /&gt;       *&lt;br /&gt;       * Therefore, the equations for the x and y coordinates are:&lt;br /&gt;       *&lt;br /&gt;       * Qx(t) = Px0(1-t)^2 + Px1(2t(1-t)) + Px2(t^2)&lt;br /&gt;       * Qy(t) = Py0(1-t)^2 + Py1(2t(1-t)) + Py2(t^2)&lt;br /&gt;       *&lt;br /&gt;       *  0 &amp;lt;= t &amp;lt;= 1&lt;br /&gt;       *&lt;br /&gt;       * A bezier curve intersects a rectangle if:&lt;br /&gt;       *&lt;br /&gt;       *  1 - Either one of its endpoints is inside of the rectangle&lt;br /&gt;       *  2 - The curve intersects one of the rectangles sides (top, bottom, left or right)&lt;br /&gt;       *&lt;br /&gt;       * The equation for a horizontal line is:&lt;br /&gt;       *&lt;br /&gt;       *   y = c&lt;br /&gt;       *&lt;br /&gt;       * The line intersects the bezier if:&lt;br /&gt;       *&lt;br /&gt;       *   Qy(t) = c and 0 &amp;lt;= t &amp;lt;= 1&lt;br /&gt;       *&lt;br /&gt;       * We can rewrite this as:&lt;br /&gt;       *&lt;br /&gt;       *   -c + Py0 + (-2Py0 + 2Py1)t + (Py0 - 2Py1 + Py2) t^2 == 0&lt;br /&gt;       *   and 0 &amp;lt;= t &amp;lt;= 1&lt;br /&gt;       *&lt;br /&gt;       * We can use the valid roots of the quadratic, to evaluate Qx(t), and see if the value&lt;br /&gt;       * falls withing the rectangle bounds.&lt;br /&gt;       *&lt;br /&gt;       * The case for vertical lines is analogous to this one.&lt;br /&gt;       * (juancn)&lt;br /&gt;       */&lt;br /&gt;      double y1 = curve.getY1();&lt;br /&gt;      double y2 = curve.getY2();&lt;br /&gt;      double x1 = curve.getX1();&lt;br /&gt;      double x2 = curve.getX2();&lt;br /&gt;&lt;br /&gt;      //If the rectangle contains one of the endpoints, it intersects the curve&lt;br /&gt;      if(rectangleContains(x1, y1, rx,ry,rw,rh)  rectangleContains(x2, y2,rx,ry,rw,rh)) {&lt;br /&gt;          return true;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      double eqn[] = new double[3];&lt;br /&gt;      double ctrlY = curve.getCtrlY();&lt;br /&gt;      double ctrlX = curve.getCtrlX();&lt;br /&gt;&lt;br /&gt;      return intersectsLine(eqn, y1, ctrlY, y2, ry, x1, ctrlX, x2, rx, rx+rw) //Top&lt;br /&gt;       intersectsLine(eqn, y1, ctrlY, y2, ry + rh, x1, ctrlX, x2,rx, rx+rw) //Bottom&lt;br /&gt;       intersectsLine(eqn, x1, ctrlX, x2, rx, y1, ctrlY, y2, ry, ry+rh) //Left&lt;br /&gt;       intersectsLine(eqn, x1, ctrlX, x2, rx+rw, y1, ctrlY, y2, ry, ry+rh); //Right&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private boolean rectangleContains(double x, double y, double rx, double ry, double rw, double rh)&lt;br /&gt;  {&lt;br /&gt;      return (x &amp;gt;= rx &amp;amp;&amp;amp;&lt;br /&gt;          y &amp;gt;= ry &amp;amp;&amp;amp;&lt;br /&gt;          x &amp;lt; rx + rw &amp;amp;&amp;amp;&lt;br /&gt;          y &amp;lt; ry + rh);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Returns true if a line segment parallel to one of the axis intersects the specified curve.&lt;br /&gt;   * This function works fine if you reverse the axes.&lt;br /&gt;   *&lt;br /&gt;   * @param eqn a double[] of lenght 3 used to hold the quadratic equation coeficients&lt;br /&gt;   * @param p0 starting point of the curve at the desired axis (i.e.: curve.getX1())&lt;br /&gt;   * @param p1 control point of the curve at the desired axis  (i.e.: curve.getCtrlX())&lt;br /&gt;   * @param p2 end point of the curve at the desired axis (i.e.: curve.getX2())&lt;br /&gt;   * @param c where is the line segment (i.e.: in X axis)&lt;br /&gt;   * @param pb0 starting point of the curve at the other axis (i.e.: curve.getY1())&lt;br /&gt;   * @param pb1 control point of the curve at the other axis  (i.e.: curve.getCtrlY())&lt;br /&gt;   * @param pb2 end point of the curve at the other axis (i.e.: curve.getY2())&lt;br /&gt;   * @param from starting point of the line segment (i.e.: in Y axis)&lt;br /&gt;   * @param to end point of the line segment (i.e.: in Y axis)&lt;br /&gt;   * @return&lt;br /&gt;   */&lt;br /&gt;  private static boolean intersectsLine(double[] eqn, double p0, double p1, double p2, double c,&lt;br /&gt;                                 double pb0, double pb1, double pb2,&lt;br /&gt;                                 double from, double to)&lt;br /&gt;  {&lt;br /&gt;      /**&lt;br /&gt;       * First we check if a line parallel to the axis we are evaluating intersects&lt;br /&gt;       * the curve (the line is at c).&lt;br /&gt;       *&lt;br /&gt;       * Then we check if any of the intersection points is between &amp;#x27;from&amp;#x27; and &amp;#x27;to&amp;#x27; in the other&lt;br /&gt;       * axis (wether it belongs to the rectangle)&lt;br /&gt;       */&lt;br /&gt;&lt;br /&gt;      //Fill the coefficients of the equation&lt;br /&gt;      eqn[2] = p0 - 2*p1 + p2;&lt;br /&gt;      eqn[1] = 2*p1-2*p0;&lt;br /&gt;      eqn[0] = p0 - c;&lt;br /&gt;&lt;br /&gt;      int nRoots = QuadCurve2D.solveQuadratic(eqn);&lt;br /&gt;      boolean result;&lt;br /&gt;      switch(nRoots) {&lt;br /&gt;      case 1:&lt;br /&gt;          result = (eqn[0] &amp;gt;= 0) &amp;amp;&amp;amp; (eqn[0] &amp;lt;= 1);&lt;br /&gt;          if(result) {&lt;br /&gt;              double intersection = evalQuadraticCurve(pb0,pb1,pb2,eqn[0]);&lt;br /&gt;              result = (intersection &amp;gt;= from) &amp;amp;&amp;amp; (intersection &amp;lt;= to);&lt;br /&gt;          }&lt;br /&gt;          break;&lt;br /&gt;      case 2:&lt;br /&gt;          result = (eqn[0] &amp;gt;= 0) &amp;amp;&amp;amp; (eqn[0] &amp;lt;= 1);&lt;br /&gt;          if(result) {&lt;br /&gt;              double intersection = evalQuadraticCurve(pb0,pb1,pb2,eqn[0]);&lt;br /&gt;              result = (intersection &amp;gt;= from) &amp;amp;&amp;amp; (intersection &amp;lt;= to);&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          //If the first root is not a valid intersection, try the other one&lt;br /&gt;          if(!result) {&lt;br /&gt;              result = (eqn[1] &amp;gt;= 0) &amp;amp;&amp;amp; (eqn[1] &amp;lt;= 1);&lt;br /&gt;              if(result) {&lt;br /&gt;                  double intersection = evalQuadraticCurve(pb0,pb1,pb2,eqn[1]);&lt;br /&gt;                  result = (intersection &amp;gt;= from) &amp;amp;&amp;amp; (intersection &amp;lt;= to);&lt;br /&gt;              }&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          break;&lt;br /&gt;      default:&lt;br /&gt;          result = false;&lt;br /&gt;      }&lt;br /&gt;      return result;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static double evalQuadraticCurve(double c1, double ctrl, double c2, double t)&lt;br /&gt;  {&lt;br /&gt;      double u = 1 - t;&lt;br /&gt;      double res = c1 * u * u + 2 * ctrl * t * u + c2 * t * t;&lt;br /&gt;&lt;br /&gt;      return res;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112186771320939666?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112186771320939666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/07/intersecting-quadcurve2d-part-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112186771320939666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112186771320939666'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/07/intersecting-quadcurve2d-part-ii.html' title='Intersecting a QuadCurve2D (Part II)'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112068087724278010</id><published>2005-07-06T17:10:00.002-03:00</published><updated>2011-06-08T15:50:28.564-03:00</updated><title type='text'>Intersecting a QuadCurve2D (Part I)</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/7243/154/1600/bezier-base.jpg"&gt;&lt;/a&gt;&lt;br /&gt;A few days ago, while I was trying to optimize the rendering code of a designer application I found something funny about Java 2D, there is no easy way to check if a rectangle intersects with a QuadCurve2D. That is with just the curve, not the area enclosed by it.&lt;br /&gt;I'll try to summarize what I learned about quadratic bezier curves, and provide a fast algorithm to check for the intersection.&lt;br /&gt;&lt;br /&gt;Quadratic bezier curves are defined by three points: a starting point, a control point, and an end point. The starting point and the end point are on the curve, the control point is outside the curve.&lt;br /&gt;&lt;br /&gt;Bezier curves are based on the parametric equation of the line, which is of the form:&lt;br /&gt;&lt;br /&gt;L(t) = P1 (1 - t) + P2 t&lt;br /&gt;&lt;br /&gt;With t in [0,1]. P1 and P2 are two arbitrary points.&lt;br /&gt;&lt;br /&gt;As I said before, a bezier curve is defined by three points. Take a look at the following diagram:&lt;br /&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" height="283" alt="" src="http://photos1.blogger.com/blogger/7243/154/320/bezier-base.jpg" width="323" border="0" /&gt;&lt;br /&gt;Here we have two main lines: from P1 to P2 and from P2 to P3, the curve is defined by a point in the line S0 to S1.&lt;br /&gt;Using the parametric ecuation of the line I mentioned before, we can write S0 and S1 as:&lt;br /&gt;&lt;br /&gt;S0(t) = P1(1-t) + P2 t&lt;br /&gt;S1(t) = P2 (1-t) + P3 t&lt;br /&gt;&lt;br /&gt;Then, the point on the bezier curve is defined as:&lt;br /&gt;&lt;br /&gt;Q(t) = S0(1-t) + S1 t&lt;br /&gt;&lt;br /&gt;Simplifying this (hocus phocus... and some mathematical mumbo jumbo) we get:&lt;br /&gt;&lt;br /&gt;Q(t) = P1 (1 - t)^2 + P2 (2t(1-t)) + P3 (t^2)&lt;br /&gt;&lt;br /&gt;So finally we have the basic ecuation for a quadratic bezier curve.&lt;br /&gt;&lt;br /&gt;(Next: &lt;a href="http://www.codng.com/2005/07/intersecting-quadcurve2d-part-ii.html"&gt;Curve intersection&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112068087724278010?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112068087724278010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/07/intersecting-quadcurve2d-part-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112068087724278010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112068087724278010'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/07/intersecting-quadcurve2d-part-i.html' title='Intersecting a QuadCurve2D (Part I)'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112008316838254314</id><published>2005-06-29T19:00:00.000-03:00</published><updated>2005-07-06T17:22:02.076-03:00</updated><title type='text'>Have you ever felt entangled?</title><content type='html'>Have you ever felt entangled while writing some code? Maybe during a particular large refactoring?&lt;br /&gt;&lt;br /&gt;Trying to make one more piece of information fit in your brain, while at the same time, keeping all the others in it's place?&lt;br /&gt;&lt;br /&gt;Or that particular frustration of knowing there must be a simpler/faster/better way of doing something but being unable to find it?&lt;br /&gt;&lt;br /&gt;Well... sometimes I do.&lt;br /&gt;&lt;br /&gt;This blog hopefully will end up having my musings on these matters, some code samples for stuff that I find interesting or it took me a long time to figure out. Eventually you'll have to put up with some of my most eccentric dissertations, but I promise that I'll try to keep those to a minimum.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112008316838254314?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112008316838254314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/06/have-you-ever-felt-entangled.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112008316838254314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112008316838254314'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/06/have-you-ever-felt-entangled.html' title='Have you ever felt entangled?'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14061308.post-112007446517057083</id><published>2005-06-29T16:44:00.000-03:00</published><updated>2005-06-29T16:48:12.176-03:00</updated><title type='text'>First Post!</title><content type='html'>I hope this will be up and running shortly. In the meantime, you might want to check &lt;a href="http://www.dynamicobjects.com/d2r/"&gt;d2r&lt;/a&gt; which is a great blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14061308-112007446517057083?l=www.codng.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codng.com/feeds/112007446517057083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.codng.com/2005/06/first-post.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112007446517057083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14061308/posts/default/112007446517057083'/><link rel='alternate' type='text/html' href='http://www.codng.com/2005/06/first-post.html' title='First Post!'/><author><name>Juan Cruz Nores</name><uri>http://www.blogger.com/profile/13999116289125025794</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
