Thursday, December 29, 2011

Book Review: The Golden Gate by Vikram Seth

Want to read a moving novel in sonnets? Grab a copy of "The Golden Gate", by Vikram Seth.

I am prejudiced against "popular" Indian authors. Past experiences have made me critical towards them, especially if their fiction is popular in the West. I don't know what I was thinking when I picked up "The Golden Gate" by Vikram Seth. I had heard of Vikram Seth, but I had not read anything by him.

The Golden Gate is a story about a few friends, and a few years of their life. The book is written entirely in verse, which took me by surprise. It has been a few years since I read verse. I need not have worried, the Golden Gate is a great way to start reading verse again. It is easy to read, and many passages in it are moving, and thought provoking. The book starts out with a person who should be happy at his success, but he feels lonely. It follows his journey, and tells you about his friends, and their lives. Written during the turbulent period of the Vietnam era, it raises interesting questions about life, ambition, following one's dreams, and what it takes to be happy and at peace.

The locations are all from the San Francisco Bay Area: San Francisco, San Jose, Marin county, and introduce the reader to the joy of living in this wonderful part of the world. It makes the reader appreciate the world we live in, and our friends.

I started out skeptical, and ended up enjoying the book immensely. I was sad when it ended, Vikram had done such a fine job of introducing the characters that they felt like friends.

Get the book, and enter the charming world of Vikram Seth's verse.


Image courtesy Wikipedia

Sunday, December 25, 2011

Book Review: The Man Who Knew Infinity

Srinivas Ramanujan was a brilliant Indian mathematician who made seminal contributions to Number Theory and the theory of continued fractions. Robert Kanigel's book, "The Man Who Knew Infinity" is a biography of Ramanujan.

The book talks about Ramanujan's life in quite some detail. Robert has provided a lot of color by traveling to the places involved, and deeply researching Ramanujan's life. The book has photographs of the places and maps of areas, making it easy to identify with the story. The biography is well balanced and impartial. If this was all the book contained, it would already be a worthy read.

What I found most interesting was the associated commentary on Indian society, values and the education system. Ramanujan was ignored by the Indian education system, largely because he refused to conform to its requirements. Ramanujan showed an early brilliance in Mathematics. But the system didn't care for exceptional performance in one field. Due to the inflexibility of the system, the talent of a brilliant mathematician was wasted. Having suffered through the Indian education system, I found the passages revealing. Even back in Ramanujan's day, the system was inflexible and idiotic. Many people recognized the inflexibility of the system, its arbitrary outcome, and the ill effect on genuine talent.

How much part did Indian society and customs play in Ramanujan's downfall? Ramanujan refused to alter his diet in cold, cloudy England. As a result, he got very little vitamin D, and suffered poor health. This is a problem that persists to this day: Indians who firmly adhere to a restricted diet suffer from problems in countries where an Indian diet is unsuitable. Ramanujan's wife was poorly treated by his mother, and this poor treatment led to misunderstanding and stress in Ramanujan's life. Would the outcome have been different if the Indian arranged marriage was not as stifling?

Ramanujan's life is full of questions. It makes me sad at the outcome. But more importantly, it makes me wonder.

Would a Ramanujan be possible today? Could a lower middle class boy with no talent for anything other than Mathematics be recognized as a genius? Could he even reach a point where he could seek collaboration or patronage from Western mathematicians?

It is a very sad tale, though one I think every Indian student should know. Indian students yearn for exposure to foreign education and worldwide recognition. This is one example of a person who got both, and yet he had a sad and lonely life. The outcome could have been so much different. Ramanujan was as good as Euler or a Gauss, according to people who worked with him. And yet his talent was squandered away. An early death, a lonely life full of struggle. And Ramanujan was lucky. Today, he probably would have no hope of success.


Image courtesy Wikipedia.

Monday, December 19, 2011

Book Review: The Male Brain & The Female Brain

Rather than waste your time with pop-culture books about men and women, how about read books with real science and insight this holiday season?

This is a review of two delightful books called "The Female Brain" and "The Male Brain" written by Louann Brizendine. Dr. Brizendine is a professor at UC San Francisco. Both books talk about the peculiarities of each brain from a scientific viewpoint. The books are scientifically accurate, and are accessible to a layperson with no background in neurology.

The books contain a lot of insight about the behavior of both men and women. For example, The Female Brain talks about how women's brain is highly geared towards social connections. It provides many examples to demonstrate this, and talks about the development of a female brain from a newborn to adult and to a mature brain. Along the way, you see the various changes in the brain. A lot of behavior changes accompany the development of the brain. This book made me understand the motivation behind the baffling behavior of friends and relatives.

The Female Brain was the earlier book. Recently, Dr. Brizendine wrote The Male Brain. The second book is as interesting and as revealing as the first. It talks of the development of the male brain through the years. There are many ways in which the adult male brain is different from the teenage male brain. Reading about the male brain allowed me to better understand how I will change as I grow older. It also allowed me to understand male toddlers behavior.

Both books are a quick read, they make cutting-edge scientific research accessible to everyone. This is scientific writing at its best.


