Archive for February, 2009

MapReduce in C# using LINQ

I recently remembered reading this article by Dare Obasanjo (Functional Programming in C# 3.0: How Map/Reduce/Filter can Rock your World) a long while ago, which was partly a response to Joel Spolsky’s article (Can Your Programming Language Do This).  In that article, Dare maps the map/reduce/filter functions to the following Linq equivalents:

  • map -> Enumerable.Select
  • reduce -> Enumerable.Aggregate
  • filter -> Enumerable.Where

At the time, I hadn’t really had a business need to play with Linq aside from casual curiosity … all of the projects at work were using other techniques for data access.  But more recently, we’ve been using linq more and more, and I experimented with how a rewrite of a feature might look if it had been written using a functional programming style with LINQ.

My experience with that reminded me of something I had read even longer ago, Google’s famous MapReduce paper (MapReduce: Simplified Data Processing on Large Clusters). Now, most of that paper deals with how they distribute the load across a large cluster of computers.  But near the very beginning, they have some small examples of the types of problems that could easily be solved by mapreduce, and even a sample pseudocode implementation of one of those programs.

map(String key, String value):
    // key: document name
    // value: document contents
    for each word w in value:
        EmitIntermediate(w, "1");

reduce(String key, Iterator values):
    // key: a word
    // values: a list of counts
    int result = 0;
    for each v in values:
        result += ParseInt(v);
    Emit(AsString(result));

Note the structure of the various inputs and outputs … in particular, the output of map (which serves as the input to reduce).  It’s a key along with an iterator of values that matched that key.  That sounds exactly like what GroupBy does.  Check out the description from this article:

The standard query operators also include the GroupBy operator, which imposes a partitioning over a sequence of values based on a key extraction function.

Using linq, I can implement the mapreduce program described above:

var wordOccurrences = words
                .GroupBy(w => w)
                .Select(intermediate => new
                {
                    Word = intermediate.Key,
                    Frequency = intermediate.Sum(w => 1)
                })
                .Where(w => w.Frequency > 10)
                .OrderBy(w => w.Frequency);

as you can see … based on google’s definition of MapReduce, I think that Dare was incorrect in asserting that select maps to map (no pun intended), and aggregate maps to reduce.  In this example, the GroupBy method is acting as the map, while the Select method does the job of reducing the intermediate results into the final list of results.

The obvious caveat here is that this isn’t distributed, it will run locally in memory.   But even without the massive scaling that google’s mapreduce data center can provide, it can be useful to think of problems in this mindset.  And when the parallel extensions for linq are finally released, you might even be able to easily take advantage of multiple cores.

Comments (3)

InstantRails: First Impression

So on a lark, I installed InstantRails last night to see what all the hubbub was about.  I grabbed the latest (v2.0) and set to following some getting started steps from a book. 

Unfortunately, it seems that things aren’t quite as easy as just downloading and getting started.  Just trying to start up a sample/demo site responded with a bunch of errors … so I ended up having to do a bunch of updates to the environment.  These are the commands I had to run to get to a point that I could run “rails demo”

gem update rails –include-depencies
gem install activerecord
gem install rake
gem install actionpack
gem install actionmailer
gem install activeresource
gem update –system

I mean, it was ultimately not too bad, but at the same time, not a great first impression.  So far, lots of the same concepts that I’ve gotten used to in ASP.NET MVC seem like they found their roots in RoR … so it’s good to see them in their original context.

Comments (1)

Converting a Lifecam VX-5000 to see IR

So I’ve recently become interested in building a multitouch table such as the one seen here.  All of the techniques for building them involve having a webcam that can see infrared, so I figured that was a first step.

The guys over at NUI Group have a great writeup and list of webcams that are easily modifiable for this purpose: http://wiki.nuigroup.com/Cameras

Despite that list, I ended up getting a Microsoft LifeCam VX-5000.  The first thing I did to test was put together the simple test rig described here (MT Mini).  Very ingenious to simply invert the webcam image so it looks like it’s just IR light.  That worked really well.

So I set about modifying the camera.  Since I couldn’t really find anything online about modifying this model, I decided to post the steps in case it helps anyone else.  Sadly, I neglected to take pictures during the process, so you’ll have to rely on my vivid descriptions :-P

  1. Remove the silver ring on the front of the camera.  It’s stuck on using a small amount of adhesive so you just kind of have to pry it off.
  2. Unscrew the two screws keeping the surrounding lens cover and remove it.
  3. Unscrew the 3 screws and remove the entire front face.  The live messenger button on top will also fall off once you remove it.
  4. Unscrew the lens, it had a small amount of some sort of adhesive, which I just had to scratch off with a knife.
  5. Remove the screws from the circuit board and remove it from the bottom casing.
  6. Unscrew the additional lens housing from the bottom of the board.  This is what’s covering the IR filter.
  7. Once you remove that, you’ll have to remove the IR filter (it looks like it reflects redish light).  It was glued on so I ended up having to kind of crack the ir filter to remove it piece by piece.
  8. Install the IR-Pass filter … of course, this is where everyone seems to hack it, since lots of guides online tend to suggest using exposed film negative.  I cut out two pieces and put them in place of the IR filter.
  9. With that done, rebuild everything you’ve just taken apart until the camera is put back together.

I used the TBeta from NUI Group for testing: http://tbeta.nuigroup.com/

And it worked pretty well … I was able to get a remote control and use it to track the IR LED that lights up when you press a button.  The next step will be to start building the FTIR surface.  Stay tuned :-P

Comments (2)

ONETUG XNA Presentation Files

As promised, here are the presentation files from the ONETUG presentation the other night.

http://codecube.net/bloguploads/ONETUG_XNA_20090129.zip

The .zip contains both the powerpoint slides that I used in the presentation, and the two sample projects I developed during the presentation.

  • TwoD
    • This sample shows some basic 2D techniques for dealing with sprites on the screen.
    • Simple velocity calculations for locomotion (Position += Velocity)
    • Orbiting one sprite around another
    • Launching projectiles at a steady pace.
    • Sprite helper class that makes it easy to position sprites around the world.
    • I didn’t use it in the sample, but I also have a ResourcePool datatype that makes it easy to reuse entities without having to reallocate new memory.  This is actually a really useful technique, I’d like to write about it in a separate blog post.
  • ThreeD
    • First Person Shooter style Camera.  It’s a GameComponent, so you just have to add it to the Components collection to use it.
    • Used the QuadDrawer class from the 3D Audio sample.  I added a few useful overloads and methods to let you draw billboarded sprites and the floor.
    • ModelSprite that makes drawing sprites and positioning it about the world easy.
    • Used the Sky box processor from the Generated Geometry sample.
    • All the helper classes (QuadDrawer, ModelSprite, and Sky) all know the camera, so they can make use of its view and projection matrix.

Thanks to everyone who showed up :-)

Comments