Seiter's Blog

Mind of the machine

Subscribe to RSS feed

Sticky post

About This Blog

,

This blog is a collection of thoughts and ideas which belong expressly to me, Kevin Seiter. Subject matter ranges from martial arts to poetry, music, physics, my personal life, the state of mankind and of course, software. Enjoy your stay.

Simcha Ariella

Many years ago, when I was just a boy, I met a young girl named Miriam Rubin. She was this brilliant, witty girl with crazy wonderful curly hair like Felicity. She had a playful, wicked smile that knew too much. I somehow managed to convince her to date me and we had a fun, childish love. She stole my first kiss by dragging me out into the stairwell during some school dance. She was bold even then, young as we were.

She invited me with her family out to a camp they had one summer. We went on walks and went to a fruit picking of some kind, although I can't remember if it was apples or something else. We shared a side cabin with her younger sister while her parents shared the main one. Her father had built a kayak entirely by himself and we tested it out on the lake. I remember us being happy there.

One day she had some pain in her abdomen and her family looked into it. It turned out to be more serious than anyone hoped. She went to some hospital a few hours from where we lived and I would occasionally take a day or two off school, drive up with her family and spend time with her. I would sit next to her bed and hold her hand. The hospital had crazy good chocolate pudding and we would sit on the couch outside her room and share one. I remember her asking me if I was okay, being away from my friends and school and all. Even then, she was thinking of me.

There was a period where we thought she was better and I was young and a boy and utterly stupid. One day, we had planned to meet at her house and hang out. She had a wonderful family and a beautiful home and we would sit in her living room next to this huge doll house that they had and talk. I forgot about our plans and played some soccer with friends instead, so she left me. I'm entirely sure that there are other reasons that I simply don't remember. Again, I was young and a boy and utterly stupid.

The next many years were not great for us. Some time later, when we were both in college, she contacted me out of the blue. We agreed to meet during a trip I was making to Plattsburgh to catch up with some friends. She told me about her life and her continued health struggles. She told me that she wanted to tie up all of her loose ends. I apologized to her for anything I had ever done to hurt her but she said I had nothing to be sorry for. She said we were both young and it was a hard time to be a couple. Even then, she was being gracious. We hugged and exchanged contact info. We talked on and off for a bit after that. She was going to have a surgery that would potentially cause her to lose some part or most of her memory. I didn't hear from her again after that.

We used to walk along the shore of Lake Champlain. There was a walking bridge across two pieces of land. On each side there were monuments and cleared grass. We spent many hours talking there. Some of my best memories are from that time and those places. Nonetheless, I was a very small part of her life. We were very young when we were together and she went on to do many things that I knew nothing about. I know she was married and I know she was in love and loved. We were young and our time together was many, many years ago.

Which is why I don't understand why it hurts so much knowing that she is gone. I hope that she was at peace, surrounded by people that she loved and that loved her. I still think of her from time to time. I'll miss you Miriam.

Simple Software?

, , ,

It was about 50 degrees outside and breezy in Half Moon Bay, California when I overheard three people discussing robots over lunch.

"So we'll buy the robot for about 50k, then we'll need about 20k more for setup and configuration. That covers pretty much everything except software, which will cost infinity."

They all laughed and one of them, who looked like the guy who paid the bills, rolled his eyes and nodded as if this joke weren't all that far from the truth.

And of course, it isn't. I've written about software for many years now with varying degrees of accuracy. As I've gotten older and experienced more projects, it has become entirely evident that software has a lot of big problems. There are many paradigms out there which promise all kinds of benefits, some of which can be realized. Unfortunately at the end of the day, complex systems are complex. And while that doesn't sound like much, it's altogether meaningful when architects around the world fall prey to silver bullet solutions, shortcuts and other methodologies that often cause more harm than good or lead customers to unreasonable expectations about results.

So what are we to do about this? How can we bring "infinity" to something more reasonable? Here are my suggestions, which are the product of experience and of nothing else.

1. Complex systems are complex: The first mistake any architect can make is to assume he/she fully understands any complex system. I'm not talking about Hello World, or your senior project. I'm talking about multi-component systems. I'm talking about moving parts and integrated systems. Many architects will go up to a white board and draw a bunch of boxes which correspond to subsystems. Since they can see all of the boxes, they assume they understand the system as a whole. I walk up to the board and say, "Draw the lines." Please draw the lines between systems and while you're at it, explain how every line works. And while you're at that, tell me what happens to the system when a line doesn't work as expected. Tell me what happens when 75% through the project, someone draws a new line. Great architects not only recognize that they don't fully understand the complex system, they embrace it. And in this way, they learn to prepare for the unknown.

