Follow by Email

Sunday, January 27, 2013

Greatness

People who change the world for the better do so because they are led to do it by their conscience. Sometimes it's intuition of what the future should look like. Sometimes it's belief in enriching people's lives. Sometimes it's a feeling about what makes the best experience. Sometimes it's the sense that they are meant to do this.

Once in a generation

When you find yourself in the presence of greatness, there is no way to ignore it. You are stricken by the clarity, the simplicity, and the inarguably correct statements. Their way of understanding is fresh and insightful. Imagine talking with a scientist or mathematician that changed the world: Euclid, Sir Isaac Newton, Karl Friedrich Gauss, Srinvasa Ramanujan, Nikola Tesla, or Albert Einstein! Imagine spending the afternoon in conversation with a great leader that forever changed the way society works, like King Solomon, Charlemagne, Emperor Augustus, or Abraham Lincoln. How I would like to sit and exchange musical ideas with a composer who forever changed the language of music such as Johann Sebastian Bach, Ludwig van Beethoven, John Lennon, or Paul McCartney (I still have that chance, since McCartney is still around!). And what could I do but sit in admiration at the brilliance of the artists and geniuses that forever affected style and ignited our imaginations, such as Leonardo da Vinci, Jan Vermeer, Vincent van Gogh, Pablo Picasso, or Maurits Cornelis Escher?

When I was an idealistic kid, I wondered about each of these people. I wondered what it would be like to be one of them. Was that even something I would want? How did they accomplish what they did? What sort of difficulties did they go through?

I had so many questions! And I was bursting with ideas also. How should I channel my creative energies? How would people look at my life's work?

It was an interesting motivation, to imagine myself in the shoes of someone great. Soon I forgot all about it, though, and immersed myself in number theory, computer programming, music, and analytic geometry.

I couldn't figure out how they did what they did. All I had was their work to look at. But, once exposed to it, I began to want to create my own music, write my own programs, investigate my own areas of mathematics. It was the start of a journey that I am still on today.

The weight

Talented people are also flawed. It's a bit like they carry the weight of their greatness that is always with them. This theme, with the ring of truth to it, has been expressed in fiction several times. For instance, Sir Arthur Conan Doyle's Sherlock Holmes, a beloved character adept at following clues and making deductions, was only the intense, enlightened sleuth when the game was afoot. During off times, he fell prey to cocaine addiction.

But is the theme of the tortured genius only around because it makes a better story? No.

Beethoven went deaf at the pinnacle of his fame. Einstein had his remorse at unleashing the atom and yet urged Roosevelt to build the atomic bomb. Van Gogh courted madness and tinnitus, even cutting off his ear. Newton's mother abandoned him, remarrying when he was only 3, which left him a furiously competitive, ruthless, and paranoid man who never had any romantic relationships of any kind. Ramanujan lived in squalor much of his life, starving at some points, and yet made discoveries of such genius that even today we are still struggling to decrypt them. When they tried to school him in modern mathematics, he spouted ideas at such a furious pace that it became useless to continue.

So let's look behind the curtain. What makes this happen?

Some people believe, once they have exerted great change on the world, that they deserve more than mere humans. This is a corrupting influence borne of pride, conceit, even megalomania. Such people may make great changes, but they are rarely truly great. This kind of flaw has brought us dictators, generals, and warriors.

Other people find, when they are working obsessively on a very hard project, that it is their destiny to solve the problem. Even that it is their duty to humanity to build it. I know that, once I am wrapped up in a problem, I often think of nothing else. It is this vacuum, however, that leads to the pathways of delusion. Still, you have to get your motivation from somewhere!

It's true that people can be driven to overcome their difficulties in life. If they are hurt by those around them, they might easily escape into a self-created world where they can feel comfortable. Such a world allows them to channel their genius. Or they might be disabled in some way. The compensating behavior for a disability can also become a framework for channeling their specific talents. This was certainly the case in Beethoven's career. In his silent world, he was no longer influenced by the local styles and instead created his own. Work can be a distraction from a painful existence. In Karl Friedrich Gauss' case, the death of his wife and son in 1809 led to a depression that he couldn't shake. Only his work could give him respite from the blackness.

Madness can be an influence that compels the genius to excel. There can be ideas in the head that are literally struggling to get out. Sometimes creation is the only therapy that helps. This was certainly the case with Vincent van Gogh. Nikola Tesla suffered from obsessive-compulsive disorder, finding it ever necessary to do things in threes and loathing to touch round objects.

Obsession can be a weight as well. Someone driven to solve a problem will exhibit behavior that is simply obsessive. This can drive them to forget about the responsibilities of life such as relationships, food, and sleep.