Friday, October 07, 2011

Book Review: A Contract With God

I came across a copy of Will Eisner's, "A Contract With God" Trilogy at my library. This includes three books, "A Contract With God", "A Life Force", and "Dropsie Avenue". I had heard vaguely of this book, so I picked it up. I was expecting a good graphic novel.

I wasn't expecting a book of this lyrical depth and insight into human behavior.

These graphic novels are about life in a poor New York neighborhood starting near the Depression and going to more recent times.  It describes the life of poor migrants to America; their dreams, their lives, and how they escape the squalor of their world.

I am struck by the depth and force of some of the stories. A few stories in the first book were very hard-hitting and thought provoking. I stopped reading after a few stories because there was so much to mull about. It is a rare book which has this level of insight coupled with such beautiful art.

These books are not for children, though they may be okay for teenagers. They have plentiful sex and nudity, putting the "graphic" back in "graphic novel". Use your own discretion if you have children or teenagers around or are squeamish about sex.

The book can be ordered from online stores. Amazon has a hardbound copy for $20 which is a steal.

When Boston Brahmins were hoping that American classical would improve upon European Continental music, Jazz was busy changing the music world. In much the same way, Will Eisner's graphic novel is the epitome of American graphic art.

Completely out of the blue, it defined the graphic novel genre and gave readers and future novelists something original and beautiful.

Friday, September 16, 2011

Linux udev: two-factor USB token turned into a car ignition key

We use two-factor authentication at work. The one-time token generator looks a lot like an automobile key. It is easy to modify Linux to make a silly car noise when the token generator is plugged in. It turns your lame one-time token into a cool ignition key for your laptop.

Here is a video that shows what it looks like:

To do this for your device, create a shell script to make the sound of a car. I have created an audio file called car.mp3 containing the car sound. The shell script plays this file with mplayer. Record the sound of your car, or grab a file from the internet.
$ cat /root/car.sh
#!/bin/bash
# Play a silly car starting sound
mplayer /root/car.mp3 &
Now you need obtain the vendor ID. Disconnect your token generator and run this command:
$ udevadm monitor
Now insert your device. You will see an output like this:
KERNEL[] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1 (usb)
KERNEL[] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0 (usb)
KERNEL[] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/0003:1050:0010.0015 (hid)
UDEV  [] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1 (usb)
UDEV  [] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0 (usb)
UDEV  [] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/0003:1050:0010.0015 (hid)
KERNEL[] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/input/input33 (input)
UDEV  [] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/0003:1050:0010.0015/hidraw/hidraw0 (hidraw)
KERNEL[] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/input/input33/event13 (input)
KERNEL[] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/0003:1050:0010.0015/hidraw/hidraw0 (hidraw)
UDEV  [] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/input/input33 (input)
UDEV  [] add  /devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1:1.0/input/input33/event13 (input)
The part after the 0003: is your vendor ID. Of course, it will be different for you. Now create a udev rule to specify the action. This is what my rule looks like:
$ cat /etc/udev/rules.d/90-token.rules
# Make a silly sound like the starting of a car
SUBSYSTEM=="usb", ATTR{idVendor}=="1050", MODE="0664", GROUP="plugdev", RUN+="/root/car.sh"
That's it, you don't need to restart anything. If you have done it correctly, then the car sound will play every time you insert your key.

Tuesday, September 13, 2011

Android ARM Assembly: Calling Assembly from Android (Part 8)

This is part eight in a series on learning ARM assembly on Android. This part covers calling Assembly code from Android applications.

Part 1: Motivation and device set up
Part 2: A walk-through of a simple ARM assembly program
Part 3: Registers, memory, and addressing modes
Part 4: Gnu tools for assembly; GCC and GDB
Part 5: Stack and Functions
Part 6: Arithmetic and Logical Expressions
Part 7: Conditional Execution
=> Part 8: Assembly in Android code

The articles follow in series, each article builds on the previous.

Native Development Kit
You've written some assembly code, made it run real fast, and now you want to include it in an Android application. What's the advantage of running little assembly programs that can't use the full feature set available to Android? You need the Android Native Development Kit.

Download the Native Development Kit from the Android development page. Follow the instructions on that page to install it. Installation is little more than unzipping the file in the correct directory.

Sample Application
My sample application has three parts. The first is the most familiar part: this is the assembly source. This is in an assembly source file called jni/multiple.s. This code computes 10y for a given value y.
	@ This file is jni/multiple.s
	.text
	.align	2
	.global	armFunction
	.type	armFunction, %function
armFunction:
	@ Multiply by 10. Input value and return value in r0
	stmfd	sp!, {fp,ip,lr}
	mov	r3, r0, asl #3
	add	r0, r3, r0, asl #1
	ldmfd	sp!, {fp,ip,lr}
	bx	lr
	.size	armFunction, .-armFunction

The assembly code is called from a C stub. The C stub must have a very fixed name: Java_name_of_package_Class_function. This looks downright ugly but is required for Java to look up the correct function. I create a C stub to hold the strange name, and to accept the weird JNI arguments. You don't need to have a C stub, but it makes life easy.