2. Hire great engineers: Time after time, this is the moral of the story. Again and again, this single factor can determine the success or failure of major components of a system. A good engineer is not one with an incredibly lengthy title. A good engineer is not the hot-off-the-press graduate and it's not the guy with 15 years of experience. A great engineer only concerns himself with the task of solving problems and if he/she has any of the above as well, fantastic. When you interview your potential engineers, ask them to describe something they are proud about having done. "Completed XYZ project" and "Met XYZ deadline" are fine answers but they aren't great answers. "I figured out how to integrate a 15 year old cold-fusion app with a modern web-service using SOAP and a few hundred lines of code I wrote." Bingo.

3. Don't blame your customer: Isn't it easy to blame the customer? A couple useless words fly out of your mouth and you feel better about the fact that you're changing something about your system yet again. Unfortunately, this does nothing to help solve the problem. Customer problems are complex and it would take me ten pages to talk about them in their entirety. I'm also completely unqualified to do so. What I can say is that I've seen this mentality in many organizations and in many engineers. I've seen it in project managers and I've seen it in myself. The truth is, this mentality does nothing to help you accomplish your goal. There are entire books devoted to managing customer expectations and project managers tend to be better at this than engineers do. The best thing you can do as an engineer is to take changes in stride and try to engineer your software to be flexible. Requirements are driven by customers and customers are human. Accept this fact and you'll find yourself in a much happier, healthier engineering state. And your customer will notice.

Related: To Engineer or Not to Engineer

Steve Jobs, 1955-2011

, , ,

Steve Jobs has passed away. Love him or hate him, he changed our world.

Rest in peace.

http://www.apple.com/stevejobs/
http://en.wikipedia.org/wiki/Steve_jobs

Clojure!

, , , ...

Some people were surprised to know that I love Clojure apparently. Take a look at my quick sort and compare it to my python and java variant and it will become obvious why this language rocks socks.

(defn quicksort [list]
  (if (< (count list) 2) list ;if the list has 0 or 1 items, return
    (let [
          pivot (first list) ; our pivot will be the first item
          rl (rest list) ; compare against everything else
          lt #(< % pivot) ; our less than predicate
          gte #(>= % pivot)] ; our greater than equal predicate
    (lazy-cat
      (quicksort (filter lt rl)) ; recurse on filtered less
      [pivot]
      (quicksort (filter gte rl)) ; recurse on filtered greater than equal
    ))))

Make sure we give this bad boy a quick test:

(def mylist (shuffle (range 1 25))) ; make some shufled list of items
(println mylist) ; take a look before sorting
(time (quicksort mylist)) ; time our three runs
(time (quicksort mylist)) ; the first should take the longest
(time (quicksort mylist)) ; magic!

And the results, of course:

[1 2 13 20 19 21 3 22 17 14 16 7 18 10 11 5 12 4 6 8 15 24 9 23]
"Elapsed time: 1.975864 msecs"
"Elapsed time: 0.109321 msecs"
"Elapsed time: 0.107011 msecs"
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)

Java Purity and Version 7

, , , ...

With Java 7 coming out in just a hair over two weeks, I thought I'd take some time to look into the language features that were being added. The main items of interest from a language perspective are:

  1. Strings in switch statements
  2. Type inference for generics (Diamond)
  3. Underscores in numbers
  4. Try with resources

Strings in switch statements is fine and arguably should have been in Java a long time ago. You can now:

    public static void switchOnString( String string )
    {
        switch( string )
        {
            case "kevin":
                System.out.println( "In Kevin" );
                // fall through
            case "rob":
                System.out.println( "In Rob" );
                break;
            default:
                System.out.println( "In Default" );
        }
    }

Type inference for generics is a pretty-print enhancement. It makes otherwise verbose generics half as much so.

// before
Map<Integer,String> myMap = new HashMap<Integer,String>();

// after
Map<Integer,String> myMap = new HashMap<>();

Unfortunately, there is no support for initializing using Diamond when the types have to be inferred.

// Diamond lets us do this cleanly
Map<Integer,Map<Integer,String>> myMap = new HashMap<>();

// sadly, we can't do this, the new HashMap has to be fully qualified
myMap.put(new Integer(5), new HashMap<>());