Producing greatness

To make a great thing is not just something that is done in a few minutes. The first thing you must do is to understand fully what the concept is for what you are making. And write it down. Clarify it. Make drawings. But never lose sight of what makes it great. Spend some time thinking about the concept. Figure out what its value is. Put the concept away and return to it later. It happens that the best things might come to you when you are driving, shaving, or even dreaming.

To produce it may take many, many tries. I have mentioned before that a large fraction of things tried often must simply be thrown away. This is the way it is when I am solving an unbounded, difficult problem with no general closed-form solution. Examples of this are common.

When Thomas Alva Edison was working on the light bulb, he tried 2000 different materials before he settled on the carbon filament. Isaac Newton spent a laborious eighteen months working on his Principia, itself the result of a decade of thought. In it, he developed the infinitesimal calculus, laboriously rewriting it in standard geometrical terms so astronomers of his day could understand it.

When producing a great product sometimes the product is not the only thing you have to produce. It is clear in many cases that you have to build a whole system of capabilities for it to live in. A context of usefulness.

For Edison, it wasn't enough to create the light bulb. He also had to create a generator of electricity so there was an ecosystem to support it. When Newton was writing his Principia, he had to incorporate and prove the work of people before him, like Johannes Kepler, whose second law, shown above, had already been empirically verified.

For Steve Jobs, it wasn't enough to produce the iPod, iPhone and iPad. He also had to build the iTunes media store, the app store, and several other web services. These are considered to be essential to the success of the iDevices.

You learn things along the way to creating and perfecting it. Some aspects of your product don't even occur to you until it gets used.

This wasn't the case with Albert Einstein, whose General Theory of Relativity finally provided the framework that superseded Newton's physical laws. While it was introduced in 1915 and correctly accounted for the procession of Mercury's perihelion (part of its orbital mechanics), it wasn't until 1959 and later that a systematic series of precision test had verified many of its provisions.

Productizing greatness

Most inventions are not so theoretical. With these, you get a chance to make sure they are right. And the best inventions, the ones that really have an effect, are productized.

If you are making a product, decide what it is that you want this product to be. Do you want it to be the lowest price product so you can sell a lot of them? Or do you want it to enrich the life of the person who buys it? You must deeply care what happens after they buy the product. It's not about what they will do with the product. It's about what the product will do for them. You must understand how it will transform their lives. How will they feel about the product? You must find a way to own the customer because they believe that their life is better. What you don't want to happen is for the user to not care at all about the product. Then it will just sit in a drawer. Instead of being on their person at all times.

To ship a product without first perfecting it is not a good thing. So, when developing the product, use it for everything. Keep on improving it and its main modes of use. Make sure that everybody using the product will appreciate it as a fundamental advancement. Ensure that it will change their lives as well as the nature of all products that come after it.

Fearlessness

Great people don't fear change. They embrace it, right? No, that misses the point! You should realize it's much more than that.

Change is their most valuable tool. Let's look at a key example that is already changing things.

In the recent conference call, when asked about the iPad, which appears to be cannibalizing Mac sales, Apple's CEO Tim Cook said this:
We’ve learned over the years not to worry about cannibalization of our own products. It’s much better for us to do that than somebody else to do it. The far, far bigger opportunity here is the 80 million to 90 million PCs that are being sold per quarter. There’s still over 300 million PCs being bought per year, and I think a great number of those people would be much better off buying an iPad or a Mac. So that’s a much bigger opportunity for Apple, and instead of being focused on cannibalizing ourselves, I look at it much more that it’s an enormous incremental opportunity for us.
Instead of fearing the cannibalization effect, he is using the effect to gain entry into a larger market. He's seeing the forest for the trees. Disruption thus becomes a useful tool and a cantilever to huge potential growth.

Disruption is necessary for change. So, if you want to change the world, think about what comes next, and how that process of disruption will occur.

Sunday, January 20, 2013

Hard Problems, Part 2

Some problems are hard nuts to crack. We have discussed this one before. Other problems are simply statically complex. As we will see, when things get hairy, there are still choices to make and techniques which work every time.

A statically complex problem has so many cases that it becomes daunting just to imagine a solution. This comes to mind because, of course, I am working on one of these problems right now. But I can't discuss it. Instead, we will look at another such problem and what it took to solve it.

In the 1980 I was working on a three-dimensional problem: rendering solid fractals. First Benoit Mandelbrot and then Loren Carpenter made famous the construction of mountains using fractal techniques. These were so-called plane-to-line functions, where the domain was a plane and the range was a line.

