Vinod Kurup

Hospitalist/programmer in search of the meaning of life

Aug 21, 2012 - 5 minute read - Comments - book-review philosophy

Thoughts on Free Will

Time for some pop philosophy. I’ve never thought too deeply about the concept of free will. Of course we have free will! I chose to live my life a certain way. I could choose to live a different way. It is my free will to choose how I live. I’ve never thought about it more deeply than that.

I recently read Walter Isaacson’s biography of Einstein and I was forced to think more deeply about free will. The biography is excellent. It gives more depth to Einstein, who, despite his flaws, is still a heroic figure. One day, I’ll do a proper review, but the piece that struck me the hardest was Einstein’s views on free will. He didn’t believe that free will existed, and not only that, he didn’t even to seem to think that this was a controversial position. It appears that Isaacson didn’t either, because he didn’t spend much time on that part of Einstein’s character. But, it seemed so strange to me, since I assumed that we all have free will.

So, I read Sam Harris’s e-book Free Will, in which he concisely explains why free will is a myth. Take any conscious decision that you might make. Let’s say you choose at this moment to go eat a pizza. Do you have the free will to make that choice? Well, you certainly can go eat pizza, but the question is if you had the free will to do it. What were the steps that led to making that choice. Somewhere in your brain, a certain set of neurons fired to trigger the idea in your mind to have a pizza. How did those neurons fire? Either there was a conscious decision to have that thought, or it was an unconscious decision that you didn’t control. And if it was a conscious decision, then you can take that back a step further and ask how that decision occurred. Eventually, you will have to start at some unconscious (or subconscious) event which triggered the series of events which eventually led to your decision to have a pizza. No matter how far back you can track the conscious trail that led to a pizza forming in your mind, eventually you are left with an unconscious starting point. Certainly all of these thoughts are heavily influenced by your life experiences. If you’ve never seen or heard of a pizza, there’s a zero percent chance that you’ll think of a eating a pizza. But all of those life experiences are themselves the result of conscious and unconscious decisions, all of which we ultimately have no specific control over.

Every thought you have is the only thought you could have at that moment. It is the result of all of the life experiences and thoughts that you have had up to that moment. If you consciously try to “create” an original thought, just to prove that you have free will, well… you can’t. Because that decision itself originated from somewhere in your subconscious, and is therefore something that you don’t have conscious control over.

In addition to this theoretical rationalization against the concept of free will, Harris describes multiple studies from neuroscience which show that neurons fire in our subconscious well before we develop the urge to act. Examples:

Bottom line: I’m convinced that I don’t have the free will that I thought I did. The question is how this should affect my life. It could be depressing. If every thought of mine originates in a way that I don’t control, then am I just being steered through life? It makes my accomplishments in life seem less “worthy”. On the other hand, it can be quite freeing. My path through life is determined. Perhaps I shouldn’t be worrying so much about every decision, because I know that they’re not really “my” decisions to make. It can also give you more empathy for others, knowing that they also have no will do anything but what they are doing.

It’s still a confusing topic, because I “feel” like I have options in life and I “feel” like taking different options will change my life. That part is true. The part that isn’t true is that I have any control over the range of available options, nor over the specific option that I choose. Even Harris seems to be a little conflicted here:

Losing a belief in free will has not made me fatalistic—in fact, it has increased my feelings of freedom. My hopes, fears, and neuroses seem less personal and indelible. There is no telling how much I might change in the future. Just as one wouldn’t draw a lasting conclusion about oneself on the basis of a brief experience of indigestion, one needn’t do so on the basis of how one has thought or behaved for vast stretches of time in the past. A creative change of inputs to the system—learning new skills, forming new relationships, adopting new habits of attention—may radically transform one’s life.

The question is how do you accomplish a ‘creative change of inputs’, if you don’t have the will to do so? I guess the idea is that while I don’t have any control over the thoughts that arise in my brain, I do have perceived control over my decisions. With whatever power my conscious brain has, I can choose things that will improve my life, with the hope that exposure to new experiences will ‘change the inputs’ to my subconscious brain. Ugh, just thinking about how this all works makes my brain hurt. I guess this is why I never studied philosophy before. :-)