Underscores in numbers is another aesthetic change, allowing erasure of underscores from numbers so that formatting can exist in the code.

long phoneNumber = 555_555_1212L;
double someCash = 12_526_123.45;

Finally, the try-with-resources. Now this one is actually something interesting. It basically allows the programmer to delegate the responsibility of closing resources to Java. Closing resources has always been kind of a pain, requiring try blocks inside finally blocks and so forth. Here's the flavor of the new syntax.

try(
   BufferedReader br = new BufferedReader(new FileReader(new File(fileName)))
){
// do something
}
catch(Exception ex)
{
// catch some exception as a consequence of doing something
}

Any time you add a language enhancement like this, however, you obscure some of the purity of the language. You lose a bit of the "what you see is what you get" feel. For example, if you declare more than one resource in the try, in what order are they processed? Let's find out. We'll build a quick object that conforms to the new AutoCloseable interface.

public class MyAutoCloseable implements AutoCloseable
{
    private String name;
    
    public MyAutoCloseable( String name )
    {
        this.name = name;
    }
    
    public void close()
    {
        System.out.println( "Closing:" + name );
    }
}

Now let's write a trivial case to test the ordering.

    try( 
        MyAutoCloseable mac1 = new MyAutoCloseable( "1" );
        MyAutoCloseable mac2 = new MyAutoCloseable( "2" );
        MyAutoCloseable mac3 = new MyAutoCloseable( "3" );
    )
        {
            System.out.println( "Do something..." );
        }
        catch( Exception ex )
        {
            System.out.println( "Exception:" + ex.getMessage() );
        }

This results in predictable, stack based resolution of the resources.

Do something...
Closing:3
Closing:2
Closing:1

But what if one of these close operations excepts? Will it continue to properly close the other two resources? If so, what if two of the closes except? Will you be able to see both exceptions? It's simple to find out by modifying our class.

public void close()
    {
        System.out.println( "Closing:" + name );
        if( name.equals("2") ) throw new NullPointerException("Closing resource two is exploding!");
        if( name.equals("3") ) throw new NullPointerException("Closing resource three is exploding!");
    }

Running this new condition results in very interesting output indeed.

Do something...
Closing:3
Closing:2
Closing:1
Exception:Closing resource three is exploding!

So the good news is that java is smart enough to make sure the resources have close() invoked regardless of whether or not other resources fail. The bad news is that you can lose exception information. The stack tied with this exception doesn't contain the second exception in the tree either. (As it shouldn't) This could actually happen with the old syntax as well but this syntax obfuscates the issue.

Moral of the story, new language features are great. Use them to your advantage as much as possible. But never forget that your responsibility as a competent developer is not only to make things work but to understand how they work.

Models and The Scientific Method

, ,

When we observe the world, we do so via a model generated by our minds. Our senses absorb data in various forms and pass that information on to our brain, which then processes this information and organizes it in some meaningful way. The concept of a mental model is not a new one. The idea that there is a disconnect between what we sense and what really exists has been around for ages. In Steven Hawking's new book "The Grand Design", he talks about these models and what they mean for Scientific Theory, which brings me to the subject of this post, which is somewhat different from the subjects Steven describes in said book.

The Scientific Method is based on the notion that one can perform observations to prove or disprove a concept. This notion is rooted in the belief that there is a level of purity involved in the process of measurement that is not involved in other forms of inference. The implication is, of course, that observation is the highest form of posit validation. The idea of a model doesn't apply strictly to human observation either, rather, even a device that performs a measurement does so with some set of assumptions. In that case, these assumptions form the foundation of the model from which measurements are made.



But observation only gets us so far. In fact, when you apply this paradigm to electrons, for example, you end up getting some very strange results. The Heisenberg Uncertainty Principle, for example, states that as one increases ones certainty with respect to the position of a particle, one decreases ones certainty with respect to the momentum of the particle. This principle is manifest entirely in the process of measurement. I'm willing to argue that this principle arises out of the application of a classical process (The Scientific Method) to a non-classical (or quantum, if you'd like) concept. (Particles)

Another outcome of this line of thought is demonstrated by a thought experiment called Schrödinger's cat. The result of this thought experiment is that one must accept that at a given time prior to observation of the state of the cat, it is both alive and dead. Statistics can be built around this that properly predict the results of experiments of this sort. These statistics are resoundingly proven to be accurate. But is this really an accurate picture of the universe?



