tag:blogger.com,1999:blog-6108290140309089402018-03-02T21:51:11.112+05:30Running UpstairsRavi Mohan's Tech Blog. To read my non technical blog, click <a href="http://pindancing.blogspot.com">here</a>Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-610829014030908940.post-87839834619729180872010-02-15T18:24:00.006+05:302010-02-15T18:57:02.528+05:30Testing Blogger's EditorI am just testing how far the built in blogger editor can help in laying out proofs. Please ignore this.<br /><br /><br />Question: prove distributivity of OR over OR ( I am using "OR" and "AND" for disjunction and conjunction operators , == for equivalence. The reasoning for each step is to the side after a --), <br /><br />(The calculus used is EQ from "A logical Approach to Discrete Math". This is theorem 3.41, just something chosen at random - but I've used only axioms + theorems proven till that point in the book ) .<br /><br /><br /><br /> prove p OR (q OR r) == (p OR q) OR (p OR r)<br /><br /><br />p OR (q OR r) -- LHS<br /><br />== ((p OR q) OR r) -- associativity of Or<br /><br />== (( p OR q) OR r) OR false -- False is the identity of OR<br /><br />== (( p OR q) OR r) OR (NOT true) -- definition of false<br /><br />== (m or r) OR (NOT true) -- substituting m for (p OR q), Leibniz<br /><br />== m OR (r OR (NOT true)) -- associativity of OR <br /><br />== m OR ( r OR (NOT (p == p)) ) -- true is identity of ==<br /><br />== m OR ( r OR ( NOT p == p )) -- distributivity of NOT over ==<br /><br />== m OR (r OR (NOT p) == r OR p ) -- distributivity of OR over == <br /><br />== m OR (r OR p == r OR (NOT p)) -- symmetry of OR<br /><br />== (m OR r OR p) == (m OR r OR (NOT p)) -- distributivity of OR over ==<br /><br />==(p OR q OR r OR p)== (m OR r OR (NOT p)) -- replacing m with (p OR q), Leibniz<br /><br />==(p OR q) OR (r OR p)== (m OR r OR (NOT p)) --associativity of OR<br /><br />==(p OR q) OR (p OR r)== (m OR r OR (NOT p)) --symmetry of OR<br /><br />==(p OR q) OR (p OR r)== (m OR (NOT p) OR r) --symmetry of OR <br /><br />==(p OR q) OR (p OR r)== (p OR q OR (NOT p) OR r) --expanding m to p OR q, Leibniz<br /><br />==(p OR q) OR (p OR r)== (p OR (NOT p) OR q OR r) --symmetry of OR <br /><br />==(p OR q) OR (p OR r)== ( true OR q OR r) -- Excluded Middle<br /><br />== (p OR q) OR (p OR r)== ( true OR r) -- true is the Zero of OR<br /><br />== (p OR q) OR (p OR r) == true -- true is the Zero of OR<br /><br />== (p OR q) OR (p OR r) -- true is the Identity of ==<br /><br />== RHS . QED<br /><br /><br /><br />Conclusion: What a mess. I need Latex dammit. Anyone know of a *non* wordpress blog with a latex plugin? (I don't want JS rendering, for which there are a few options. I want an image (png, gif, jpeg whatever) generated on the server and plugged in appropriately).Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com2tag:blogger.com,1999:blog-610829014030908940.post-989114734414033262009-05-18T10:58:00.006+05:302009-05-18T12:01:19.549+05:30Some guidelines on portingThis is in response to some difficulties encountered by a friend in porting a library from Common Lisp to Scheme. I am very short of time so this is less polished than usual. Apologies in advance.<br /><br />I generally port something from one language to another when <br />(1) I want to learn a new language. I learned Ruby by porting the FIT library from Java. It ended up in my never using FIT and not seeing enough of a reason to shift my choice of scripting language from Python, but it was still an interesting exerscise.<br />(2) My clients need to work with or on the *code* I deliver. If a scientist has to look at or modify code, for example then the final deliverable has to be in a mainstream language like Python or Java vs a more powerful language like Erlang or Haskell or even Scheme.(though I can sometimes get away with Scheme). So I prototype in whatever language seems appropriate to the domain and then port it to Java or Python or C. <br /> <br />After doing this a few times, I've found a few "shortcuts".<br /><br />(1) There are three variables - the source language, the target language, the domain. Make sure you know at *least* two of them at the expert level. If you don't, fix that first. Struggling with two things at the same time(say the domain and the target language) is a recipe for suboptimal outcomes.<br /><br />(2) Do NOT port line by line from source to target. Even when the source and target languages are roughly similair, say Python to Ruby, or Scheme to Common Lisp, doing this often misses the idioms of the target language and ends up looking stilted. Eg. "meta programming" in Ruby (vs Python) and iteration in Scheme (vs Common Lisp).<br /><br />(3) DO use an intermediate form. This is, in my experience, *the* key to a succesful port. The intermediate form could be English, ("here the foo is converted to baz via a fold left accumulator combo") Logic, pseudo code, whatever is appropriate. Translate from the source code to the intermediate language (at multiple levels - function, module, design and architecture) and then from the intermediate language to the target language. In the latter step write *idiomatic* target language. Beware the idioms of the source language leaking into the target language.<br /><br />(4) When the source and target languages have different paradigms (say Prolog (logic)to Java ( a kind of bastardised OO) ) make sure you are fluent in both *paradigms* before you undertake the translation. Otherwise, you often end up with ugly code. A variant of this occurs when you are moving up or down the "blub ladder", even within the same paradigm say smalltalk to Java or C to Pascal.<br /> <br />Moving down is tedious but often conceptually straightforward. Moving up is harder in a different way because the lesser language often hides abstractions that are directly expressible in the higher (a complicated nest of for next lops. ifs and assignments may (in the end) decompose cleanly into sequence ops in haskell but it is sometimes difficult to see and/or extract those).Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com0tag:blogger.com,1999:blog-610829014030908940.post-48406642232335359162009-05-08T23:08:00.000+05:302009-05-08T23:09:04.416+05:30Twittering<a href="http://twitter.com/ravi_mohan">here</a>. <br /><br />I am not completely convinced of the awesomeness of Twitter, but it seems useful to jot down thoughtlets not big enough for a complete blog entry.<br /><br />We'll see how it goes.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com1tag:blogger.com,1999:blog-610829014030908940.post-5824439550262955192009-03-24T16:19:00.005+05:302009-03-25T12:38:11.314+05:30Ada Lovelace Day: Daphne KollerVia <a href="http://beingsunayana.wordpress.com/2009/03/24/ada-lovelace-day-jeannette-wing/">Sunayana's Blog</a> I came to know about the Ada Lovelace Day pledge whereby people write about women in computing they admire. <br /><br /><br />Now, I am personally not convinced there is a real crisis surrounding a "lack of women in computing". My attitude towards "women in computing" is expressed perfectly in George RR Martin's Novel "A Game of Thrones" by Syrio Forel, The First Sword of Bravos, when he is teaching Arya Stark, who is a very atypical girl, - given the medival setting of the story - and a bit of a tomboy, the finer points of sword fighting. He calls her "boy" a few too many times till she gets irritated and says "But I am a girl" And Syrio replies , "Boy, Girl you are a sword". Likewise for me, in computing , "Boy, Girl, you are a mind" I could care less about a person's chromosomal makeup.<br /><br />That said , let me talk about a mind I admire, which happens to reside in a woman' body. :-)<br /><br /><a href="http://ai.stanford.edu/~koller/">Daphne Koller</a> is a professor at Stanford whose research is about applying probabilistic techniques to complex domains. I've never met her (I should be lucky enough to study in Stanford!) but I've exchanged a few emails with her.<br /><br />I was coding up a robotics algorithm and the paper elucidating the algorithm had a reference to one of her papers, <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.7474">"Using learning for approximation in stochastic processes</a>". This paper explained a brilliant, elegant idea - in essence, instead of, in a particle filter (say) generating the t+ 1'th generation of particles from the t'th generation, the idea is to (a) create a probability distribution pd from the t'th generation and (b) sample from pd to get the t+1th generation.<br /><br />Unfortunately there wasn't enough information in the paper to code up a density tree , so I wrote to Dr Koller asking her if she had some code available. She didn't, (the code was lost a long time ago!) but she very graciously supplied me with enough detail so I could figure out the data structure myself and successfully complete my coding effort.<br /><br />Dr Koller's<a href="http://ai.stanford.edu/~koller/papers.cgi"> papers</a> are a treasure trove for anyone interested in her research areas and she is tremendously admired within the research community.Very few people combine brilliance and grace. Dr Koller is one of them. She is a great role model for anyone in computing (irrespective of chromosmal make up) to look up to and learn fromRavihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com2tag:blogger.com,1999:blog-610829014030908940.post-4441619104658929832009-03-22T22:38:00.005+05:302009-03-23T01:23:25.494+05:30GnuPlot In Actionis a great (e)book. I got the early access version from Manning and it is very well written. Phillip Jaanert has done a great job. I've been using it to visualize the output of some algorithms I've been coding up.<br /><br />here is a graph I created with GnuPlot for the optimal decisions for different learning rates for 2000 one armed bandits (essentially a stateless value function less precursor to Reinforcement Learning)<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WD4ydpP4v1g/ScZyLA1llII/AAAAAAAAAFY/Xn0MLl2Qw_Y/s1600-h/bandit.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_WD4ydpP4v1g/ScZyLA1llII/AAAAAAAAAFY/Xn0MLl2Qw_Y/s320/bandit.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5316061943686337666" /></a>Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com4tag:blogger.com,1999:blog-610829014030908940.post-35273469481804772412009-02-21T09:36:00.005+05:302009-02-22T08:50:16.507+05:30Gitting It after allI finally moved to git (from Subversion). The key to understanding git is to understand how the various "objects" (blobs, trees, commits and tags) form a Directed Acyclic Graph, and then understand the various version control commands in terms of modifications of and traversals on this data structure. Approaching GIT from a "this is another version control system like [your favorite VCS]" is the *wrong* way to go and results in people end up confused because then git will seem to be doing things (annoyingly) differently from what they are used to.<br /><br />The one minor nitpick I have is that most of the java ide s don't work well with git, but at least to me that is a blessing in disguise. I had planned to do a project with the Java/Eclipse combination but git (and the development workflow it enables) was so compelling that I am using Emacs and Haskell instead. <br /><br />Which is a definite win. :-)<br /><br />Update:- Apparently the Intellij IDE <a href="http://www.jetbrains.com/idea/features/version_control.html">has a GIT plugin in the latest version</a>. I greatly admire the product, though I don't use it myself these days.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com2tag:blogger.com,1999:blog-610829014030908940.post-24866389016089117612009-02-06T08:49:00.003+05:302009-02-06T11:20:19.320+05:30Exploring Game EnginesA few of us meet on the last Saturday of every month to review our technical progress (or the lack of it). This is somewhat like an iteration meeting in an agile project but focussed on personal achievement. I've written on such "Loser's Club" meetings <a href="http://ravimohan.blogspot.com/2007/10/intoxicating-conversation.html">before</a>. <br /><br />Recently we added a new wrinkle - each participant of the monthly meeting sends a weekly progress report to the others explaining what he worked on this week.<br /><br /><br />The following is the (lightly edited) report I sent a few minutes ago.<br /><br /><span style="font-style:italic;"><br />For the first time in a very long time I worked every day of the week without unnecessary distractions. <br /><br />As you know, I am working on an AI simulation project. Visualization is a key component and to understand how best to do this, I've been working on understanding the game loop in game engines and what modifications need to be made to use it in simulations. There seems to be a trade off between running the simulation as fast as the hardware allows (needed for effective sims) and slowing the simulation down to (some small multiple of) the screen refresh rate (typically 50-75 Hz) so humans can interact effectively. Networking multiple machines (the simulations needs to, ultimately, run on a cluster) has <a href="http://gafferongames.com/game-physics/networked-physics/"> design implications</a> on implementing the Game Clock (or Sim Clock).<br /><br /> One approach is to completely decouple the sim (which could write the results out into a file, say) and the display (which could work off that file). For some algorithms, ( eg <a href="http://en.wikipedia.org/wiki/Apprenticeship_learning">Apprenticeship Learning</a>) , where human intervention and process modeling is part of the learning process, this approach would be problematic, and anyway networking is still an issue, so I need to find a good approach). <br /><br />I have the beginnings of a really nice game framework (if I do say so myself). I have implemented multiple buffering strategies (pointer flips vs image redraw - The j2se comes with all this bundled up but since the final implementation will not be in Java I am implementing them from scratch to get a good understanding of how it works - only machine for e.g pointer flips give a 50 % boost to the fps), image loading, and a controller that allows either human or algorithm control (most game engines tie the event handling into the guts of the game).<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WD4ydpP4v1g/SYuvrpayS7I/AAAAAAAAAFQ/gGthjuzg7w0/s1600-h/Screenshot.png"><img style="cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_WD4ydpP4v1g/SYuvrpayS7I/AAAAAAAAAFQ/gGthjuzg7w0/s320/Screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5299522550918958002" /></a><br /><br /><br /><br />I've attached a (really yucky for now) screenshot. It just shows some sprites moving against a nondescript background, but I am doing some interesting experiments behind the scenes.<br /><br />In the coming week, I hope to resolve the sim vs game timing issue and also understand (a) tiled backgrounds and (b) how level editors work.<br /><br />Regards,<br /></span><br /><br />The act of writing out what was accomplished every week is very helpful. There's nothing like having to write "Nothing useful accomplished this week" a few times in a row, to alert one to the fact that your life is flowing down the drain!<br /><br />Last week, I also read <a href="http://www.amazon.com/One-Jump-Ahead-Challenging-Supremacy/dp/0387949305">"One Jump Ahead:: Challenging Human Supremacy In Checkers"</a>, which is an account by <a href="http://www.cs.ualberta.ca/people/profile.php?who=95883">Dr.Jonathan Schaeffer</a> of how he built <a href="http://www.cs.ualberta.ca/~chinook/">Chinook</a>, a program to beat the Checkers World Champion. This is a very interesting and (to researchers) very inspiring book. Jonathan also explains how he went on to <a href="http://www.cs.ualberta.ca/~chinook/publications/solving_checkers.html">solve Checkers</a> (in the sense that Tic Tac Toe is a completely solved game). All in all, a great account of how research is really done.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com4tag:blogger.com,1999:blog-610829014030908940.post-77381613037463541832009-01-30T22:18:00.000+05:302009-01-31T09:04:10.702+05:30Fad AlertWith a subsection of the Ruby Fanboy crowd moving to Clojure, there is a lot of uninformed talk about Software Transactional Memory (STM), mostly regarding how it "solves" concurrency in a multiple core scenario and how it is very "intuitive".<br /><br /> Bryan Cantrill restores sanity to the discussion via his blog post, <a href="http://blogs.sun.com/bmc/entry/concurrency_s_shysters">"Concurrency's Shysters"</a>(Be sure to read the <a href="http://portal.acm.org/citation.cfm?doid2=1400214.1400228">ACM paper</a> he refers to in the post).<br /><br />Unless you really understand the various concurrency mechanisms, to the point where you can implement some of them and know the theory therof, please please don't code concurrent programs. Thanks in advance. <br /><br />PS: This is not a knock on Clojure itself. Rich Hickey, its creator, is extremely talented, dedicated and very knowledgeable. Clojure is a great piece of software. This post is a reaction to some uninformed enterprise developers' mumblings on how Clojure is the next bandwagon to jump on.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com2tag:blogger.com,1999:blog-610829014030908940.post-8056335629529741222009-01-19T21:12:00.000+05:302009-01-19T21:25:52.011+05:30Book TreksWorking through every single exercise in a good technical book is a fascinating (and educational!) endeavour. Two of my friends are working through some tough technical books in this fashion (and blogging about it).<br /><br />My friend Manoj wanted to take a break from writing J2EE code and so took a sabbatical to work through <a href="http://mitpress.mit.edu/sicp/">SICP</a>. He is blogging his progress <a href="http://lawfulsamurai.blogspot.com/search/label/SICP">here</a>. Another friend, Himanshu, is working through Van Roy and Haridi's <a href="http://www.info.ucl.ac.be/~pvr/book.html">"Concepts, Techniques and Models of Computer Programming"</a> and is putting up the answers to the exercises <a href="http://ctamcp-himanshu.blogspot.com/">here</a>.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com0tag:blogger.com,1999:blog-610829014030908940.post-11009230034615620452008-12-25T19:02:00.000+05:302008-12-25T19:10:25.504+05:30Two levels of mathematicsI've <a href="http://ravimohan.blogspot.com/2008/01/engineering-some-working-definitions.html">written about</a> the connection between programming and mathematics before. My latest discovery is that there are two "levels" (for lack of a better word) Mathematics - one inhabited by engineers and one by mathematicians. This divide seems to carry over into books as well - thus, taking Calculus as an example, <a href="http://www.amazon.com/Calculus-Gilbert-Strang/dp/0961408820">Gilbert Strang's book</a> is an Engineer's guide and <a href="http://www.amazon.com/Calculus-Michael-Spivak/dp/0914098896">Spivak's book</a> is for mathematicians.I am working through the latter, and while it is <em>very</em> clearly written, it is a whole different level from any book on Calculus I've worked with before.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com0tag:blogger.com,1999:blog-610829014030908940.post-47250582905341606252008-10-03T12:14:00.000+05:302008-10-03T20:47:30.799+05:30An Unsatisfactory Proof<span style="font-weight:bold;">To be proved</span><br /><br /> "If the symmetric difference of sets A and B is a subset of A, prove that B is a subset of A"<br /><br /><br /><br />symmetric difference of A and B = A U B \ A ^ B (using U for union , ^ for intersection and \ for difference).<br /><br />What I've come up with <br /><br /><span style="font-weight:bold;"><br />The Proof</span><br /><br />Let x be an arbitrary element of B. <br /><br />Then x is also an element of A (case 1) or it is not (case 2). <br /><br />case 1.<br /><br />If an arbitrary element of B is an element of A then B is a subset of A . <br /><br />case 2.<br /><br />x is an element of B but is not an element of A. In which case, it is an element of (A U B) \ ( A ^ B), ie it is an element of the symmetric difference of the sets A and B. Since it is given that the symmetric difference of A and B is a subset of A, x is an element of A.<br /><br />Since x is an element of A in both cases and since x is an arbitrary element of B, we conclude that B is a subset of A.<br /><br />Q.E.D<br /><br />I keep getting the feeling there is a more elegant way to prove this. If anyone wants to write to me (or comment here) I'd appreciate it much.<br /><br />PS: - the proposition is obviously true (draw a Venn diagram to see why). I am asking for help on the (structure of the) proof itself.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com5tag:blogger.com,1999:blog-610829014030908940.post-46179940003778146152008-09-05T08:43:00.000+05:302008-09-05T17:02:56.223+05:30The key to understanding proofsis to realize that the <span style="font-style:italic;">exposition</span> of a proof is distinct from its <span style="font-style:italic;">derivation</span>. The (published) <span style="font-style:italic;">exposition</span> is a very condensed description of the what and why. The (usually unpublished) <span style="font-style:italic;">derivation</span> is about the how (the proof was derived). Reading carefully between the lines of the exposition one can often discern a faint outline of the creator's thought process but that's about it. <br /><br />A (weak) analogy is having the binary code of a program that does something wonderful.Without the source code(the step by step derivation of the proof), one has to use disassemblers (digging into the exposition)to figure out how it works. Having the source code would be better in some contexts, but most proofs are "binary only".<br /><br />Having said that, nothing stops me from starting from the givens and trying to prove the conclusion myself, which is a worthwhile exercise in itself. ("worthwhile" as in "what does not kill me makes me stronger" ;-) )Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com3tag:blogger.com,1999:blog-610829014030908940.post-43855077390305734572008-07-12T18:20:00.000+05:302008-07-12T19:39:46.933+05:30The JVM and Tail RecursionIn an attempt to investigate the performance of a trampolined interpreter on the JVM, I discovered something interesting.<br /><br />First, some background. In essence, trampolining is a strategy used to avoid stack overflow on platforms (like the JVM) that save to the stack even when not necessary , e,g while doing a tail recursive function call. So after doing a CPS transform and then trampolining it by returning a lambda wrapped "thunk", my interpreter *should have* handled an infinite tail recursive call *without* a stack overflow exception. But it failed anyway!<br /><br />After <a href="http://www.cs.indiana.edu/~dfried/">Dan Friedman</a> pointed out (by email) that "If you use exceptions in Java, you will regain tail recursion. I think that is the only way to get around Java. ", I did some digging and found something even more interesting. <br /><br />Tail recursive (java) functions are properly handled by some java JVMs (specifically the JITs) and not others! See <a href="http://www.ibm.com/developerworks/java/library/j-diag8.html#code_block_4.0">this article</a> for a good explanation. <br /><br />Try running Listings 4 and 5 (from the referenced article) on your JVM :-D . I suspect that C# code equivalent to the two listings in the article (numbered 4 and 5) would both run perfectly. Can someone with a Windows machine and dotNet installed let me know if it works? (post a comment here or send me email! Thanks in advance!)<br /><br />Footnote: the conversion of the tail recursive function (in the article) into the while loop form is one example of how a trampolining interpreter could "break stack build up".Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com2tag:blogger.com,1999:blog-610829014030908940.post-58725977733233034162008-07-02T17:29:00.000+05:302008-07-12T19:23:10.865+05:30DirectionsThis is the first post on my brand new blog. The essential difference between this blog and <a href="http://ravimohan.blogspot.com/">the old one</a> is a change of "voice" and focus.<br /><br /> Unlike the "catch all" nature of the old blog, this one will have a sharper focus, specifically on things technical (mostly code/mathematics/algorithms etc - but "technical" is used very broadly - I could very well end up dissecting the Black Scholes Equation for pricing derivatives, for example.). I will create a separate blog for non technical ruminations (TBD).<br /><br />So what's happening on my end? Life is insanely busy (as usual) and I am meeting great people (as usual) and situations (as usual) and the great difficulty (as always) is choosing among the zillion challenges to tackle next. "So little done, so much to do", to quote Cecil Rhodes, but hey it beats a boring, "normal" life any day.<br /><br />On the technical/programming front, I am investigating the impact of various (language) interpreter designs on execution time. Over the coming weekend, for example, I am trying to get some sense of how much overhead trampolining adds to interpretation time (vs a normal recursive descent parser). <br /><br />So that is what I'll write about in the next few entries. And then there is the reinforcement learning library I wrote for the good folks in the DRDO (Defence Research Development Organization for non Indian readers). I could probably spin that off into an open source project once I (find some time to) tidy it up a bit. <br /><br />Then there's the derivation of concurrent algorithms, the relational-algebra to SQL query generator thingy I've been fiddling with off and on for a while now, and thoughts on programming with typed channels and machine learnng algorithms as programming primitives. Lots of interesting things to write about.<br /><br />Stay tuned.<br /><br />Hello Word! It is good to be back.Ravihttp://www.blogger.com/profile/03630087669712445498noreply@blogger.com12