Free Will is short and cheap and I highly recommend it.

Aug 19, 2012 - 1 minute read - Comments - blog

Facebook is killing blogging

Looks like August 18th was International-Prominent-Bloggers-Complain-About-Facebook-Killing-Blogging Day. I was just two weeks too early.

On a side note, I’m really enjoying Scott Hanselman’s podcast This Developer’s Life. It’s an homage to the awesome This American Life, but focused on programming issues. They interview interesting programmers, but they carefully edit the interviews to focus on the parts that are the most interesting, interspersing them with music and effects. It’s really well done.

Aug 16, 2012 - 1 minute read - Comments - fatherhood happiness

A great moment

I woke up, got ready and went downstairs. I am not a morning person. I try to do as little thinking as possible, because thinking eventually leads to the rational conclusion that I should just go back to bed. I get to the coffee machine, grab my plastic mug and start pouring. Suddenly, I’m woken from my daze. I hear little footsteps pounding across the hallway above me. I look towards the bottom of the stairs and see a little figure race around the corner with a determined, slightly fearful look in her face. She’s afraid that she’s too late and that I’ve already left for work. She spies me and I must be smiling because her face melts into the biggest, happiest smile and her pace quickens. We run to meet each other in a big hug. “Daddy, can I watch the milk go in your coffee?”

Moments like that are so joyous, and I have underestimated how much they mean to me. I want to capture them and never let them go.

Aug 7, 2012 - 2 minute read - Comments - inspiring science

NASA Curiosity Lands

Like the rest of the geek world, we’ve been excited by Curiosity’s successful trip to Mars. Here’s a cool video which combines an animation of Curiosity’s landing mixed with the real reactions of the astronauts that got it there. (Found on thekidshouldseethis.com)

I’ve been disappointed that real space travel is unlikely to become a reality during my life. I honestly thought it would when I was a kid. But watching Curiosity gives me hope that we will be able to continue exploring our universe. This trip to Mars was much more of an achievement than the last one. Here’s an animation of the last trip (2003 Mars Exploration). Note that the final landing was achieved by an air bag dropped roughly from high up in the air. Not much precision required there.

Curiosity is huge (NASA) Curiosity is huge (NASA)

The Curiosity rover is too large for the airbag approach (See image at right comparing it to previous rovers), so an alternate system was devised using a sky crane which gently lowered the rover onto the Martian surface. Dropping an airbag seems much easier than gently landing a rover without damage. The real advance in our lifetime is that our machines are getting more intelligent. And the exciting thing is that I can actually participate in that type of exploration. I think I just convinced myself to learn how to program a robotic car!

Aug 3, 2012 - 2 minute read - Comments - blog writing

Blogging Again

I’m going to start blogging more. I know I’ve said that before, so take it for what it’s worth. I think there is value in blogging. I’ve been thinking about my life a lot lately, trying to find what makes me tick. One of those things that gets me excited is programming. I started thinking about that and remembered this meme that had passed around the blog world a few years back. It was a list of questions related to how you got started programming. I remember it especially because I remember reading MarkD’s version and thinking how similar it was to my own beginnings. Then, because I love going off on tangents, I googled for ‘How I got started in programming’ to read other responses. Many of the posts I found were on abandoned blogs. And now, for the ‘causal relationship not supported by data’ statement. This is because of Facebook and Twitter. OK, maybe it’s just the natural decay of blogs. But I am concerned about the fact that most people write in forums that are controlled by other people rather in their own forum. That was one of the cool promises of the web. A little place of your own that you controlled. Facebook and Twitter and Google+ are all cool services, but the more time I spend on them, the less time I spend here. I’m sure other people have written about this with more eloquence than I could, but the bottom line is that I want to keep writing. I want to learn more about myself, I want to teach others what little I know, and I want to learn from others. I’ve been journalling a lot lately and that has been useful, but the act of hitting ‘publish’ will make my writing better. That’s what this blog is for and I’m going to start using it again.

