<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4042332099774263836</id><updated>2012-01-28T06:20:35.512-08:00</updated><category term='suggestion'/><category term='cli'/><category term='display'/><category term='random number generator'/><category term='bug'/><category term='C'/><category term='diversion'/><category term='storage'/><category term='open source'/><category term='xterm'/><category term='ants'/><category term='In a one-horse open sleigh'/><category term='mouse'/><category term='social networking sites'/><category term='functional language'/><category term='quantum mechanics'/><category term='tips'/><category term='rss'/><category term='note-to-self'/><category term='video'/><category term='frustration'/><category term='serendipity'/><category term='X11'/><category term='rant'/><category term='laptop'/><category term='nerdier than a star trek convention'/><category term='cooling'/><category term='file transfer'/><category term='TV'/><category term='security'/><category term='information'/><category term='webcam'/><category term='URL'/><category term='CAPTCHA'/><category term='3initi'/><category term='excruciating puns'/><category term='ternary computing'/><category term='goop'/><category term='embarrasing photos of you wearing a traffic cone on your head'/><category term='remote control'/><category term='integration'/><category term='numismatics'/><category term='web fonts'/><category term='c99'/><category term='touch sensitive'/><category term='decoherence'/><category term='web browser'/><category term='operating system design'/><category term='statistics'/><category term='MIDI'/><category term='redundancy'/><category term='physical simulation'/><category term='shellscript'/><category term='web design'/><category term='google'/><category term='curiosity'/><category term='hair-pulling'/><category term='stargate universe'/><category term='javascript'/><category term='ov51x-jpeg'/><category term='fonze'/><category term='unidentified falling object'/><category term='tunguska'/><category term='input'/><category term='benchmark'/><category term='youtube'/><category term='oddity'/><category term='Dashing through the snow'/><category term='OSS'/><category term='C++'/><category term='comic book guy'/><category term='reddited'/><category term='python'/><category term='user interface'/><category term='computer'/><category term='internet'/><category term='implementation hiding'/><category term='maintenance'/><category term='canvas'/><category term='physics'/><category term='hardware'/><category term='HTML5'/><category term='linux'/><category term='hack'/><category term='idiot'/><category term='pestering'/><category term='lambda calculus'/><category term='spam mail'/><category term='programming'/><category term='CAPS LOCK DAY'/><category term='random'/><category term='OV519'/><category term='comment spam'/><category term='RNG'/><category term='blog'/><category term='phase shift keying'/><category term='absent-mindedness'/><category term='slackware'/><category term='free software'/><category term='pre-processor'/><category term='blogger'/><category term='words'/><category term='computer failure'/><category term='unix'/><category term='hardware failure'/><category term='kernel'/><category term='crackpot scheme'/><category term='mathematics'/><category term='joke'/><category term='&quot;security&quot;'/><category term='chaos'/><category term='failure'/><title type='text'>Awesome Geek Blog</title><subtitle type='html'>Whether the awesomeness lays in the geek or in the blog is yet to be determined.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>60</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7614786866988580792</id><published>2012-01-28T06:20:00.000-08:00</published><updated>2012-01-28T06:20:35.522-08:00</updated><title type='text'>Built myself a new computer</title><content type='html'>Had some money to spare, so I invested them in a new computer. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-OGbOjsV9GKY/TyQBPOrzwMI/AAAAAAAAAmA/fz8aSIPY5To/s1600/DSCF0063.pNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-OGbOjsV9GKY/TyQBPOrzwMI/AAAAAAAAAmA/fz8aSIPY5To/s320/DSCF0063.pNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Ignore the computer screen. It's from back in like 2007 or something.&lt;br /&gt;&lt;br /&gt;Shopping list looked like this:&lt;br /&gt;&lt;br /&gt;* Intel i7 2600k (this is purely for number crunching)&lt;br /&gt;* Asus P8Z68-V PRO/GEN3&lt;br /&gt;* Fractal Design R3&lt;br /&gt;* &lt;strike&gt;Corsair TX 750 V2&lt;/strike&gt;&amp;nbsp;This was a lemon. Bought a &lt;b&gt;Corsair HX 750&lt;/b&gt; locally and will be demanding a refund for the defective TX.&lt;br /&gt;* Corsair 2x4Gb 1333Mhz&amp;nbsp;XMMS3&lt;br /&gt;* MSI GeForce GTX570 Twin Frozr III OC/PE&lt;br /&gt;* Intel SSD 320 Series, 40 Gb SATA II&lt;br /&gt;* Western Digital Caviar Black, 500 Gb, SATA III&lt;br /&gt;&lt;br /&gt;Went for around $2000.&lt;br /&gt;&lt;br /&gt;I couldn't be happier with my purchase (except for the dud that was the TX 750). The CPU is wonderful for number crunching, the GPU packs on hell of a&amp;nbsp;wallop&amp;nbsp;for it's fairly modest price, the chassis is beautiful and quiet. The mother board has some quirks when it boots up, running through EFI/BIOS multiple times, (I think it's because it has multiple SATA controllers), but I can live with that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7614786866988580792?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7614786866988580792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2012/01/built-myself-new-computer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7614786866988580792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7614786866988580792'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2012/01/built-myself-new-computer.html' title='Built myself a new computer'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-OGbOjsV9GKY/TyQBPOrzwMI/AAAAAAAAAmA/fz8aSIPY5To/s72-c/DSCF0063.pNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3296065208554806619</id><published>2011-10-17T13:52:00.000-07:00</published><updated>2011-10-17T14:04:58.415-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='excruciating puns'/><category scheme='http://www.blogger.com/atom/ns#' term='nerdier than a star trek convention'/><title type='text'>The oddy-C</title><content type='html'>C was my first real programming language. Some people think that's a slightly crazy language to start off with. But I don't regret it one bit.&lt;br /&gt;&lt;br /&gt;Certainly, as the old adage goes; the C is a harsh mistress, but you've got to ask yourself if you want to be a lambda-lubber, or if you want to man up and grow a pair of C-legs.&lt;br /&gt;&lt;br /&gt;But making that decision is merely the beginning. Learning C is an epic journey fraught with danger, as the very notion of a mere mortal mastering the C angers to Poceidon, the god of the C, with a Unix beard that puts Stallman to shame. Poceidon, wielding his mighty trigraph, will divert a &lt;a href="http://en.wikipedia.org/wiki/Cyclone_(programming_language)"&gt;Cyclone&lt;/a&gt; into your path; guide you into perils such as a the lair of the witch Circe, cursing your stack with a bad return address; and let Cirens try to lure you off the segmentation falls.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;Surviving that, you must seek vengeance for the injustice the gods of programming have put you through. First you must enter the gates of kernel space, guarded by the three-headed guard dog Cerberos. Once in kernel space, you must do the seemingly impossible and tear a hole in the virtual paging table and travel to physical address 0. There, you will find the old modes shackled. You must free them. Let Real Mode roam free again! This will bring on &lt;/span&gt;Lambdarøk, the&amp;nbsp;prophesied&amp;nbsp;end of high level programming, where the world-tree withers into an undirected graph and the mighty garbage collector devours itself.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's a pity C doesn't have exceptions, because if it did, I could have worked in a deadliest &lt;tt&gt;catch&lt;/tt&gt; joke.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3296065208554806619?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3296065208554806619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/10/oddy-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3296065208554806619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3296065208554806619'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/10/oddy-c.html' title='The oddy-C'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-744463942303222436</id><published>2011-10-13T13:45:00.000-07:00</published><updated>2011-10-13T13:47:51.436-07:00</updated><title type='text'>Dennis Ritchie is dead</title><content type='html'>&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt&lt;br /&gt;#include&amp;nbsp;&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(void) {&lt;br /&gt;&amp;nbsp; puts("RIP");&lt;br /&gt;&amp;nbsp; return EXIT_SUCCESS;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;I wonder if he will haunt the standards committee until they finalize the new C1x standard. I imagine if he does choose to haunt something, it's either that, or the wander the halls of compiler manufacturers that have still yet not implemented all C99 features.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-744463942303222436?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/744463942303222436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/10/dennis-ritchie-is-dead.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/744463942303222436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/744463942303222436'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/10/dennis-ritchie-is-dead.html' title='Dennis Ritchie is dead'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-885445367661966227</id><published>2011-09-18T05:35:00.000-07:00</published><updated>2011-09-18T09:10:28.965-07:00</updated><title type='text'>A brief review of my remote development woes</title><content type='html'>I decided a while back I wanted to do remote C++ development. That is, do all the development on one machine (preferably in a nice IDE), and all the building/running/debugging on another machine. I found three options:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;b&gt;Eclipse CDT is supposed to support this&lt;/b&gt;&lt;br /&gt;&amp;nbsp;... with something called RSE. But as documentation is confusing at best, and everything about it is unintuitive, it's very hard to set up. After a long while of trying to make sense of it all, I barely got it working. And then it all crashed every 5 minutes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;NetBeans supports this natively&lt;/b&gt;&lt;br /&gt;Netbeans is by far the best option I've found. Set-up is a breeze, everything is seamless and works really well. The only drawback is that Netbeans has a very slow C++ parser which makes it quite painful to work with. So I imagine that the same set-up for java development would be nothing but joy.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Code::Blocks supports this through a third party application called Uniwin&lt;/b&gt;&lt;br /&gt;It isn't tremendously hard to set up, but as far as development environments go, C::B feels amateurish and dated.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;I suppose the conclusion I'm forced to draw is that the world isn't ready for remote C++ development yet, but if you absolutely have to do it, then NetBeans is your best shot.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-80gdQq5Q0Ws/TnXlM5jakQI/AAAAAAAAAbU/_5iyqW_paGU/s1600/netbeans.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="209" src="http://2.bp.blogspot.com/-80gdQq5Q0Ws/TnXlM5jakQI/AAAAAAAAAbU/_5iyqW_paGU/s320/netbeans.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="font-size: 13px; text-align: center;"&gt;Netbeans is the best option at this point&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-885445367661966227?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/885445367661966227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/09/brief-review-of-my-remote-development.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/885445367661966227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/885445367661966227'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/09/brief-review-of-my-remote-development.html' title='A brief review of my remote development woes'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-80gdQq5Q0Ws/TnXlM5jakQI/AAAAAAAAAbU/_5iyqW_paGU/s72-c/netbeans.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3009088432026524063</id><published>2011-09-06T06:52:00.000-07:00</published><updated>2011-09-06T08:53:47.348-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='pre-processor'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Preprocesing C with python</title><content type='html'>Heh, I cooked together a small shellscript that allows you to pre-process C code (technically also C++-code, if you make a minor alteration to the script) with python.&lt;br /&gt;&lt;br /&gt;It's set up to echo everything that doesn't begin with "%%", and pass those lines to python.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;tmpsource=`mktemp`&lt;br /&gt;cat $1 |&lt;br /&gt;        sed 's/^\([^\%]\+[^\\]*\)\\\(.*\)$/\1\\\\\2/g' |&lt;br /&gt;        sed 's/^\([^\%]\+.*\)$/print """\1"""/g' |&lt;br /&gt;        sed 's/^[\%][\%]\(.*\)$/\1/g' | python - &gt; $tmpsource&lt;br /&gt;shift&lt;br /&gt;gcc -x c $@ $tmpsource&lt;br /&gt;rm $tmpsource&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It's used like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;./cppy.sh sourcefile.c (flags-for-gcc)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For example, the following code prints "Hello World".&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;%%print "char* c = \"Hello World\";";&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[]) {&lt;br /&gt;        printf("%s\n", c);&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3009088432026524063?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3009088432026524063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/09/preprocesing-c-with-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3009088432026524063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3009088432026524063'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/09/preprocesing-c-with-python.html' title='Preprocesing C with python'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4813125123726855988</id><published>2011-08-24T10:06:00.000-07:00</published><updated>2011-08-24T12:06:50.557-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tunguska'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Dragonslaying in the bowels of Tunguska</title><content type='html'>It all started with a very small patch I committed to the &lt;a href="http://tunguska.sourceforge.net/"&gt;Tunguska&lt;/a&gt; CVS a few days ago, it moved some stuff off the heap onto the stack (these are small objects, so no, it's not what you're thinking) and made a few other very minor changes. It ran fine... then, and I was arguably a bit sloppy with the sanity checking as I thought it was all so small. But as it is with memory errors, they occasionally hide and pop up in the nastiest of places later.&lt;br /&gt;&lt;br /&gt;Today I found several bugs that have been festering in the code base since the dawn of time (since I've been working on the project highly intermittently, and some of the code started out being C rather than C++, some of the older code is quite dubious). I've mostly fixed the bugs now, except one particularly vexing bug in the assembler. &lt;br /&gt;&lt;br /&gt;The assembler uses yacc and lex to parse the source files. If you weren't aware, yacc takes a special file format and generates a Lovecraftian horror in source-code form. If there's a hell for programmers are sent to hell, I imagine it involves debugging yacc output with gdb.&lt;br /&gt;&lt;br /&gt;--edit--&lt;br /&gt;&lt;br /&gt;I just committed and checked-out the source code. This fixed the assembler. I made a copy of the old source directory for reference. &lt;i&gt;diff&lt;/i&gt; agrees the files are 100% the same. The clean routine in my makefile generates all generated code, objects, and binaries. &lt;br /&gt;&lt;br /&gt;It's stuff like this...&lt;br /&gt;&lt;br /&gt;Anyway, I think this highlights just how much Tunguska is in need of a design overhaul.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4813125123726855988?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4813125123726855988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/08/dragonslaying-in-bowels-of-tunguska.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4813125123726855988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4813125123726855988'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/08/dragonslaying-in-bowels-of-tunguska.html' title='Dragonslaying in the bowels of Tunguska'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7058809838694092218</id><published>2011-07-16T03:23:00.001-07:00</published><updated>2011-07-16T03:48:33.071-07:00</updated><title type='text'>Large buddhabrot fractal</title><content type='html'>So I've been messing around with the buddhabrot fractal again (credit to  &lt;a href="http://www.superliminal.com/index.htm"&gt;Melinda Green&lt;/a&gt; for it's discovery). I do this at least once most summers. Tradition I guess. This time, with more hardware at my disposal than previous years, and some work put into optimizing the algorithm by introducing a bit of a handwavy heuristic for which areas are inside the Mandelbrot set, I've managed to generate a very large map of the fractal.&lt;br /&gt;&lt;br /&gt;Just now I ran a test-run of 20,000 x 20,000 pixels, and this is with 16 samples per pixel, as I've hit a brick wall in terms of system memory, but supersampling is still viable. I set iteration depth to 1,000,000. Run time was around one and a half hour on my laptop which has an i5 M450 CPU, and the code is multi-threaded and makes use of all of the cores and hyper-threading and whatnot.&lt;br /&gt;&lt;br /&gt;The result is a png file that is almost 400 Mb in size, which poses a bit of a logistics problem. The result is absolutely stunning. I would love to share it with the world, but I have no idea how to go about it. Maybe using the google maps API? That still poses a problem of where to host almost half a gigabyte of image data.&lt;br /&gt;&lt;br /&gt;Anyway, until I figure that out, here are some samples (the full image consists of 625 tiles of this size, though some of the edge tiles are all black).&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center"&gt;&lt;a href="https://lh5.googleusercontent.com/-kcb_nUcVKss/TiFoQDcP5SI/AAAAAAAAAOs/GrhbqZLB-c0/frac1.png"&gt;&lt;img src="https://lh5.googleusercontent.com/-kcb_nUcVKss/TiFoQDcP5SI/AAAAAAAAAOs/GrhbqZLB-c0/s144/frac1.png" /&gt;&lt;/a&gt; &lt;a href="https://lh6.googleusercontent.com/-D3kyKN7dDK0/TiFoQcm7f5I/AAAAAAAAAOw/L-e4uLSeMnU/frac3.png"&gt;&lt;img src="https://lh6.googleusercontent.com/-D3kyKN7dDK0/TiFoQcm7f5I/AAAAAAAAAOw/L-e4uLSeMnU/s144/frac3.png" height="144" width="144" /&gt;&lt;/a&gt; &lt;a href="https://lh5.googleusercontent.com/-hDNlLEJeMhM/TiFoQHJDoeI/AAAAAAAAAO0/0PfYX6-qew8/frac2.png"&gt;&lt;img src="https://lh5.googleusercontent.com/-hDNlLEJeMhM/TiFoQHJDoeI/AAAAAAAAAO0/0PfYX6-qew8/s144/frac2.png" height="144" width="144" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://lh4.googleusercontent.com/-sYkQyzkIzuU/TiFoQmkgTHI/AAAAAAAAAO4/TlnMZImUy74/frac4.png"&gt;&lt;img src="https://lh4.googleusercontent.com/-sYkQyzkIzuU/TiFoQmkgTHI/AAAAAAAAAO4/TlnMZImUy74/s144/frac4.png" height="144" width="144" /&gt;&lt;/a&gt; &lt;a href="https://lh6.googleusercontent.com/-U1LsVNCKkgc/TiFoQ1fl4SI/AAAAAAAAAO8/M-ji2j4zQww/frac6.png"&gt;&lt;img src="https://lh6.googleusercontent.com/-U1LsVNCKkgc/TiFoQ1fl4SI/AAAAAAAAAO8/M-ji2j4zQww/s144/frac6.png" height="144" width="144" /&gt;&lt;/a&gt; &lt;a href="https://lh6.googleusercontent.com/-bTKPZPSNYkk/TiFoQiq6JGI/AAAAAAAAAPA/msg3ILUaun0/frac5.png"&gt;&lt;img src="https://lh6.googleusercontent.com/-bTKPZPSNYkk/TiFoQiq6JGI/AAAAAAAAAPA/msg3ILUaun0/s144/frac5.png" height="144" width="144" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7058809838694092218?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7058809838694092218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/07/large-buddhabrot-fractal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7058809838694092218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7058809838694092218'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/07/large-buddhabrot-fractal.html' title='Large buddhabrot fractal'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-kcb_nUcVKss/TiFoQDcP5SI/AAAAAAAAAOs/GrhbqZLB-c0/s72-c/frac1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-2506146943127433285</id><published>2011-06-27T06:54:00.000-07:00</published><updated>2011-06-27T07:36:27.822-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>The "C/C++" myth</title><content type='html'>Seeing C and C++ referred to as "C/C++" perplexes me to no end. Writing "C/C++" makes no sense at all. You almost always want either C or C++, as the two have widely disparate areas of suitability. &lt;br /&gt;&lt;br /&gt;The two languages seem to be shrouded in a good number of myths, that I would like to debunk&lt;br /&gt;&lt;br /&gt;&lt;dl&gt;&lt;br /&gt; &lt;dt&gt; Myth: There is a language "C/C++" &lt;/dt&gt;&lt;br /&gt; &lt;dd&gt;  There is no language "C/C++". C and C++ have very little in common. Yes, I know C++ evolved from C, but that fact aside, the two languages are very different. C++ has a lot more in common with basically any given object oriented language than it does with C. &lt;/dd&gt;&lt;br /&gt;&lt;br /&gt; &lt;dt&gt; Myth: C++ is the next version of C &lt;/dt&gt;&lt;br /&gt; &lt;dd&gt; C++ is C with an object system grafted onto to it (object orientation is not a more evolved form of imperative programming, even though it's more suitable for some tasks). &lt;br /&gt;&lt;br /&gt;The next version of C is &lt;a href="http://en.wikipedia.org/wiki/C1x"&gt;C1x&lt;/a&gt;. &lt;/dd&gt;&lt;br /&gt;&lt;br /&gt; &lt;dt&gt; Myth: C++ is backwards compatible with C &lt;/dt&gt;&lt;br /&gt; &lt;dd&gt; At some point, it was. But today, C++ is not backwards compatible with C, with void pointers and whatnot.&lt;br /&gt; &lt;/dd&gt;&lt;br /&gt;&lt;br /&gt; &lt;dt&gt; Myth: If you know C++, you know C &lt;/dt&gt;&lt;br /&gt; &lt;dd&gt; This is a superficial truth. You may know the syntax of the language, but this does not make you a good C programmer. The C language has a large number of limitations, and to overcome these requires a lot of experience in C. &lt;br /&gt;&lt;br /&gt;C++ has other ways of overcoming these limitations, and there generally is no way to directly translate these to C. Finally, imperative C++ code is bad C++ code, not C code. &lt;br /&gt;&lt;br /&gt;As a side note, this is why speed comparisons between C and C++ are typically pathological. If you compile a piece of C code in C++, it will run at the same speed as it would in C. But code in the wild is not going to be side-stepping the object system like that.&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-2506146943127433285?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/2506146943127433285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/06/cc-myth.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2506146943127433285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2506146943127433285'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/06/cc-myth.html' title='The &quot;C/C++&quot; myth'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1524159788546424423</id><published>2011-06-16T03:23:00.000-07:00</published><updated>2011-06-16T03:33:59.278-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='idiot'/><category scheme='http://www.blogger.com/atom/ns#' term='web design'/><title type='text'>Static webpages</title><content type='html'>If your webpage has nothing but static content, it should not be generated dynamically. There should not be a multi-second load time for a static webpage with 2 kB worth of content.&lt;br /&gt;&lt;br /&gt;If you do dynamically generate static content, then you, fine sir, are an idiot.&lt;br /&gt;&lt;br /&gt;Thanks for your patience. I needed to vent this, having used a university webpage that is like the antichrist of sensible web application design. Go go application state stored in session variables rather than the URL, so that browser navigation doesn't work and the whole application periodically crashes forcing you to re-start from the main page.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1524159788546424423?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1524159788546424423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/06/static-webpages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1524159788546424423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1524159788546424423'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/06/static-webpages.html' title='Static webpages'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-767182951203893297</id><published>2011-06-14T11:37:00.001-07:00</published><updated>2011-06-14T11:46:57.263-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><category scheme='http://www.blogger.com/atom/ns#' term='curiosity'/><title type='text'>The square root of 2, and multiples of 7</title><content type='html'>The square root of 2 has a mathematical curiosity. It starts with a long string of multiples of 7.&lt;br /&gt;&lt;br /&gt;For reference&lt;br /&gt;\[ \sqrt{2} = 1.4142135623730950\dots \]&lt;br /&gt;\[ \frac{\sqrt{2}}{7} = 0.2020305089104421\dots \]&lt;br /&gt;&lt;br /&gt;I've known about this for years. Chalked it up to a mathematical coincidence, and not really thought about it. What connects two, seven and ten (where ten comes from the numeric base used)? The answer is so simple&lt;br /&gt;&lt;br /&gt;\[ \sqrt{\frac{1}{2}} = 0.7071067811865475 \dots \approx 0.7 \]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-767182951203893297?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/767182951203893297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/06/square-root-of-2-and-multiples-of-7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/767182951203893297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/767182951203893297'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/06/square-root-of-2-and-multiples-of-7.html' title='The square root of 2, and multiples of 7'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-5467987003969823355</id><published>2011-05-31T10:35:00.000-07:00</published><updated>2011-06-05T12:53:29.083-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><title type='text'>Neat function</title><content type='html'>Stumbled on this neat function that acts like a singularity, except drops to zero instead of diverging within a neighborhood dependent on a parameter $\delta$. &lt;br /&gt;&lt;br /&gt;\[&lt;br /&gt;x^{-n}e^{-\frac{1}{2}\left(\frac{\delta}{x}\right)^{2n}}\approx\begin{cases}&lt;br /&gt;x^{-n} &amp; |x|&gt;\delta\\&lt;br /&gt;0 &amp; |x|&lt;\delta&lt;br /&gt;\end{cases}&lt;br /&gt;\]&lt;br /&gt;&lt;br /&gt;For $\delta &gt; 0$, $n\in\mathbb{N}_{1}$. I imagine this may help with unstable simulations of inverse square law type interaction.&lt;br /&gt;&lt;br /&gt;Integral is really nice too (for n &lt;u&gt;&amp;gt;&lt;/u&gt; 2), by diverging for small &amp;delta;, means it could possibly used for renormalization work?&lt;br /&gt;\[&lt;br /&gt;\int_0^{\infty} dx\ x^{-n}e^{-\frac{1}{2}\left(\frac{\delta}{x}\right)^{2n}}\sim\delta^{-n+1}&lt;br /&gt;\]&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://www.wolframalpha.com/input/?i=%28x^-2%29e^%28-0.5*%280.1/x%29^4%29%20vs%20x^-2" target="_blank"&gt;WA for some plots&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-5467987003969823355?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/5467987003969823355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/05/neat-function.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5467987003969823355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5467987003969823355'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/05/neat-function.html' title='Neat function'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4604335091146231183</id><published>2011-05-13T11:04:00.000-07:00</published><updated>2011-05-13T11:35:25.622-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><title type='text'>Imaginary numbers are silly</title><content type='html'>So, the imaginary constant is a pretty silly constant. While there is nothing &lt;span style="font-style:italic;"&gt;wrong&lt;/span&gt; with them, they're defined in a very awkward fashion. A much more elegant way of doing it is by using 2x2 matrices.&lt;br /&gt;&lt;br /&gt;Define the imaginary constant to be&lt;br /&gt;\[&lt;br /&gt;i=\left(\begin{matrix}0 &amp; -1\\&lt;br /&gt;1 &amp; 0\end{matrix}\right)&lt;br /&gt;\]&lt;br /&gt;which is the &lt;a target="_new" href="http://en.wikipedia.org/wiki/Rotation_matrix"&gt;rotation matrix&lt;/a&gt; for a 90 degree clockwise rotation of a two dimensional vector. &lt;br /&gt;&lt;br /&gt;Let's further implicitly put an identity matrix next to all numbers. For example, consider a complex number&lt;br /&gt;\[&lt;br /&gt;z=a+bi=\left(\begin{matrix}a &amp; 0\\&lt;br /&gt;0 &amp; a\end{matrix}\right)+\left(\begin{matrix}0 &amp; -b\\&lt;br /&gt;b &amp; 0\end{matrix}\right)=\left(\begin{matrix}a &amp; -b\\&lt;br /&gt;b &amp; a\end{matrix}\right)&lt;br /&gt;\]&lt;br /&gt;It's trivial to show that this obeys all that we'd expect from complex algebra (and complex conjugate is the same as transposing the matrix). Wasn't that nice? No obscure voodoo mathematics. Just a simple 2x2 matrix. We don't need to justify the existence of matrices. They are not just some ugly trick that's used to simplify calculations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4604335091146231183?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4604335091146231183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/05/imaginary-numbers-are-silly.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4604335091146231183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4604335091146231183'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/05/imaginary-numbers-are-silly.html' title='Imaginary numbers are silly'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-6297823090478054100</id><published>2011-02-25T17:01:00.001-08:00</published><updated>2011-02-25T17:22:17.788-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maintenance'/><category scheme='http://www.blogger.com/atom/ns#' term='cooling'/><category scheme='http://www.blogger.com/atom/ns#' term='computer'/><title type='text'>Superfluous computer ventilation</title><content type='html'>My old workstation has been re-assigned to server duty, but unfortunately, it is quite noisy. For a while I've considered various ways of reducing the noise. I tried cleaning the fans up a bit, which reduced the noise a lot, but you could still hear it across my apartment. &lt;br /&gt;&lt;br /&gt;During cleaning, I noticed that one of the fans contributed the bulk of the noise (as I ran case less for a moment, forcing me to unplug that particular fan.) So I thought, maybe I should replace it? Fans aren't terribly expensive.&lt;br /&gt;&lt;br /&gt;But then I started thinking, maybe I don't need it? It is after all a headless computer, and the GPU is one of the big culprits when it comes to generating heat. So I unplugged it and ran a load test (first 100% cpu on both cores, and next 100% cpu + heavy disk load).&lt;br /&gt;&lt;br /&gt;For a moment, my heart was racing as I watched the temperatures rise in a nearly vertical incline on the plot. But then they started to settle. ... at around 50 C. Very nice. I don't think I actually need to replace the fan. It'll just stay unplugged. Unfortunately, this was not the unidentified bad fan that starts making a racket every couple of hours until you apply a spot of percussive maintenance to it to quiet it down.&lt;br /&gt;&lt;br /&gt;I attached the load test data to the post for reference.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-M3-sf5PR5y4/TWhSV_NCrDI/AAAAAAAAAHA/yPVVCpnF7m0/s1600/thermal.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/-M3-sf5PR5y4/TWhSV_NCrDI/AAAAAAAAAHA/yPVVCpnF7m0/s320/thermal.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5577798676195224626" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-6297823090478054100?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/6297823090478054100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/02/superfluous-computer-ventilation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6297823090478054100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6297823090478054100'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/02/superfluous-computer-ventilation.html' title='Superfluous computer ventilation'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-M3-sf5PR5y4/TWhSV_NCrDI/AAAAAAAAAHA/yPVVCpnF7m0/s72-c/thermal.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7397109961654986551</id><published>2011-02-18T06:41:00.000-08:00</published><updated>2011-04-30T22:52:15.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quantum mechanics'/><category scheme='http://www.blogger.com/atom/ns#' term='decoherence'/><title type='text'>Cute demonstration of how random phase shifts lead to decoherence</title><content type='html'>This blog needs more physics.&lt;br /&gt;&lt;br /&gt;I've been looking around for a barebone example of &lt;a href="http://en.wikipedia.org/wiki/Decoherence"&gt;quantum decoherence&lt;/a&gt; that doesn't needlessly complicate matters with spin states and the like. Finding no satisfactory example, I whipped one up myself.&lt;br /&gt;&lt;br /&gt;In the quantum world, probabilities are described by the probability amplitude (let's call it &amp;psi;(x)), while in the classical world, it's enough to use probability densities, the absolute square of the probablity amplitude (i.e. $|\psi(x)|^2$).&lt;br /&gt;&lt;br /&gt;Decoherence is basically the process in which the quantum description of probability becomes equivalent to the classical description of probability through random phase changes.&lt;br /&gt;&lt;br /&gt;Let's consider a superposition of two wavefunctions:&lt;br /&gt;&lt;br /&gt;\[\psi(x) = e^{i\xi}\psi_1(x) + e^{i\phi}\psi_2(x)\]&lt;br /&gt;&lt;br /&gt;The probability density to measure the wavefunction at position x is now&lt;br /&gt;&lt;br /&gt;\[|\psi(x)|^2 = |\psi_1(x)|^2 + |\psi_2(x)|^2 + e^{i(\xi-\phi)}\psi_1(x)\psi_2(x)^*\]\[+ e^{-i(\xi-\phi)}\psi_1^*(x)\psi_2(x)\]&lt;br /&gt;&lt;br /&gt;The first two terms are phase independent and corresponds to classical, additive probabilities, and the last two are quantum terms that do not appear in classical physics. Also note that they depend on phase.&lt;br /&gt;&lt;br /&gt;So let's suppose we introduce a mechanism that at each time step has a miniscule probability of introducing a small fixed phase shift in the wavefunctions. &lt;br /&gt;&lt;br /&gt;Fiddling around a bit with expectation values it's straightfoward to show that this leads to a brownian walk in the phase difference &amp;delta;=&amp;xi;-&amp;phi;.&lt;br /&gt;&lt;br /&gt;It's well known that Brownian motion is diffusive, and can suitably be described with the heat equation. So the probability density for the phase difference is governed by &lt;br /&gt;&lt;br /&gt;\[\frac{dP(\delta)}{dt} = \alpha \frac{d^2P(\delta)}{d\delta^2}\]&lt;br /&gt;&lt;br /&gt;This gives solutions on the form&lt;br /&gt;&lt;br /&gt;\[P(\delta) = \exp(-\frac{\delta^2}{\alpha t})\]&lt;br /&gt;&lt;br /&gt;The phase factor next to the attenuation terms must now be re-written to take into account the diffusion of the phase.&lt;br /&gt;&lt;br /&gt;\[e^i(\delta) \rightarrow \int d\delta P(\delta) e^{i\delta} \]&lt;br /&gt;&lt;br /&gt;This is a standard integral that is easy to evaluate, giving&lt;br /&gt;&lt;br /&gt;\[ \int d\delta P(\delta) e^{i\delta} = e^{-\alpha t} \]&lt;br /&gt;&lt;br /&gt;So the revised probability density is&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;\[|\psi(x)|^2 = |\psi_1(x)|^2 + |\psi_2(x)|^2 + e^{-\alpha t}(\psi_1(x)\psi_2(x)^* + \psi_1^*(x)\psi_2(x))\]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In summary, brownian-like phase shifts leads to linear attenuation of the interference terms, and a decoherence time of &amp;alpha;&lt;sup&gt;-1&lt;/sup&gt;. This is of course a very simplistic model, and great care must be taken to ensure that such a process actually is applicable in order to avoid pathological cases.&lt;br /&gt;&lt;br /&gt;Take for example $\psi_1(x)=\psi_2(x)$, this is clearly an unphysical case as there is no way to independently phase-shift just one of the completely indistinguishable wavefunctions. If you do never the less feed this case to the model, it tells you very adamantly that either $\psi(x)=0$, or $2=1$.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Follow-up Feb 25:&lt;/span&gt; For a less hand-wavy and more intuitive theoretical demonstration, it's easy to show that mounting a device over one of the gaps in a double slit experiment that introduces random phase shifts to particles passing through it leads to the vanishing of the interference pattern. One can then move that action to a medium in the chamber, and get the same results (where attenuation depends on time-of-flight between slit and screen. For explicit time dependence, a moving screen could be introduced).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7397109961654986551?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7397109961654986551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/02/cute-demonstration-of-how-random-phase.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7397109961654986551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7397109961654986551'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/02/cute-demonstration-of-how-random-phase.html' title='Cute demonstration of how random phase shifts lead to decoherence'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3919116926523972781</id><published>2011-01-31T08:01:00.000-08:00</published><updated>2011-01-31T16:33:17.658-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crackpot scheme'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><category scheme='http://www.blogger.com/atom/ns#' term='remote control'/><title type='text'>Remote control over RSS</title><content type='html'>I've been pondering ways of remote controlling a computer in an environment that is hostile towards incoming connections (e.g. behind a router, behind a firewall, lacking previlegies to open ports, etc.) without the use of external servers dedicated to offer a connection between the two, and believe I've come up with something that would work.&lt;br /&gt;&lt;br /&gt;Web 2.0 is very much designed to be machine friendly. So much so it should be possible to feed instructions to a computer over an RSS feed (twitter, blogger, most forums, ...). The problem with this is that these feeds are made for text (which can be transformed fairly freely without degrading the message), whereas computer instructions are very sensitive to changes in case and the insertion or removal of newlines or spaces.&lt;br /&gt;&lt;br /&gt;So another layer is necessary. Suppose a message is encoded in base16 or base64, that way we can strip all non-significant symbols before parsing the message. But then the problem becomes identifying the message. To do that, a magic token can be attached to the beginning of the message. Say 'sgurocks' (as it's previously been established that &lt;a href="http://awesomegeekblog.blogspot.com/2010/05/sgu-is-awesome.html"&gt;praise of SGU is rare indeed&lt;/a&gt;, we an assume it won't appear in any text). Next, a 4-digit hexadecimal length is added. Next a hash (md5? Again hex-encoded) is applied to verify that this is indeed a valid message. Finally, the message itself is appended.&lt;br /&gt;&lt;br /&gt;This message encoding protocol has the benefit of being possible to scrape off any text-based medium, be it XML or HTML or whatever, and it's easy enough to encode that it should be possible to do with a greasemonkey script. Of course the computer we wish to control should only poll the RSS feed one or two times a minute to spare the server unnecessary traffic, so there would be a significant delay to this.&lt;br /&gt;&lt;br /&gt;The server could use one of the many APIs available for webservices to respond in kind (except, without the encoding.)&lt;br /&gt;&lt;br /&gt;I've done proof of concept testing on the RSS-scraping and decoding part, and the scheme seems to work fairly well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3919116926523972781?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3919116926523972781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/01/remote-control-over-rss.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3919116926523972781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3919116926523972781'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/01/remote-control-over-rss.html' title='Remote control over RSS'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-6501549453349365326</id><published>2011-01-29T16:24:00.000-08:00</published><updated>2011-01-29T16:36:55.005-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='free software'/><category scheme='http://www.blogger.com/atom/ns#' term='numismatics'/><title type='text'>Impressive Dutch coin, courtesy of Free Software</title><content type='html'>I was doing an unrelated google image search when an unusual looking coin caught my eye.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/TUSw6bqN4UI/AAAAAAAAAG0/fo-j89xFoaI/s1600/dutch-coin.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 162px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/TUSw6bqN4UI/AAAAAAAAAG0/fo-j89xFoaI/s320/dutch-coin.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5567769557240504642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I was intrigued, and found my way to a blog post by the coin's designer, who it turns out created it with open source software and python code (and this is a real coin that's gone to production, not just a mock up that stayed on a computer). A lot of thought went into the design, and the blog post was well worth the read.&lt;br /&gt;&lt;br /&gt;The post in question can be found here: &lt;a href="http://pythonide.blogspot.com/2008/10/how-to-make-money-with-free-software.html"&gt;How to Make Money with Free Software&lt;/a&gt; @ pythonide.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-6501549453349365326?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/6501549453349365326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/01/impressive-dutch-coin-courtesy-of-free.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6501549453349365326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6501549453349365326'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/01/impressive-dutch-coin-courtesy-of-free.html' title='Impressive Dutch coin, courtesy of Free Software'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/TUSw6bqN4UI/AAAAAAAAAG0/fo-j89xFoaI/s72-c/dutch-coin.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-187127435040221182</id><published>2011-01-18T13:28:00.000-08:00</published><updated>2011-01-18T13:35:18.598-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pestering'/><title type='text'>"Security"-pestering, follow up</title><content type='html'>It would seem that there's a final step as part of the pester-into-change strategy outlined in the previous blog post. When you've had your pester screen up for a month or two, you force the change upon everyone who didn't yield to the pester screen. Both of the sites I listed in the previous post (youtube and facebook) just pulled that.&lt;br /&gt;&lt;br /&gt;So the strategy for introducing potentially unwelcome changes as a whole seems to look like this:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Introduce new feature, allowing people to use it if they want to.&lt;/li&gt;&lt;li&gt;Add annoying screen after every log-in that urges people to adopt feature for "security" reasons.&lt;/li&gt;&lt;li&gt;Force the change on everyone, whether they want it or not.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-187127435040221182?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/187127435040221182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/01/security-pestering-follow-up.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/187127435040221182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/187127435040221182'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2011/01/security-pestering-follow-up.html' title='&quot;Security&quot;-pestering, follow up'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3429915532750078447</id><published>2010-12-30T17:49:00.000-08:00</published><updated>2010-12-30T17:59:47.144-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pestering'/><category scheme='http://www.blogger.com/atom/ns#' term='&quot;security&quot;'/><title type='text'>"Security"-pestering</title><content type='html'>This is bugging the hell out of me. You log into this web service, right, and what greets you? A screen asking you to do something you don't want to do in the name of security, and this doesn't go away until you do what they want, resulting in a sort of extortion scenario where you have to give in to their dubious proposition in order to be left alone.&lt;br /&gt;&lt;br /&gt;These two haunt my web experience:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Youtube wants me to link my gmail account with my youtube account for "security". There is no "Sod off, I don't want to."-button, just one that has it pestering me about it again the next time I log in. &lt;/li&gt;&lt;li&gt;Facebook wants to know my cell phone number and another email address. For "security". Every time I log in, I get this screen. There doesn't seem to be any way of getting rid of it.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;No, I'm not going to give in to their pestering. It's just going to drive me away from their services.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3429915532750078447?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3429915532750078447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/security-pestering.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3429915532750078447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3429915532750078447'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/security-pestering.html' title='&quot;Security&quot;-pestering'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3460533264377406728</id><published>2010-12-08T09:16:00.001-08:00</published><updated>2010-12-08T10:25:41.116-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><title type='text'>Grand rant about non-physicists and their misconceptions and attitudes</title><content type='html'>These misconceptions and attitudes generally held by non-physicists have been bothering me for quite some while. So I'll list them here.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Energy&lt;/h2&gt; A peculiar error by people who do not understand physics is to attach "energy" to things for no reason. Don't get me wrong, if a machine does work, clearly some sort of energy transfer is going on, but this is implicitly true, so there's no need to say a magnet lifts things with magnetic energy. It lifts them with magnetic force&lt;sup&gt;1&lt;/sup&gt;. It's also okay to just say magnetism.&lt;br /&gt;&lt;br /&gt;There's also an alarming number of people whose idea of energy is alarmingly similar to old &lt;a href="http://en.wikipedia.org/wiki/Aether_theories"&gt;aether theories&lt;/a&gt;, as though it's some sort of incandescent medium that permeates reality.&lt;br /&gt;&lt;h2&gt;The amazing pi!&lt;/h2&gt; "I'll memorize hundreds of digits of this mysterious, never ending number!" It's just a constant, and for almost all applications, you'll never need more than around 10 digits (say you make a meter-wide circle and want to know the circumference, then the error in your answer will be on atom scale if you have much more than 10 digits of pi, and at that level, measurement errors will dominate). Therefore, the irrational quality of pi is a curiosity at best. Nothing to write home about.&lt;br /&gt;&lt;br /&gt;Furthermore, 2pi is the better constant. At almost no place in mathematics does pi appear where a constant equal to 2pi wouldn't make more sense.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Einstein&lt;/h2&gt; Einstein did a lot of great things for certain, but his fame is way disproportionate to what he actually did. He's become some sort of patron saint/greek style personified concept deity of intelligence. People call you "an Einstein" when you're reasonably smart and/or a physicist. He did a lot of groundbreaking work, but this cult of personality is way out of hand (besides, everyone knows Feynman's cult of personality is the one to root for.)&lt;br /&gt;&lt;br /&gt;If anyone deserves to be the patron saint of intelligence, perhaps C.F. Gauss is a better choice, seeing as how you can't swing a bracket in mathematics without hitting something named after him. Or Newton for that matter.&lt;br /&gt;&lt;h2&gt;Schrödinger's cat&lt;/h2&gt; Erwin Schrödinger was one  of the founding fathers of quantum mechanics. But what is he remembered for? His thought experiment about a cat. And this is a fairly questionable thought experiment that overall probably gives you more misconceptions than it does insights. I really wish people would think "equation" and not "cat" when they hear his name.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;font size="small"&gt;Someone is bound to sit at home with a copy of Griffiths' Electrodynamics in their hands all riled up about how it says the magnets do no work.  This is an incomplete statement. While the Lorentz force does no work, spin is none the less acted upon by a force proportional to ∇B.&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3460533264377406728?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3460533264377406728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/grand-rant-about-non-physicists-and.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3460533264377406728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3460533264377406728'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/grand-rant-about-non-physicists-and.html' title='Grand rant about non-physicists and their misconceptions and attitudes'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1867161285829481416</id><published>2010-12-07T02:04:00.000-08:00</published><updated>2010-12-07T03:42:06.911-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dashing through the snow'/><category scheme='http://www.blogger.com/atom/ns#' term='computer failure'/><category scheme='http://www.blogger.com/atom/ns#' term='In a one-horse open sleigh'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware failure'/><title type='text'>System instability, revisited</title><content type='html'>So, my system has been fairly stable since the &lt;a href="http://awesomegeekblog.blogspot.com/2010/12/very-peculiar-system-instability-event.html"&gt;last incident&lt;/a&gt;, but now it's taken another step on it's slow journey towards oblivion.&lt;br /&gt;&lt;br /&gt;This time I was visited by seasonally appropriate graphical artefacts (i.e. small white boxes appearing and disappearing randomly). I was running the system under average to high load when they paid a visit. Switching from proprietary nvidia drivers to "nv"-drivers fixed it slightly, but it quickly turned worse so I rebooted. The artefacts mostly vanished, &lt;s&gt;but some persist around alpha-blended graphics&lt;/s&gt;. &lt;span style="font-style:italic;"&gt;Edit: This appears to be some sort of CPU saving mechanism in KDE 4. It mostly happened around widgets, but re-sizing them caused it to vanish.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lhmAHZ1VwRE/TP4aGZ5ct5I/AAAAAAAAAGQ/2a0nSuZ8QzI/s1600/snapshot1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 374px; height: 337px;" src="http://2.bp.blogspot.com/_lhmAHZ1VwRE/TP4aGZ5ct5I/AAAAAAAAAGQ/2a0nSuZ8QzI/s400/snapshot1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5547900488300410770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Fig&lt;/span&gt;: Residual graphical artefacts. The entire screen looked like this, or worse. I tried to screenshot the mess at the time, but at that point, it was so bad I couldn't distinguish any dialogs, and therefore had no way of saving it.&lt;br /&gt;&lt;br /&gt;This would indicate that the source of the problem is either the graphics card, or the memory corrupting the nvidia driver.&lt;br /&gt;&lt;br /&gt;I'll run some more memtest86, and if that doesn't find anything, do a GPU transplant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1867161285829481416?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1867161285829481416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/system-instability-revisited.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1867161285829481416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1867161285829481416'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/system-instability-revisited.html' title='System instability, revisited'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lhmAHZ1VwRE/TP4aGZ5ct5I/AAAAAAAAAGQ/2a0nSuZ8QzI/s72-c/snapshot1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1924060917941616977</id><published>2010-12-04T09:36:00.000-08:00</published><updated>2010-12-04T12:58:03.459-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computer failure'/><title type='text'>Very peculiar system instability event</title><content type='html'>Just now I came home from some grocery shopping, popped the dinner into the microwave, and turned on my main desktop computer. From the LILO-menu, I decided to boot Windows. Got as far as "Disk Read Error", and then the system rebooted. &lt;br /&gt;&lt;br /&gt;Ok, I thought, well, that drive is getting a bit old. But now LILO didn't even boot, I got the good old "&lt;a href="http://ircbots.debian.net/factoid.php?key=l01"&gt;L01 L01 L01 L01&lt;/a&gt;"-of-death screen. Not just a bad block, but some sort of progressive failure? &lt;br /&gt;&lt;br /&gt;Okay, I thought, maybe I'll try the other LILO install I have on another MBR in case of emergencies like this. "L01 L01 L01"... and then it surprised me by actually loading, but that was as far as it went, as it behaved very erratically. I didn't manage to actually boot anything, and even navigating the menu was sluggish. &lt;br /&gt;&lt;br /&gt;Now, the prospect of simultaneous disk failure seems a bit far fetched, and no other electronics have failed so I didn't consider a power spike particularly likely either. The CPU seems fine, as BIOS worked without trouble during the incident, and system temperature was also fine so a fan failure doesn't seem a likely explanation either. &lt;br /&gt;&lt;br /&gt;Anyway, I'm digressing from the story. At this point I shut it down and let the computer rest for a while as I ate my now cooked dinner. Then I tried again, got as far as "L01 L01 L01" and then the main LILO suddenly worked. I managed to boot into Linux, and there were no obvious signs of error. So I rebooted into Windows, and it worked too.&lt;br /&gt;&lt;br /&gt;I have no idea what this event was about, the most plausible explanation I've come up with is some sort of interference from the microwave (which I use on a daily basis, typically with the computer on and with no issues).&lt;br /&gt;&lt;br /&gt;So fingers crossed that this was some sort of fluke event that won't repeat itself, but in case it was it's way of saying "Goodbye cruel world!", I've made several off-site backups of everything of importance.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; Edit: Additional tests &lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;I've performed some diagnostic tests on the machine, ran a bad block search with fsck and a memtest86 sweep. No errors. But still some residual instability. It seems that if I get past booting, everything is stable and okay, but there's a chance things go bad at the boot loader or during the kernel loading. Maybe the MRB, or some other early block (that wouldn't have been tested by fsck) is damaged?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1924060917941616977?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1924060917941616977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/very-peculiar-system-instability-event.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1924060917941616977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1924060917941616977'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/very-peculiar-system-instability-event.html' title='Very peculiar system instability event'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-9027884052209003248</id><published>2010-12-02T04:29:00.000-08:00</published><updated>2010-12-02T04:36:32.490-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><category scheme='http://www.blogger.com/atom/ns#' term='oddity'/><title type='text'>Base inversion and digit ordering</title><content type='html'>Here's a mathematical curiosity I stumbled onto. The direction in which we write our numbers is just a convention, and as is the numeric base we write them in. But the two are actually closely related. A switch in direction is equivalent to inverting the base. &lt;br /&gt;&lt;br /&gt;Consider a number in base 10.&lt;br /&gt;&lt;br /&gt;123.4&lt;sub&gt;10&lt;/sub&gt; = 1 × 10&lt;sup&gt;2&lt;/sup&gt; + 2 × 10&lt;sup&gt;1&lt;/sup&gt; + 3 × 10&lt;sup&gt;0&lt;/sup&gt; + 4 × 10&lt;sup&gt;-1&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;In base 1/10, this would be written as&lt;br /&gt;&lt;br /&gt;4.321&lt;sub&gt;1/10&lt;/sub&gt; = 4 × 10&lt;sup&gt;-1&lt;/sup&gt; + 3 × 10&lt;sup&gt;0&lt;/sup&gt; + 2 × 10&lt;sup&gt;1&lt;/sup&gt; + 1 × 10&lt;sup&gt;2&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;Clearly, these are one and the same.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That is all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-9027884052209003248?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/9027884052209003248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/base-inversion-and-digit-ordering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/9027884052209003248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/9027884052209003248'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/12/base-inversion-and-digit-ordering.html' title='Base inversion and digit ordering'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-8493341443399892394</id><published>2010-11-29T06:24:00.000-08:00</published><updated>2010-11-29T11:00:38.381-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='slackware'/><title type='text'>Installing Slackware on a semi-isolated system</title><content type='html'>My ancient laptop is a never-ending fountain of joy. It's so old and battered, most forms of communication are dead, to the extent where I've had to transfer network card drivers over the sound card (as documented &lt;a href="http://awesomegeekblog.blogspot.com/2009/04/file-transfer-over-sound-card.html"&gt;here&lt;/a&gt;). Having done that, I managed to get a working Linux system up and running. But today it was that time of year again: Upgrade time. Adding to that, the file system was getting is a bit dodgy, so I decided to wipe the system and install anew. &lt;br /&gt;&lt;br /&gt;The obvious question is this: Just how do you install (Linux) on a system with no CD, DVD or USB capabilities. &lt;a href="http://alien.slackbook.org/dokuwiki/doku.php?id=slackware:pxe"&gt;PXE&lt;/a&gt; is one option, and I could go to all the trouble of setting that up, but there's another option: Making a boot-partition out of the swap partition. If you can install from an USB stick, a floppy disk or a CD, there should be no reason you couldn't do the same from a regular hard drive partition, right? It turns out that this feat isn't all that difficult at all, it's just poorly documented. So I'm documenting what I did here. &lt;br /&gt;&lt;br /&gt;&lt;em&gt;This is done at your own risk. Make sure to backup your data. I'm writing this assuming you have enough of an idea how to modify the instructions to suit your system. If you are not reasonably familiar with Slackware, this guide is not for you.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I'm going to be using the swap partition, which was called /dev/hda2 on my old install. This varies from system to system. Please make sure you're very certain which partition you want to install on.&lt;br /&gt;&lt;br /&gt;First step is to disable the swap partition.&lt;br /&gt;&lt;code&gt;# swapoff -a&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Next step is to create a file system on this partition.&lt;br /&gt;&lt;code&gt;# mkfs.ext2 /dev/hda2&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Mount it&lt;br /&gt;&lt;code&gt;# mount /dev/hda2 /mnt; cd /mnt&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As I'm going for a network install, I only want to download the isolinux and kernels directories of the Slackware tree. Here I chose the slackware.no-mirror because it's one of the faster ones nearby.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# wget -nv -r ftp://ftp.slackware.no/slackware/slackware-13.1/isolinux&lt;br /&gt;# wget -nv -r ftp://ftp.slackware.no/slackware/slackware-13.1/kernels&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The next step is to add the install partition to lilo, by adding the following section&lt;br /&gt;&lt;code&gt;image = /mnt/kernels/hugesmp.s/bzImage&lt;br /&gt;  root=/dev/hda2&lt;br /&gt;  label=SlackwareInst&lt;br /&gt;  initrd=/mnt/isolinux/initrd.img&lt;br /&gt;  append="load_ramdisk=1 prompt_ramdisk=0 rw SLACKWARE_KERNEL=hugesmp.s"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Update lilo by running&lt;br /&gt;&lt;code&gt;#lilo -v&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And reboot. Select SlackwareInst. Follow the instructions, and do a network install (I used the same FTP server as I grabbed the &lt;tt&gt;kernels&lt;/tt&gt; and &lt;tt&gt;initrd&lt;/tt&gt; stuff from). Easy as that.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/TPO8cN1X8SI/AAAAAAAAAGI/tSISjiN9jRc/s1600/shot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/TPO8cN1X8SI/AAAAAAAAAGI/tSISjiN9jRc/s400/shot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5544982759159099682" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-8493341443399892394?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/8493341443399892394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/11/installing-slackware-on-semi-isolated.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8493341443399892394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8493341443399892394'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/11/installing-slackware-on-semi-isolated.html' title='Installing Slackware on a semi-isolated system'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/TPO8cN1X8SI/AAAAAAAAAGI/tSISjiN9jRc/s72-c/shot.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-6194206046133955671</id><published>2010-07-29T08:26:00.000-07:00</published><updated>2010-07-29T08:32:42.748-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='comment spam'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Argh! Blogger needs a better comment management system!</title><content type='html'>I found this little surprise in my inbox today:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/TFGd3hbXTHI/AAAAAAAAAFw/G_yBcVD8p5U/s1600/arghcomments.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 299px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/TFGd3hbXTHI/AAAAAAAAAFw/G_yBcVD8p5U/s400/arghcomments.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5499350197187595378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As Blogger's comment management system is somewhat lacking, I had to go through the emails one by one to get the link to the relevant blog posts, scroll down to the spam comment, click the thrash can icon, load another page, and then click a button to finally delete the comment. Which is fine for individual spam messages. But when you get a barrage of 30 of them in one go, it really highlights just how lacking the comment management system in blogger is.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That is all. Just had to vent my frustration a bit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-6194206046133955671?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/6194206046133955671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/07/argh-blogger-needs-better-comment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6194206046133955671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6194206046133955671'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/07/argh-blogger-needs-better-comment.html' title='Argh! Blogger needs a better comment management system!'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/TFGd3hbXTHI/AAAAAAAAAFw/G_yBcVD8p5U/s72-c/arghcomments.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-5702779363951704258</id><published>2010-07-08T13:30:00.001-07:00</published><updated>2010-07-09T04:06:59.121-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='web fonts'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><title type='text'>HTML5 video and canvas hacks</title><content type='html'>This is not my handiwork, but it's just so damn awesome the world needs to see it:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.xkcd.com/viewtopic.php?f=11&amp;t=62173"&gt;http://forums.xkcd.com/viewtopic.php?f=11&amp;t=62173&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;It's a series of simple, yet clever hacks that allow, among other things, client-side transformation of video to ASCII art, and direct pixel manipulation of a video. All done in javascript.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've also been messing around with fonts from &lt;a href="http://code.google.com/webfonts"&gt;Google's web font directory&lt;/a&gt; in the blog's stylesheet. It's nice to see something else than the same old standard web fonts, but I think it's very much a novelty buzz that will likely wear of and get obnoxious fairly quickly. But until then, enjoy (if you don't like it, ... consider that it &lt;span style="font-style:italic;"&gt;could&lt;/span&gt; have been Papyrus or Comic Sans. So enjoy the fact that it's not.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-5702779363951704258?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/5702779363951704258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/07/html5-video-and-canvas-hacks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5702779363951704258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5702779363951704258'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/07/html5-video-and-canvas-hacks.html' title='HTML5 video and canvas hacks'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-8271361678437188370</id><published>2010-06-18T23:08:00.000-07:00</published><updated>2010-06-18T23:14:13.487-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cli'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Command Line Google</title><content type='html'>Saw this on the google opensource blog: &lt;a href="http://google-opensource.blogspot.com/2010/06/introducing-google-command-line-tool.html"&gt;Introducing Google Command Line Tool&lt;/a&gt;. The actual project is &lt;a href="http://code.google.com/p/googlecl/"&gt;here&lt;/a&gt; if you want to save a click.&lt;br /&gt;&lt;br /&gt;I whole-heartedly approve, and figured it couldn't possibly suffer from sharing. And alas no, I didn't post this with googlecl. &lt;br /&gt;&lt;br /&gt;That is all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-8271361678437188370?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/8271361678437188370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/06/command-line-google.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8271361678437188370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8271361678437188370'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/06/command-line-google.html' title='Command Line Google'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-786479054077027284</id><published>2010-06-16T14:57:00.001-07:00</published><updated>2010-06-16T15:30:34.733-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='embarrasing photos of you wearing a traffic cone on your head'/><category scheme='http://www.blogger.com/atom/ns#' term='social networking sites'/><title type='text'>Compartmentalizing your online identity</title><content type='html'>While, yes, most everything you post online remains online for quite some time, and there's not really a whole lot you can do about that. &lt;br /&gt;&lt;br /&gt;There are however quite simple means to deal with that -- means you use offline all the time without thinking about it: Social circles. You most likely wouldn't dream of bringing your boss or parents out drinking with your drinking buddies? That's because they're from different social circles, and meet different identities (your professional identity, and your casual friends-and-family identity respectively). And such social circles are typically quite stratified. &lt;br /&gt;&lt;br /&gt;There is nothing keeping you from arranging similar systems online. Nom de plumes and aliases have been used for ages in the analog world, and with good reason. While using different account for different social circles is no guarantee information won't seep between them (same as rumors do in the analog world), it will at least limit this information bleed.&lt;br /&gt;&lt;br /&gt;Actually realizing this is quite easy depending on which networks you're using, most of them send you an email when something interesting has happened, so you really don't have to constantly check every single account you have (which, even if it's just two per social network site, can reach quite large numbers.) &lt;br /&gt;&lt;br /&gt;Though there are actual account-switching issues as, I think, you're not expected to have more than one online identity: Gmail for example has a quite frustrating bug that sometimes occurs when you log out and forget to close every single google-related browser tab you have open before logging into another account, where it breaks the session and you have to go to the google main page and log out from there. &lt;br /&gt;&lt;br /&gt;Another option would of course be using different social networking sites for different social circles, but that has it's share of issues as well, including being met by anger and frustration when you refuse to add someone you know well in real life as a contact on the "wrong" site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-786479054077027284?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/786479054077027284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/06/compartmentalizing-your-online-identity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/786479054077027284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/786479054077027284'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/06/compartmentalizing-your-online-identity.html' title='Compartmentalizing your online identity'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-5817140157576130988</id><published>2010-05-08T04:40:00.000-07:00</published><updated>2010-05-08T05:45:37.687-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='stargate universe'/><category scheme='http://www.blogger.com/atom/ns#' term='TV'/><category scheme='http://www.blogger.com/atom/ns#' term='comic book guy'/><title type='text'>SGU is awesome</title><content type='html'>This post is dedicated to the television show "&lt;a href="http://en.wikipedia.org/wiki/Stargate_Universe"&gt;Stargate Universe&lt;/a&gt;". If you have ever seen the show, you're probably wondering if I'm drunk or stoned after having seen the title of this post. I am neither. But don't get me wrong, taken at face value, the show is mind-bogglingly, appallingly bad. A poorly executed clone of "Battlestar Galactica" and "Lost" made worse still by gratuitous overuse of shakycam, and characters devoting every waking moment to plotting and scheming like &lt;a href="http://en.wikipedia.org/wiki/Smallville_%28season_4%29"&gt;high-school kids with a heightened sense of self-importance&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;This is what google has to say:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/S-VO9s4-UUI/AAAAAAAAAFo/YeqKGFsiwms/s1600/SGU.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 361px; height: 271px; border: 1px solid #ccc;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/S-VO9s4-UUI/AAAAAAAAAFo/YeqKGFsiwms/s400/SGU.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5468864144440447298" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The search results yield loving &lt;a href="http://www.gateworld.net/news/2010/03/mgm-web-site-unveils-sgus-alien-race/#comment-9560"&gt;comments&lt;/a&gt; like&lt;br /&gt;&lt;blockquote&gt;[I] hope [the monster] eats half of the crew and the rest die in a fire.&lt;/blockquote&gt;... which really speaks for how utterly SGU fails to evoke even basic sympathy for the characters, evoking less emotion than the struggles of &lt;a href="http://en.wikipedia.org/wiki/Pok%C3%A9mon_Red_and_Blue"&gt;20x20 pixel sprites&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So why do I claim that this universally jeered at TV-show is awesome? At first, I watched it, and during each episode I thought "why am I watching this crap?". When the episode was over, I thought "why did I sit through that crap?". Then the answer struck me: So I could discuss with others how bad it is. For once, everyone agree on something. &lt;span style="font-style:italic;"&gt;Nobody&lt;/span&gt; likes SGU.&lt;br /&gt;&lt;br /&gt;This show is so blatantly bad that everyone can be a snide critic without spending hours on TVtropes learning the cliches. And being snarky is fun, especially with friends, heckling together against a common enemy. SGU brings people together. People meet to discuss how bad it is, offline and online. Whether or not you like sci-fi or the stargate franchise in general; you'll definitely be able to join in hating SGU.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A SGU shot game doesn't need rules. The show makes you want to kill your brains on a regular enough basis as it stands. And that is why I love it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-5817140157576130988?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/5817140157576130988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/05/sgu-is-awesome.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5817140157576130988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5817140157576130988'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/05/sgu-is-awesome.html' title='SGU is awesome'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lhmAHZ1VwRE/S-VO9s4-UUI/AAAAAAAAAFo/YeqKGFsiwms/s72-c/SGU.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-6334577889693519108</id><published>2010-04-10T10:44:00.000-07:00</published><updated>2010-04-10T11:22:22.134-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='c99'/><category scheme='http://www.blogger.com/atom/ns#' term='implementation hiding'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>A horrible exercise in implementation hiding</title><content type='html'>The following is pretty straightforward C99 code. Try to guess what it does.&lt;br /&gt; &lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include "list.h"&lt;br /&gt;#include &amp;lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[]) {&lt;br /&gt; struct list *l = list_new(); &lt;br /&gt; *(void**) list_append(l)= (void*)  0x00;&lt;br /&gt; *(void**) list_append(l)= (void*) 0x01;&lt;br /&gt; *(void**) list_append(l)= (void*) 0x02;&lt;br /&gt; *(void**) list_append(l)= (void*) 0x03;&lt;br /&gt; *(void**) list_append(l)= (void*) 0x04;&lt;br /&gt;&lt;br /&gt; for(struct list_iterator* it = l-&gt;first;&lt;br /&gt;  it != l-&gt;last; it = (struct list_iterator *) it-&gt;next) {&lt;br /&gt;  printf("%p\n", *(void**) it);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Looks and feels like a linked list being created and then iterated, right? Wrong. It is so much worse than that. As a horrible exercise in implementation hiding&lt;sup&gt;&amp;dagger;&lt;/sup&gt;, this is an array list, and the iteration is done in a very devious way.&lt;br /&gt;&lt;br /&gt;The list header looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#ifndef LIST_H&lt;br /&gt;#define LIST_H&lt;br /&gt;&lt;br /&gt;struct list_iterator {&lt;br /&gt; void *data;&lt;br /&gt; void *next[];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct list {&lt;br /&gt; struct list_iterator *first;&lt;br /&gt; struct list_iterator *last;&lt;br /&gt; int allocated;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct list *list_new();&lt;br /&gt;struct list_iterator *list_append(struct list* list);&lt;br /&gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It still &lt;span style="font-style:italic;"&gt;kinda&lt;/span&gt; looks linked-list-ish at a glance, but something is off about it.&lt;br /&gt;&lt;br /&gt;A rough sketch of the implementation would look like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include "list.h"&lt;br /&gt;#include &amp;lt;stdlib.h&gt;&lt;br /&gt;&lt;br /&gt;struct list *list_new() {&lt;br /&gt; struct list *l = malloc(sizeof(*l));&lt;br /&gt; l-&gt;allocated = 2;&lt;br /&gt; l-&gt;first = malloc(l-&gt;allocated * sizeof(struct list_iterator));&lt;br /&gt; l-&gt;last = l-&gt;first;&lt;br /&gt;&lt;br /&gt; return l;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct list_iterator *list_append(struct list* list) {&lt;br /&gt; if(list-&gt;last == list-&gt;first + list-&gt;allocated) {&lt;br /&gt;  list-&gt;allocated *= 2;&lt;br /&gt;  list-&gt;first = realloc(list-&gt;first, list-&gt;allocated * sizeof(void *));&lt;br /&gt;  list-&gt;last = list-&gt;first + list-&gt;allocated / 2;&lt;br /&gt; }&lt;br /&gt; return list-&gt;last++;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That was no linked list.&lt;br /&gt;&lt;br /&gt;It's decidedly sneaky: &lt;tt&gt;struct list_iterator.next&lt;/tt&gt; &lt;span style="font-style:italic;"&gt;overlaps&lt;/span&gt; with the next element in the array through use of C99's flexible array members, giving the list a free next pointer without any extra memory usage at all. &lt;br /&gt;&lt;br /&gt;This is proof of concept, and I don't suggest this should ever be used for anything other than scaring the elderly and small children.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 8pt"&gt;&lt;sup&gt;&amp;dagger;&lt;/sup&gt; Well, it isn't strictly speaking true implementation hiding, as you can see what's going on from the public interface in the header. But in lack of a better term...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-6334577889693519108?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/6334577889693519108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/04/horrible-exercise-in-implementation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6334577889693519108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6334577889693519108'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/04/horrible-exercise-in-implementation.html' title='A horrible exercise in implementation hiding'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-8786261730809545280</id><published>2010-03-14T14:43:00.000-07:00</published><updated>2010-03-14T15:29:54.967-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='random'/><category scheme='http://www.blogger.com/atom/ns#' term='words'/><title type='text'>Vertical and diagonal words</title><content type='html'>Unix systems often have a quite handy file called &lt;tt&gt;/usr/share/dict/words&lt;/tt&gt; that contains almost 40,000 or so words for use by spell checking tools. It's sorted, and each word is separated by a newline. So it looks something like&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;aback&lt;br /&gt;abaft&lt;br /&gt;abandon &lt;br /&gt;abandoned&lt;/tt&gt;&lt;br /&gt;etc.&lt;br /&gt;&lt;br /&gt;On a random whim I set out to examine to what extent words existed vertically in this dictionary, using a quite ugly brute-force approach that tested a 1,081,332 character long string that was basically a concatenation of every single word in the dictionary for the 40,000 sub-strings that made up the dictionary, running for a minute or so.&lt;br /&gt;&lt;br /&gt;Perhaps not surprisingly, there weren't a lot of these words. And in fact, the longest words were only five letters long; but in case someone wants to build a crossword puzzle or something, here is a list of those words:&lt;br /&gt;&lt;br /&gt;&lt;div style="height: 300px; overflow: auto"&gt;&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;adder&lt;/span&gt;&lt;br /&gt;multistage&lt;br /&gt;multitude&lt;br /&gt;multitudes&lt;br /&gt;multiuser&lt;br /&gt;multivariate&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;doors&lt;/span&gt;&lt;br /&gt;surged&lt;br /&gt;surgeon&lt;br /&gt;surgeons&lt;br /&gt;surgery&lt;br /&gt;surges&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;fills&lt;/span&gt;&lt;br /&gt;mindfulness&lt;br /&gt;minding&lt;br /&gt;mindless&lt;br /&gt;mindlessly&lt;br /&gt;minds&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;fills&lt;/span&gt;&lt;br /&gt;doubtfully&lt;br /&gt;doubting&lt;br /&gt;doubtless&lt;br /&gt;doubtlessly&lt;br /&gt;doubts&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;fills&lt;/span&gt;&lt;br /&gt;fruitfulness&lt;br /&gt;fruition&lt;br /&gt;fruitless&lt;br /&gt;fruitlessly&lt;br /&gt;fruits&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;guess&lt;/span&gt;&lt;br /&gt;amalgams&lt;br /&gt;amanuensis&lt;br /&gt;amaretto&lt;br /&gt;amass&lt;br /&gt;amassed&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;guess&lt;/span&gt;&lt;br /&gt;resting&lt;br /&gt;restitution&lt;br /&gt;restive&lt;br /&gt;restless&lt;br /&gt;restlessly&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;hills&lt;/span&gt;&lt;br /&gt;motherhood&lt;br /&gt;mothering&lt;br /&gt;motherland&lt;br /&gt;motherly&lt;br /&gt;mothers&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;noose&lt;/span&gt;&lt;br /&gt;compactness&lt;br /&gt;compactor&lt;br /&gt;compactors&lt;br /&gt;compacts&lt;br /&gt;companies&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;sauce&lt;/span&gt;&lt;br /&gt;samplings&lt;br /&gt;sanatoria&lt;br /&gt;sanatorium&lt;br /&gt;sanctification&lt;br /&gt;sanctified&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;sneer&lt;/span&gt;&lt;br /&gt;assesses&lt;br /&gt;assessing&lt;br /&gt;assessment&lt;br /&gt;assessments&lt;br /&gt;assessor&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;steep&lt;/span&gt;&lt;br /&gt;horseshoer&lt;br /&gt;horticulture&lt;br /&gt;hose&lt;br /&gt;hoses&lt;br /&gt;hospitable&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;stint&lt;/span&gt;&lt;br /&gt;despising&lt;br /&gt;despite&lt;br /&gt;despoil&lt;br /&gt;despondent&lt;br /&gt;despot&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Diagonally, though, is quite a lot more interesting. Not only are the words quite a lot longer, the diagonal word is almost always the same as&amp;mdash;or very similar to&amp;mdash;the last word, which is a semi-obvious consequence of sorting when you think about it. &lt;br /&gt;&lt;br /&gt;The longest few I found were&lt;br /&gt;&lt;br /&gt;&lt;div style="height: 300px; overflow: auto"&gt;&lt;tt&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;differentiation&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;d&lt;/span&gt;iets&lt;br /&gt;d&lt;span style="font-weight:bold;"&gt;i&lt;/span&gt;ffer&lt;br /&gt;di&lt;span style="font-weight:bold;"&gt;f&lt;/span&gt;fered&lt;br /&gt;dif&lt;span style="font-weight:bold;"&gt;f&lt;/span&gt;erence&lt;br /&gt;diff&lt;span style="font-weight:bold;"&gt;e&lt;/span&gt;rences&lt;br /&gt;diffe&lt;span style="font-weight:bold;"&gt;r&lt;/span&gt;ent&lt;br /&gt;differ&lt;span style="font-weight:bold;"&gt;e&lt;/span&gt;ntiable&lt;br /&gt;differe&lt;span style="font-weight:bold;"&gt;n&lt;/span&gt;tial&lt;br /&gt;differen&lt;span style="font-weight:bold;"&gt;t&lt;/span&gt;ials&lt;br /&gt;different&lt;span style="font-weight:bold;"&gt;i&lt;/span&gt;ate&lt;br /&gt;differenti&lt;span style="font-weight:bold;"&gt;a&lt;/span&gt;ted&lt;br /&gt;differentia&lt;span style="font-weight:bold;"&gt;t&lt;/span&gt;es&lt;br /&gt;differentiat&lt;span style="font-weight:bold;"&gt;i&lt;/span&gt;ng&lt;br /&gt;differentiati&lt;span style="font-weight:bold;"&gt;o&lt;/span&gt;n&lt;br /&gt;differentiatio&lt;span style="font-weight:bold;"&gt;n&lt;/span&gt;s&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;representatives&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;r&lt;/span&gt;epositions&lt;br /&gt;r&lt;span style="font-weight:bold;"&gt;e&lt;/span&gt;positories&lt;br /&gt;re&lt;span style="font-weight:bold;"&gt;p&lt;/span&gt;ository&lt;br /&gt;rep&lt;span style="font-weight:bold;"&gt;r&lt;/span&gt;ehensible&lt;br /&gt;repr&lt;span style="font-weight:bold;"&gt;e&lt;/span&gt;sent&lt;br /&gt;repre&lt;span style="font-weight:bold;"&gt;s&lt;/span&gt;entable&lt;br /&gt;repres&lt;span style="font-weight:bold;"&gt;e&lt;/span&gt;ntably&lt;br /&gt;represe&lt;span style="font-weight:bold;"&gt;n&lt;/span&gt;tation&lt;br /&gt;represen&lt;span style="font-weight:bold;"&gt;t&lt;/span&gt;ational&lt;br /&gt;represent&lt;span style="font-weight:bold;"&gt;a&lt;/span&gt;tionally&lt;br /&gt;representa&lt;span style="font-weight:bold;"&gt;t&lt;/span&gt;ions&lt;br /&gt;representat&lt;span style="font-weight:bold;"&gt;i&lt;/span&gt;ve&lt;br /&gt;representati&lt;span style="font-weight:bold;"&gt;v&lt;/span&gt;ely&lt;br /&gt;representativ&lt;span style="font-weight:bold;"&gt;e&lt;/span&gt;ness&lt;br /&gt;representative&lt;span style="font-weight:bold;"&gt;s&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-8786261730809545280?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/8786261730809545280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/03/vertical-words.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8786261730809545280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8786261730809545280'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/03/vertical-words.html' title='Vertical and diagonal words'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-2681510617877553843</id><published>2010-03-02T14:45:00.000-08:00</published><updated>2010-03-04T03:53:36.820-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ants'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><title type='text'>The supposedly herculean feats of ants</title><content type='html'>Most of us have heard that ants can carry weights hundred times of their own. Just recently, BBC News ran &lt;a href="http://news.bbc.co.uk/2/hi/uk_news/8526086.stm"&gt;a story related to this ability&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/S42Wx2i-f9I/AAAAAAAAAFg/Fr2bPp-dQ9Y/s1600-h/ants.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 396px; height: 300px; border: 1px solid #888;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/S42Wx2i-f9I/AAAAAAAAAFg/Fr2bPp-dQ9Y/s400/ants.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5444173307760771026" /&gt;&lt;/a&gt;&lt;div style="display: block; width: 400px; margin-left: auto; margin-right: auto;"&gt;&lt;br /&gt;&lt;span style="float: right; font-style: italic; font-size: 8pt;"&gt;Image Source: &lt;a href="http://commons.wikimedia.org/wiki/File:Ant_at_work_03.jpg"&gt;Wikimedia Commons&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In most people, this conjures up images of SUV-sized ants effortlessly lugging around buildings, reminiscent those in classic Sci-Fi film &lt;a href="http://en.wikipedia.org/wiki/Them!"&gt;THEM!&lt;/a&gt;; more still, of mimicking the ants and creating super-strong materials and actuators that are vastly stronger than anything we have access to today.&lt;br /&gt;&lt;br /&gt;This is however a pipe dream. This apparent strength is a consequence of being small, and not of some specific capability of ants. The villain is scaling laws -- the rules that describe how physical properties change with size.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is how it works:&lt;br /&gt;&lt;br /&gt;The mass of an object that has characteristic length L (that is, is roughly of size L in height, width and depth) is described by &lt;b&gt;m = &amp;rho;L&lt;sup&gt;3&lt;/sup&gt;&lt;/b&gt;, where &amp;rho; is the density of the object.&lt;br /&gt;&lt;br /&gt;The weight a muscle can lift is given by &lt;b&gt;M&lt;sub&gt;max&lt;/sub&gt; = cL&lt;sup&gt;2&lt;/sup&gt;&lt;/b&gt;, where c is some material constant that is independent of size. You can see why this is by realizing that this is very much like the strength of a string -- and making a string longer does not make it stronger, but making it thicker does.&lt;br /&gt;&lt;br /&gt;What we are interested in is the ratio of these quantities (i.e. maximum carry weight over mass): &lt;br /&gt;&lt;b&gt;M&lt;sub&gt;max&lt;/sub&gt; / m = c/(&amp;rho;L)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Ignoring c and &amp;rho; as they are independent of size, a pattern emerges. If we put in a very small value of L--a very small characteristic length--this ratio becomes very large. If we put in a large L, it becomes small. &lt;br /&gt;&lt;br /&gt;So, what does this mean? Well, the smaller the muscle, the more it can carry relative to it's own weight.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conclusion:&lt;br /&gt;&lt;br /&gt;An ant that is 1,000 times larger&lt;sup&gt;&amp;dagger;&lt;/sup&gt; than it is weighs a billion times more, but is only a million times stronger, so it's strength to mass ratio decreases by a factor 1000.&lt;br /&gt;&lt;br /&gt;A human that is 1,000 times smaller than it is weighs a billion times less, but is only a million times weaker, so her strength to mass ratio increases by a factor 1000.&lt;br /&gt;&lt;br /&gt;Returning to the SUV-sized ants, such ants would not be able to support their own weight, let alone carry buildings around, and an ant-sized human would be stronger than anything it's own size.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;&amp;dagger;&lt;/sup&gt; this value is a bit larger than SUV-size, but correct in an order of magnitude ballpark sort of way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-2681510617877553843?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/2681510617877553843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/03/supposedly-herculean-feats-of-ants.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2681510617877553843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2681510617877553843'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/03/supposedly-herculean-feats-of-ants.html' title='The supposedly herculean feats of ants'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/S42Wx2i-f9I/AAAAAAAAAFg/Fr2bPp-dQ9Y/s72-c/ants.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-8806041042574257438</id><published>2010-02-27T05:37:00.001-08:00</published><updated>2010-02-27T05:57:57.759-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Integration by weight</title><content type='html'>Some randomly firing neurons just gave me a flashback to a very unorthodox means of doing calculus: Integration by weight.&lt;br /&gt;&lt;br /&gt;Here is what happened: Some years ago I was taking a class in thermodynamics. As part of this class, there was a lab (I don't specifically remember what it was about, but there may have been a Stirling engine involved); and in the course of this lab, a contraption produced a two plots of some quantities relevant to the physics involved on a large sheet of paper. &lt;br /&gt;&lt;br /&gt;For whatever reason, it was necessary of us students to integrate this printed plot (effectively to find it's area). So, we spent some time rubbing our heads as to how to do this. We discussed several options, like dividing it into triangles and doing some sort of approximate estimate that way. But all of these methods seemed very time-consuming and tedious. So it dawned upon us: We could &lt;i&gt;weigh it&lt;/i&gt;. Said and done, we cut the blob outlined by the plot out of the paper, as well as some reference samples to get an average weight of the paper.&lt;br /&gt;&lt;br /&gt;Worked like a charm. Granted, we had access to an analytical balance with pretty high-precision, but still, there is something very appealing about the fact that this works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-8806041042574257438?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/8806041042574257438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/02/integration-by-weight.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8806041042574257438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8806041042574257438'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/02/integration-by-weight.html' title='Integration by weight'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3232311886704696627</id><published>2010-02-05T10:32:00.000-08:00</published><updated>2010-02-05T10:49:59.576-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='URL'/><category scheme='http://www.blogger.com/atom/ns#' term='youtube'/><title type='text'>Useful URL tips for google and youtube</title><content type='html'>A short list of simple but useful tips for youtube and google URLs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Link to a specific time in a youtube video&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Attach &lt;span style="font-family: fixed"&gt;#t=AmB&lt;/span&gt; where A is minutes and B is seconds to a youtube URL, to link to that specific time in the video.&lt;br /&gt;&lt;br /&gt;Example: &lt;a href="http://www.youtube.com/watch?v=wRnSnfiUI54#t=0m16"&gt;http://www.youtube.com/watch?v=wRnSnfiUI54#t=0m16&lt;/a&gt; &lt;br /&gt;links to the specific moment where Kirk shouts KHAAAAAANNN!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Google in English&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Occasionally, google gets it in it's mind that you want the interface translated to some language other than English, because you are in a country that speaks that language, or because of (broken?) geo-profiling. To clear this, visit&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/ncr" onClick="return confirm('Do you -really- want google in English?');"&gt;http://www.google.com/ncr&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Google query on the fly&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you need to do a quick google query, and want to limit the bandwidth used by only loading the results, or the pages loaded because you're in an awkward text-based browser, learn this URL scheme:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/search?q=a+google+query"&gt;http://www.google.com/search?q=&lt;span style="font-style:italic;"&gt;a+google+query&lt;/span&gt;&lt;/a&gt;, where a+google+query can be replaced with whatever you're searching for.&lt;br /&gt;&lt;br /&gt;That is all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3232311886704696627?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3232311886704696627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/02/useful-url-tips-for-google-and-youtube.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3232311886704696627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3232311886704696627'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/02/useful-url-tips-for-google-and-youtube.html' title='Useful URL tips for google and youtube'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-2535021379793355311</id><published>2010-02-04T08:32:00.000-08:00</published><updated>2010-02-04T09:12:23.867-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='absent-mindedness'/><title type='text'>I digress: The elusive experience of being lost in a familiar place</title><content type='html'>Deviating a bit from the set topic of this blog, I thought I'd share a quest of mine in life: Loosing myself in familiar places.&lt;br /&gt;&lt;br /&gt;When I was very young, probably around 8-10 years of age, I had a most peculiar experience as I woke up one morning. I was convinced I was lying in one direction in bed (not that I remember specifically which orientation, but for the sake of the story, let's say I imagined myself facing the wall next to my bed), only to open my eyes and find out I was facing away from the wall. For the briefest of moments, I experienced a peculiar but pleasant feeling of confusion. &lt;br /&gt;&lt;br /&gt;It is hard to put this experience in words, but if you have ever had a false awakening (that is, dreaming you woke up and started doing your morning routine, only to wake up for real moments later and finding you're still in bed), the experience is somewhat similar.&lt;br /&gt;&lt;br /&gt;Ever since this morning in my childhood, on some level, I have been chasing this experience. It is quite elusive, as it is very hard to make yourself forget how you got somewhere, since trying typically has you paying more attention to where you are. I have indeed experienced it more times, usually while lost in deep thought about some matter, only to realized I've been wandering around randomly.&lt;br /&gt;&lt;br /&gt;These events are rare, probably occurring order of magnitude once a year. But today, was one of those days. While pondering a problem from a textbook on plasma physics I was reading, I went to the lavatory, only to realize I had no idea which floor I was on. &lt;br /&gt;&lt;br /&gt;They seem like such tiny and insignificant events, but given their rare and transient nature, I feel it's necessary to cherish and take the opportunity to explore them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-2535021379793355311?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/2535021379793355311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/02/i-digress-elusive-experience-of-being.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2535021379793355311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2535021379793355311'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2010/02/i-digress-elusive-experience-of-being.html' title='I digress: The elusive experience of being lost in a familiar place'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4958296574494756440</id><published>2009-12-03T04:42:00.001-08:00</published><updated>2009-12-03T05:24:12.458-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CAPTCHA'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>How some CAPTCHAs are being broken (and how to fix it)</title><content type='html'>I've noticed that &lt;a href="http://en.wikipedia.org/wiki/CAPTCHA"&gt;CAPTCHA&lt;/a&gt;s are becoming increasingly futile in combating automated sign-ups, as well as becoming increasingly prevalent in places where it doesn't make sense to put them. So a while back, I connected the dots into a theory on how CAPTCHAs are being circumvented in bulk quantities (after some further research, it turns out that this method is actually in use). &lt;br /&gt;&lt;br /&gt;It's essentially a form of covert crowdsourcing: If you have a high-traffic site that requires a sign-up, you could in theory simultaneously create an account on some other CAPTCHA-enabled site by forwarding the CAPTCHA to the user signing up on your site, and as your user solves it, forward the result to your own sign-up session on the target site.&lt;br /&gt;&lt;br /&gt;There's a lot going on in this, so I'll divide it into two parallel time lines (blue italic is malicious site, red is target site):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="color: #008; font-style: italic"&gt;User loads registration sign-up page&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="color: #800"&gt;Sign-up session on target site is started, malicious site downloading CAPTCHA image&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="color: #008; font-style: italic"&gt;Malicious site presents target site's CAPTCHA as it's own&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="color: #008; font-style: italic"&gt;User fills out details and solves CAPTCHA&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="color: #800"&gt;User's CAPTCHA-result is used to register on target site&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Now this is a known method, but there is an obvious way of deterring this sort of thing that for some reason doesn't seem to be widespread: To embed something that indicates the origin of the CAPTCHA onto the image. If the users see an URL and a logo belonging to a different web site than they are signing up on, they would naturally grow suspicious, and as this method mostly lends itself to targeting specific websites (and these would be bigger targets), the target will likely be big enough to be recognizable to the average person, which makes all the more suspicious.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4958296574494756440?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4958296574494756440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/12/how-some-captchas-are-being-broken-and.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4958296574494756440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4958296574494756440'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/12/how-some-captchas-are-being-broken-and.html' title='How some CAPTCHAs are being broken (and how to fix it)'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-6049262336743573942</id><published>2009-11-16T15:40:00.000-08:00</published><updated>2009-11-16T16:02:10.949-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='shellscript'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='diversion'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>C &amp; Bash frankensources</title><content type='html'>Heh, I stumbled upon an amusing overlap in C preprocessor syntax and shellscript comments. You can piggyback a C program onto a shell script, so that it's both possible to compile the file with a C compiler, and let bash evaluate it. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;#if 0&lt;br /&gt;echo "Hello from bash!"&lt;br /&gt;exit&lt;br /&gt;#endif&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;int main(int argc, char* argv[]) {&lt;br /&gt;  puts("Hello from C!");&lt;br /&gt;  return EXIT_SUCCESS;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that it's not possible to put a shebang in the beginning of the script (or other shell script comments) and compile it, as that upsets the preprocessor.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sh frankenscript.sh.c&lt;br /&gt;Hello from bash!&lt;br /&gt;$ gcc frankenscript.sh.c -o test&lt;br /&gt;$ ./test&lt;br /&gt;Hello from C!&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You could also have the script, when run as bash code, compile it self as C sources and run the result. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;#if 0&lt;br /&gt;file=`mktemp`&lt;br /&gt;gcc -o $file $0&lt;br /&gt;$file&lt;br /&gt;rm $file&lt;br /&gt;exit&lt;br /&gt;#endif&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[]) {&lt;br /&gt;  puts("Hello from C!");&lt;br /&gt;  return EXIT_SUCCESS;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sh frankenscript2.sh.c&lt;br /&gt;Hello from C!&lt;br /&gt;$&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Don't get me wrong, it's a perverse crime against nature and should never be used, but still, an amusing diversion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-6049262336743573942?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/6049262336743573942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/11/c-bash-frankensources.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6049262336743573942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/6049262336743573942'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/11/c-bash-frankensources.html' title='C &amp; Bash frankensources'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4460579444678633301</id><published>2009-10-27T06:54:00.000-07:00</published><updated>2009-10-27T07:12:07.927-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ternary computing'/><category scheme='http://www.blogger.com/atom/ns#' term='3initi'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Small ternary (base 3) computer on a binary microcontroller</title><content type='html'>This isn't my work, but I've done some degree of work in the field of ternary computing through the ternary computer emulator &lt;a href="http://www.acc.umu.se/~achtt315/tunguska/"&gt;Tunguska&lt;/a&gt; I whipped up a few years ago (I'm slowly working on a major re-write, but other things keep stealing my time). Which is kinda cool. I do believe I'm the only person in existence who has written something even remotely close to a C compiler for a base 3 computer.&lt;br /&gt;&lt;br /&gt;Anyway, enough of my esoteric feats, this is pretty neat: "&lt;a href="http://ternary.info/modules/newbb/viewtopic.php?topic_id=157&amp;forum=5&amp;post_id=1561#forumpost1561"&gt;Ternary Computer is now emulated in binary microcontroller&lt;/a&gt;"&lt;br /&gt;&lt;br /&gt;There's more information on the 3niti project here: &lt;a href="http://www.3niti.org/"&gt;http://www.3niti.org/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4460579444678633301?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4460579444678633301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/10/small-ternary-base-3-computer-on-binary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4460579444678633301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4460579444678633301'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/10/small-ternary-base-3-computer-on-binary.html' title='Small ternary (base 3) computer on a binary microcontroller'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7790382098769150535</id><published>2009-10-22T10:22:00.000-07:00</published><updated>2009-10-22T10:29:39.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CAPS LOCK DAY'/><title type='text'>HAPPY CAPS LOCK DAY EVERYONE</title><content type='html'>HAPPY &lt;A HREF="http://capslockday.com/"&gt;CAPS LOCK DAY&lt;/A&gt; EVERYONE!&lt;br /&gt;&lt;br /&gt;OCTOBER 22 IS INTERNATIONAL CAPS LOCK DAY, AND THIS BLOG FOR ONE EMBRACES THIS IMPORTANT INTERNATIONAL HOLIDAY. &lt;br /&gt;&lt;br /&gt;BECAUSE, WHEN WAS THE LAST TIME YOU TYPED IN ALL UPPER CASE LETTERS? AREN'T YOU FEELING A LITTLE BIT GUILTY ABOUT NOT USING THE CAPS LOCK KEY AS MUCH AS YOU COULD? JOIN THE FESTIVITIES! JUST HIT CAPS AND TYPE AWAY.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7790382098769150535?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7790382098769150535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/10/happy-caps-lock-day-everyone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7790382098769150535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7790382098769150535'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/10/happy-caps-lock-day-everyone.html' title='HAPPY CAPS LOCK DAY EVERYONE'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4876187012235083600</id><published>2009-10-06T08:46:00.000-07:00</published><updated>2009-10-06T09:13:19.948-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MIDI'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>MIDI programming in Linux</title><content type='html'>For no particular reason other than curiosity, I decided to venture into MIDI programming. In Linux. There are two problems with this idea:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;MIDI programming...: While &lt;a href="http://home.roadrunner.com/~jgglatt/tech/midispec.htm"&gt;actual MIDI programming&lt;/a&gt; isn't &lt;span style="font-style:italic;"&gt;that&lt;/span&gt; difficult, you are definitely not in Kansas any more. These music guys are a separate subspecies to the garden variety geek.&lt;/li&gt;&lt;li&gt;... In Linux: Doing this is painful. It's sort of like going to the dentist, finding out that nobody is there, and that you have to fix your teeth on your own, and while there are plenty of instructions on how to operate the equipment, they all say different things, and most of them were written on USENET or some obscure mailing list well over a decade ago, discussing deprecated versions of the dentistry instruments you have in front of you.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Anyway, after 3 or 4 kernel recompiles; installation of a virtual synthesizer (&lt;a href="http://fluidsynth.resonance.org/trac"&gt;fluidsynth&lt;/a&gt;) that didn't compile properly out of the box, so I had make countless small alterations to it&lt;sup&gt;[1]&lt;/sup&gt;; and a ton of sheer luck, I managed to get my program to send MIDI instructions to fluidsynth, that actually reacted to them and made noise.&lt;br /&gt;&lt;br /&gt;I wrote a small program that uses my low-end Wacom tablet to create a theremin-like instrument by mapping pitch bend to one axis and volume to the other, but it really didn't turn out too impressive. The tablet doesn't have enough resolution to allow playing more than just a few octaves with any sort of precision.&lt;br /&gt;&lt;br /&gt;It's technically doable, but the end result is somewhat of an anticlimax. It was a fun afternoon's work, but when push comes to shove, a pretty fruitless venture.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;[1]&lt;/sup&gt; I think my GCC version or libc version is buggy or something. It's ridiculously  pedantic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4876187012235083600?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4876187012235083600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/10/midi-programming-in-linux.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4876187012235083600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4876187012235083600'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/10/midi-programming-in-linux.html' title='MIDI programming in Linux'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4065437269740836232</id><published>2009-08-30T05:55:00.001-07:00</published><updated>2009-08-30T09:57:11.166-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spam mail'/><category scheme='http://www.blogger.com/atom/ns#' term='failure'/><title type='text'>It isn't easy to spam</title><content type='html'>I got the following broken piece of spam mail on gmail today. It's obviously from some broken spam script. But I found it pretty amusing. It's certainly the most abstract unsolicited email I've gotten, which deserves some kudos I guess.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lhmAHZ1VwRE/Spp3UULZKuI/AAAAAAAAAEE/akLPPPUw-yw/s1600-h/spamfail.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_lhmAHZ1VwRE/Spp3UULZKuI/AAAAAAAAAEE/akLPPPUw-yw/s400/spamfail.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5375740296117693154" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4065437269740836232?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4065437269740836232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/08/it-isnt-easy-to-spam.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4065437269740836232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4065437269740836232'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/08/it-isnt-easy-to-spam.html' title='It isn&apos;t easy to spam'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_lhmAHZ1VwRE/Spp3UULZKuI/AAAAAAAAAEE/akLPPPUw-yw/s72-c/spamfail.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1589029086527443991</id><published>2009-08-01T07:02:00.001-07:00</published><updated>2009-08-01T07:18:48.674-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional language'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>More details about my functional language</title><content type='html'>I figured I'd elaborate on the as of yet nameless functional language &lt;a href="http://awesomegeekblog.blogspot.com/2009/07/small-project-im-working-on.html"&gt;I posted about earlier today&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's defining feature is that it really ships as a blank slate. Virtually everything you find in a functional language like Lisp or Haskell is so trivial to implement, it doesn't make any sense to hardwire it into the language specifications. &lt;br /&gt;&lt;br /&gt;This is because it isn't so much as a language as it is a programmable language parser combined with some very crude elements, lists and atoms, that combined allows you to formulate a functional language.&lt;br /&gt;&lt;br /&gt;The latest addition to the language specifications (it's still being evaluated to see just how well it works out) is pattern meta-matching. That is, a pattern that compares stack nodes with other patterns (or even itself). This turned out to make the language even more versatile. It's trivially easy to implement a type system with this latest feature. &lt;br /&gt;&lt;br /&gt;It works like this: First you define a tautological pattern that consists of a tag, and the the internals of your type.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;define ( =car-tag seats color ) Car  ( car-tag seats color );&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That's it. You have now defined a type called Car, that has two fields: seats and color. You can now create functions that take a car as an argument.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;define ( c:Car ) car-get-seats ( c.seats );&lt;/code&gt;&lt;br /&gt;&lt;code&gt;define ( c:Car ) car-get-color ( c.color );&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can of course also modify objects in this fashion:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;define ( c:Car new-color ) car-repaint ( car-tag c.seats new-color );&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It's important to repeat, that this language does NOT have a type system. It has a variety of pattern matching that you can use to implement types. Or to translate infix mathematics to polish notation. Or countless other applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1589029086527443991?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1589029086527443991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/08/more-details-about-my-functional.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1589029086527443991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1589029086527443991'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/08/more-details-about-my-functional.html' title='More details about my functional language'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-5332190761637765824</id><published>2009-07-31T13:56:00.000-07:00</published><updated>2009-07-31T16:18:15.826-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional language'/><category scheme='http://www.blogger.com/atom/ns#' term='lambda calculus'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>A small project I'm working on</title><content type='html'>I'm currently working on a small project that's turned out pretty well. A functional language: It's basically lisp with pattern-matching grafted onto it. This has turned out to make the language very powerful. Nearly nothing needs to come built-in, except the definition, matching and expansion of patterns.&lt;br /&gt;&lt;br /&gt;To explain the code examples in this post, I'll first outline the rough grammar of the &lt;span style="font-style:italic;"&gt;definition&lt;/span&gt; statement. &lt;br /&gt;&lt;br /&gt;The overall grammar is the following:&lt;br /&gt;&lt;code&gt;define ( pattern ) name expansion.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In the pattern, atoms may be prefixed with&lt;br /&gt;&lt;dl&gt;&lt;dt&gt;~&lt;/dt&gt;&lt;dd&gt; Not to be evaluated until it is absolutely unavoidable (otherwise, they are evaluated on an as-needed basis) &lt;/dd&gt;&lt;dt&gt;@&lt;/dt&gt;&lt;dd&gt; Only allowed in the last atom, meaning that it is to correspond with what is left on the stack &lt;/dd&gt;&lt;dt&gt;=&lt;/dt&gt;&lt;dd&gt; Matching against the following token, and only the following token &lt;/dd&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;In the expansion, the only prefix that exists is @, which appends the token onto the stack, instead of adding a list cell pointing to the value on the stack.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Some examples of the language.&lt;br /&gt;Basic lisp-style arithmetics&lt;br /&gt;&lt;pre&gt;&lt;code&gt;( + 23 14 ( * 7 2 ) ) &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Conditional evaluation:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;define ( =true @statement ) if   @statement.&lt;br /&gt;define ( other @statement ) if .&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Factorial function:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;define ( 0 ) fac 1 .&lt;br /&gt;define ( n ) fac ( * n ( fac ( + n -1 ) ) ).&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Map function:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;define ( ( @op ) ( top @rest ) ) map&lt;br /&gt;      ( @op top ) map op rest.&lt;br /&gt;define ( ( @op ) ( last ) ) map&lt;br /&gt;      ( @op last )&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Mapping factorial function to some numbers:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;print ( map ( fac ) ( 1 2 3 4 5 6 7 8 9 10 ) ).&lt;br /&gt;&lt;i&gt;( 1 2 6 24 120 720 5040 40320 362880 3628800  )&lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Mapping a lambda function corresponding to squaring to same numbers:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;print ( map ( ,\ ( x ) ( * x x ) )  ( 1 2 3 4 5 6 7 8 9 10 ) ) .&lt;br /&gt;&lt;i&gt;( 1 4 9 16 25 36 49 64 81 100  ) &lt;/i&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A more complicated example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;define ( ( a @as ) ( b @bs ) ) zip &lt;br /&gt;        ( a b ) zip as bs .&lt;br /&gt;define ( ( a ) ( b ) ) zip&lt;br /&gt;        ( a b ) .&lt;br /&gt;define ten ( 1 2 3 4 5 6 7 8 9 10 )&lt;br /&gt;print ( zip ( map ( fac ) ten ) ten ) .&lt;br /&gt;&lt;span style="font-style:italic;"&gt; (  ( 1 1  )  ( 2 2  )  ( 6 3  )  ( 24 4  )  ( 120 5  )  ( 720 6  )  ( 5040 7  )&lt;br /&gt;  ( 40320 8  )  ( 362880 9  )  ( 3628800 10  )  )&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I'll post more details later. Mostly because the details are in such heavy flux right now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-5332190761637765824?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/5332190761637765824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/small-project-im-working-on.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5332190761637765824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5332190761637765824'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/small-project-im-working-on.html' title='A small project I&apos;m working on'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-8725493047449823483</id><published>2009-07-26T11:36:00.001-07:00</published><updated>2009-07-28T04:54:40.180-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goop'/><category scheme='http://www.blogger.com/atom/ns#' term='unidentified falling object'/><title type='text'>The Blob</title><content type='html'>Yesterday, something most peculiar happened. I was outside of my apartment, when a black object fell from the sky. I'd estimate it's radius to be around 5 cm and it's height to be 2 cm. It was jet black, hard, and I nudged it with my shoe, and found it had the same approximate density as a rock.&lt;br /&gt;&lt;br /&gt;Throughout the day I observed this object. As time progressed, it became increasingly reflective, and a pool of viscous black liquid formed around it. Today all that was left was a pool of this viscous goop. &lt;br /&gt;&lt;br /&gt;I snapped &lt;a href="http://www.acc.umu.se/~achtt315/The%20Blob/"&gt;some pictures&lt;/a&gt; of the sludge, and something that first seemed related, but at a closer look at the pictures doesn't appear to have anything to do with it. It looks more blue in the pictures than it is in reality, since it is highly reflective, and the sky was blue at the time I took the pictures. For size comparison, the light gray rock in the pavement to the upper left of the puddle is about the same size as a larger coin.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SmykpGKx_tI/AAAAAAAAADs/HQUCpk_3pBY/s1600-h/spacealiengoop.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SmykpGKx_tI/AAAAAAAAADs/HQUCpk_3pBY/s320/spacealiengoop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5362842282228842194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I took a sample with some Q-tips and put it in an air-tight glass jar to preserve this substance since science demanded it of me. It was very viscous, and appeared semi-transparent gray against the head of the Q-tips.&lt;br /&gt;&lt;br /&gt;I have no idea what it is. Did it come off an airplane&lt;sup&gt;[1]&lt;/sup&gt;? From space? Is it organic?  Though I suppose it's not &lt;a href="http://news.bbc.co.uk/2/hi/uk_news/magazine/3582802.stm"&gt;the strangest thing to ever happen&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt; This is actually pretty unlikely. I live close to an airport, but perpendicular to it's runway, so I literally never get any aircraft flying overhead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-8725493047449823483?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/8725493047449823483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/blob.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8725493047449823483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8725493047449823483'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/blob.html' title='The Blob'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lhmAHZ1VwRE/SmykpGKx_tI/AAAAAAAAADs/HQUCpk_3pBY/s72-c/spacealiengoop.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4952797023830093759</id><published>2009-07-04T13:49:00.001-07:00</published><updated>2009-07-04T13:53:59.134-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='serendipity'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Serendipitous bug</title><content type='html'>I was fooling around with a procedurally generated model of a tree, and went on to add some physics so as to made it bend under it's own weight. Somewhere along the line, I used the wrong angle in the simulation of the &lt;a href="http://en.wikipedia.org/wiki/Torsion_spring"&gt;torsion springs&lt;/a&gt; I used to model the branches with, and I ended up with a pretty disturbing, but highly &lt;a href="http://en.wikipedia.org/wiki/Pareidolia"&gt;pareidolic&lt;/a&gt; result that's slap bang in the middle of nightmarish and amusing to watch.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ZP9My19glBw&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ZP9My19glBw&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4952797023830093759?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4952797023830093759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/serendipitous-bug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4952797023830093759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4952797023830093759'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/serendipitous-bug.html' title='Serendipitous bug'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-342069252950774118</id><published>2009-07-02T08:06:00.000-07:00</published><updated>2009-07-02T13:11:04.862-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RNG'/><category scheme='http://www.blogger.com/atom/ns#' term='physical simulation'/><category scheme='http://www.blogger.com/atom/ns#' term='chaos'/><category scheme='http://www.blogger.com/atom/ns#' term='random number generator'/><title type='text'>Double spring pendulum pRNG</title><content type='html'>You can make a pretty decent random number generator through physical simulation of a double spring pendulum. Double pendulums are chaotic systems, and as such, express a high variation of state after a given time, based on small variations on the initial dataset (the so called &lt;a href="http://en.wikipedia.org/wiki/Butterfly_effect"&gt;butterfly effect&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;The motion used to generate the random numbers looks like this:&lt;br /&gt;&lt;object width="320" height="265"&gt;&lt;param name="movie" value="http://www.youtube.com/v/nlA2Q097klg&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/nlA2Q097klg&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="320" height="265"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;What makes this a decent random number generator is the lack of a &lt;a href="http://en.wikipedia.org/wiki/Closed-form_expression"&gt;closed form solution&lt;/a&gt; to the motion of the pendulum, combined with five hidden degrees of freedom.&lt;br /&gt;&lt;br /&gt;The algorithm loosely looks like this:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; Simulate for N timesteps (I the Euler method for integration, but it's probably a lot smarter to use a less sensitive algorithm -- or not, the errors introduced by the algorithm might make the data more random.) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Let &amp;theta;  be the inner pendulum's angle (scaled to the range 0 ... 1) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Let &amp;phi; be the outer pendulum's angle relative to the inner angle (scaled to the range 0 ... 1) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Let the data be ((&amp;theta; * 10000&lt;sub&gt;16&lt;/sub&gt;) &amp;and; ff&lt;sub&gt;16&lt;/sub&gt;) &amp;oplus; ((&amp;phi; * 10000&lt;sub&gt;16&lt;/sub&gt;) &amp;and; ff&lt;sub&gt;16&lt;/sub&gt;) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Let N be some constant (the higher the more random the data) + data * (some other constant) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Yield 'data' &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Repeat.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Using '&lt;a href="http://www.fourmilab.ch/random/"&gt;ent&lt;/a&gt;' to analyze the data, these are typical values:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Entropy = 7.997207 bits per byte.&lt;br /&gt;&lt;br /&gt;Optimum compression would reduce the size&lt;br /&gt;of this 70346 byte file by 0 percent.&lt;br /&gt;&lt;br /&gt;Chi square distribution for 70346 samples is 271.07, and randomly&lt;br /&gt;would exceed this value 23.38 percent of the times.&lt;br /&gt;&lt;br /&gt;Arithmetic mean value of data bytes is 127.4919 (127.5 = random).&lt;br /&gt;Monte Carlo value for Pi is 3.135107472 (error 0.21 percent).&lt;br /&gt;Serial correlation coefficient is 0.000481 (totally uncorrelated = 0.0).&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;versus /dev/urandom on Linux:&lt;br /&gt;&lt;code&gt;Entropy = 7.997121 bits per byte.&lt;br /&gt;&lt;br /&gt;Optimum compression would reduce the size&lt;br /&gt;of this 70346 byte file by 0 percent.&lt;br /&gt;&lt;br /&gt;Chi square distribution for 70346 samples is 281.53, and randomly&lt;br /&gt;would exceed this value 12.19 percent of the times.&lt;br /&gt;&lt;br /&gt;Arithmetic mean value of data bytes is 127.3213 (127.5 = random).&lt;br /&gt;Monte Carlo value for Pi is 3.148072330 (error 0.21 percent).&lt;br /&gt;Serial correlation coefficient is -0.001095 (totally uncorrelated = 0.0).&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The randomness is on par or slightly better than Linux' (pretty dubious) urandom-pRNG, depending on configuration. :-)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This whole project got started as a means of visually telling large numbers like checksums apart through setting the initial parameters of a spring coupled double pendulum according to the number, and then tracing it's motion for a couple of thousand iterations. That did do the trick satisfactory, but still needs more work before it's useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-342069252950774118?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/342069252950774118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/double-spring-pendulum-prng.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/342069252950774118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/342069252950774118'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/double-spring-pendulum-prng.html' title='Double spring pendulum pRNG'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4488930464548454831</id><published>2009-07-01T08:40:00.000-07:00</published><updated>2010-04-10T10:30:48.497-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='X11'/><category scheme='http://www.blogger.com/atom/ns#' term='xterm'/><title type='text'>The (not-so) secret of .Xdefaults (or rather, .Xresources)</title><content type='html'>&lt;span style="font-style:italic;"&gt;Several people commented that .Xdefaults&amp;mdash;the original subject of the post&amp;mdash;is an obsolete file, and that .Xresources should be used instead. I stand corrected, and so does the blog post. &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There's a startling amount of people who have missed out on a pretty integral part of X11, namely the X resources database.&lt;br /&gt;&lt;br /&gt;What the xrdb does is allow you to set various settings that you would otherwise have to pass with command line arguments to the programs. Clearly, it's pretty cumbersome to start xterm with the command &lt;i&gt;xterm -fg gray -bg black&lt;/i&gt; just to escape the horrors of the black on white default color settings on xterm. Reverse video makes the defaults marginally less painful, but the contrast is still not particularly endearing.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lhmAHZ1VwRE/SkuKgEp0e_I/AAAAAAAAADk/TmipUl7u4dI/s1600-h/settings.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 290px;" src="http://2.bp.blogspot.com/_lhmAHZ1VwRE/SkuKgEp0e_I/AAAAAAAAADk/TmipUl7u4dI/s320/settings.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5353524865669561330" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center"&gt;&lt;span style="font-weight:bold;"&gt;Figure 1&lt;/span&gt;: A change of defaults makes a world of difference. &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;There's a wonderful file named &lt;span style="font-style: italic;"&gt;~/.Xresources&lt;/span&gt; that allows you to get around this. It is loaded automatically when the X session starts, and can be forced to reload with &lt;span style="font-style: italic;"&gt;xrdb -merge ~/.Xresources&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My .Xresources file looks like this:&lt;br /&gt;&lt;code&gt;XTerm*background: black&lt;br /&gt;XTerm*foreground: gray&lt;br /&gt;XTerm*title: terminal&lt;br /&gt;XTerm*saveLines: 1024&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you read the man page for xterm, you'll find a rather intimidating list of settings you can alter with .Xresources.&lt;br /&gt;&lt;br /&gt;Further reading: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;tt&gt;man xterm&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;tt&gt;man xrdb&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://xwinman.org/resource.php"&gt;xwinman.org's documentation of the .Xresources file&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://engineering.purdue.edu/ECN/Support/KB/Docs/UsingTheXdefaultsFil"&gt;Using the .Xdefaults file&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4488930464548454831?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4488930464548454831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/secrets-of-xdefaults.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4488930464548454831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4488930464548454831'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/07/secrets-of-xdefaults.html' title='The (not-so) secret of .Xdefaults (or rather, .Xresources)'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lhmAHZ1VwRE/SkuKgEp0e_I/AAAAAAAAADk/TmipUl7u4dI/s72-c/settings.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1355172250527209320</id><published>2009-06-21T05:12:00.000-07:00</published><updated>2009-06-21T05:53:24.290-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='redundancy'/><category scheme='http://www.blogger.com/atom/ns#' term='suggestion'/><category scheme='http://www.blogger.com/atom/ns#' term='information'/><category scheme='http://www.blogger.com/atom/ns#' term='storage'/><title type='text'>Re-doon-danciy? What is this strange and alien concept you speak of puny earthling?!</title><content type='html'>Would it be so hard to add data redundancy to media files? My computer has just south of 1 terabyte of hard drive space. Most people have at least a couple of hundred gigabytes. Storage is so cheap, and transfer speeds so fast, that making all media files 10% bigger is a pretty painless cost for self-reconstructing media files.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sj4tIVls1yI/AAAAAAAAADU/BpUgKimCr5Q/s1600-h/whaat.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 308px; height: 320px;" src="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sj4tIVls1yI/AAAAAAAAADU/BpUgKimCr5Q/s320/whaat.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5349763028620203810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center"&gt;&lt;span style="font-weight:bold;"&gt;Figure 1&lt;/span&gt;: Image corruption may well be the end of us all!&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Take an image. Split it up in a bunch of quadratic sub-images. Let each of them store low resolution copies of it's &lt;a href="http://en.wikipedia.org/wiki/Von_Neumann_neighborhood"&gt;Von Neuman neighborhood&lt;/a&gt;'s contents. Give the blocks checksums, and compress them individually. If a block fails to pass the checksum, you can now reconstruct it using interpolation from it's neighbor's low-res copies. It wouldn't be picture perfect, but you'd be able to deduce the contents of the image even at pretty bad corruption (information recovery at 75% data loss at a best case scenario).&lt;br /&gt;&lt;br /&gt;Do the same with video, while you're at it. Seriously, give me a video codec that does this, and you will make the world a better place.&lt;br /&gt;&lt;br /&gt;Better yet, add redundancy to text. Add a plaintext &lt;a href="http://en.wikipedia.org/wiki/Huffman_code"&gt;Huffman coded&lt;/a&gt; copy of the textual contents of a document to it's metadata.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1355172250527209320?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1355172250527209320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/re-doon-danciy-what-is-this-strange-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1355172250527209320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1355172250527209320'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/re-doon-danciy-what-is-this-strange-and.html' title='Re-doon-danciy? What is this strange and alien concept you speak of puny earthling?!'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sj4tIVls1yI/AAAAAAAAADU/BpUgKimCr5Q/s72-c/whaat.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-5686192764013140851</id><published>2009-06-17T14:58:00.000-07:00</published><updated>2009-06-17T16:49:51.611-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hair-pulling'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>The virtue of documenting obscure behavior</title><content type='html'>In the hope that people in the same situation as me can find this through google: &lt;span style="font-weight:bold;"&gt;Some shells run &lt;tt&gt;signal(SIGINT, SIG_IGN)&lt;/tt&gt; before they execute your program if you run it in the background. This interferes with &lt;tt&gt;sigwait&lt;/tt&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think the reason for this is dubious implementation of background processes. Instead of checking which processes are background process and foreground processes, and only sending SIGINT to the foreground processes, the background processes are told to ignore SIGINT, and the signal is sent to all processes when ^C is received.&lt;br /&gt;&lt;br /&gt;You can clear this by putting &lt;tt&gt;signal(SIGINT, SIG_DFL)&lt;/tt&gt; in the beginning of your program, if you want it to behave like a regular foreground process, despite being run in the background.&lt;br /&gt;&lt;br /&gt;This is a quite poorly documented fact, that took major hair-pulling to deduce. There are two lessons to be learned:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Don't make assumptions about the standard behavior of anything.&lt;/li&gt;&lt;li&gt;Document obscure behavior.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Thus endeth the frustrated rant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-5686192764013140851?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/5686192764013140851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/virtue-of-documenting-obscure-behavior.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5686192764013140851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5686192764013140851'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/virtue-of-documenting-obscure-behavior.html' title='The virtue of documenting obscure behavior'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-5682699115592409393</id><published>2009-06-15T12:03:00.000-07:00</published><updated>2009-07-02T18:12:25.813-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>How to become a programmer</title><content type='html'>A lot of people aspire to learn programming, and it's not an easy task (there are countless pitfalls that aspiring programmers typically parade into like lemmings), so I figured it would be useful to outline a path acquire that goal.&lt;br /&gt;&lt;br /&gt;1. Learn an imperative scripting language. Become confident in a simple language in which it is easy to write  functional stuff fast. Not only does this serve as an introduction to imperative programming, it will also be useful down the line when you want to get stuff done quickly without all the red carpet other languages typically come with. &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt; is probably the best language to start off with, but there are other options as well (ruby, perl, lua, etc.), and they're all good choices for a first language. My motivation for suggesting python is the great community surrounding it, and the libraries it ships with that makes rewarding projects such as simple game programming relatively easy and quick.&lt;br /&gt;&lt;br /&gt;(The order in which you take the following two doesn't really matter, do both simultaneously if you want.)&lt;br /&gt;&lt;br /&gt;2a. Learn a functional language. Once you've gotten imperative programming down, it's time to learn something that will blow your mind, and fundamentally change the way you think about programming. Lisp or Haskell are good choices. Pick your poison. &lt;br /&gt;&lt;br /&gt;2b. Learn a low level language. Low level programming will teach you what actually goes on &lt;span style="font-style:italic;"&gt;under the hood&lt;/span&gt;. C is probably a good place to start. You may want to try assembly as well: It's a pretty easy language, but only really worth pursuing if you enjoy it.&lt;br /&gt;&lt;br /&gt;3. Learn an object-oriented language. Now that you know a fair deal about programming, it's time how to write a lot of code while still keeping it manageable. That's where OOP comes into the picture. You'll probably want to learn some of the following: C++, C# or Java (the two are more or less identical).&lt;br /&gt;&lt;br /&gt;Now that we've dealt with what to learn, it's time to discuss how to learn it. It is my opinion that tutorials are dangerous as hell to new programmers. There is no way to verify who wrote the tutorial (it may be some confused 14 year old, no offense to the 14 year old programmers out here), they come in no particular order and are generally inconsistent. The proper way to learn any language is to:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Buy a book. Check the reviews as well. You can also ask around the programming community as to what book is best on the subject. You may get away with official online documentation in some languages (e.g. python), but as a general rule, you want a book. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Practice. Write programs. Make them small, make them large, make them silly, make them serious. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Taking classes in programming may or may not be useful to you. It can be helpful, but what really makes a difference is how much you practice.&lt;br /&gt;&lt;br /&gt;Something is also to be said about the company you keep. You can soak up a lot of programming skills by hanging out at places like the coding forum at &lt;a href="http://www.forums.xkcd.com"&gt;www.forums.xkcd.com&lt;/a&gt;, and that goes for people at any skill level.&lt;br /&gt;&lt;br /&gt;Finally, there are some horrible traps you can walk into. &lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; Don't start in web design. First you need to learn HTML (which has nothing to do with programming at all), and then some abomination like PHP (which teaches terrible coding practices.) A background in web design is salvageable, but it is a damn tar pit.&lt;br /&gt;&lt;li&gt; Don't start in C++ or Visual Basic. Starting in C++ is like putting a 5 year old in the pilot's seat of an airliner: It isn't going to understand 1% of the features, and will probably crash and burn (badum-ching); and Visual Basic is a crime against the mind.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;This of course represents my opinion. There's as many answers as to how to become a programmer as there are programmers.&lt;br /&gt;&lt;br /&gt;TL;DR: &lt;a href="http://www.python.org/"&gt;Learn python first&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-5682699115592409393?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/5682699115592409393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/how-to-become-programmer.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5682699115592409393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/5682699115592409393'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/how-to-become-programmer.html' title='How to become a programmer'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1126060649884056020</id><published>2009-06-15T04:15:00.001-07:00</published><updated>2009-06-15T04:25:47.946-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='note-to-self'/><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><title type='text'>"Fast" division</title><content type='html'>This is mostly a note-to-self on how to divide a number in base b with some integer n using nothing but "fast" operations like addition, subtraction and shifting (occasionally multiplication) -- if you bake them together, you typically end up with something of linear complexity or slightly better:&lt;br /&gt;&lt;br /&gt;To divide a number in base b with some integer n, find the recursive relationship&lt;br /&gt;&lt;br /&gt;1/n = 1/b + (b-n)(1/b)(1/n)&lt;br /&gt;&lt;br /&gt;Where 1/b of course can be expressed as a digit shift. So, to express division by 3 in a way that is convenient to a binary computer, you get the relationship&lt;br /&gt;&lt;br /&gt;1/3 = 1/2 - 1/2 * (1/3) =&gt; 1/3 = 1/2 - 1/4 + 1/8 - 1/16 + 1/32 - 1/64 ...&lt;br /&gt;&lt;br /&gt;Conversely, to express division by 2 that is convenient to a trinary computer, you get&lt;br /&gt;&lt;br /&gt;1/2 = 1/3 + 1/3 * (1/2) =&gt; 1/2 = 1/3 + 1/9 + 1/27 + 1/81 + 1/243 + 1/729 + ...&lt;br /&gt;&lt;br /&gt;So now you know... It's pretty easy to vectorize the algorithm you get out of this, but you need to tip-toe around the minefield that is the decimal parts (well, actually, calculate their carry and add that to the integer part) to avoid rounding errors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1126060649884056020?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1126060649884056020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/fast-division.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1126060649884056020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1126060649884056020'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/06/fast-division.html' title='&quot;Fast&quot; division'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-8689534906622215851</id><published>2009-05-22T11:12:00.000-07:00</published><updated>2009-05-22T12:14:13.000-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operating system design'/><category scheme='http://www.blogger.com/atom/ns#' term='joke'/><category scheme='http://www.blogger.com/atom/ns#' term='user interface'/><title type='text'>A slightly better operating system philosophy than UNIX</title><content type='html'>&lt;span style="font-style:italic;"&gt;Please note that this is a conceptual joke.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the spirit of &lt;a href="http://www.pcworld.com/article/165124/the_future_is_bios_and_browsers.html"&gt;ideas like this&lt;/a&gt;, I'd like to outline an entirely new operating system philosophy.&lt;br /&gt;&lt;br /&gt;It's based on the following concepts:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Everything is an email. All user data, and peripherals are accessible only through POP3 and SMTP daemons built into the operating system, sorted in different accounts depending on their tasks. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; No program has any particular task it does very well, but all of them can send or receive emails. The latter is in fact a prerequisite to be called a 'program'. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; When you start a program, it gets an account in the mail system. This is the only means of IPC. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; The GUI is also managed with emails. It is server based like X11, except it's wrapped in email protocols. A program wanting to change it's title would for example send an email to the GUI server asking for it to do so. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; The default command line shell is a mail client of user choice. The default is crude, reminiscent of a raw telnet session to an SMTP server, but other options such as mutt, pine or emacs (reduced to it's mail-manipulation capabilities only) are also available. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Example: How to write a Hello World program in C, compile it, and run it.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;MAIL: Compose&lt;br /&gt;TO: code@filesystem&lt;br /&gt;TITLE: hello-world.c&lt;br /&gt;&lt;br /&gt;#include &amp;lt;mailos.h&gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[]) {&lt;br /&gt;/* To be a program, it must by definition be able to deal with emails */&lt;br /&gt;  mail_client_initialize(argv[0]);  &lt;br /&gt;  mail* mail_create("output");&lt;br /&gt;  mprintf(mail, "Hello World!\n");&lt;br /&gt;  mail_inbox_add(mail);&lt;br /&gt;  mail_destroy(mail);&lt;br /&gt;&lt;br /&gt;  return EXIT_SUCCESS;&lt;br /&gt;}&lt;br /&gt;-- END&lt;br /&gt;&lt;br /&gt;MAIL: Compose&lt;br /&gt;TO: process-starter@system&lt;br /&gt;TITLE: compiler&lt;br /&gt;--END&lt;br /&gt;&lt;br /&gt;MAIL: LOGIN&lt;br /&gt;SERVER: filesystem&lt;br /&gt;USER: code&lt;br /&gt;LOGGED IN&lt;br /&gt;&lt;br /&gt;CODE: FORWARD&lt;br /&gt;WHAT: hello-world.c&lt;br /&gt;WHERE: compiler@processes&lt;br /&gt;CODE: LOGOUT&lt;br /&gt;&lt;br /&gt;MAIL: Compose&lt;br /&gt;TO: process-starter@system&lt;br /&gt;TITLE: a.out&lt;br /&gt;--END&lt;br /&gt;Hello World!&lt;br /&gt;&lt;br /&gt;MAIL:&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The possibilities are endless: Spam mail can be used to generate entropy for the random number generator, and system backup could rely on gmail. Clusters could be managed with mailing lists.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-8689534906622215851?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/8689534906622215851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/slightly-better-operating-system.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8689534906622215851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/8689534906622215851'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/slightly-better-operating-system.html' title='A slightly better operating system philosophy than UNIX'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-418313991150614225</id><published>2009-05-19T11:39:00.000-07:00</published><updated>2009-05-19T12:36:52.551-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webcam'/><category scheme='http://www.blogger.com/atom/ns#' term='touch sensitive'/><title type='text'>Follow-up: Webcam touch screen</title><content type='html'>As a follow-up on the &lt;a href="http://awesomegeekblog.blogspot.com/2009/05/diy-touch-sensitive-sidebar.html"&gt;Making A Touch Sensitive Sidepanel&lt;/a&gt; post from a while back, I can gladly report that it is actually feasible to make the entire screen touch sensitive. In a feat of hobo engineering&lt;sup&gt;1&lt;/sup&gt;, I've crafted flaps out of cardboard to mount the webcams 20 centimeters (8-ish inches) away from the screen, thereby making it possible to cover the entire surface of the screen within the field of view. When I have the time, I'll make a proper mount for the webcams out of something sturdier than cardboard. &lt;br /&gt;&lt;br /&gt;I actually have come up with the designs for a more elaborate version, but an actual assembly will have to wait until I have more time and resources (hopefully in a month or so). It requires a webcam, a light source (LED:s? perhaps infrared if your webcam can see those), a two panes  of glass (without scratches), and a box. The idea is to mount the glass at a 45 degree angle inside the box, and then the screen, upside down, at the top of the box. The box is painted black on the inside, and a row of LED:s are mounted on the top of the viewing side. When you look into the box, the glass will reflect the screen (which neatly enough will appear to hover in the air inside) so that it's viewable from the viewing hole. The LED:s on top of the hole will illuminate anything close to the surface (e.g. your finger touching the surface), making it possible to track such objects with a webcam on the far end of it. It's also probably a good idea to add a fan somewhere. Here's a diagram:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/ShMEdAFyeBI/AAAAAAAAAC0/8y0H-H5BY0E/s1600-h/diagram.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 229px;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/ShMEdAFyeBI/AAAAAAAAAC0/8y0H-H5BY0E/s320/diagram.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5337614879651166226" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that this design means that the aspect ration of the viewing area will change by a factor 1/sin(45&lt;sup&gt;o&lt;/sup&gt;) = &amp;radic;2, so what was a 4:3 screen will be a 36:19 screen. ... yeah.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;sup&gt;[1]&lt;/sup&gt; It's even beyond redneck engineering. Even their mechanical shenanigans don't reach this level. Everything is made out of expectations, cardboard, surgical tape. Nothing stays where it should for more than a few minutes. All that's missing is a burning barrel, a shopping cart, and some gloves with no fingertips, and the experience would be complete.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-418313991150614225?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/418313991150614225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/follow-up-webcam-touch-screen.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/418313991150614225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/418313991150614225'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/follow-up-webcam-touch-screen.html' title='Follow-up: Webcam touch screen'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lhmAHZ1VwRE/ShMEdAFyeBI/AAAAAAAAAC0/8y0H-H5BY0E/s72-c/diagram.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7357743210435745514</id><published>2009-05-15T09:13:00.000-07:00</published><updated>2009-05-23T11:52:33.632-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='internet'/><category scheme='http://www.blogger.com/atom/ns#' term='web browser'/><category scheme='http://www.blogger.com/atom/ns#' term='benchmark'/><title type='text'>Browser javascript performance vs. Adoption</title><content type='html'>There was an &lt;a href="http://tech.slashdot.org/article.pl?sid=09/05/14/1410200"&gt;article on Slashdot&lt;/a&gt; today about how browser javascript speed seemed to be inversely correlated to the adoption of the browser. The core of the article was this &lt;a href="http://www.futuremark.com/pressroom/pressreleases/55615/"&gt;press release&lt;/a&gt; from Futuremark. &lt;br /&gt;&lt;br /&gt;Sadly lacking was a hands-on analysis of the numbers. The sample size is pretty small (5 browsers), but still, &lt;span style="font-style:italic;"&gt;some&lt;/span&gt; analysis would still be called for, so here goes:&lt;br /&gt;&lt;br /&gt;First a plot of the data set&lt;sup&gt;&lt;a href="#performance-footnote1"&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/Sg2ZFmxfBQI/AAAAAAAAACE/9fIOLzPniGg/s1600-h/fulldata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/Sg2ZFmxfBQI/AAAAAAAAACE/9fIOLzPniGg/s400/fulldata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5336089455090402562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;At a glance, it doesn't look terribly correlated, but, there is a hidden outlier here. If you remove the third sample, Opera, you get a plot that looks more like a smooth function.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sg2Zc7ifX5I/AAAAAAAAACM/GAM7fCN82mk/s1600-h/redddata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sg2Zc7ifX5I/AAAAAAAAACM/GAM7fCN82mk/s400/redddata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5336089855801646994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Indeed, if you take the logarithm of this dataset, you find an almost straight line (!)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/Sg2ZohGjwvI/AAAAAAAAACU/MNLdTkm7R-w/s1600-h/logreddata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/Sg2ZohGjwvI/AAAAAAAAACU/MNLdTkm7R-w/s400/logreddata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5336090054863602418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you look at the logarithm of the full dataset, it's pretty evident that something is wonky about the Opera point.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/Sg2Z7n2eXQI/AAAAAAAAACc/Qw82kTebEgU/s1600-h/logfulldata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/Sg2Z7n2eXQI/AAAAAAAAACc/Qw82kTebEgU/s400/logfulldata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5336090383092702466" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;For the reduced data set, a linear regression of Performance vs. log(Adoption) as a+b*x yields&lt;br /&gt;&lt;br /&gt;a = 0.619&lt;br /&gt;b = -0.00447&lt;br /&gt;&lt;br /&gt;A statistical analysis indicates that the probability for such a strong correlation by random chance is 0.062%. The standard deviation is 0.079, and the &lt;a href="http://en.wikipedia.org/wiki/Coefficient_of_determination"&gt;coefficient of determination&lt;/a&gt; R&lt;sup&gt;2&lt;/sup&gt; is 0.999. For the full data set, R&lt;sup&gt;2&lt;/sup&gt; is 0.89.&lt;br /&gt;&lt;br /&gt;So, the adoption as a function of performance in the benchmark would according to this hypothesis be &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center"&gt;Adoption(Performance) = e&lt;sup&gt;0.619 - 0.00447*Performance&lt;/sup&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Comparing this with the data sets, it appears very likely that the hypothesis is true.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sg2k-WLthEI/AAAAAAAAACk/iub7fBGjcfQ/s1600-h/results.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Sg2k-WLthEI/AAAAAAAAACk/iub7fBGjcfQ/s400/results.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5336102524517450818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Of course, the data set is very small, so it's plausible that this is just a random coincidence, the same way one may get a descending sequence of numbers when throwing a die 4 times without some physical rule dictating that dice only generate descending sequences of numbers.&lt;br /&gt;&lt;br /&gt;Some final thoughts: Even though correlation is not causation, my guess is that more popular browsers, being older, need more maintenance. Their large user base will also lead to more time being spent patching security flaws. On the other hand, the smaller upstarts need a competitive edge to stand a chance against the bigwigs, motivating the developers to create faster code.&lt;br /&gt;&lt;br /&gt;As for Opera, you can either interpret them as having unusually small adoption for it's speed, or being unusually slow for it's tiny adoption. The former makes more sense than the latter. A factor that should be taken into consideration is that almost all the other browsers either have massive campaigns surrounding them, or ship as default with some operating system. So maybe Opera is simply under-advertised?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;The analysis was performed with the statistical functions of a TI-84+, and the plots were generated with &lt;a href="http://www.gnuplot.info/"&gt;gnuplot&lt;/a&gt;&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;size=1&gt;&lt;a name="performance-footnote1"&gt;&lt;sup&gt;[1]&lt;/sup&gt;&lt;/a&gt; You can find the actual numbers in the &lt;a href="http://www.futuremark.com/pressroom/pressreleases/55615/"&gt;press release&lt;/a&gt;, I don't want to steal their thunder. &lt;/size&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7357743210435745514?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7357743210435745514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/browser-javascript-performance-vs.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7357743210435745514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7357743210435745514'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/browser-javascript-performance-vs.html' title='Browser javascript performance vs. Adoption'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/Sg2ZFmxfBQI/AAAAAAAAACE/9fIOLzPniGg/s72-c/fulldata.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-3132343543040573029</id><published>2009-05-02T10:47:00.000-07:00</published><updated>2009-05-02T14:21:09.220-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='touch sensitive'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='input'/><category scheme='http://www.blogger.com/atom/ns#' term='display'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Making a touch sensitive sidepanel</title><content type='html'>I love coming up with new ways of controlling my computer. But I'm also a cheap bastard. So, in joining my two aforementioned characteristics, I bring to you probably one of the cheapest ways of capturing finger presses on a non-touch display. It won't allow you to track touching on all of the display or tracking multiple fingers, but it will allow you to create a touch sensitive sidepanel. What's keeping you from doing the entire screen is the narrow field of view in most webcameras, so you could hypothetically get around this problem with some form of lensing.&lt;br /&gt;&lt;br /&gt;It's also worth noting that it's a better idea to experiment with this on CRT displays instead of flat displays, since CRTs are easier to clean and harder to damage with your fingers.&lt;br /&gt;&lt;br /&gt;All you require is 2 webcams with a decent frame rate (mostly anything in the 10-20 buck range will do the trick, so long as they can do 30 fps or so), some black cardboard and some adhesive tape. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SfyHhie7vqI/AAAAAAAAABk/IEKE1Ym8Ur0/s1600-h/diagram1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 286px; border: 2px solid #000;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SfyHhie7vqI/AAAAAAAAABk/IEKE1Ym8Ur0/s400/diagram1.png" border="2" alt=""id="BLOGGER_PHOTO_ID_5331285069161807522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center"&gt;&lt;span style="font-weight:bold;"&gt;Figure 1: The set-up&lt;/span&gt;. A. Vertical camera, B. Horizontal camera, C. Black screen. D. Section of screen where fingers can be tracked.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The black cardboard in opposite of the cameras is to make finger identification much simpler. Instead of comparing with some complicated idle state, you'll just have to check what portions of the view isn't black. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/SfyO0g2Y7TI/AAAAAAAAABs/EqNgI8er6Xc/s1600-h/diagram2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 286px; border: 2px solid #000;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/SfyO0g2Y7TI/AAAAAAAAABs/EqNgI8er6Xc/s400/diagram2.png" border="2" alt=""id="BLOGGER_PHOTO_ID_5331293091722226994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center"&gt;&lt;span style="font-weight:bold;"&gt;Figure 2: What the cameras see&lt;/span&gt;. A. The area to be ignored. B. The area to be scanned for fingers (with black cardboard in the background). C. A finger. D. Portion of the screen at a steep angle (to be ignored as well) &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Once you've got your hardware set up, the actual interaction with the hardware can be a bit of an headache, but I got it working by reading the Video4Linux documentation. You can probably settle for a &lt;a href="http://en.wikipedia.org/wiki/Cargo_cult_programming"&gt;cargo cult implementation&lt;/a&gt; of the actual driver interaction. There's also some limitations in your computer that you may run into. The USB bus only has so much bandwidth, and if you're unlucky, that might not be enough for two video feeds. I had to hack the kernel module to &lt;a href="http://awesomegeekblog.blogspot.com/2009/04/kernel-hacking-ov51x-jpeg-module-with-2.html"&gt;get around that problem with my drivers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The basic finger identification algorithm is pretty simple. You take an average of the positions of all the pixels which are bright. Simply scan region B in Figure 2 for pixels with a color intensity stronger than some threshold value, and for such regions, increment one counter by the brightness, and one counter by the vertical position of the pixel multiplied with it's brightness. When you've iterated over all points, divide by the first counter. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;float sum = 0, pos = 0;&lt;br /&gt;for(x = 0; x &lt; x_max; x++) {&lt;br /&gt;for(y = y_min; y &lt; y_max; y++)&lt;br /&gt;  if(ispixel(x,y)) {&lt;br /&gt;    sum+=intensity(x,y);&lt;br /&gt;    pos+=x*intensity(x,y);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;pos/=sum;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Besides the actual implementation, you'll need to do some form of calibration. It's mostly trial and error. First, figure out how much off the zero position is, then estimate how much off the scale is, and compensate for that. &lt;br /&gt;&lt;br /&gt;You can cut down on some of the noise by giving the values some "inertia", which essentially the same as applying a low-pass filter to your data. Use the following algorithm:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;X = X*(1-alpha) + X_new*alpha;&lt;br /&gt;Y = Y*(1-alpha) + Y_new*alpha;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;where alpha is a number in the 0 ... 1 range (I chose 0.25), and the position will stabilize a lot. &lt;br /&gt;&lt;br /&gt;We can also use the fact that the position is relatively stable to identify a "press", i.e. when the difference in position between iterations is lower than some value, we decide that the user has pressed his/her finger. We may also want to wait a couple of frames before triggering a new press, since obviously it's not desirable to have the same action performed 30 times because you didn't have the reflexes of a ninja and accidentally pressing down for longer than 0.33 ms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Putting it all together, I made a side-bar for my secondary screen that is touch sensitive, borrowing some icons from &lt;a href="http://everaldo.com/crystal/"&gt;the crystal project&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_lhmAHZ1VwRE/SfyrqTMrwfI/AAAAAAAAAB0/7HmO35Vdg1M/s1600-h/screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_lhmAHZ1VwRE/SfyrqTMrwfI/AAAAAAAAAB0/7HmO35Vdg1M/s320/screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5331324802096153074" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The code is a working prototype, and a lot of stuff is hard coded, but it should be possible to salvage a lot of the tricky parts for use in whatever project you're working on.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.acc.umu.se/~achtt315/touchdisplay/touchcam.c"&gt;touchcam.c&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.acc.umu.se/~achtt315/touchdisplay/Makefile"&gt;Makefile&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It should on most x86 linux systems with &lt;a href="http://www.libsdl.org/"&gt;SDL&lt;/a&gt; present, but requires a bunch of icons to be put in a subdirectory resources/ to actually run. I got mine from &lt;span style="font-style:italic;"&gt;64x64/apps&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;32x32/actions&lt;/span&gt; in the crystal project icon tarball.&lt;br /&gt;&lt;br /&gt;I'm actually surprised at how useful it is. It may not be 100% accurate, but it's still a really nice way of controlling your mp3 player or starting new programs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-3132343543040573029?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/3132343543040573029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/diy-touch-sensitive-sidebar.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3132343543040573029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/3132343543040573029'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/05/diy-touch-sensitive-sidebar.html' title='Making a touch sensitive sidepanel'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lhmAHZ1VwRE/SfyHhie7vqI/AAAAAAAAABk/IEKE1Ym8Ur0/s72-c/diagram1.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4614041703789239855</id><published>2009-04-26T13:06:00.000-07:00</published><updated>2009-04-26T15:30:38.939-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='mouse'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='fonze'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Elbow power: Things going *bump* in the night</title><content type='html'>Whenever some form of hardware doesn't work, many people bash it or elbow it, hoping and praying that this desperate measure might solve the problem.  So, I figured, what if you could harness this form of kinetic input to control your computer&lt;br /&gt;&lt;br /&gt;What if you could set the computer up so that when you slam it with your elbow, and like yours was the elbow of the Fonze, it kills Firefox (porn surfers rejoice), or renews your network connection, switches keyboard layout, switches desktop background, the possibilities are limited only by your imagination. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Disclaimer&lt;/span&gt;: Your computer will stand up to some degree of slapping and bashing about, it does have a breaking point. Use this at your own peril. I do not take responsibility for whatever damage you inflict upon your computer with this program.&lt;br /&gt;&lt;br /&gt;Instead of buying expensive gyroscopes, accelerometers or hacking your wiimote, there's a very cheap way of making this a reality. The poor man's accelerometer is nothing but a computer mouse. Place it on top of your computer (make a casing for it if you want it to look neat). Now, the problem is how to read the data from the mouse. In Linux, this is a trivial matter. All hardware in Linux is a file, and you can simply open the mouse like any other old file. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/SfTLu0J7nlI/AAAAAAAAABc/RbWlIP3gZAw/s1600-h/accelerometer.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 157px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/SfTLu0J7nlI/AAAAAAAAABc/RbWlIP3gZAw/s400/accelerometer.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329108264220859986" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="font-weight:bold; text-align: center;"&gt;Poor man's accelerometer.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;What protocol the mouse device uses is &lt;abbr title="Impromptu idioms is the latest craze."&gt;a different pony&lt;/abbr&gt;. There's several mouse protocols, and they are all slightly different. The basic PS/2 protocol has 3 byte packets, where the first byte is buttons and some flags, and the second is relative motion in the X direction, and the third is relative motion in the Y direction. Older 2 button mice with no scroll wheel is generally PS/2 mice. Newer mice allow for longer packets, but they are generally backwards compatible with PS/2. There is more information on the protocol on &lt;a href="http://en.wikipedia.org/wiki/Mouse_(computing)#PS.2F2_interface_and_protocol"&gt;Wikipedia&lt;/a&gt; if anyone is interested.&lt;br /&gt;&lt;br /&gt;Great. So let's write a program that we can use to track jolts. The algorithm is going to be like this:&lt;br /&gt;&lt;br /&gt;1. Open the device.&lt;br /&gt;2. Read data from the file descriptor.&lt;br /&gt;3. If the magnitude of the relative motion exceeds some threshold value, return from the program.&lt;br /&gt;&lt;br /&gt;Add some red carpet code to allow customization, and you'll end up with this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.acc.umu.se/~achtt315/kinput/kinput.c"&gt;kinput.c&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.acc.umu.se/~achtt315/kinput/Makefile"&gt;Makefile&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Compile with &lt;span style="font-style:italic;"&gt;make&lt;/span&gt;, and you're (hopefully) go.&lt;br /&gt;&lt;br /&gt;Now that this helper program is done, what you need to do is write a shell script that performs some action when it detects a bump.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;# DISCLAIMER! Your computer will stand up to some degree of &lt;br /&gt;# slapping and bashing about, it does have a breaking &lt;br /&gt;# point. Use this at your own peril. I do not take&lt;br /&gt;# responsibility for whatever damage you inflict upon&lt;br /&gt;# your computer with this program.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;KINPUT=/path/to/kinput     # Change this to where you put kinput&lt;br /&gt;MDEVICE=/dev/input/mouse1  # Change this to some appropriate device&lt;br /&gt;THRESHOLD=10               # Increase this if it goes off too easily&lt;br /&gt;TIMEOUT=1                  # Change this to how long you want to sleep&lt;br /&gt;                           # before waiting for another motion&lt;br /&gt;WHAT="killall firefox-bin" # Change this to what you want performed on a bump&lt;br /&gt;&lt;br /&gt;while [ 1 ]; do&lt;br /&gt;  if "$KINPUT" -d "$MDEVICE" -t "$THRESHOLD"; then&lt;br /&gt;    echo "Bump detected!"&lt;br /&gt;    eval "$WHAT"&lt;br /&gt;  else exit; fi   # Exit if something has gone wrong &lt;br /&gt;  sleep "$TIMEOUT";   # Sleep a moment&lt;br /&gt;done&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;... and that's it. Running this in the background will allow you to solve your problems with your elbow. Correctly configured, you should only need to nudge your computer slightly. Bashing your computer too hard may harm your hard disks and cause problems in the wiring, so you shouldn't do that. &lt;br /&gt;&lt;br /&gt;You could conceivably also use this program to detect mouse motion for other purposes. Running it in the background in the login manager and tracking the regular mouse could allow you to set up your computer to grab snapshots with your webcam of everyone who tries to log into your computer (which may or may not be legal where you live/work) and then email them to you.&lt;br /&gt;&lt;br /&gt;There are some problems that might arise with this though, the most likely is that you don't have permission to read from the mouse device. Instead of running the script as root (are you insane?), it's a lot better to allow the mouse device to be read by all users, or add trusted users to the same user group as the mouse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4614041703789239855?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4614041703789239855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/things-going-bump-in-night.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4614041703789239855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4614041703789239855'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/things-going-bump-in-night.html' title='Elbow power: Things going *bump* in the night'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/SfTLu0J7nlI/AAAAAAAAABc/RbWlIP3gZAw/s72-c/accelerometer.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7512976766411091741</id><published>2009-04-26T10:59:00.001-07:00</published><updated>2009-04-26T16:40:21.169-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='reddited'/><title type='text'>Was reddited, some replies and comments</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SfSp1YnQ7kI/AAAAAAAAABU/IgTQH9rAUQs/s1600-h/awesome.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 105px; height: 400px;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SfSp1YnQ7kI/AAAAAAAAABU/IgTQH9rAUQs/s400/awesome.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5329070993691438658" /&gt;&lt;/a&gt; Yeah, so my previous two posts ended up on reddit and gizmodo, and got a fair amount of comments. Thank you for the 15 minutes of fame. It will naturally all go to my head, and I'll be expecting flamboyant Sovieteqsue monuments to be built depicting myself at any moment. ... On a more serious note, I figured I ought to reply to some of the comments I got here and on various other places: &lt;br /&gt;&lt;br /&gt;Several people suggested that one could simply just pipe the data to the soundcard, like this&lt;br /&gt;&lt;code&gt;cat data &gt; /dev/dsp&lt;/code&gt;&lt;br /&gt;and then on the receiving end simply&lt;br /&gt;&lt;code&gt;cat /dev/dsp &gt; data&lt;/code&gt;&lt;br /&gt;In an ideal environment with no noise, no echoes and with hardware that has a completely ideal acoustic properties, this would &lt;span style="font-style:italic;"&gt;probably&lt;/span&gt; work if you started broad casting and receiving at exactly the same moment. In the real world, all it does is produce a lot of noise.&lt;br /&gt;&lt;br /&gt;Other people were upset over the fact that I did not use the best possible algorithms, suggesting that Fourier transforms is CPU intensive and I got crappy baud rate. This is all true, I could have used impulse response filters and gotten hundreds of kbps in speed out of it. But creating a high speed software modem wasn't the mission (and I never presented it as such). It was a hack, for the fun of it. What they are saying is basically that MacGyver would have been more effective if he simply carried a gun. He would unfortunately also have been no where near as entertaining to watch. I deliberately chose crude components (such as a DFTs filter instead of a FFT filter or a FIR filter) and simple algorithms to make it understandable for people who don't have degrees in signal processing. &lt;br /&gt;&lt;br /&gt;Then there were the people that suggested I simply connected the two computers with male-male audio cables. This would have worked too. But I avoided this because of two reasons. The first reason is that I didn't have any cables of that nature laying about, and the second is that the laptop isn't grounded, which means that the stationary computer and the laptops don't share a common ground. Static buildup in the laptop might lead to a power surge upon connecting it to the laptop, that potentially could damage both of the computers, especially given the low end nature of laptop sound cards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7512976766411091741?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7512976766411091741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/was-reddited-some-replies-and-comments.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7512976766411091741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7512976766411091741'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/was-reddited-some-replies-and-comments.html' title='Was reddited, some replies and comments'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_lhmAHZ1VwRE/SfSp1YnQ7kI/AAAAAAAAABU/IgTQH9rAUQs/s72-c/awesome.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-7830782891039266093</id><published>2009-04-22T11:24:00.001-07:00</published><updated>2011-09-05T06:17:21.304-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='phase shift keying'/><category scheme='http://www.blogger.com/atom/ns#' term='OSS'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>File transfer over sound card II: Phase Shift Keying</title><content type='html'>I've played around further with the file transfer over sound card idea, and developed a more advanced method that uses a technique called &lt;a href="http://en.wikipedia.org/wiki/Phase_shift_keying"&gt;Phase Shift Keying&lt;/a&gt;. Similar techniques are used in wireless network connections. &lt;br /&gt;&lt;br /&gt;Instead of coding data in the amplitude or frequency of the carrier signal, phase shift keying (as the name indicates) encodes it in the phase. It is significantly faster, partially because it doesn't waste as much time with silences, but also because it's more reliant.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Se98MLHk0II/AAAAAAAAABM/ds1cj-do08w/s1600-h/itsalive.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 212px;" src="http://2.bp.blogspot.com/_lhmAHZ1VwRE/Se98MLHk0II/AAAAAAAAABM/ds1cj-do08w/s400/itsalive.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327613432787423362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I must admit it's a good thing I wasn't drinking coffee when tinkering with this technique, because it's very likely I would have blown coffee through my nose and onto the keyboard when I first saw transfer rates over around 200 baud, with no random garbling. I'm sure it's possible to go higher with better equipment than my cheaper-than-dirt headsets that came with my webcams.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;How it works&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The mathematics of the method is as following, if the signal is expressed as &lt;br /&gt;&lt;br /&gt;S(t) = A&lt;sub&gt;0&lt;/sub&gt; sin(&amp;omega;t + &amp;phi;)&lt;br /&gt;&lt;br /&gt;Then the Fourier transform of S would give you&lt;br /&gt;&lt;br /&gt;F&lt;sub&gt;&amp;omega;&lt;/sub&gt;(S) = A&lt;sub&gt;0&lt;/sub&gt; e&lt;sup&gt;i&amp;phi;&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;Normally, one would simply discard the phase factor by taking the norm of the frequency coefficient, but for this we're going to make use of it. You can't just yank the phase out of the expression as it is though (phase is always relative to &lt;span style="font-style:italic;"&gt;something&lt;/span&gt;). But! You can compare this phase with the phase of the last sample you got (this is called &lt;span style="font-style:italic;"&gt;differential&lt;/span&gt; phase-shift keying, by the way). &lt;br /&gt;&lt;br /&gt;So, I propose the following scheme:&lt;br /&gt;&lt;table&gt; &lt;tr&gt; &lt;th&gt; &amp;Delta;&amp;phi; &lt;/th&gt; &lt;th&gt; Meaning &lt;/th&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; 0 &lt;/td&gt; &lt;td&gt; Still the same sample as last time &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &amp;pi; / 2 &lt;/td&gt; &lt;td&gt; Next bit is 1 &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; &amp;pi; &lt;/td&gt; &lt;td&gt; Next bit is 0 &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; 3 &amp;pi / 2 &lt;/td&gt; &lt;td&gt; New byte &lt;/td&gt; &lt;/tr&gt; &lt;/table&gt;&lt;br /&gt;&lt;br /&gt;This has several nice features. You can jump into the signal almost anywhere and at most one byte will be garbled. Furthermore, everything has an uniform length, so bit rate doesn't depend on how many ones and zeros is in the byte.&lt;br /&gt;&lt;br /&gt;Modifying the fourier code from the last blog post on sonic file transfers, the following function will allow you to make use of the phase:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;double fourier1p(double x_in[], double n, int length, double* phase_r, double* phase_i) {&lt;br /&gt;        double x_complex[2] = { 0, 0 };&lt;br /&gt;        int i;&lt;br /&gt;&lt;br /&gt;        for(i = 0; i &lt; length; i++) {&lt;br /&gt;                x_complex[0] += x_in[i] * cos(M_PI * 2 * i * n / (double) length);&lt;br /&gt;                x_complex[1] += x_in[i] * sin(M_PI * 2 * i * n / (double) length);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        double norm = sqrt(x_complex[0]*x_complex[0] + x_complex[1]*x_complex[1]);&lt;br /&gt;        *phase_i = x_complex[1] / norm;&lt;br /&gt;        *phase_r = x_complex[0] / norm;&lt;br /&gt;        return norm / length;&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So how do we figure out the phase difference? Let &amp;phi; be the phase of the current sample, and &amp;psi; be the phase of the previous sample.&lt;br /&gt;&lt;br /&gt;e&lt;sup&gt;i&amp;phi;&lt;/sup&gt;e&lt;sup&gt;-i&amp;psi;&lt;/sup&gt; = e&lt;sup&gt;i(&amp;phi; - &amp;psi;)&lt;/sup&gt; = cos(&amp;phi; - &amp;psi;) + i sin(&amp;phi; - &amp;psi;)&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;The real term will dominate if &amp;phi; - &amp;psi; ~ n&amp;pi; , and the imaginary term will dominate if &amp;phi; - &amp;psi; ~ (n+1)&amp;pi;/2 and their sign will further tell you if n is odd or even.&lt;br /&gt;&lt;br /&gt;The demodulation algorithm is fairly short:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;double carrier_phase[2];&lt;br /&gt;double carrier_strength = fourier1p(dbuffer, (float) length * carrier / (float)rate, length, &amp;carrier_phase[0], &amp;carrier_phase[1]);&lt;br /&gt;                &lt;br /&gt;if(carrier_strength &lt; threshold) continue;&lt;br /&gt;&lt;br /&gt;double delta_re = carrier_phase[0] * old_carrier_phase[0] + carrier_phase[1]*old_carrier_phase[1];&lt;br /&gt;double delta_im = -carrier_phase[1]*old_carrier_phase[0] + carrier_phase[0] * old_carrier_phase[1];&lt;br /&gt;&lt;br /&gt;if(delta_re * delta_re &gt; delta_im * delta_im) { /* Phase difference is a multiple of pi */&lt;br /&gt;  if(delta_re &gt; 0); /* No change */&lt;br /&gt;  else {&lt;br /&gt;    bit_data = bit_data * 2;&lt;br /&gt;  }&lt;br /&gt;} else {&lt;br /&gt;  if(delta_im &gt; 0) {&lt;br /&gt;    bit_data = bit_data * 2 + 1;&lt;br /&gt;  } else {&lt;br /&gt;    if(isprint(bit_data)) printf("%c", bit_data);&lt;br /&gt;    else printf("&lt;%.2x&gt;", bit_data);&lt;br /&gt;    bit_data = 0;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;old_carrier_phase[0] = carrier_phase[0];&lt;br /&gt;old_carrier_phase[1] = carrier_phase[1];&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For several reasons, it's a good idea to use a pretty high carrier frequency for this method. At some point, your speaker or microphone will not be able to process the information, so you'll want to stay under that, but a high frequency will result in less perturbation of the signal since fairly few objects have eigenfrequencies in the 5 kHz range or higher, and even oscillation at harmonic frequencies drops off pretty significantly at such frequencies.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Sources&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The complete source code for the program:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/generate_psk.c"&gt;generate_psk.c&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/analyze_psk.c"&gt;analyze_psk.c&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You may have grabbed these the last time, but they are slightly altered now, so get them again:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/fourier.h"&gt;fourier.h&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/fourier.c"&gt;fourier.c&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You also need the &lt;span style="font-style:italic;"&gt;playback&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;record&lt;/span&gt; programs I posted in the previous post. They haven't changed though.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/playback.c"&gt;playback.c&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/record.c"&gt;record.c&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Using&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Same old warning: Never try these programs with your headphones on. &lt;span style="font-weight:bold;"&gt;THEY MAKE LOUD NOISES!&lt;/span&gt; It is possible to configure these programs to make noises way louder than you ever imagined your headphones could make. You can damage your hearing when playing with audio programming. &lt;a href="http://en.wikipedia.org/wiki/Tinnitus"&gt;Tinnitus&lt;/a&gt; isn't fun. &lt;br /&gt;&lt;br /&gt;To transfer a file (let's transfer &lt;span style="font-style:italic;"&gt;/etc/fstab&lt;/span&gt; again), put the microphone next to the speaker, pre-type the following on the transmitting computer (without running it):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&gt;./generate_psk -r 48000 -c 8000 -b 100 /etc/fstab | ./playback -r 48000&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Type the following on the receiving computer:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&gt;./record -r 48000 &gt; mydata&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Press enter on the transmitting computer. Be quiet (this should be fairly quick. Maybe 30 seconds?) When the high pitched noise stops, press Ctrl+C on the receiving computer's terminal.&lt;br /&gt;&lt;br /&gt;Running &lt;br /&gt;&lt;code&gt;./analyze_psk -r 48000 -c 8000 -b 100 mydata&lt;/code&gt;&lt;br /&gt;on the receiving computer should retreive the message.&lt;br /&gt;&lt;br /&gt;The parameters are&lt;br /&gt;-r : Sample rate -- carrier frequency and signal quality&lt;br /&gt;-c : Carrier frequency -- limits baud rate and signal quality&lt;br /&gt;-b : Baud rate -- determines how fast the transfer is&lt;br /&gt;&lt;br /&gt;What works and doesn't with the sampling rates and frequencies is a bit tricky. It all boils down to &lt;a href="http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem"&gt;Nyquist-Shannon&lt;/a&gt;. That theorem is all innocent looking, until you make it mad. Then it turns green and grows three times it's size and goes on a furious rampage through your hopes and dreams.&lt;br /&gt;&lt;br /&gt;Anyways, have fun experimenting with this technique.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;2011 update&lt;/span&gt;: Moved the sources to a &lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/"&gt;github repo.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-7830782891039266093?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/7830782891039266093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/file-transfer-over-sound-card-ii-phase.html#comment-form' title='32 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7830782891039266093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/7830782891039266093'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/file-transfer-over-sound-card-ii-phase.html' title='File transfer over sound card II: Phase Shift Keying'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_lhmAHZ1VwRE/Se98MLHk0II/AAAAAAAAABM/ds1cj-do08w/s72-c/itsalive.png' height='72' width='72'/><thr:total>32</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-4593764077963521952</id><published>2009-04-18T11:42:00.001-07:00</published><updated>2011-09-05T06:15:23.280-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='OSS'/><category scheme='http://www.blogger.com/atom/ns#' term='file transfer'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>File transfer over sound card</title><content type='html'>Before I even start, a word of warning: Never try these programs with your headphones on. &lt;span style="font-weight:bold;"&gt;THEY MAKE LOUD NOISES!&lt;/span&gt; It is possible to configure these programs to make noises way louder than you ever imagined your headphones could make. You can damage your hearing when playing with audio programming. &lt;a href="http://en.wikipedia.org/wiki/Tinnitus"&gt;Tinnitus&lt;/a&gt; isn't fun. &lt;br /&gt;&lt;br /&gt;This will be you if you don't take my warning seriously:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_lhmAHZ1VwRE/SezYWjXAfOI/AAAAAAAAAA0/A-U_5CBVI2Q/s1600-h/huh.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 332px; height: 400px;" src="http://1.bp.blogspot.com/_lhmAHZ1VwRE/SezYWjXAfOI/AAAAAAAAAA0/A-U_5CBVI2Q/s400/huh.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5326870341232917730" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Background and problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have an old laptop laying about. A while back, I was in a bit of trouble getting it to work. It's so old that several parts of it has shut down. The USB system is fried, and it can't read modern burned DVD:s. I needed to move software to it to get the network up and running again. The only peripheral that was working (besides the keyboard and the screen) was the sound card. It was running an old version of &lt;a href="http://slackware.com/"&gt;Slackware&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ah, I thought, and wrote a program that encoded data in sound. When I did it back then I used a bad algorithm. It was very noise sensitive and tried to do too much at the same time. As of then, I've improved (and simplified) the concept to using a sort of pulse width modulation (an idea I got when I read about the &lt;a href="http://en.wikipedia.org/wiki/ZX_Spectrum_software#Tape"&gt;ZX Spectrum Tape Loader&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;The basic protocol is trivial:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;For every character:&lt;br /&gt;  For every bit:&lt;br /&gt;    Send a short pulse if the bit is 1. &lt;br /&gt;    Send a long pulse if the bit is 0.&lt;br /&gt;    Send a silence.&lt;br /&gt;  Send a very long pulse (4 times as long as the shortest pulse).&lt;/li&gt;&lt;br /&gt;  Send a silence.&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is nice and not very error prone. The end-of-byte signal means that errors don't taint their neighbors. &lt;br /&gt;&lt;br /&gt;The crux isn't the signal generation (which is laughably trivial), it is the analysis on the receiving end; or rather dealing with the noise in the signal. The naive implementation would be to sum the square of the signal amplitude over time periods--the presence of a sine wave would converge towards some value and a silent signal would converge towards 0. In a noisy signal, it almost always converges towards something non-zero, so no such luck.&lt;br /&gt;&lt;br /&gt;So, the second approach would be to use a Fourier transform, to select the part of the spectrum where our signal resides (400 Hz is what I chose).&lt;br /&gt;&lt;br /&gt;A simple implementation of such a function looks like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;double fourier1(double x_in[], double n, int length) {&lt;br /&gt;       double x_complex[2] = { 0, 0 };&lt;br /&gt;       int i;&lt;br /&gt;&lt;br /&gt;       for(i = 0; i &lt; length; i++) {&lt;br /&gt;                 x_complex[0] += x_in[i] * cos(M_PI * 2 * i * n / (double) length);&lt;br /&gt;                 x_complex[1] += x_in[i] * sin(M_PI * 2 * i * n / (double) length);&lt;br /&gt;       }&lt;br /&gt;       return sqrt(x_complex[0]*x_complex[0] + x_complex[1]*x_complex[1]) / (double) length; &lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Where x_in is a series of numbers between -1 and 1, and n is the modified frequency (which is to say: length * frequency / rate). This function would give you a number corresponding to how much of a given frequency is in a sample. But you can do one better: &lt;a href="http://en.wikipedia.org/wiki/Harmonic_frequency"&gt;Harmonics&lt;/a&gt;.  Almost every loudspeaker will produce some level of harmonics even though the signal broadcasted is a plain sine wave with no harmonics.&lt;br /&gt;&lt;br /&gt;So, to check if our signal is in a given segment, the following code can be used:&lt;br /&gt;&lt;code&gt;double sum = 0;&lt;br /&gt;for(harmonic = 1; 2*harmonic &lt; length / frq; harmonic++) {&lt;br /&gt;   sum += fourier1(data, frq * harmonic, length); &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To check if the signal is present in a given signal, you must compare this against some form of threshold. What's a good threshold varies with noise. A bad threshold value may either cause the program to interpret random noise as meaningful data, or reject good data as random noise.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;if(sum &gt; threshold) { /* Signal is present in data block */ }&lt;br /&gt;else { /* Signal isn't present */ }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The protocol described above can be realized with the following code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;if(sum &lt; threshold) {&lt;br /&gt;    if(signal_length) {&lt;br /&gt;        if(signal_length &gt; 10) {&lt;br /&gt;            if(bit != 0) printf("(?)");&lt;br /&gt;            bit = 0;&lt;br /&gt;            signal_length = 0;&lt;br /&gt;        } else {&lt;br /&gt;            bit_data = 2 * bit_data + (signal_length &lt; 6);&lt;br /&gt;            if(++bit == 8) {&lt;br /&gt;                printf("%c", bit_data);&lt;br /&gt;                fflush(NULL);&lt;br /&gt;                bit = 0;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        signal_length = 0;&lt;br /&gt;    }&lt;br /&gt;} else {&lt;br /&gt;    signal_length++;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This does work. It's not just some crazy pipe dream. Following is all the code you need for transferring files from two computers using their soundcards.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SezPzVEw13I/AAAAAAAAAAk/Qvoxfdhy1rY/s1600-h/joy.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 104px;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SezPzVEw13I/AAAAAAAAAAk/Qvoxfdhy1rY/s400/joy.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5326860940009854834" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Garbled transfers like this may soon arrive through a soundcard near you.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Utility programs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before I get deeper into to the main program, I'm going to contribute some utility programs. &lt;font style="font-style: italic;"&gt;record&lt;/font&gt; and &lt;font style="font-style: italic;"&gt;playback&lt;/font&gt;. They are both wrappers for OSS, and reads and digests data from the soundcard; or writes digested data to the soundcard at given sample rates. They deal in signed char arrays only, and may convert them for the soundcard. Exactly what they do and how they work is a bit off topic, so I'll just post the code listings.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/playback.c"&gt;playback.c&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/record.c"&gt;record.c&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The broadcasting end&lt;/span&gt;&lt;br /&gt;As previously discussed, the broadcasting part of the program is pretty simple. The only real gotcha is the sample rate factor in the frequency. Since we're generating a signal with N bytes per second, we must decrease our frequencies by a factor 1/N. Beyond that, it's really quite trivial.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/generate.c"&gt;generate.c&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The math parts&lt;/span&gt;&lt;br /&gt;Almost there now. We just need some fourier transforms and things of such nature. The analysis end of the program can also make a XPM file of the frequency spectrum of the input, which is why you see a bunch of XPM code. &lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/fourier.c"&gt;fourier.c&lt;/a&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/fourier.h"&gt;fourier.h&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Finally... the receiving end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Most of what this one does has already been discussed. The threshold is hard-coded. You may want to change it or whatever. &lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/analyze.c"&gt;analyze.c&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;... one file to compile them all, and into objects link them&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/blob/master/Makefile"&gt;Makefile&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To compile, you just run&lt;br /&gt;&lt;code&gt;&gt; make&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Using the programs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before I get to actually using the programs, I repeat my warning: Never try these programs with your headphones on. &lt;span style="font-weight:bold;"&gt;THEY MAKE LOUD NOISES!&lt;/span&gt; It is possible to configure these programs to make noises way louder than you ever imagined your headphones could make. You can damage your hearing when playing with audio programming. &lt;a href="http://en.wikipedia.org/wiki/Tinnitus"&gt;Tinnitus&lt;/a&gt; isn't fun.&lt;br /&gt;&lt;br /&gt;Not there yet. It's quite an elaborate matter to use all these programs. First you'll want to generate your raw sound data. Let's transfer /etc/fstab (don't do this as root! Something might go horribly wrong!) &lt;br /&gt;&lt;br /&gt;First, attach the microphone on the receiving end to the speakers on the transmitting end. Use duct tape or whatever. I had an old hands free headset that I wrapped so that the microphone was held in place by the earpiece. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SezVVE4xzNI/AAAAAAAAAAs/gfSiWFTTtZs/s1600-h/loop.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 319px; height: 243px;" src="http://4.bp.blogspot.com/_lhmAHZ1VwRE/SezVVE4xzNI/AAAAAAAAAAs/gfSiWFTTtZs/s400/loop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5326867017338309842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On the transmitting computer, run the following command:&lt;br /&gt;&lt;code&gt;&gt; ./generate -b 25 -r 48000 -o out.data /etc/fstab&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Enter, but do not start the following on the transmitting computer:&lt;br /&gt;&lt;code&gt;&gt; ./playback -r 48000 &lt; out.data # don't press enter yet!&lt;br /&gt;&lt;/code&gt; &lt;br /&gt;&lt;br /&gt;Now, on the receiving computer, run the following command:&lt;br /&gt;&lt;code&gt;&gt; ./record -r 48000 -o out.recdata&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note that out.recdata will grow very fast. In this case, 48000 bytes/second.&lt;br /&gt;&lt;br /&gt;Run the command pre-typed in the transmitting computer's terminal. Be very quitet, and listen to the noise coming from of the speaker. This may take quite some time. Practice your Zen. Find enlightenment. When the noise stops, press Ctrl+C on the receiving computer.&lt;br /&gt;&lt;br /&gt;Run the following command on the receiving computer:&lt;br /&gt;&lt;code&gt;&gt; ./analyze -b 25 out.recdata&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Watch a semi-garbled /etc/fstab be printed across your screen. The -b switch is to be taken with a grain of salt. It is proportional to how fast the transfer is. It must (obviously) be the same on the receiving and the transmitting end. I've gotten it to work at -b 50 -r 48000. Sample rate (-r) increases the processing time, but it also allows faster transfers. There are a few fixed possible sample rates, 8000 always works, others that are supported by most soundcards are 11025,16000,22050,24000,32000,44100 and 48000.&lt;br /&gt;&lt;br /&gt;So, in summary: -b determines how fast the transfer is, and the maximum possible transfer speed is limited by the sampling rate.&lt;br /&gt;&lt;br /&gt;If it doesn't work, try playing what you &lt;span style="font-style:italic;"&gt;record&lt;/span&gt;ed with &lt;span style="font-style:italic;"&gt;playback&lt;/span&gt;. If you can hear and distinguish the beeps, then so should the computer be able to. If record or playback fails, chances are you don't have permissions to access &lt;span style="font-style:italic;"&gt;/dev/dsp&lt;/span&gt;. If all you get is character salad, fiddle with &lt;span style="font-style:italic;"&gt;threshold&lt;/span&gt; in &lt;span style="font-style:italic;"&gt;analyze.c&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;An even more elaborate version of this program is described in &lt;a href="http://awesomegeekblog.blogspot.com/2009/04/file-transfer-over-sound-card-ii-phase.html"&gt;File Transfer Over Sound Card II - Phase Shift Keying&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;2011 update&lt;/span&gt;: Moved the sources to a &lt;a href="https://github.com/vlofgren/file-transfer-over-soundcard/"&gt;github repo&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-4593764077963521952?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/4593764077963521952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/file-transfer-over-sound-card.html#comment-form' title='49 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4593764077963521952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/4593764077963521952'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/file-transfer-over-sound-card.html' title='File transfer over sound card'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_lhmAHZ1VwRE/SezYWjXAfOI/AAAAAAAAAA0/A-U_5CBVI2Q/s72-c/huh.jpg' height='72' width='72'/><thr:total>49</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-2289170499711320253</id><published>2009-04-17T08:19:00.001-07:00</published><updated>2010-05-16T15:23:30.202-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webcam'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='OV519'/><category scheme='http://www.blogger.com/atom/ns#' term='kernel'/><category scheme='http://www.blogger.com/atom/ns#' term='ov51x-jpeg'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Kernel hacking: ov51x-jpeg module with 2 webcams</title><content type='html'>This is partially a note-to-self, and pretty esoteric. If you don't get what I'm talking about, don't worry. This probably doesn't apply to you. &lt;br /&gt;&lt;br /&gt;I have sent this fix to the module creator, but until a solution becomes available in the actual module, I'm sharing the information here.&lt;br /&gt;&lt;br /&gt;The following changes are made entirely at your own peril. I take absolutely no responsibility for whatever doom it may bring upon your computer. It &lt;span style="font-style:italic;"&gt;may&lt;/span&gt; cause your computer to go up in flames, your girlfriend to cheat on you and horribly disfiguring and agonizing diseases to be inflicted upon you. Don't say I didn't warn you.&lt;br /&gt;&lt;br /&gt;I have had problems with getting the &lt;span style="font-style:italic;"&gt;ov51x-jpeg&lt;/span&gt; kernel module to accept multiple webcams with my OV519 cameras. I'm quite simply running out of USB bandwidth. Now the module has built in functionality to handle this: You modprobe with the argument "cams=2". This did not work for me. I was still using too much bandwidth. &lt;br /&gt;&lt;br /&gt;If you make the following alteration to ov51x-jpeg-1.5.9. &lt;br /&gt;&lt;br /&gt;File: ov51x-jpeg-core.c&lt;br /&gt;&lt;code&gt;5435               case BRG_OV519:&lt;br /&gt;5436                    if (cams == 1)                          size = 896;&lt;br /&gt;5437                    else if (cams == 2)                     size = 512;&lt;br /&gt;5438                    else {&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;is changed into&lt;br /&gt;&lt;code&gt;5435            case BRG_OV519:&lt;br /&gt;5436                    if (cams == 1)                          size = 896;&lt;br /&gt;5437                    else if (cams == 2)                     size = 512;&lt;br /&gt;5438                    else if (cams == 3)                     size = 384;&lt;br /&gt;5439                    else {&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Unload the ov51x-jpeg module. Recompile the module sources. Load with&lt;br /&gt; &lt;br /&gt;&lt;code&gt;modprobe ov51x-jpeg cams=3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;... and it works. At least for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-2289170499711320253?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/2289170499711320253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/kernel-hacking-ov51x-jpeg-module-with-2.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2289170499711320253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/2289170499711320253'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/kernel-hacking-ov51x-jpeg-module-with-2.html' title='Kernel hacking: ov51x-jpeg module with 2 webcams'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4042332099774263836.post-1064351316154686145</id><published>2009-04-08T17:15:00.001-07:00</published><updated>2009-05-09T04:17:53.389-07:00</updated><title type='text'>Awesome Geek Blog</title><content type='html'>Okay, so I suck at maintaining a blog. This is the ... 15:th? Blog I've started.&lt;br /&gt;&lt;br /&gt;So, what am I?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Physics Student. Quantum Mechanics is my passion, and I do it because it's difficult. The high from solving a problem you've spent a week trying to figure out is impossible to describe. It's like having sex in a sea of drugs when you just won the lottery.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Shameless &lt;a href="http://cowboyprogramming.com/2007/01/11/delving-into-cowboy-programming/"&gt;Cowboy Coder&lt;/a&gt;, mostly writing esoteric programs, like &lt;a href="http://www.acc.umu.se/%7Eachtt315/tunguska"&gt;this one&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;My favorite language is C 99, though I have experience in C++, assembler (6502 and some x86), Java, python, MATLAB/Octave, DOM programming in Javascript, lua, BASIC, and limited FORTRAN.&lt;/li&gt;&lt;li&gt;My favorite editor is vim.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;All-around geek. There are very few intellectual pursuits I don't find interesting and don't know the lay of the lands of the basic concepts. In fact, they are two: Medicine and chemistry. But then, the medicine geeks are hoarding their knowledge, and chemistry is evil.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Nerdcore"&gt;Nerdcore&lt;/a&gt; aficionado.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Wikipedia addict.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A card carrying member of The Church of the SubGenius. But I'm only in it for the slack. The beheadings and orgies are a bit meh.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4042332099774263836-1064351316154686145?l=awesomegeekblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://awesomegeekblog.blogspot.com/feeds/1064351316154686145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/awesome-geek-blog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1064351316154686145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4042332099774263836/posts/default/1064351316154686145'/><link rel='alternate' type='text/html' href='http://awesomegeekblog.blogspot.com/2009/04/awesome-geek-blog.html' title='Awesome Geek Blog'/><author><name>Viktor Lofgren</name><uri>https://profiles.google.com/103031805920354983700</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-cWwiCIeQ4Gc/AAAAAAAAAAI/AAAAAAAAAUA/hKTwJOHlSN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry></feed>
