<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Matthieu Brucher's blog</title> <link>http://matt.eifelle.com</link> <description /> <lastBuildDate>Wed, 01 Sep 2010 20:17:22 +0000</lastBuildDate> <generator>http://wordpress.org/?v=2.9.1</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/eifelle/CPPV" /><feedburner:info uri="eifelle/cppv" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Book review: Beautiful Testing: Leading Professionals Reveal How They Improve Software</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/_5-BvPKbmFc/</link> <comments>http://matt.eifelle.com/2010/08/31/book-review-beautiful-testing-leading-professionals-reveal-how-they-improve-software/#comments</comments> <pubDate>Tue, 31 Aug 2010 07:33:21 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Book review]]></category> <category><![CDATA[Development process]]></category> <category><![CDATA[O'Reilly]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[Performance Testing]]></category> <category><![CDATA[Test patterns]]></category> <category><![CDATA[Test-Driven Development]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1352</guid> <description><![CDATA[Testing is one of the basis to create robust and correct code. O&#8217;Reilly has published in its &#8220;Beautiful&#8221; series a lot of books on different parts of the development process. This is the testing part.Content and opinions
According to this book, testing has three aspects: testers, process and tools.
Perhaps the biggest issue in testing is getting [...]]]></description> <content:encoded><![CDATA[<p>Testing is one of the basis to create robust and correct code. O&#8217;Reilly has published in its &#8220;Beautiful&#8221; series a lot of books on different parts of the development process. This is the testing part.<br
/> <span
id="more-1352"></span></p><h4>Content and opinions</h4><p>According to this book, testing has three aspects: testers, process and tools.</p><p>Perhaps the biggest issue in testing is getting motivated testers. The first part of the book has only three chapters. I guess there is no silver bullet for getting a beautiful team of testers, it&#8217;s mainly about people getting along.</p><p>The second part is the one that got the most attention in the book. In retrospective, thanks to this book, I&#8217;ve discovered many aspects of testing are never addressed , and I thought that some code couldn&#8217;t even be tested. I was obviously very wrong. For instance, testing mathematical code can be done, a chapter gives a pretty good direction to follow. Several chapters address fuzzing and thus an aspect of testing that is mainly done after discovering a flaw (whereas fuzzing may give a shot at fixing the bug before it is discovered), or also software testing over a network. In fact the broad scope of projects that participated in this part gives me hope and shame at the same time (because there are many things I didn&#8217;t test for, didn&#8217;t anticipate, &#8230;).</p><p>The last part handles tools that are used during testing. It&#8217;s not about the usual xUnit, but more about some of the once-upon-a-time small tools that morphed into one of the pillars of testing in its project, or Open Source tools (valgrind, &#8230;) or even others.</p><h4>Conclusion</h4><p>A very broad scope of projects, of people and of workflow are depicted inside this book. If there are many beautiful processes out there, there are not so many ways of getting beautiful people inside test teams. Also, it seems that many beautiful tools were mainly small project tools that were written for a simple crude purpose and that were progressively refactored into something more powerful.</p><p>I especially liked some chapters in the process part, for instance the statistical one. It&#8217;s something very difficult to test, and although the chapter doesn&#8217;t solve the ultimate issue of statistics, it helps creating something that looks like real random tests.</p><p>Also, I won&#8217;t see Q&#038;A the same way now.</p><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/uploads/2009/12/BN_Logo_3tier.jpg) right bottom no-repeat #ffffff;"> <a
rel="nofollow" href="http://r.popshops.com/r/ZWc2UDRXY2J5UE5xSkVkNmVGeDVFY0Y3WVdhOEJldjhBL3B0UVhjK0trZz0K"><img
style="width: 150px;" src="http://images.barnesandnoble.com/images/49590000/49591814.JPG" border="0" alt="Beautiful Testing: Leading Professionals Reveal How They Improve Software" /></a><br
/> <a
rel="nofollow" href="http://r.popshops.com/r/ZWc2UDRXY2J5UE5xSkVkNmVGeDVFY0Y3WVdhOEJldjhBL3B0UVhjK0trZz0K">Beautiful Testing: Leading Professionals Reveal How They Improve Software</a><br
/> Price: $44.99<br
/> This unique book offers essays from 25 leading software testers that illustrate the qualities and techniques necessary to make software testing an art in itself. The latest entry in O&#8217;Reilly&#8217;s successful series that includes &#8220;Beautiful Code&#8221; (9780596510046) and &#8220;Beautiful Teams&#8221; (9780596518028), this book demonstrates through personal stories and many examples the simplicity, maintainability, flexibility, and efficiency required to test every aspect of a software project.</div><div
class="subcolumns"><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/amazon_US_small.gif) right bottom no-repeat #ffffff;"><div
style="width: 57px; float: left; margin-right: 5px;"> <a
href="http://www.amazon.com/exec/obidos/ASIN/0596159811/masbl03-20" target="_blank"><img
src="http://ecx.images-amazon.com/images/I/61X2oBf7OFL._SL75_.jpg" width="57" height="75" border="0" /></a></div><div><p><a
href="http://www.amazon.com/exec/obidos/ASIN/0596159811/masbl03-20" target="_blank">Beautiful Testing: Leading Professionals Reveal How They Improve Software (Theory in Practice)</a> (Paperback)<br
/> <span
style="font-size: 0.8em;">by <strong>Tim Riley, Adam Goucher</strong></span><br
/> ISBN: 0596159811</p><p><strong>Price:</strong> <span
style="color: #990000; font-weight: bold;">USD 43.76</span><br
/> <strong>39 used &#038; new</strong> available from <span
style="color: #990000; font-weight: bold;">USD 33.34</span></p><p> <img
src="http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/stars-5.gif" class="asa_rating_stars" /> | 5 | 5</div><div
style="clear: both;"></div></div></div>
<p><a href="http://feedads.g.doubleclick.net/~a/z9xv_z3dDCvUZFCKs4yF6641mUw/0/da"><img src="http://feedads.g.doubleclick.net/~a/z9xv_z3dDCvUZFCKs4yF6641mUw/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/z9xv_z3dDCvUZFCKs4yF6641mUw/1/da"><img src="http://feedads.g.doubleclick.net/~a/z9xv_z3dDCvUZFCKs4yF6641mUw/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/_5-BvPKbmFc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/08/31/book-review-beautiful-testing-leading-professionals-reveal-how-they-improve-software/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/08/31/book-review-beautiful-testing-leading-professionals-reveal-how-they-improve-software/</feedburner:origLink></item> <item><title>Optimization scikit: separation of orthogonally convoluted signals</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/f3tNbLr586A/</link> <comments>http://matt.eifelle.com/2010/08/10/optimization-scikit-separation-of-orthogonally-convoluted-signals/#comments</comments> <pubDate>Tue, 10 Aug 2010 07:18:26 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Generic optimizers]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[numpy]]></category> <category><![CDATA[Optimization]]></category> <category><![CDATA[scikit]]></category> <category><![CDATA[scipy]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1331</guid> <description><![CDATA[My last blog post on optimization helped me generate orthogonal sequences. Now, I will use those sequences to separate two signals. The basic use case is a linear system with two inputs, one output, and instead of recording the response of one input at a time, one plays both inputs simultaneously with specific sequences so [...]]]></description> <content:encoded><![CDATA[<p><a
href="http://matt.eifelle.com/2010/07/27/genetic-algorithms-in-python/">My last blog post on optimization</a> helped me generate orthogonal sequences. Now, I will use those sequences to separate two signals. The basic use case is a linear system with two inputs, one output, and instead of recording the response of one input at a time, one plays both inputs simultaneously with specific sequences so that they can be separated in another process.<br
/> <span
id="more-1331"></span></p><h4>A separation cost function</h4><p>In fact the process is really easy. Each input will be convoluted with one sequence generated by last time&#8217;s genetic algorithm. Both sequences are not orthogonal, so the resulting separated signal will have a signal to noise ratio (SNR) probably around the orthogonality amount of the sequences.</p><p>The cost function will be the squared error between the recorded signal and the sum of the convolutions of the estimated signals with their associated combs plus a fraction of the sum of the absolute values of the signals. This additional terms can be seen as regularisation, but also the whole function can be interpreted as the likelihood of an error following a Gaussian law and the input signals following Laplacian laws. The function is thus written this way:</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left2">Download <a
href="http://matt.eifelle.com/wp-content/plugins/wp-codebox/wp-codebox.php?p=1331&amp;download=source_separation.py">source_separation.py</a></span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p13313"><td
class="code" id="p1331code3"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Function<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #dc143c;">signal</span>, combs<span style="color: black;">&#41;</span>:
    <span style="color: #008000;">self</span>.<span style="color: #dc143c;">signal</span> = <span style="color: #dc143c;">signal</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">combs</span> = combs
    <span style="color: #008000;">self</span>.<span style="color: black;">mu</span> = <span style="color: #ff4500;">20000</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> create_estimation<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, x<span style="color: black;">&#41;</span>:
    length = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> / <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">combs</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> numpy.<span style="color: black;">convolve</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#91;</span>:length<span style="color: black;">&#93;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">combs</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:length<span style="color: black;">&#93;</span> + numpy.<span style="color: black;">convolve</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#91;</span>length:<span style="color: black;">&#93;</span>, <span style="color: #008000;">self</span>.<span style="color: black;">combs</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:length<span style="color: black;">&#93;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__call__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, x<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> numpy.<span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: #dc143c;">signal</span> - <span style="color: #008000;">self</span>.<span style="color: black;">create_estimation</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> + numpy.<span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>numpy.<span style="color: #008000;">abs</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> / <span style="color: #008000;">self</span>.<span style="color: black;">mu</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> gradient<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, x<span style="color: black;">&#41;</span>:
    error = <span style="color: #008000;">self</span>.<span style="color: #dc143c;">signal</span> - <span style="color: #008000;">self</span>.<span style="color: black;">create_estimation</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>
    grad = numpy.<span style="color: black;">zeros</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    length = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> / <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">combs</span><span style="color: black;">&#41;</span>
    grad<span style="color: black;">&#91;</span>:length<span style="color: black;">&#93;</span> = - <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">*</span> numpy.<span style="color: black;">convolve</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">combs</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, error<span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:length<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
    grad<span style="color: black;">&#91;</span>length:<span style="color: black;">&#93;</span> = - <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">*</span> numpy.<span style="color: black;">convolve</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">combs</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, error<span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:length<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> grad + numpy.<span style="color: black;">sign</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> / <span style="color: #008000;">self</span>.<span style="color: black;">mu</span></pre></td></tr></table></div><p>Besides the cost, this class also returns the correct analytical gradient (it is not easy to derive, but it is in fact a simple cross correlation between the error each estimated input signal).</p><h4>Application</h4><p>Now that this is in place, an optimizer can be designed:</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left2">Download <a
href="http://matt.eifelle.com/wp-content/plugins/wp-codebox/wp-codebox.php?p=1331&amp;download=source_separation.py">source_separation.py</a></span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p13314"><td
class="code" id="p1331code4"><pre class="python" style="font-family:monospace;">  <span style="color: #ff7700;font-weight:bold;">from</span> scikits.<span style="color: black;">optimization</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
  fun = Function<span style="color: black;">&#40;</span><span style="color: #dc143c;">signal</span>, combs<span style="color: black;">&#41;</span>
&nbsp;
  mystep = step.<span style="color: black;">FRPRPConjugateGradientStep</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  mylinesearch = line_search.<span style="color: black;">WolfePowellRule</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  mycriterion = criterion.<span style="color: black;">criterion</span><span style="color: black;">&#40;</span>ftol = <span style="color: #ff4500;">0.0001</span>, iterations_max = <span style="color: #ff4500;">500</span><span style="color: black;">&#41;</span>
  myoptimizer = optimizer.<span style="color: black;">StandardOptimizer</span><span style="color: black;">&#40;</span>function = fun,
                                            step = mystep,
                                            line_search = mylinesearch,
                                            criterion = mycriterion,
                                            x0 = numpy.<span style="color: black;">zeros</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">*</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">signal</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
  xf = myoptimizer.<span style="color: black;">optimize</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div><p>To separate both signals correctly, the optimizer will consists of a Polak-Ribière-Polyak conjugate gradient with a Fletcher-Reeves variant (it always finds the best conjugate factor and has an auto-restart behavior), a Wolfe-Powell line search and the stop criterion will stop the optimization after 500 iterations or if the relative cost doesn&#8217;t vary more than 0.0001.</p><p>Now, I&#8217;ve convoluted two signals (drawn for a Laplacian distribution) with two combs (10 impulses each). I&#8217;ve added a small amount of white noise. In the end, with combs not entirely orthogonal and white noise, the SNR may not be lower than 10dB, but with the additional hypothesis on the distribution of the input signals, it might just be enough. The optimization looks like this:</p><p><center><object
width="425" height="344"><param
name="movie" value="http://www.youtube.com/v/1vl2eQZCX34&#038;hl=fr&#038;fs=1"></param><param
name="allowFullScreen" value="true"></param><param
name="allowscriptaccess" value="always"></param><embed
src="http://www.youtube.com/v/1vl2eQZCX34&#038;hl=fr&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center></p><p>As you can see, the crude strating estimate is efficiently corrected but the estimation degrades a the end of the signals. In the end, we have a little more than 10dB, but with other signals, the SNR is lower than 10 dB.</p><h4>Conclusion</h4><p>With a more complex comb, better SNR would be achieved, but at the cost of longer output signals. It means that sometimes, it&#8217;s better to record each input separately. Of course, if you need very long input sequences, you can use longer orthogonal sequences. You can also combine more than two signals!</p><p>As usual, the code may be found on <a
href="http://bazaar.launchpad.net/~matthieu-brucher/%2Bjunk/optimization-tutorials/files/head%3A/tut5/">Launchpad</a>.</p><form
action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input
type="hidden" name="cmd" value="_xclick" /> <input
type="hidden" name="business" value="matthieu.brucher@gmail.com" /><input
type="hidden" name="item_name" value="Buy Me a Coffee!" /><input
type="hidden" name="currency_code" value="USD" /><span
style="font-size:10.0pt"><strong> Buy Me a Coffee!</strong></span><br
/><br
/><select
id="amount" name="amount" class=""><option
value="3">Capuccino - 3$</option><option
value="6">Frappuccino - 6$</option><option
value="10">Hot Chocolate - 10$</option><option
value="20">Expensive Coffee - 20$</option><option
value="50">Alien Coffee - 50$</option></select><br
/><br
/><strong>Other Amount:</strong><br
/><br
/><input
type="text" name="amount" size="10" title="Other donate" value="" /><br
/><br
/><strong> Your Email Address :</strong><input
type="hidden" name="on0" value="Reference" /><br
/><br
/><input
type="text" name="os0" maxlength="60" /> <br
/><br
/> <input
type="hidden" name="no_shipping" value="2" /> <input
type="hidden" name="no_note" value="1" /> <input
type="hidden" name="mrb" value="3FWGC6LFTMTUG" /> <input
type="hidden" name="bn" value="IC_Sample" /> <input
type="hidden" name="return" value="http://matt.eifelle.com" /><input
type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but11.gif" name="submit" alt="Make payments with payPal - it's fast, free and secure!" /></form>
<p><a href="http://feedads.g.doubleclick.net/~a/S8eIKfrJoyRuJXWpyKD8awm67P4/0/da"><img src="http://feedads.g.doubleclick.net/~a/S8eIKfrJoyRuJXWpyKD8awm67P4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/S8eIKfrJoyRuJXWpyKD8awm67P4/1/da"><img src="http://feedads.g.doubleclick.net/~a/S8eIKfrJoyRuJXWpyKD8awm67P4/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/f3tNbLr586A" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/08/10/optimization-scikit-separation-of-orthogonally-convoluted-signals/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/08/10/optimization-scikit-separation-of-orthogonally-convoluted-signals/</feedburner:origLink></item> <item><title>Book review: Masterminds of Programming</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/RZOQcpMfrVQ/</link> <comments>http://matt.eifelle.com/2010/08/03/book-book-masterminds-of-programming/#comments</comments> <pubDate>Tue, 03 Aug 2010 07:13:15 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Book review]]></category> <category><![CDATA[C++]]></category> <category><![CDATA[O'Reilly]]></category> <category><![CDATA[Python]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1322</guid> <description><![CDATA[When twenty or so langage creators are put together to make a book, it can only be interesting. It&#8217;s a good revealer of character, as they tend to open their heart. In fact I think that&#8217;s exactly what happened in this book.Content and opinions
I won&#8217;t make the list of the chosen langages. They are taken [...]]]></description> <content:encoded><![CDATA[<p>When twenty or so langage creators are put together to make a book, it can only be interesting. It&#8217;s a good revealer of character, as they tend to open their heart. In fact I think that&#8217;s exactly what happened in this book.<br
/> <span
id="more-1322"></span></p><h4>Content and opinions</h4><p>I won&#8217;t make the list of the chosen langages. They are taken from the successful ones, in terms of quality as well as fame, which means that some are less known than others. Each chapter is very different, and, as I&#8217;ve said, very revealing.</p><p>Depending on the interviewed, the addressed topics are different. For some authors, you get questions and answers very close to their langages. For others, you have some feedback on how they see the programming field and its future evolution. Some will tell you how much their langage is great and that is a shame it is not more used or that it could replace almost everything. Other will tell you that they fill their langage slipped through their hands.</p><p>There is no single line of code, it&#8217;s really a thoughts book, and this is the point of the book: you don&#8217;t get advice on how you will write code or design your application. You get inner reasons for some langages and their success. You get leads for the future of your program, how langages may evolve and on what you may focus your attention. Unfortunately, the chapter I almost liked the most is the last one (on Eiffel). It&#8217;s funny that in this precise chapter, Bertrand Meyer talks about the treasures he found in the last chapter of <u>Structured Programming</u> (Dijkstra <em>et al</em>).</p><h4>Conclusion</h4><p>From a cultural point of view, this book is a gold mine. For an ego point of view, this book is a revealer. All things considered, a lot of things can be learnt by reading this book on the philosophical approach of some langages.</p><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/uploads/2009/12/BN_Logo_3tier.jpg) right bottom no-repeat #ffffff;"><a
rel="nofollow" href="http://r.popshops.com/r/Rk1EZVF4UXFrNi9UditqWGZBbXcyZ1M5ZXpoNFJSYjdRZHlDd2c2VHJDST0K"><img
style="width: 150px;" src="http://images.barnesandnoble.com/images/40870000/40871068.JPG" border="0" alt="Masterminds of Programming: Conversations with the Creators of Major Programming Languages (Theory in Practice (O'Reilly) Series)" /></a><br
/> <a
rel="nofollow" href="http://r.popshops.com/r/Rk1EZVF4UXFrNi9UditqWGZBbXcyZ1M5ZXpoNFJSYjdRZHlDd2c2VHJDST0K">Masterminds of Programming: Conversations with the Creators of Major Programming Languages (Theory in Practice (O&#8217;Reilly) Series)</a><br
/> Price: $34.19</div><div
class="subcolumns"><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/amazon_US_small.gif) right bottom no-repeat #ffffff;"><div
style="width: 57px; float: left; margin-right: 5px;"> <a
href="http://www.amazon.com/exec/obidos/ASIN/0596515170/masbl03-20" target="_blank"><img
src="http://ecx.images-amazon.com/images/I/51lQmSOdOlL._SL75_.jpg" width="57" height="75" border="0" /></a></div><div><p><a
href="http://www.amazon.com/exec/obidos/ASIN/0596515170/masbl03-20" target="_blank">Masterminds of Programming: Conversations with the Creators of Major Programming Languages (Theory in Practice (O&#8217;Reilly))</a> (Paperback)<br
/> <span
style="font-size: 0.8em;">by <strong>Federico Biancuzzi, Chromatic</strong></span><br
/> ISBN: 0596515170</p><p><strong>Price:</strong> <span
style="color: #990000; font-weight: bold;">USD 26.39</span><br
/> <strong>53 used &#038; new</strong> available from <span
style="color: #990000; font-weight: bold;">USD 4.96</span></p><p> <img
src="http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/stars-4.gif" class="asa_rating_stars" /> | 4 | 11</div><div
style="clear: both;"></div></div></div>
<p><a href="http://feedads.g.doubleclick.net/~a/Ek8ZcPwWlZ0turBWNshqn-IW6EQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/Ek8ZcPwWlZ0turBWNshqn-IW6EQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Ek8ZcPwWlZ0turBWNshqn-IW6EQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/Ek8ZcPwWlZ0turBWNshqn-IW6EQ/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/RZOQcpMfrVQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/08/03/book-book-masterminds-of-programming/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/08/03/book-book-masterminds-of-programming/</feedburner:origLink></item> <item><title>Genetic algorithms in Python</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/eJl2-tf11bA/</link> <comments>http://matt.eifelle.com/2010/07/27/genetic-algorithms-in-python/#comments</comments> <pubDate>Tue, 27 Jul 2010 07:04:23 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Generic optimizers]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[Optimization]]></category> <category><![CDATA[PyEvolve]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1308</guid> <description><![CDATA[Although I&#8217;m fond of numerical optimization through gradients, &#8230; there are some times where a global optimization is much more powerfull. For instance, I have to generate two sequences/combs that are orthogonal and for which their autocorrelation is almost an impulse. The two combs have a fixed number of impulse, so it&#8217;s a perfect job [...]]]></description> <content:encoded><![CDATA[<p>Although I&#8217;m fond of numerical optimization through gradients, &#8230; there are some times where a global optimization is much more powerfull. For instance, I have to generate two sequences/combs that are orthogonal and for which their autocorrelation is almost an impulse. The two combs have a fixed number of impulse, so it&#8217;s a perfect job for genetic algorithms.<br
/> <span
id="more-1308"></span><br
/> <a
href="http://en.wikipedia.org/wiki/Genetic_algorithm">Genetic algorithms</a> are a global optimization technique. The parameters are encoded in a genome, and then different populations are grown. The fittest individuals survive and give new individuals. The usual implementation in Python is <a
href="http://pyevolve.sf.net">PyEvolve</a>, a pure Python package that isn&#8217;t depended on anything except if you want to save and plot populations.</p><h4>Creating a genome and a cost function</h4><p>So my goal is to minimize crosscorrelation and autocorrelation, safe for the middle value of autocorrelation. I won&#8217;t use a fixed-size sequence, I will encode in the genome the distance between two impulses. This will allow for a really small genome with a lot of possibilities.</p><p>For this purpose, I create a class named <strong>OrthogonalSequences</strong>:</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left2">Download <a
href="http://matt.eifelle.com/wp-content/plugins/wp-codebox/wp-codebox.php?p=1308&amp;download=GA.py">GA.py</a></span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p13087"><td
class="code" id="p1308code7"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> OrthogonalSequences<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, size, number<span style="color: black;">&#41;</span>:
    <span style="color: #008000;">self</span>.<span style="color: black;">size</span> = size
    <span style="color: #008000;">self</span>.<span style="color: black;">number</span> = number
    <span style="color: #008000;">self</span>.<span style="color: black;">genome_length</span> = size <span style="color: #66cc66;">*</span> number
&nbsp;
  @<span style="color: #008000;">staticmethod</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> convert_slice_to_time<span style="color: black;">&#40;</span>chromosome<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;&quot;
    Converts a chromosome in a time sequence
    &quot;&quot;&quot;</span><span style="color: #483d8b;">&quot;
    total = numpy.cumsum(chromosome)
    array = numpy.zeros(total[-1]+1)
    array[total] = 1
    array[0] = 1
    return array
&nbsp;
  def evaluate(self, chromosomes):
    &quot;</span><span style="color: #483d8b;">&quot;&quot;&quot;
    Evaluate the cost (square of error) of the genome by evaluating cross- and autocorrelation.
    &quot;&quot;&quot;</span><span style="color: #483d8b;">&quot;
    value = 0
    for i in range(self.number):
      slice_i = self.convert_slice_to_time(chromosomes[i * self.size:(i+1) * self.size])
      value += .1 * len(slice_i)
      for j in range(i, self.number):
        slice_j = self.convert_slice_to_time(chromosomes[j * self.size:(j+1) * self.size])
        correlation = numpy.correlate(slice_i, slice_j, mode = &quot;</span>full<span style="color: #483d8b;">&quot;)
        if (i == j):
          correlation[len(slice_i)-1] -= self.size
&nbsp;
        value += numpy.sum(correlation ** 2)
&nbsp;
    return value</span></pre></td></tr></table></div><p>In fact this class will only be used to evaluate a genome. As I have two combs (and more if you&#8217;d like), I need to pass this information to the evaluation function, and thus nothing is more easy than Python for this. I&#8217;ve also added a small factor that adds a cost for lengthy combs.</p><h4>Setting up the optimizer</h4><p>Now, the only thing remaining is to set all objects and launch the optimization:</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left2">Download <a
href="http://matt.eifelle.com/wp-content/plugins/wp-codebox/wp-codebox.php?p=1308&amp;download=GA.py">GA.py</a></span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p13088"><td
class="code" id="p1308code8"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
  <span style="color: #ff7700;font-weight:bold;">from</span> pyevolve <span style="color: #ff7700;font-weight:bold;">import</span> G1DList, GSimpleGA, Consts
  <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
  size = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">10</span>
  size -= <span style="color: #ff4500;">1</span>
  number = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">2</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">2</span>
  rangemax = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">3</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">100</span>
  generations = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">4</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">50</span>
  population = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">5</span> <span style="color: #ff7700;font-weight:bold;">else</span> <span style="color: #ff4500;">100</span>
&nbsp;
  genome = G1DList.<span style="color: black;">G1DList</span><span style="color: black;">&#40;</span>number<span style="color: #66cc66;">*</span>size<span style="color: black;">&#41;</span>
  sequences = OrthogonalSequences<span style="color: black;">&#40;</span>size, number<span style="color: black;">&#41;</span>
  ga = GSimpleGA.<span style="color: black;">GSimpleGA</span><span style="color: black;">&#40;</span>genome<span style="color: black;">&#41;</span>
&nbsp;
  genome.<span style="color: black;">setParams</span><span style="color: black;">&#40;</span>rangemin=<span style="color: #ff4500;">1</span>, rangemax=rangemax<span style="color: black;">&#41;</span>
  genome.<span style="color: black;">evaluator</span>.<span style="color: #008000;">set</span><span style="color: black;">&#40;</span>sequences.<span style="color: black;">evaluate</span><span style="color: black;">&#41;</span>
&nbsp;
  ga.<span style="color: black;">setMinimax</span><span style="color: black;">&#40;</span>Consts.<span style="color: black;">minimaxType</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;minimize&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
  ga.<span style="color: black;">setPopulationSize</span><span style="color: black;">&#40;</span>population<span style="color: black;">&#41;</span>
  ga.<span style="color: black;">setElitism</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
  ga.<span style="color: black;">setGenerations</span><span style="color: black;">&#40;</span>generations<span style="color: black;">&#41;</span>
  ga.<span style="color: black;">evolve</span><span style="color: black;">&#40;</span>freq_stats = generations/<span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">print</span> ga.<span style="color: black;">bestIndividual</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div><h4>Results</h4><p>Now the result is the following for 2 sequences of 10 impulses:</p><pre>Gen. 1 (2.00%): Max/Min/Avg Fitness(Raw) [436.73(387.20)/317.81(349.20)/363.94(363.94)]
Gen. 5 (10.00%): Max/Min/Avg Fitness(Raw) [417.89(375.20)/340.39(345.20)/348.24(348.24)]
Gen. 10 (20.00%): Max/Min/Avg Fitness(Raw) [419.21(379.20)/339.65(345.20)/349.34(349.34)]
Gen. 15 (30.00%): Max/Min/Avg Fitness(Raw) [417.72(377.20)/341.16(345.20)/348.10(348.10)]
Gen. 20 (40.00%): Max/Min/Avg Fitness(Raw) [419.40(375.20)/337.80(345.20)/349.50(349.50)]
Gen. 25 (50.00%): Max/Min/Avg Fitness(Raw) [419.86(389.20)/341.55(345.20)/349.88(349.88)]
Gen. 30 (60.00%): Max/Min/Avg Fitness(Raw) [418.25(381.20)/341.41(345.20)/348.54(348.54)]
Gen. 35 (70.00%): Max/Min/Avg Fitness(Raw) [418.08(375.20)/340.08(345.20)/348.40(348.40)]
Gen. 40 (80.00%): Max/Min/Avg Fitness(Raw) [418.42(375.20)/339.53(345.20)/348.68(348.68)]
Gen. 45 (90.00%): Max/Min/Avg Fitness(Raw) [418.80(381.20)/340.76(345.20)/349.00(349.00)]
Gen. 50 (100.00%): Max/Min/Avg Fitness(Raw) [417.94(371.20)/338.92(345.20)/348.28(348.28)]
Total time elapsed: 2.478 seconds.
- GenomeBase
        Score:                   345.200000
        Fitness:                 338.919595

        Slot [Evaluator] (Count: 1)
                Name: evaluate
        Slot [Initializator] (Count: 1)
                Name: G1DListInitializatorInteger
                Doc:  Integer initialization function of G1DList

   This initializator accepts the *rangemin* and *rangemax* genome parameters.

        Slot [Mutator] (Count: 1)
                Name: G1DListMutatorSwap
                Doc:  The mutator of G1DList, Swap Mutator
        Slot [Crossover] (Count: 1)
                Name: G1DListCrossoverSinglePoint
                Doc:  The crossover of G1DList, Single Point

   .. warning:: You can't use this crossover method for lists with just one element.

- G1DList
        List size:       18
        List:            [36, 48, 1, 11, 95, 37, 34, 38, 25, 10, 29, 64, 19, 11, 62, 68, 7, 15]
</pre><p>Here are the visual results for this optimization:</p><table><tr><td><center><div
id="attachment_1314" class="wp-caption aligncenter" style="width: 310px"><a
href="http://matt.eifelle.com/wp-content/uploads/2010/07/comb0.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/07/comb0-300x226.png" alt="" title="Comb 0" width="300" height="226" class="size-medium wp-image-1314" /></a><p
class="wp-caption-text">The first comb</p></div></center></td><td><center><div
id="attachment_1315" class="wp-caption aligncenter" style="width: 310px"><a
href="http://matt.eifelle.com/wp-content/uploads/2010/07/comb1.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/07/comb1-300x226.png" alt="" title="Comb 1" width="300" height="226" class="size-medium wp-image-1315" /></a><p
class="wp-caption-text">The second comb</p></div></center></td></tr><tr><td
colspan="2"><center><div
id="attachment_1316" class="wp-caption aligncenter" style="width: 310px"><a
href="http://matt.eifelle.com/wp-content/uploads/2010/07/correlations.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/07/correlations-300x226.png" alt="" title="Correlations between the combs" width="300" height="226" class="size-medium wp-image-1316" /></a><p
class="wp-caption-text">Correlations between the combs</p></div></center></td></tr></table><p>They are not perfect, far from it, but remember that they are only combs with positive impulses. This means that you can&#8217;t get a perfect result. An almost-perfect result would be that the crosscorrelation is below 1, but with only one value of 2, it&#8217;s still pretty good.</p><h4>Before the end</h4><p>The process is very fast for 2 sequences of 10 impulses. If you add more sequences and more impulses, the computation time will rise fastly, but PyEvolve has now the ability to use the <strong>multiprocessing</strong> module, which means it can do parallel optimizations now.</p><p>PyEvolve can do much more, I only barely scratch the surface of its capablities, but I hope this example will make you try this package.</p><form
action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input
type="hidden" name="cmd" value="_xclick" /> <input
type="hidden" name="business" value="matthieu.brucher@gmail.com" /><input
type="hidden" name="item_name" value="Buy Me a Coffee!" /><input
type="hidden" name="currency_code" value="USD" /><span
style="font-size:10.0pt"><strong> Buy Me a Coffee!</strong></span><br
/><br
/><select
id="amount" name="amount" class=""><option
value="3">Capuccino - 3$</option><option
value="6">Frappuccino - 6$</option><option
value="10">Hot Chocolate - 10$</option><option
value="20">Expensive Coffee - 20$</option><option
value="50">Alien Coffee - 50$</option></select><br
/><br
/><strong>Other Amount:</strong><br
/><br
/><input
type="text" name="amount" size="10" title="Other donate" value="" /><br
/><br
/><strong> Your Email Address :</strong><input
type="hidden" name="on0" value="Reference" /><br
/><br
/><input
type="text" name="os0" maxlength="60" /> <br
/><br
/> <input
type="hidden" name="no_shipping" value="2" /> <input
type="hidden" name="no_note" value="1" /> <input
type="hidden" name="mrb" value="3FWGC6LFTMTUG" /> <input
type="hidden" name="bn" value="IC_Sample" /> <input
type="hidden" name="return" value="http://matt.eifelle.com" /><input
type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but11.gif" name="submit" alt="Make payments with payPal - it's fast, free and secure!" /></form>
<p><a href="http://feedads.g.doubleclick.net/~a/C1NxKpQx29VZkDocO8H1xLbxhVQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/C1NxKpQx29VZkDocO8H1xLbxhVQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/C1NxKpQx29VZkDocO8H1xLbxhVQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/C1NxKpQx29VZkDocO8H1xLbxhVQ/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/eJl2-tf11bA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/07/27/genetic-algorithms-in-python/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/07/27/genetic-algorithms-in-python/</feedburner:origLink></item> <item><title>Book review: Hacking Roomba: ExtremeTech</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/dRurjajGhHA/</link> <comments>http://matt.eifelle.com/2010/07/20/book-book-hacking-roomba-extremetech/#comments</comments> <pubDate>Tue, 20 Jul 2010 06:44:16 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Book review]]></category> <category><![CDATA[Wiley]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1295</guid> <description><![CDATA[I&#8217;ve recently bought a fourth generation Roomba, which is a vacuum cleaning robot. I bought this brand because it is well-known and has a good history of hackable robots. So the next step was to figure out how to hack it, and hence this book.Content and opinions
The book is split in three parts with progress [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;ve recently bought a fourth generation <a
href="http://www.irobot.com/">Roomba</a>, which is a vacuum cleaning robot. I bought this brand because it is well-known and has a good history of hackable robots. So the next step was to figure out how to hack it, and hence this book.<br
/> <span
id="more-1295"></span></p><h4>Content and opinions</h4><p>The book is split in three parts with progress hacking solutions. It is to be mentioned that it is dedicated to hacking the third generation, but the interface should be the same, although some instructions may have changed. Perhaps a new edition of the book may be needed.</p><p>iRobot had the good idea of opening their pets to hackers. It is done through a serial interface called ROI. The first encompasses the creation (or the buying) of a connector between a PC and the Roomba. There are several solutions, from a simple serial cable to a Bluetooth interface. Once you have a connector, you need to learn and use the interface to make the robot move and feel. Each captor and motor is explained as well as how it can be interacted with. The main examples are given through a Java library (I would have prefered a Python library, of course).</p><p>The second part is perhaps the least interesting. It starts with making an application to steer the robot. It is done with <a
href="http://www.processing.org/">Processing</a>, an obscur language that runs on the JVM. <a
href="http://www.infoworld.com/d/developer-world/top-five-scripting-languages-the-jvm-855">Why not one of the top five script language on it</a>? You may then use the inner beeper to make some music. Indeed, it can be fun, but it&#8217;s also not that easy, even with the help of the book. More fun is making art drawings with addition of pens sticked on the Roomba. I was a big fan of these kind of drawngs when I was young. The last chapter exposes the Roomba as a big input device such as a mouse. Of course, it can help doing some sports&#8230;</p><p>The last part is about using additional platforms to make a more complicated robot. First, you may connect it to the Internet to steer it from the other end of the world, the next step being using WiFi. Then, you may upgrade its brain with a classic Linux board, adding a camera, &#8230; OK, this is fun, but it&#8217;s not a cleaner anymore. It begins to be even very ugly and not that autonomous unless you stick a big battery pack. But I have to be agree on some aspects of the mod: it&#8217;s a good basis for building one&#8217;s custom robot. But you may find a skeletton for less (or not).</p><h4>Conclusion</h4><p>I intend to keep my Roomba as a vacuum cleaner, not a complete robot with a wifi router on top of it. Still, it is interesting to know that you can do a lot with it, and first of all with a simple serial cable or a Bluetooth connection.</p><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/uploads/2009/12/BN_Logo_3tier.jpg) right bottom no-repeat #ffffff;"><a
rel="nofollow" href="http://r.popshops.com/r/a0ExSGx1YUhML0JZWGQ3dnhrK0FkZG4rM2I2MWNic2V0UStmbHE0ZlRLYz0K"><img
style="width: 150px;" src="http://images.textbooks.com/TextbookInfo/Covers/0470072717.gif" border="0" alt="Hacking Roomba" /></a><br
/> <a
rel="nofollow" href="http://r.popshops.com/r/a0ExSGx1YUhML0JZWGQ3dnhrK0FkZG4rM2I2MWNic2V0UStmbHE0ZlRLYz0K">Hacking Roomba</a><br
/> Price: $20.22<br
/> By Kurt &#8211; John Wiley &amp; Sons, Inc. (00) &#8211; Paperback &#8211; ISBN 10 0470072717 &#8211; ISBN 13 9780470072714</div><div
class="subcolumns"><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/amazon_US_small.gif) right bottom no-repeat #ffffff;"><div
style="width: 60px; float: left; margin-right: 5px;"> <a
href="http://www.amazon.com/exec/obidos/ASIN/B0015DCQI0/masbl03-20" target="_blank"><img
src="http://ecx.images-amazon.com/images/I/512d%2BgqfCrL._SL75_.jpg" width="60" height="75" border="0" /></a></div><div><p><a
href="http://www.amazon.com/exec/obidos/ASIN/B0015DCQI0/masbl03-20" target="_blank">Hacking Roomba: ExtremeTech</a> (Paperback)<br
/> <span
style="font-size: 0.8em;">by <strong>Tod E. Kurt</strong></span><br
/> ISBN:</p><p><strong>Price:</strong> <span
style="color: #990000; font-weight: bold;"> &#8212;</span><br
/> <strong>22 used &#038; new</strong> available from <span
style="color: #990000; font-weight: bold;">USD 30.00</span></p><p> <img
src="http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/stars-4.5.gif" class="asa_rating_stars" /> | 4.5 | 7</div><div
style="clear: both;"></div></div></div>
<p><a href="http://feedads.g.doubleclick.net/~a/pqh7y5FBF-NC8-BqGBGAJq-9Ees/0/da"><img src="http://feedads.g.doubleclick.net/~a/pqh7y5FBF-NC8-BqGBGAJq-9Ees/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/pqh7y5FBF-NC8-BqGBGAJq-9Ees/1/da"><img src="http://feedads.g.doubleclick.net/~a/pqh7y5FBF-NC8-BqGBGAJq-9Ees/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/dRurjajGhHA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/07/20/book-book-hacking-roomba-extremetech/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/07/20/book-book-hacking-roomba-extremetech/</feedburner:origLink></item> <item><title>Dimensionality reduction: Refactoring the manifold module</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/7A1EtG3xcx8/</link> <comments>http://matt.eifelle.com/2010/07/13/dimensionality-reduction-refactoring-the-manifold-module/#comments</comments> <pubDate>Tue, 13 Jul 2010 07:05:40 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Manifold learning]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[scikit]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1290</guid> <description><![CDATA[It&#8217;s been a while since I last blogged about manifold learning. I don&#8217;t think I&#8217;ll add much in terms of algorithms to the scikit, but now that a clear API is being defined (http://sourceforge.net/apps/trac/scikit-learn/wiki/ApiDiscussion), it&#8217;s time for the manifold module to comply to it. Also, documentation will be enhanced and some dependencies will be removed.
I&#8217;ve [...]]]></description> <content:encoded><![CDATA[<p>It&#8217;s been a while since I last blogged about manifold learning. I don&#8217;t think I&#8217;ll add much in terms of algorithms to the scikit, but now that a clear API is being defined (<a
href="http://sourceforge.net/apps/trac/scikit-learn/wiki/ApiDiscussion">http://sourceforge.net/apps/trac/scikit-learn/wiki/ApiDiscussion</a>), it&#8217;s time for the manifold module to comply to it. Also, documentation will be enhanced and some dependencies will be removed.</p><p>I&#8217;ve started a branch available on <a
href="http://github.com/mbrucher/scikit-learn">github.com</a>, and I will some examples in the scikit as well. I may explain them here, but I won&#8217;t rewrite what is already published. A future post will explain the changes, and I hope that interested people will understand the modifications and apply them to my former posts. It&#8217;s just that I don&#8217;t have much time to change everything&#8230;</p>
<p><a href="http://feedads.g.doubleclick.net/~a/WP5TPWHAArLGNzZbm0q4WMPLWT4/0/da"><img src="http://feedads.g.doubleclick.net/~a/WP5TPWHAArLGNzZbm0q4WMPLWT4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/WP5TPWHAArLGNzZbm0q4WMPLWT4/1/da"><img src="http://feedads.g.doubleclick.net/~a/WP5TPWHAArLGNzZbm0q4WMPLWT4/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/7A1EtG3xcx8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/07/13/dimensionality-reduction-refactoring-the-manifold-module/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/07/13/dimensionality-reduction-refactoring-the-manifold-module/</feedburner:origLink></item> <item><title>QtVST: a Chamberlin Variable Filter</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/GXW3XSNs5Ew/</link> <comments>http://matt.eifelle.com/2010/07/06/qtvst-a-chamberlin-variable-filter/#comments</comments> <pubDate>Tue, 06 Jul 2010 07:17:52 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[C++]]></category> <category><![CDATA[Digital filters]]></category> <category><![CDATA[Music]]></category> <category><![CDATA[digital filter]]></category> <category><![CDATA[pyVST]]></category> <category><![CDATA[Qt]]></category> <category><![CDATA[VST]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1251</guid> <description><![CDATA[After my last post on QtAgain, I&#8217;ve decided to test a few simple digital filters. I&#8217;ve tried to make them as generic as possible, and with a VST interface.A templated Chamberlin filter
A Chamberlin filter is a IIR (Infinite Impulse Response) filter, and it is possible to make it output high-, band- or low-pass signals. It [...]]]></description> <content:encoded><![CDATA[<p>After <a
href="http://matt.eifelle.com/2010/03/02/fixing-the-qtagain-plugin/">my last post on QtAgain</a>, I&#8217;ve decided to test a few simple digital filters. I&#8217;ve tried to make them as generic as possible, and with a VST interface.<br
/> <span
id="more-1251"></span></p><h4>A templated Chamberlin filter</h4><p>A Chamberlin filter is a IIR (Infinite Impulse Response) filter, and it is possible to make it output high-, band- or low-pass signals. It has only two parameters that are independent.</p><p>The equations are very simple:<br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/07/equations.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/07/equations.png" alt="" title="Chamberlin Equations" class="aligncenter size-full wp-image-1279" /></a></center></p><p>Each of the series is either the low-pass, the band-pass or the high-pass output.</p><p>There are some factors that are pre-computed:<br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/07/factors.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/07/factors.png" alt="" title="Digital Factors" class="aligncenter size-full wp-image-1280" /></a></center></p><p>The first is a function of the <strong>C</strong>ut frequency and the <strong>S</strong>ampling frequency, a &#8220;numerical frequency&#8221;. The second one is the numerical attenuation, between 0 and 2.</p><p>This is an excerpt of the actual code, I&#8217;ve only displayed the relevant code.</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left2">Download <a
href="http://matt.eifelle.com/wp-content/plugins/wp-codebox/wp-codebox.php?p=1251&amp;download=variable_filter.h">variable_filter.h</a></span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p125110"><td
class="code" id="p1251code10"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Data_Type<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">class</span> VariableFilter
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  <span style="color: #0000ff;">typedef</span> Data_Type DataType<span style="color: #008080;">;</span>
&nbsp;
  <span style="color: #0000ff;">void</span> process<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> DataType<span style="color: #000040;">*</span> in, DataType<span style="color: #000040;">*</span> out, <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> nb_samples<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">long</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> nb_samples<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      yh <span style="color: #000080;">=</span> in<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000040;">-</span> yl <span style="color: #000040;">-</span> numerical_attenuation <span style="color: #000040;">*</span> yb<span style="color: #008080;">;</span>
      yb <span style="color: #000080;">=</span> numerical_frequency <span style="color: #000040;">*</span> yh <span style="color: #000040;">+</span> yb<span style="color: #008080;">;</span>
      yl <span style="color: #000080;">=</span> numerical_frequency <span style="color: #000040;">*</span> yb <span style="color: #000040;">+</span> yl<span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>selected <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        out<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> yl<span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>selected <span style="color: #000080;">==</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        out<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> yb<span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0000ff;">else</span>
      <span style="color: #008000;">&#123;</span>
        out<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> yh<span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span> 
&nbsp;
<span style="color: #0000ff;">protected</span><span style="color: #008080;">:</span>
  <span style="color: #0000ff;">void</span> compute_factors<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    numerical_frequency <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #000040;">*</span> std<span style="color: #008080;">::</span><span style="color: #0000dd;">sin</span><span style="color: #008000;">&#40;</span>M_PI <span style="color: #000040;">*</span> cutoff_frequency <span style="color: #000040;">/</span> sampling_frequency<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    numerical_attenuation <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #000040;">*</span> attenuation<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div><p>Now, I&#8217;ve written a simple GUI for this plugin.</p><h4>GUI with Qt</h4><p>I&#8217;ve used the QtAgain skeletton to wrap the filter and to make it available to <a
href="http://matt.eifelle.com/2010/03/09/annoucement-pyvst-0-1/">PyVST</a>. It&#8217;s really easy to add other parameters to the skeletton, so I will not write everything here again. There are three parameters, 2 numerical ones, and one three-state variable.</p><p><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/editor.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/editor-300x102.png" alt="" title="Chamberlin editor" width="300" height="102" class="aligncenter size-medium wp-image-1274" /></a></center></p><h4>Results</h4><p>I&#8217;ve recorded the filter&#8217;s outputs for 6kHz as central frequency, and an attenuation factor of .3. The output signal was generated from a random signal, and then an FFT was performed on the inputs and the outputs and displayed.</p><p>Note: I didn&#8217;t convert the scale to dB.</p><p><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/HighPass.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/HighPass-300x172.png" alt="" title="High Pass" width="300" height="172" class="aligncenter size-medium wp-image-1273" /></a></center><br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/BandPass.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/BandPass-300x172.png" alt="" title="Band Pass" width="300" height="172" class="aligncenter size-medium wp-image-1276" /></a></center><br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/LowPass.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/LowPass-300x172.png" alt="" title="Low Pass" width="300" height="172" class="aligncenter size-medium wp-image-1275" /></a></center></p><p>As you may have noted, the filter amplifies the signal near the central frequency for each output for the attenuation I&#8217;ve selected. The issue is that selecting a higher one has also an impact on the stability of the filter at higher frequencies. The sum of the numerical attenuation and the numerical frequency should always be inferior to 2.</p><h4>Conclusion</h4><p>This numerical is really simple to implement, and it has few parameters. The dark side of this filter is that is not always stable and the central frequency seems to be always amplified. Other filters can be better balanced.</p><p>The code is available on <a
href="https://code.launchpad.net/~matthieu-brucher/+junk/QtVST">Launchpad</a>.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/UIA7N1qzkOFhqiBTuIt6tcOFZqo/0/da"><img src="http://feedads.g.doubleclick.net/~a/UIA7N1qzkOFhqiBTuIt6tcOFZqo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/UIA7N1qzkOFhqiBTuIt6tcOFZqo/1/da"><img src="http://feedads.g.doubleclick.net/~a/UIA7N1qzkOFhqiBTuIt6tcOFZqo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/GXW3XSNs5Ew" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/07/06/qtvst-a-chamberlin-variable-filter/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/07/06/qtvst-a-chamberlin-variable-filter/</feedburner:origLink></item> <item><title>Optimization scikit: a conjugate-gradient optimization</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/vDBq41JcUk8/</link> <comments>http://matt.eifelle.com/2010/06/29/optimization-scikit-a-conjugate-gradient-optimization/#comments</comments> <pubDate>Tue, 29 Jun 2010 07:36:19 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Generic optimizers]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[numpy]]></category> <category><![CDATA[Optimization]]></category> <category><![CDATA[scikit]]></category> <category><![CDATA[scipy]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1254</guid> <description><![CDATA[In my last post about optimization, I&#8217;ve derived my function analytically. Sometimes, it&#8217;s not as easy. Sometimes also, a simple gradient optimization is not enough.
scikits.optimization has a special class for handling numerical differentiation, and several tools for conjugate gradients.Numerical Differentiation
Differentiation is accomplished through helper class. The new function has to be derived from of two [...]]]></description> <content:encoded><![CDATA[<p>In my <a
href="http://matt.eifelle.com/2010/04/27/optimization-scikit-a-gradient-based-optimization/">last post about optimization</a>, I&#8217;ve derived my function analytically. Sometimes, it&#8217;s not as easy. Sometimes also, a simple gradient optimization is not enough.</p><p>scikits.optimization has a special class for handling numerical differentiation, and several tools for conjugate gradients.<br
/> <span
id="more-1254"></span></p><h4>Numerical Differentiation</h4><p>Differentiation is accomplished through helper class. The new function has to be derived from of two classes,<br
/> <strong>ForwardFiniteDifferences</strong> or <strong>CenteredFiniteDifferences</strong>. In these classes, gradient and Hessian are computed based on the actual cost function. You may also override the gradient so that only the Hessian is numerically computed.</p><p>A single parameter, <strong>difference</strong>, is the delta that will be applied on each parameter to compute the derivatives. This number is arbitrally fixed, and may be changed in numerical differentiation fails.</p><p>Here is what a weighted sinc function looks like (the weights are given by <strong>self.a</strong>):</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p1254code13'); return false;">View Code</a> PYTHON</span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p125413"><td
class="code" id="p1254code13"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> scikits.<span style="color: black;">optimization</span>.<span style="color: black;">helpers</span> <span style="color: #ff7700;font-weight:bold;">import</span> ForwardFiniteDifferences
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Function<span style="color: black;">&#40;</span>ForwardFiniteDifferences<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    ForwardFiniteDifferences.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">a</span> = numpy.<span style="color: #dc143c;">array</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__call__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, x<span style="color: black;">&#41;</span>:
    t = numpy.<span style="color: black;">sqrt</span><span style="color: black;">&#40;</span>numpy.<span style="color: #008000;">sum</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">a</span> <span style="color: #66cc66;">*</span> x<span style="color: black;">&#41;</span><span style="color: #66cc66;">**</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> -numpy.<span style="color: black;">sinc</span><span style="color: black;">&#40;</span>numpy.<span style="color: black;">pi</span> <span style="color: #66cc66;">*</span> t<span style="color: black;">&#41;</span></pre></td></tr></table></div><h4>Conjugate Gradient</h4><p>Conjugate gradient is an optimization technique that uses the new gradient as well as the last descent direction or gradient to create a new descent direction. Besides this, the line search must have some properties. You don&#8217;t need an exact one, but it must obey some rules, known as the Wolfe-Powell rules. There are two formulations, both available in the scikit. I suggest you read some of the reference book I give at the end of the topic to choose the right line search, as well as the appropriate conjugate gradient.</p><p>Besides the well-known Fletcher Reeves conjugate gradient, there are several other factors that can be used, as the Polak-Ribière-Polyak that can also be combined with Fletcher-Reeves one to form what is perhaps the best formulation. The different available conjugate gradients are available in the documentation.</p><h4>Application</h4><p>OK, let&#8217;s see what it can do. I&#8217;ve assembled a Fletcher-Reeves conjugate gradient with Wolfe-Powell rules line search.</p><div
class="wp_codebox_msgheader"><span
class="right"><sup><a
href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span
style="color: #99cc00">?</span></a></sup></span><span
class="left"><a
href="javascript:;" onclick="javascript:showCodeTxt('p1254code14'); return false;">View Code</a> PYTHON</span><div
class="codebox_clear"></div></div><div
class="wp_codebox"><table><tr
id="p125414"><td
class="code" id="p1254code14"><pre class="python" style="font-family:monospace;">mystep = step.<span style="color: black;">FRConjugateGradientStep</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
mylinesearch = line_search.<span style="color: black;">WolfePowellRule</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
mycriterion = criterion.<span style="color: black;">criterion</span><span style="color: black;">&#40;</span>ftol = <span style="color: #ff4500;">0.0001</span>, iterations_max = <span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span>
myoptimizer = optimizer.<span style="color: black;">StandardOptimizer</span><span style="color: black;">&#40;</span>function = fun,
                                          step = mystep,
                                          line_search = mylinesearch,
                                          criterion = mycriterion,
                                          x0 = numpy.<span style="color: #dc143c;">array</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>.35, .45<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div><p>I didn&#8217;t display the result, because in fact it didn&#8217;t finished at 100 iterations.</p><p>Here are animations on the evolution of the value of the cost function and the position of the parameters.</p><p><center><object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param
name="allowFullScreen" value="true" /><param
name="allowscriptaccess" value="always" /><param
name="src" value="http://www.youtube.com/v/lEgjmdtfmFU&amp;hl=fr_FR&amp;fs=1&amp;" /><param
name="allowfullscreen" value="true" /><embed
type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/lEgjmdtfmFU&amp;hl=fr_FR&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></center></p><p><center><object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param
name="allowFullScreen" value="true" /><param
name="allowscriptaccess" value="always" /><param
name="src" value="http://www.youtube.com/v/8Lgy6-_K-Kg&amp;hl=fr_FR&amp;fs=1&amp;" /><param
name="allowfullscreen" value="true" /><embed
type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/8Lgy6-_K-Kg&amp;hl=fr_FR&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></center></p><p>Knowing that Fletcher-Reeves adds to the new gradient a fraction of the last direction, this circular evolution can be understood. In fact, with a simple gradient, it works better, as well as if a Polak-Ribière-Polyak is used. It all depends on how the different ingredients are mixed, as well as if the Wolfe-Powell rules are close to an exact line search.</p><h4>Conclusion</h4><p>I think that trying different solutions is what is fun about optimizations. With conjugate gradient, a lot of different optimizers can be built. With numerical differentitation, you don&#8217;t have to rely on analytical gradient. Know though that the more the parameters, the longest it takes to compute the gradient (O(n)) and I don&#8217;t even speak about the Hessian (O(n²)).</p><p>Here are some useful books that explain the theory and the ideas behind these topics:</p><p><a
href="http://www.amazon.com/gp/product/144193765X?ie=UTF8&amp;tag=masbl03-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=144193765X">Optimization Theory and Methods: Nonlinear Programming</a><img
class=" hxmcvxtkhsxxstgvfndl hxmcvxtkhsxxstgvfndl" style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=masbl03-20&amp;l=as2&amp;o=1&amp;a=144193765X" border="0" alt="" width="1" height="1" /></p><p><a
href="http://www.amazon.com/gp/product/0387303030?ie=UTF8&amp;tag=masbl03-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0387303030">Numerical Optimization</a><img
class=" hxmcvxtkhsxxstgvfndl hxmcvxtkhsxxstgvfndl" style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=masbl03-20&amp;l=as2&amp;o=1&amp;a=0387303030" border="0" alt="" width="1" height="1" /></p><p><a
href="http://www.amazon.com/gp/product/0470183527?ie=UTF8&amp;tag=masbl03-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0470183527">Engineering Optimization: Theory and Practice</a><img
class=" hxmcvxtkhsxxstgvfndl hxmcvxtkhsxxstgvfndl" style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=masbl03-20&amp;l=as2&amp;o=1&amp;a=0470183527" border="0" alt="" width="1" height="1" /></p><p>Link to the tutorial code: <a
href="https://code.launchpad.net/~matthieu-brucher/+junk/optimization-tutorials">Launchpad</a>.</p><form
action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input
type="hidden" name="cmd" value="_xclick" /> <input
type="hidden" name="business" value="matthieu.brucher@gmail.com" /><input
type="hidden" name="item_name" value="Buy Me a Coffee!" /><input
type="hidden" name="currency_code" value="USD" /><span
style="font-size:10.0pt"><strong> Buy Me a Coffee!</strong></span><br
/><br
/><select
id="amount" name="amount" class=""><option
value="3">Capuccino - 3$</option><option
value="6">Frappuccino - 6$</option><option
value="10">Hot Chocolate - 10$</option><option
value="20">Expensive Coffee - 20$</option><option
value="50">Alien Coffee - 50$</option></select><br
/><br
/><strong>Other Amount:</strong><br
/><br
/><input
type="text" name="amount" size="10" title="Other donate" value="" /><br
/><br
/><strong> Your Email Address :</strong><input
type="hidden" name="on0" value="Reference" /><br
/><br
/><input
type="text" name="os0" maxlength="60" /> <br
/><br
/> <input
type="hidden" name="no_shipping" value="2" /> <input
type="hidden" name="no_note" value="1" /> <input
type="hidden" name="mrb" value="3FWGC6LFTMTUG" /> <input
type="hidden" name="bn" value="IC_Sample" /> <input
type="hidden" name="return" value="http://matt.eifelle.com" /><input
type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but11.gif" name="submit" alt="Make payments with payPal - it's fast, free and secure!" /></form>
<p><a href="http://feedads.g.doubleclick.net/~a/lB-3VWSmm7HfrhNIpgT7mt1TeI0/0/da"><img src="http://feedads.g.doubleclick.net/~a/lB-3VWSmm7HfrhNIpgT7mt1TeI0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/lB-3VWSmm7HfrhNIpgT7mt1TeI0/1/da"><img src="http://feedads.g.doubleclick.net/~a/lB-3VWSmm7HfrhNIpgT7mt1TeI0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/vDBq41JcUk8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/06/29/optimization-scikit-a-conjugate-gradient-optimization/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/06/29/optimization-scikit-a-conjugate-gradient-optimization/</feedburner:origLink></item> <item><title>Optimally use massively parallel clusters resources</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/ZIWMCGF71KA/</link> <comments>http://matt.eifelle.com/2010/06/15/optimally-use-massively-parallel-clusters-resources/#comments</comments> <pubDate>Tue, 15 Jun 2010 07:53:10 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Distributed Computing]]></category> <category><![CDATA[High Performance Computing]]></category> <category><![CDATA[Tools]]></category> <category><![CDATA[Batch scheduling]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1208</guid> <description><![CDATA[We have now several petaflopic clusters available in the Top500. Of course, we are trying to get the most of their peak computational power, but I think we should sometimes also look at optimal resource allocation.
I&#8217;ve been thinking about this for several months now, for work that has thousands of tasks, each task being massively [...]]]></description> <content:encoded><![CDATA[<p>We have now <a
href="http://www.top500.org/">several petaflopic clusters available in the Top500</a>. Of course, we are trying to get the most of their peak computational power, but I think we should sometimes also look at optimal resource allocation.</p><p>I&#8217;ve been thinking about this for several months now, for work that has thousands of tasks, each task being massively data parallel. Traditionnally, one launches a job through one&#8217;s favorite batch scheduler (favorite or mandatory&#8230;) with fixed resources and during an estimated amount of time. This may work well in research, but in the industrial world, there often a new job that arises and that needs part of your scarce resources. You may have to stop your work, loose your current advances and/or restart the job with less resources. And then the cycle goes on.</p><p><span
id="more-1208"></span></p><h4>Static resource allocation</h4><p>How can resource allocation work? Let&#8217;s start with a simple case where you have 2 applications with different priorities. One of them has a priority of 70 (it&#8217;s supposed to finish in three days) whereas the other one has a priority of 50 (four days left). They share the cluster so that 66% is allocated to the first application and 33% to the second one.<br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/Allocation-2.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/Allocation-2-300x165.png" alt="" title="Dispatch and allocation of two applications" width="300" height="165" class="aligncenter size-medium wp-image-1241" /></a></center></p><p>What happens if a third application must be launched with a higher priority, because it has to ne finished by tomorrow? You may stop the other two programs, you may loose a lot of work if you didn&#8217;t implement checkpoints (besides, one of them may be an of-the-shelf program you bought yesterday) or suspend it. Either way, this is what you will get:<br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/Allocation-3.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/Allocation-3-300x165.png" alt="" title="Dispatch and allocation for three applications" width="300" height="165" class="aligncenter size-medium wp-image-1242" /></a></center></p><p>In fact, even if you use dynamic resource allocation, this is what you must get to have your results by the time you need them, but obviously, you have lost your two other applications. Some batch schedulers allow applications to be suspended, but this is a double-edge sword:</p><ul><li>your cluster must support job suspension, and thus have access to drives to save the job state (which is not possible for medium to large-scaled clusters)</li><li>if your application does not scale to your entire cluster (it happens), although one of the other two applications could go on, it is not possible, all processes are put to sleep</li></ul><p>So all things considered, you have to implement dynamic resource allocation.</p><h4>Dynamic resource allocation</h4><p>How does this work? Each application must be aware that it can be allocated more resources or deallocated some at all time. To be portable on all clusters, you cannot suspend part of your program, it must really go away. The batch scheduler must also notice that your application has freed some of its resources. You thus have to allocate small jobs that will communicate together (this can be done with MPI-2).</p><p>This means that you will have hundreds or thousands of small works. All of them will not have to be connected to the scheduler, only one master must be. Of course, this can easilly be done by using a specific queue. Each application on this queue will thus receive orders from the batch scheduler and act upon it. Another advantage is that also the application gets no resource at one point, it still has a saved state that enable the continuation of a run.<br
/><center><a
href="http://matt.eifelle.com/wp-content/uploads/2010/06/Dynamic-workflow.png"><img
src="http://matt.eifelle.com/wp-content/uploads/2010/06/Dynamic-workflow-300x165.png" alt="" title="Dynamic resource allocation workflow" width="300" height="165" class="aligncenter size-medium wp-image-1244" /></a></center></p><p>Of course, this is not easy to do. How can this be applied to an of-the-shelf application? Well, in this case, you may create a bogus application on the master queue that will at least allow other applications to be allocated resources beside it.</p><p>You do not have to implement this on top of MPI. It can be really hard to do (handling data moves between processors, change the decomposition, &#8230;), and you may implement another solution. In my case, I have thousands different tasks that can be run on very few cores, so this is my elementary unit. I don&#8217;t need all tasks to communicate between them, so I create each time brand new independent jobs and I also can tell the scheduler it can kill jobs that are not responding before the next allocation phase.</p><h4>Conclusion</h4><p>To finish, I&#8217;ll say that I know that <a
href="http://www.platform.com/">LSF</a> allows plugins that help dispatch jobs on specific hosts of your cluster (to have the best communication location). There seems to be a way of implementing the needs gathering and the resource assignment, but the documentation is not clear (at all). A specific daemon may be needed. I don&#8217;t know if other batch scheduler allow plugins to modify their behavior, if you know of them and their API, please do tell <img
src='http://matt.eifelle.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p>
<p><a href="http://feedads.g.doubleclick.net/~a/b2zG1Ob5K0S0OATMbQ0yr_hPG6g/0/da"><img src="http://feedads.g.doubleclick.net/~a/b2zG1Ob5K0S0OATMbQ0yr_hPG6g/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/b2zG1Ob5K0S0OATMbQ0yr_hPG6g/1/da"><img src="http://feedads.g.doubleclick.net/~a/b2zG1Ob5K0S0OATMbQ0yr_hPG6g/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/ZIWMCGF71KA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/06/15/optimally-use-massively-parallel-clusters-resources/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/06/15/optimally-use-massively-parallel-clusters-resources/</feedburner:origLink></item> <item><title>Book review: Building Automation: Communication Systems with EIB/KNX, LON and BACnet</title><link>http://feedproxy.google.com/~r/eifelle/CPPV/~3/Du_W5IvRf9A/</link> <comments>http://matt.eifelle.com/2010/06/08/book-review-building-automation-communication-systems-with-eibknx-lon-and-bacnet/#comments</comments> <pubDate>Tue, 08 Jun 2010 07:16:30 +0000</pubDate> <dc:creator>Matt</dc:creator> <category><![CDATA[Book review]]></category> <category><![CDATA[Electronic]]></category> <category><![CDATA[General]]></category> <category><![CDATA[Springer]]></category> <category><![CDATA[Building automation]]></category><guid isPermaLink="false">http://matt.eifelle.com/?p=1203</guid> <description><![CDATA[After last week review, I&#8217;ve decided to try another book from a much higher standard publisher, Springer. The price is also far higher, but it covers what I think are the current best supports for building automation.Content and opinions
There are three book&#8217;s authors, three German people, as Germany is one of the countries where building [...]]]></description> <content:encoded><![CDATA[<p>After <a
href="http://matt.eifelle.com/2010/06/01/book-review-smart-home-automation-with-linux/">last week review</a>, I&#8217;ve decided to try another book from a much higher standard publisher, Springer. The price is also far higher, but it covers what I think are the current best supports for building automation.<br
/> <span
id="more-1203"></span></p><h4>Content and opinions</h4><p>There are three book&#8217;s authors, three German people, as Germany is one of the countries where building automation is well developped.</p><p>The first chapter describes what building automation is. Its sub-categories are also explained (control, measurement and management), and I have to say that there are some differences that I didn&#8217;t apprehend before. Automation has several clear benefits: comfort with automatic heating, lights, &#8230; but also economies as a good heating control will lead to less consumption. This can really help in commercial or industrial buildings. It&#8217;s also astonishing to see that even new bulding do not come with a complete automation system. Heating is almost handled, but lights and blinds are not. Heating is not completely handled in my opinion because settings cannot be given outside your office.</p><p>The second chapter is perhaps the less interesting of the five. If you have basis in telecommunications, it will be a rehearsal of your first class. If you have not, you will at least know how it can work.</p><p>Now, the book has three chapters on each of the main automation technologies, Konnex, LON and BACnet. Each time, the chapter is independent, and sometimes you even learn something on a technology when reading the next one. When I say independent, I mean that you don&#8217;t need to read the other chapters if you want to read only one. It also means that you will see redundancy. This could be explained by each author writting his own chapter without much interaction on their content.</p><p>Each time, you will learn every detail of the different busses, with perhaps sometimes too many. For BACnet, you will go through the Ethernet interface in detail, although it is something really common in the ISO model. But to select the right bus, you need to know everything it can provide.</p><h4>Conclusion</h4><p>Contrary to my last book, this one was really interesting. I didn&#8217;t know that KNX was mainly based on one BCU (Bus Coupling Unit) with different actuators. Although you can also do management with KNX, I concur that it is a control bus at heart. I also appreciate the fact that each bus is open in the sense that there are several manufacturers that can provide appliances, and that their operation is clearly explained.</p><p>If you don&#8217;t know what building automation is and if you want to build your home, a commercial building, or if you renovate something, this book can help you should an adequate automation bus. Don&#8217;t forget that in these times of peak energy, economy associated with better comfort is a horse that can win the race.</p><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/uploads/2009/12/BN_Logo_3tier.jpg) right bottom no-repeat #ffffff;"> <a
rel="nofollow" href="http://r.popshops.com/r/bnNjRDhOVjd0cGhZc01QNXl4Z0dOaUFlc0l2UlcxeDUzOGRNY291MXpjST0K"><img
style="width: 150px;" src="http://images.barnesandnoble.com/images/42490000/42499788.JPG" border="0" alt="Building Automation: Communication Systems with Eib/Knx, Lon Und Bacnet" /></a><br
/> <a
rel="nofollow" href="http://r.popshops.com/r/bnNjRDhOVjd0cGhZc01QNXl4Z0dOaUFlc0l2UlcxeDUzOGRNY291MXpjST0K">Building Automation: Communication Systems with Eib/Knx, Lon Und Bacnet</a><br
/> Price: $87.2</div><div
class="subcolumns"><div
style="border: 1px solid #000; padding: 5px; margin-bottom: 15px; background: url(http://matt.eifelle.com/wp-content/plugins/amazonsimpleadmin/img/amazon_US_small.gif) right bottom no-repeat #ffffff;"><div
style="width: 50px; float: left; margin-right: 5px;"> <a
href="http://www.amazon.com/exec/obidos/ASIN/3540888284/masbl03-20" target="_blank"><img
src="http://ecx.images-amazon.com/images/I/41LQEKV2%2BKL._SL75_.jpg" width="50" height="75" border="0" /></a></div><div><p><a
href="http://www.amazon.com/exec/obidos/ASIN/3540888284/masbl03-20" target="_blank">Building Automation: Communication systems with EIB/KNX, LON and BACnet (Signals and Communication Technology)</a> (Hardcover)<br
/> <span
style="font-size: 0.8em;">by <strong>Hermann Merz, Thomas Hansemann, Christof Hübner</strong></span><br
/> ISBN: 3540888284</p><p><strong>Price:</strong> <span
style="color: #990000; font-weight: bold;">USD 87.20</span><br
/> <strong>33 used &#038; new</strong> available from <span
style="color: #990000; font-weight: bold;">USD 74.00</span></p><p> |  | 0</div><div
style="clear: both;"></div></div></div>
<p><a href="http://feedads.g.doubleclick.net/~a/tHpDfDcRQniB2p83A0FDGrfg8Ig/0/da"><img src="http://feedads.g.doubleclick.net/~a/tHpDfDcRQniB2p83A0FDGrfg8Ig/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/tHpDfDcRQniB2p83A0FDGrfg8Ig/1/da"><img src="http://feedads.g.doubleclick.net/~a/tHpDfDcRQniB2p83A0FDGrfg8Ig/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/eifelle/CPPV/~4/Du_W5IvRf9A" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://matt.eifelle.com/2010/06/08/book-review-building-automation-communication-systems-with-eibknx-lon-and-bacnet/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://matt.eifelle.com/2010/06/08/book-review-building-automation-communication-systems-with-eibknx-lon-and-bacnet/</feedburner:origLink></item> </channel> </rss><!-- Served from: matt.eifelle.com @ 2010-09-01 22:43:48 by W3 Total Cache -->