Maybe one of these days, I’ll even put up my own answers to ‘How I Got Started in Programming’, but in the meantime, go read MarkD’s

Nov 29, 2011 - 5 minute read - Comments - clojure math programming

On Factoring Large Numbers

I wonder how many of my blog posts are based on stories from This American Life. Probably not enough. Every time I start to listen to a show, I’m certain that I’m not going to be interested and within a minute I’m trapped and can’t stop listening. It’s that good. A recent show was about people who people who pursued crazy ideas. The first story was about a mathematician named Frank Nelson Cole. Marin Mersenne had claimed in the 17th century that 267-1 was a prime number. He was prominent enough that the claim was felt to be accepted wisdom and there was certainly no way to test the claim in the days before computers. That’s a big honking number: 147,573,952,589,676,412,927.

In 1903, Frank Nelson Cole walked into a meeting of mathematicians to present his talk. The title was boring, something like “On the factoring of large numbers”. Without speaking a word, he walked up to the chalkboard and started to write a large number, followed by another large number and then started to multiply them together. It took a while, but by the time he started to get towards the solution, the crowd of mathematicians understood that he was proving that he had found two numbers whose product was the famous “prime” number 267-1. As he came close to finishing, the anticipation peaked and cheering began. He finished the calculation and sat down, never speaking a word.

Stories like that give me the chills. Can you imagine how excited he must have been when he found those 2 roots? I get that sensation every once in a while when I make a programming breakthrough, solving a problem which I had been banging my head on for a while. It’s nowhere as profound as what he did, but I think I can understand the exhilaration he must have felt.