In order to determine the answer to that question, we are left with the tools provided by The Scientific Method. But these tools all require us to perform a measurement. I'm willing to argue that this is the real problem with the current state of physics. Physicists around the world today are struggling to find a "Theory of Everything", a unified theory of physics. I argue that they are looking in the wrong places. The problems that arise when trying to unify Quantum Theory with Relative Theory are caused by the fact that The Scientific Method is a process formed within the classical model of the universe.

So, is there another process we can use to verify posits about the nature of reality which is framed in a non-classical model? Can we determine the laws of nature without using the process of observation and measurement? That is, in my opinion, what the real question on everyone's mind should be.

Layered Functional Interpretation

, ,

Let's say for a moment you have a simple set of functions which all accept similar arguments and affect them in fundamentally similar ways. Take, for example, the following functions:

function applyEarth(int damage,Object target)
{target.life.interpretDamage(damage, DamageType.EARTH);}

function applyFire(int damage,Object target)
{target.life.interpretDamage(damage, DamageType.FIRE);}

function applyWater(int damage,Object target)
{target.life.interpretDamage(damage, DamageType.WATER);}

Let's go on to say that our Object target is going to be affected by three invocations of any of these three functions. Your task is to write a interpreter that will determine the optimal invocations for applying these functions. In this scenario, any of the combinations will be as effective as the others. Simple enough. (Fire,Fire,Fire, for example, is equivalent to Earth,Earth,Earth and Earth,Fire,Water)

Now let's say that our Object target has a certain set of properties:

Object target{EARTH_RESIST=5;FIRE_RESIST=4;WATER_RESIST=3;}

These properties affect the amount of damage target receives when it's life total interprets damage in obvious ways. (Earth resist lowers the effective amount of earth damage, for example but has no affect on water damage)

Now it is obvious the there is a clearly optimal invocation layering. (Water,Water,Water) In this particular scenario, your interpreter is fairly simple because it can quickly determine every set of invocations as well as every resultant based on the Object's properties. Unfortunately, this strategy quickly falls apart.

What happens when you Object has 500 properties? (Linear scale problem) What if you have 500 invocations? (Linear scale problem) Or worse, what if your object has a property that says, every time I'm hit with fire damage, my earth resist decreases. (Exponential scale problem) The fact of the matter is that any brute-force effort here fails sort of miserably. What we can do, however, is build classification sets.

A classification set is simply a way of saying cause and effect. A classification set can have any size and as the size of these sets increases, the computational requirement also increases. (Exponentially) Here's an example of the classification sets for our original scenario.

{Fire->(Damage-Fire Resist)}
{Earth->(Damage-Earth Resist)}
{Water->(Damage-Water Resist)}
{Fire->(Damage-Fire Resist),Fire->(Damage-Fire Resist)}
{Fire->(Damage-Fire Resist),Earth->(Damage-Earth Resist)}
{Fire->(Damage-Fire Resist),Water->(Damage-Water Resist)}
{Earth->(Damage-Earth Resist),Earth->(Damage-Earth Resist)}
...

Using classification sets you can group certain types of properties together and then use brute-force on the classifications instead of the properties themselves. This minimizes the computational requirement but diminishes the efficacy of the interpreter. The fact of the matter is that as you add fundamentally different properties to a system, you significantly increase the complexity of the interpretation.

The moral of the story is that the next time you are playing WoW and you think to yourself, "Why is it that I can only have 12 buffs at a time?" you will now know why. You will also know why even though there may be hundreds of spells and abilities, they all affect targets in fundamentally similar ways. (50 different spells that do fire damage, for example, can be examined as a single classification set)

The INCREDIBLE Review

, , , ...

It's thin, sleek and powerful. But is it really Incredible?

Let me start by saying that I am a lover of all things electronic. I've been scoffed at for the ownership of a ZUNE and I've been scoffed at for the ownership of an iTouch. But this morning at 7AM, I picked up one of the first HTC Droid INCREDIBLE handsets from the Verizon Wireless store in town and I doubt I'll get scoffed at for carrying this piece of fine art around. But 12 hours in, the honeymoon stage is already over and it is obvious that while Google and HTC have done an excellent job, there is still some work to be done.



If you don't know already, the HTC Incredible is the latest in a slew of super-powered Android phones to hit the market. It sports a 1GHZ Snapdragon processor, 8GB of internal memory, a ridiculously vibrant touch-screen and a whopping 8 megapixel camera. It comes with Android 2.1 and HTC's Sense UI on top to smooth out the rough edges. All of this is railed on Verizon's CDMA network which is arguably the best in the nation.