How to make nice fractals

In plainer English, you could create a mountain by making the height (z) a function of x and y. So, x and y are subdivided, and each time you subdivide, you add some random amount of z that depends upon the size of the x,y patch. In this way your mountain has a predictable fractal dimension. But now I would create such a thing by using Fourier transforms in the frequency domain: create a circular spot, transform it from the spatial domain to the frequency domain, randomize its phase, then transform it back into the spatial domain. This is shown in my blog post Textures, Part 2.

Once this technique is demonstrated, it becomes tempting to implement it. Which, of course, I did! I remember going to SIGgraph in 1980 and bringing a poster created at Calma on a Versatec raster plotter of some fractal mountains. Each facet was shaded using dither patterns, which I coded specifically for the poster. I presented it to Benoit Mandelbrot.

I'm sure Mandelbrot could've cared less about my rather amateurish fractal forgeries. There were so many people there, also. But I was undaunted and continued to play with fractals.

And so here comes the problem: what if you make a space-to-line function?

A space-to-line function is a function where w can be evaluated as a function of x, y, and z. Imagine that every point in space has a w value. And that w varies fractally. This construction can make clouds and rocks and all sorts of things!

So I decided to create a renderer that could display such a thing. The first way it could be displayed was simply to facet the zeroset of the surface, where w = 0. In a plane-to-line function, the zeroset z = 0 is simply a coastline. In a space-to-line function, the zeroset w = 0 is an actual surface of the object.

The problem can then be refined to this: how can you render the zeroset of the space-to-line function?

My answer to the problem was an early implementation of what is now called Marching Cubes. This technique was invented later by Lorensen and Cline and published in the 1987 SIGgraph proceedings. But I was using it in 1984. I won't say I invented it. Actually, it's a rather obvious solution.

My solution to the problem was to split the volume into small cubes. By evaluating the function for w at each corner of the cube, it will be found to be less than or equal to zero (a 0 bit) or greater than zero (a 1 bit). Since each cube has 8 corners, this was conveniently an 8-bit number.

Thus there were 256 cases to consider. That's a lot of cases, hence it was statically complex.

This is the first time I ever wrote a program to write the program to solve the problem. The program that generated the code for marching cubes was cloudtst.c, written in C on February 6, 1984, designed to run on a DEC VAX 11-780.

When a problem is this complex, it's hard to get every case right and consistent with every other case. This leads to the need to make sure each case is correct by having each case be generated by a program.

I categorized the eight bits into topological cases. And then I used the program to decide, for one of the 256 cases, which topological case it fell into. Then I mapped the solution for the topological case onto the 8-bit case.

Actually, the way I framed the problem was even more clever, since I allowed myself the luxury of subdividing a cube into 8 sub-cubes and faceting them. This meant that I could recursively subdivide the volume I was rendering, only subdividing it where it needed to be subdivided. This would minimize the total number of facets output and thus cut down on the time to render the fractal volume.

Code that writes code

It sounds a bit recursive, doesn't it? But there are several advantages to writing code that writes code. I will discuss them now.

The first and most obvious thing is this: if a program writes the code, then you won't have to. This is advantageous because there might be a lot of code to write. With a lot of complicated cases. And a program can make sure that each case is correct. So you won't have to. All you have to make sure of is that the program that analyzes the cases will get the right answer in each case.

The second advantage happens when you are generating a lower-level language. The program can see to all the details. This is useful when optimizing something. Lower-level languages are inherently more efficient because they are closer to the machine they run on. There is no hidden complexity. Each instruction is atomic. If you have to break each operation into smaller operations, the program can do it slavishly for you. This is the reason that people write compilers.

The third and most important advantage is also useful to you. To fix bugs, even those occurring in several cases, you only have to change the program that writes the code, not all the cases. This turns out to be characteristic of the code-writing-code process. Each bug in the generated code can be attacked one-by-one in the generating code. And eventually a perfectly correct program is the result. This can be done without tediously fixing each case in the generated code one at a time. Actually, many cases in the generated code can come from one part of the program, so a single bug fix in the generating program can fix several bugs in the generated program. This illustrates the power of this approach.

What language should you use? You have two choices to make. First, you choose a language to write the generating program in. This is usually a high-level language. One that you can work in with extreme freedom and ease. This can be something as utilitarian as C or ripe in data structures like C++. It can also be Python, a common choice nowadays. The second choice is the language used for the program you are generating. This should generally be chosen for its efficiency. Sometimes you do not have a choice. For instance, I have written code that generates programs in various forms of assembler, in C, in fragment shaders, and in OpenCL.