I decided to see what those 2 roots are, using my new favorite language, Clojure. I’m by no means an expert in anything, let alone programming and especially functional programming, but here’s how I went about it. The REPL is such a fun way to explore things like this:

  1. I need a range of numbers which I’ll then test one-by-one to see if they divide into 267-1 evenly.

     user=> (def n 18)
     #'user/n
     user=> (range 2 n)
     (2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)
    
  2. I need a way to take a square root. (There’s no need to check numbers higher than the square root of 267-1)

     user=> (Math/sqrt n)
     4.242640687119285
    
  3. So the numbers I need to test are:

     user=> (range 2 (inc (int (Math/sqrt n))))
     (2 3 4)
    
  4. I need to find the remainder of a division (Of note, mod also does the same thing, but rem is a lot faster)

     user=> (rem 9 2)
     1
    
  5. Can I find all the lower roots of a number? The #(...) syntax is syntactic sugar for an anonymous function. The % is a placeholder for the value which is being iterated over. So the following function takes each value in the list returned by range and supplies it to rem. If that rem function is equal to zero, then the #(...) anonymous function returns true and filter keeps the value.

     user=> (def n 100)
     #'user/n
     user=> (filter #(= (rem n %) 0) (range 2 (inc (int (Math/sqrt n)))))
     (2 4 5 10)
    
  6. Now let’s map over each of those values, finding the corresponding higher root for each value. vector creates a vector (think list) with the first value being the supplied value and the second value being the other root (/ n %):

     user=> (map #(vector % (/ n %)) (filter #(= (rem n %) 0) (range 2 (inc (int (Math/sqrt n))))))
     ([2 50] [4 25] [5 20] [10 10])
    
  7. Based on that experimentation, here’s my first stab at the function:

     user=> (defn roots [n]
              (let [lower-factors (range 2 (inc (int (Math/sqrt n))))
                    is-factor? (fn [a] (= (rem n a) 0))]
                (map  #(vector % (/ n %)) (filter is-factor? lower-factors))))
     #'user/roots
     user=> (roots 294)
     ([2 147] [3 98] [6 49] [7 42] [14 21])
    
  8. Now let’s get our big number (267-1)

     user=> (dec (Math/pow 2 67))
     1.4757395258967641E20
    
  9. Hmmm… that looks like it might not be a precise value. Oh well, let’s try it:

     user=> (roots (dec (Math/pow 2 67)))
     ([2 7.378697629483821E19] [3 4.9191317529892135E19] [4
     3.6893488147419103E19] [5 2.9514790517935284E19] [6
     2.4595658764946067E19] [7 2.108199322709663E19] [8
     1.8446744073709552E19] [9 1.6397105843297378E19] [10
     1.4757395258967642E19] [11 1.3415813871788765E19] [12
     1.2297829382473034E19] [13 1.1351842506898186E19] [14
     1.0540996613548315E19] [15 9.838263505978427E18] [16
     9.223372036854776E18] [17 8.6808207405692006E18] [18
     8.1985529216486892E18] [19 7.7670501362987581E18] [20
     7.3786976294838211E18.....
     C-c C-c (ABORT, ABORT!!!)
    
  10. OK, that didn’t work. It clearly found way too many roots, because 267-1 was an approximation. We have to use BigIntegers which have appropriate precision even with large numbers.

     user=> (def two67minus1 (dec (.pow (BigInteger. "2") 67)))
     #'user/two67minus1
     user=> two67minus1
     147573952589676412927
    
  11. Cool, that looks more precise than our previous value. To see the difference, check their type.

     user=> (type (dec (Math/pow 2 67)))
     java.lang.Double
     user=> (type (dec (.pow (BigInteger. "2") 67)))
     java.math.BigInteger
    
  12. OK, Time for the big test:

     user=> (roots two67minus1)
     ([193707721 761838257287])
    
  13. Cool!!! It works! Those are the roots of 267-1. How long did that take to compute? (We need doall to make the time command wait for all of the values to be calculated, otherwise it will return after the first value is calculated. This has something to do with the laziness of clojure sequences)

     user=> (time (doall (roots two67minus1)))
     "Elapsed time: 2.2697318183297E7 msecs"
     ([193707721 761838257287])
    

6 hours 18 minutes. I’m sure there’s a quicker way to do this. I do a lot of redundant testing. For example, once we know that 2 is not a factor, we shouldn’t check any more even factors. I’d be interested in any advice to make it run faster.

I can’t even fathom how you’d go about doing this without a computer. Can you imagine how frustrating it must’ve been any time you had a simple error? Just amazing…

Nov 12, 2011 - 4 minute read - Comments - clojure programming android

ClojureScript and PhoneGap

Phonegap is a tool that allows you to develop apps in HTML5 + javascript and makes it easy to deploy them to multiple mobile platforms, including Android and iOS.

ClojureScript is a dialect of the awesome language, Clojure, that compiles to Javascript (after a pass through the Google Closure optimizer). Because Clojure, ClojureScript and Google Closure can be confusing terms, I’ll use CLJS instead of ClojureScript for the remainder of this post.

What I wanted to do: Write a simple CLJS app that runs on my Android phone using these tools.

Get HelloWorld working with PhoneGap

Following these instructions will get the Android SDK, Eclipse plugin and PhoneGap working. If you already have the Android SDK, you’ll be able to skip most of it. I’m most comfortable in Emacs, so I’ll be using that instead of Eclipse. Here is the command-line command for creating your project (the -t refers to your android target which you can find by doing android list avds):

$ android create project -n HelloPhoneGap -t 2 -p HelloPhoneGap -k com.phonegap.helloworld -a App

By the end of these instructions, you should have a copy of an app called HelloPhoneGap on your phone which, when clicked, shows a ‘Hello World’ screen.

Setup CLJS

Follow the simple instructions, recreated here because they’re just so simple.

$ git clone git://github.com/clojure/clojurescript.git
$ cd clojurescript
$ ./script/bootstrap

That’s it. The CLJS compiler and REPL are ready to work.

Get HelloWorld working via HTML

Follow the instructions under the heading Using ClojureScript on a Web Page to build a Javascript file and associated HTML file for testing.

Put CLJS and PhoneGap together

OK, let’s make something a little interactive on the phone. I’m going to build a BMI calculator that takes a person’s height and weight in Imperial (i.e. American) units and calculates a Body Mass Index. BMI is simply weight divided by the square of height, with units of kg/m2.

Here’s the CLJS file:

    (ns bmi)
    
    (defn height [feet inches]
      (-> feet (* 12) (+ inches) (* 2.54) (/ 100)))
    
    (defn weight [lbs]
      (/ lbs 2.2))
    
    (defn bmi [h w]
      (js/Math.round (/ w (* h h))))
    
    (defn ^:export alertDismissed []
      nil)
    
    (defn ^:export displaybmi [form]
      (let [h (height (js/parseInt form.f.value) (js/parseInt form.i.value))
            w (weight (js/parseInt form.l.value))]
        (js/navigator.notification.alert (bmi h w) hello.alertDismissed)))

Basically, we create simple functions to convert Imperial heights and weights to metric values, calculate a BMI and then use displaybmi to parse form parameters, calculate the BMI and show that result in an Android notification popup. alertDismissed is a callback that gets called when the user dismisses the notification. (I’m just discarding the information here). Those are the only 2 functions that are needed by the HTML file, so those are the only 2 that need the :export metadata tag. navigator.notification.alert is a PhoneGap API call that does the actual notification.

The calls prefixed by js/ are understood by the CLJS compiler to refer to the global JavaScript namespace. If you didn’t include that prefix, the compiler would assume you meant a call in the local bmi namespace, which would obviously fail.

Here’s the HTML file (in HelloPhoneGap/assets/www/):

<!DOCTYPE HTML>
<html>
  <head>
    <title>BMI calculator</title>
    <script type="text/javascript" charset="utf-8" src="phonegap-1.0.0.js"></script>
    <script type="text/javascript" charset="utf-8" src="bmi.js"></script>
  </head>
  <body>
    <h1>BMI calculator</h1>

    <form>
      Height: <input name="f" size="2"> ft. <input name="i" size="2"> in. <br>
      Weight: <input name="l" size="2"> lbs.<br>
      <input type="button" value="Calculate BMI" onclick="bmi.displaybmi(this.form)">
    </form>
   </body>
</html>

Now compile the CLJS and move the compiled JS file to HelloPhoneGap/assets/www/

$ ./bin/cljsc bmi.cljs '{:optimizations :simple :pretty-print true}' > bmi.js
$ cp bmi.js ~/dev/HelloPhoneGap/assets/www/

The :simple value for optimizations and the true value for pretty-print make it so that we can read the resulting JS file, but can be changed to :advanced and false respectively when ready for production.

Now, go back into the HelloPhoneGap Android project and compile it and send it to the emulator (C-c C-c i in emacs). You should now have a simple BMI calculator working on Android.

BMI Android Screenshot BMI Android Screenshot

Next steps

The promise of PhoneGap is that you could use similar HTML/Javascript to create iOS versions as well, but I haven’t done that yet. There are tons of API calls available on both platforms which are supposed to give you the same access that native apps have. Using ClojureScript means you get to use a modern functional language to create your app, while getting access to the features that only JavaScript APIs provide.

Sep 8, 2011 - 2 minute read - Comments - linux sysadmin

Fixing wireless on eeePC

I have an ASUS eeePC 1000, running Ubuntu 10.10. Wireless worked flawlessly at home, which is where I use it 99% of the time. On our most recent trip, however, it wasn’t working. It couldn’t connect to a WPA-secured network. Here are the relevant error messages:

NetworkManager[770]: <warn> Activation (wlan0/wireless): association took too long.
NetworkManager[770]: <warn> (wlan0): link timed out.
NetworkManager[770]: <warn> Activation (wlan0) failed for access point (linksys)
NetworkManager[770]: <warn> Activation (wlan0) failed.
NetworkManager[770]: <info> (wlan0): deactivating device (reason: 0).

After a little googling on my phone, I found out that others had this problem with the rt2860sta wireless driver. Fortunately, there is a solution, which involved downloading the source code for the latest driver, modifying it a bit and rebuilding the driver. Here are the instructions:

Step 1: Download the driver

Download the latest rt2860sta driver.

Step 2: Rename and extract the downloaded file

Mine was named download.php, but it’s really a tar file:

vinod@ike:~ $ mkdir test
vinod@ike:~ $ mv download.php test/driver.tar
vinod@ike:~ $ cd test/
vinod@ike:~/test $ tar xf driver.tar 
vinod@ike:~/test $ mv 2010_07_16_RT2860_Linux_STA_v2.4.0.0 driver
vinod@ike:~/test $ cd driver

Step 3: Apply patch

Step 4: Backup old driver

vinod@ike~/test/driver/ $ sudo ifconfig wlan0 down
vinod@ike~/test/driver/ $ sudo rmmod rt2860sta
vinod@ike~/test/driver/ $ mkdir backup
vinod@ike~/test/driver/ $ sudo mv /etc/Wireless/RT2860STA backup/
vinod@ike~/test/driver/ $ sudo mv /lib/modules/2.6.35-30-generic/kernel/drivers/staging/rt2860/rt2860sta.ko backup/

Step 5: Install and activate new driver

vinod@ike:~/test/driver $ sudo make install
vinod@ike:~/test/driver $ sudo depmod -a
vinod@ike:~/test/driver $ sudo modprobe rt2860sta
```

### Step 6: Fix problems with hibernation

A separate problem is that wireless has been flaky when the computer
wakes from hibernation, but [it's also fixable](http://www.twentyways.com/2010/11/19/fixing-wireless-issues-with-asus-eeepc-1000he-running-ubuntu-10-10/).

Add the following lines to `/etc/modprobe.d/blacklist.conf`:

    blacklist rt2800pci
    blacklist rt2800lib
    blacklist rt2x00usb
    blacklist rt2x00pci
    blacklist rt2x00lib
 
Create a new file called `/etc/pm/config.d/unload_wireless` with the following line:

    SUSPEND_MODULES="rt2860sta"

Reboot and you should have WPA-compatible, hibernatable wireless.

### References:

1. [rt2860sta driver installation](http://www.ctbarker.info/2010/05/ubuntu-1004-wireless-chipsets-and-wpa.html)
2. [Proper hibernation](http://www.twentyways.com/2010/11/19/fixing-wireless-issues-with-asus-eeepc-1000he-running-ubuntu-10-10/)
3. [Ubuntu Forums thread](http://ubuntuforums.org/showthread.php?t=1476007)

Sep 6, 2011 - 2 minute read - Comments - family friends

Surprise, I'm 40!

Vinod is surprised Vinod is surprised

Have you ever been in one of those dreams where everything seems normal and then a flying car (or something equally crazy) comes out of nowhere? I’m used to having experiences like that when I’m dreaming, but it was quite surreal to have it during waking hours.

Mala and Kavi had gone ahead (surreptiously to plan a surprise party for someone else!). We were to meet at the ferris wheel at the Navy Pier. I found her and she took my hand. She started leading me through the crowds of tourists. I could sense excitement in her demeanor, but didn’t think anything of it. She led me towards a group of people and I caught a glimpse of someone who looked like my Dad. That’s weird… why would he be here? It’s at that point that neurons started to malfunction and I began to feel like I was in a dream. Then I saw Mala’s mom and got even more confused. Slowly the group of strangers came into focus and revealed themselves as my friends and family from around the country. It was, without a doubt, the best birthday present that I have ever received, or expect to receive. Thanks to Mala for months of planning, and for wanting to make me feel special even though I feel this way every day when I wake up next to her. Thanks to all my friends and family who could make it and to the ones who couldn’t. If this is the culmination of 40 years on this earth, I can’t wait for the next 40!

Vinod is 40 Vinod is 40

Aug 16, 2011 - 1 minute read - Comments - food

Mala's Bolognese

Mala's Bolognese Mala's Bolognese

I have just had the most amazing Italian meal that I’ve had outside of Roberto’s in the Bronx. Mala made fresh homemade Pappardelle and a Bolognese sauce that she just learned at Revolution’s cooking class. The thing is, she made this yesterday, and I just tried it today as leftovers and it was still amazing. This sure is going to make going lo-carb impossible.