All of that sounds good on paper but how well does it all come together? The answer is a complex one. The INCREDIBLE has a terrible habit of performing feats of pure phone genius one moment and then doing things in the next that simply don't make sense. This process isn't more evident than in the voice recognition features of Android 2.1.

Press a button, say something like "Papa Johns pizza, Syracuse New York" and viola, the INCREDIBLE gives you exactly what you're looking for. The voice recognition is so good in fact, that I kept increasing the complexity of my verbiage just to see how far I could take it. The software finally failed when I threw, "terrible transvestites titillate triple tempura" at it. In all honesty though, it is without a doubt the best speech recognition software I've ever had the pleasure of using.

Unfortunately, after finding Papa Johns spot on, you have to click no less than five buttons to get directions to said location. It's cumbersome, unnecessary and simply annoying. This is a theme that repeats itself throughout the software. The hardware isn't without it's problems either. Sure the back of the phone looks cool; unfortunately the camera lens is the highest level item on the surface and doesn't come with a lens cap, so any time you set your phone on a surface face-up, the lens rubs against it. Only time will tell if the material is affected by this or if it can stand up to it just fine but it's a simple design flaw nonetheless.



Hardware: The HTC Incredible is simply put, a hardware work of art. It's fast, sleek and put together very well. I'd love to see a lens cap though.

Software: Android + Google Cloud + App Marketplace = Awesome. Better control of the software stack would allow a more seamless user experience though and certain features simply feel clunky. This is contrasted by apps that look beautiful, run great and put other apps of their type on other devices to shame. It is difficult as a user to reconcile these two facts.

Overall: The HTC Incredible is a fantastic phone with a fantastic carrier. While it is hard to find many flaws with it, there are some, just as there are with any device. Users looking for a powerful smart-phone on Big Red have an easy decision to make. Those of you who are less concerned about carrier might want to hold your cash a few months and see what the EVO turns out like as well as other offerings coming out this year from Microsoft, Dell and others. For more detailed reviews, head over to any of the links below.


http://www.engadget.com/2010/04/19/droid-incredible-review/
http://gizmodo.com/5520071/htc-droid-incredible-review-more-like-impressive
http://www.infosyncworld.com/reviews/cell-phones/htc-droid-incredible/10909.html

My Problem with Non-Linearly Complex Divergences

I've been struggling with something I read recently about mapping of gravity divergences using test particles and I'm wondering if any of you have any ideas how it works or even better, can explain why the way I'm understanding it is incomplete or incorrect. To wrap up the problem tersely, let's imagine for a moment we have two particles of mass > 0 in a simple reference frame, as shown:



Now what I read was that you can create a mapping of the gravitational divergences using these so-called "test" particles. You simply imagine them, they have zero mass, and you use them to determine the gravitational effect at that position, which is simply the sum of the gravitational vectors between the test particle and all gravitational objects in the frame. Using a series of these particles, you can map a gravitational field of a system. Take test particle I for example, and this follows:



My problem with this is that the resultant, -IAB, is a vector. Vectors have magnitude. This magnitude creates a resultant acceleration which is based on the mass of the object the vector is applied to. For example, when you jump off a tall building you rush toward the earth but it makes little effort to rush toward you, even though Newton's Laws tell us that the gravitational force on you from the earth is the same as the gravitational force on the earth from you. (They are equal and opposite.) Since this vector is divided by the mass of the object, and we are so very light in comparison to the mass of the earth, we rush toward the earth more than it rushes toward us.

Having said that, our test particle can't be applied to the resultant vector -IAB because it's mass is zero. As the test particle's mass approaches zero, it's velocity approaches infinity.(Note that velocities > c are not allowed!) Also, you can't simply give your test particle mass > 0 because then it will cause an acceleration on A and B which will move them at t = t + 1. This results in a mapped field which does not correctly represent the actual field you are attempting to investigate.

My gut feeling is that the notion of the test particle as a means of creating a gravitational map is flawed. In a minor way, sure (since you can give i an arbitrarily small m > 0 such that the acceleration on A and B is negligible) but flawed nonetheless. It seems to me this is similar to the uncertainty principle, in a way. You can know the masses of the particles in the system (I think?) but you cannot properly map their gravitational field without affecting it in some, however minor, way.

Someone correct me if I'm wrong?
June 2012
S M T W T F S
May 2012July 2012
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30