The type jint is a java int that you can treat as a 32 bit int value. Other types are jboolean, jbyte, jchar, jshort, jlong, jfloat, jdouble, and jobject. Notice the signature of the JNI function: it accepts the environment, which is a JNIEnv pointer, and an arbitrary object. Finally, we have the input value, which is an integer. In its implementation, we call our ARM assembly function on the input. The return value is a jint, which indicates that we are returning an integer.
/* This file is jni/hello-jni.c */

#include <jni.h>

/* This stub calls the function. It helps to have a stub like this to
 * save yourself the hassle of defining the function call in
 * Assembly. */
jint Java_com_eggwall_android_assembly_AssemblyActivity_factorialJNI(
	JNIEnv* env, jobject object, jint input) {
	/* Try calling some local code */
	return armFunction(input);
}
Finally, there is a file that defines the sources in a Makefile. This is the jni/Android.mk file. It puts together the stub and the assembly code into a library called "hello-jni".
# This file is jni/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

# I want ARM, not thumb.
LOCAL_ARM_MODE := arm

# Name of the local module
LOCAL_MODULE    := hello-jni
# The files that make up the source code
LOCAL_SRC_FILES := hello-jni.c multiple.s

include $(BUILD_SHARED_LIBRARY)

The stub and the assembly input are compiled by calling the following command from the root directory of your project. This is the directory that contains jni/, src/, res/, ..etc. I am assuming the ndk is installed in /usr/local/android-sdk-linux_x86/android-ndk-r6b.
$ ls
AndroidManifest.xml  assets/  bin/  build.properties  build.xml  default.properties
gen/  jni/  libs/  local.properties  obj/  proguard.cfg  res/  src/
$ /usr/local/android-sdk-linux_x86/android-ndk-r6b/ndk-build
Compile arm    : hello-jni <= multiple.s
SharedLibrary  : libhello-jni.so
Install        : libhello-jni.so => libs/armeabi/libhello-jni.so

Finally, there is a Java source code to create the Activity in Android. This code creates an Android application. It extends Activity, and overrides the onCreate method. In this, it creates a TextView, which is a label, and then sets the contents of the label to the return value of the function. It defines a function called factorialJNI which accepts an integer input and returns an integer. It is marked as native, indicating that its implementation is not in Java.

Finally, a static initialisation loads the jni library that was defined in the XML file.
package com.eggwall.android.assembly; 
 
import android.app.Activity; 
import android.widget.TextView; 
import android.os.Bundle; 
 
public class AssemblyActivity extends Activity { 
	@Override 
	public void onCreate(Bundle savedInstanceState) { 
		super.onCreate(savedInstanceState); 
		// Create a new Textview 
		TextView  tv = new TextView(this); 
		// Print the multiple of 13 through assembly. 
		tv.setText("The multiple was: " + factorialJNI(13)); 
		setContentView(tv); 
	} 
	/**
	 * Multiply the number by 10.
	 * @param input, the number to be multiplied
	 * @return the multiple of the number
	 */ 
	public native int factorialJNI(int input); 
	/* This is used to load the 'hello-jni' library on application
	 * startup. The library has already been unpacked into
	 * /data/data/com.eggwall.android.AssemblyActivity/lib/libhello-jni.so at
	 * installation time by the package manager.
	 */ 
	static { 
		System.loadLibrary("hello-jni"); 
	} 

} 
That is a lot of code to run a single assembly function! But now that you've seen the overall structure, you can begin modifying it to run your own assembly code. This is not a good way to experiment with assembly programming, though. Assembly programs can be hard to debug and it helps to have good tools during development. I would recommend developing using emacs, gcc, gdb, and other GNU tools, just as before. When the code is working correctly, hook it into Android Java source. The Android NDK has some useful debugging facilities, but I would consider them options of last resort.
You can download the entire ARM Android assembly example as an Eclipse project here.

Speed versus Complexity
Just because you are calling assembly code does not automatically make your program faster. The Dalvik virtual machine runs most code fairly fast, and the effort to develop assembly code is not worth the minor improvement in code execution speed. Here are some reasons why you might want to use native code.
  1. Legacy code. You have a lot of existing code that you want to plug into Android.
  2. Optimised code. You have CPU-intensive code that has been carefully optimised.
Assembly code takes a longer to develop, more effort to maintain, and is difficult to port. There are few people who can read assembly code, so your code will be out of reach of many programmers.

A careful consideration of implementation speed and code complexity will lead you to the correct balance.
Things to try out
  1. Create a new function called factorial(int a) and its corresponding stub. Call it from Java.
  2. Create a new source file called factorial.s, and put the function in there. Modify jni/Android.mk to run it correctly.
  3. Try adding an input area, where a number is entered. Pass this number to the assembly source code, and print out its factorial.
My example builds upon the hello-jni example that ships with the NDK. You can read the other NDK samples for inspiration. You can learn more by reading the JNI reference. It covers the data types, and the various functions available from native code.