Mathias Brandewinder on .NET, VSTO and Excel development, and quantitative analysis.
by Mathias 24. July 2010 17:35

When I moved to California a few years back, I soon realized that to get anything done in the Silicon Valley, you pretty much have to have a car. So, I purchased my first car. Fast forward today: I live in San Francisco now, and noticed that I am driving less and less. Bicycle is very convenient in my neighborhood, and I don’t have to commute to work on a daily basis. Which got me thinking – do I really need a car? Public transportation only is not an option, because coverage is too spotty, but what about using a car sharing service?

The 2 major services available in my area are ZipCar and CityCarShare; their pricing system is largely similar: they both:

  • charge by the hour of usage,
  • charge a higher cost over the week-end,
  • offer a discount for full-day rental,
  • have a pay-as-you-go option, and better rates with minimum commitment plans.

Both include gas, with one difference: ZipCar charges by the hour, whereas CityCarShare has a hybrid pricing, with a lower per-hour cost, and a per-mile cost.

By contrast, when you own a car, you

  • pay a large upfront investment (buying the car),
  • recoup some of the upfront cost if you resell eventually.
  • pay regular fixed costs (insurance, registration taxes, garage),
  • pay by the mile (gas),
  • pay some additional costs, like maintenance, which are somewhat linked to mileage.

In addition to that, you bear the risk that your car gets damaged or totaled in an accident.

More...

by Mathias 13. July 2010 14:45

Found on Epic Win FTW – The Sparklines of Excel 2010 are cool, but this is an Epic Win indeed. Pretty amazing, and another shining example of how Excel is used for lots of purposes, some of them probably never considered by Microsoft :)

MarioExcel

by Mathias 28. June 2010 13:14

A client asked me recently a fun probability question, which revolved around figuring out the probability of success of a research program. In a simplified form, here is the problem: imagine that you have multiple labs, each developing products which have independent probabilities of succeeding – what is the probability of more than a certain number of products being eventually successful?

Let’s illustrate on a simple example. Product A has a 30% probability of success, and product B a 60% probability of success. Combining these into a probability tree, we work out that there is an 18% chance of having 2 products successful, 18% + 12 % + 42% = 72% chance of having 1 or more products succeed, and 28% chances of a total failure.

SimpleBinaryTree

It’s not a very complicated theoretical problem. Practically, however, when the number of products increases, the number of outcomes becomes large, fairly fast – and working out every single combination by hand is extremely tedious.

Fortunately, using a simple trick, we can generate these combinations with minimal effort. The representation of integers in base 2 is a decomposition in powers of 2, resulting in a unique sequence of 0 and 1. In our simplified example, if we consider the numbers 0, 1, 2 and 3, their decomposition is

0 = 0 x 2^2 + 0 x 2^1 –> 00

1 = 0 x 2^2 + 1 ^ 2^1 –> 01

2 = 1 x 2^2 + 0 x 2^1 –> 10

3 = 1 x 2^2 + 1 x 2^2 –> 11

As a result, if if consider a 1 to encode the success of a product, and a 0 its failure, the binary representation of integers from 0 to 3 gives us all possible outcomes for our two-products scenario.

More...

by Mathias 13. June 2010 12:30

In my last post I explored how ExcelDNA can be used to write high-performance UDFs for Excel, calling .Net code without the overhead of VSTO. Using .Net instead of VBA for intensive computations already yields a nice improvement. Still, I regretted that ExcelDNA supports .Net up to 3.5 only, which puts the Task Parallel Library off limits – and is too bad  because the TPL is just totally awesome to leverage the power of multi-cores.

As it turned out, this isn’t totally correct. Govert  Van Drimmelen (the man behind ExcelDNA) and Jon Skeet (the Chuck Norris of .Net) pointed that while the Task Parallel Library is a .Net 4.0 library, the Reactive Extensions for .Net 3.5 contains an unsupported 3.5 version of the TPL – which means that it should be possible to get parallelism to work with ExcelDNA.

This isn’t a pressing need of mine, so I thought I would leave that alone, and wait for the 4.0 version of ExcelDNA. Yeah right. Between my natural curiosity, Ross McLean’s comment (have fun at the Excel UK Dev Conference!), and the fact that I really want to know if I could get the Walkenbach test to run under 1 second, without too much of an effort, I had to check. And the good news is, yep, it works.

Last time we saw how to turn an average PC into a top-notch performer; let’s see how we can inject some parallelism to get a smoking hot calculation engine.

More...

by Mathias 7. June 2010 10:23

Some time ago, I came across ExcelDNA, an open-source library designed to integrate .Net into Excel, via a  post by the Grumpy One, who described it as an interesting way to get Excel to talk to a compiled library. Sounds right down my alley, but I still managed to let 6 months pass until I finally tried it.

This reminded me of another post, by J-Walk this time, where he uses a random walk simulation in VBA to benchmark system performance. Back then, I ran the VBA code, and also the equivalent C# in a console app, out of curiosity: 11.38 seconds, vs. 2.73 seconds. Why not try the same experiment, and see if we can get the best of both worlds and bring some of the C# power into Excel via ExcelDNA?

So I created a Class Library, with the following method, a close equivalent to the VBA benchmark code:

public class Experiment
{
  public static string RandomWalk()
  {
     var stopwatch = new Stopwatch();
     stopwatch.Start();
     var position = 0;
     var random = new Random();
     for (var run = 0; run < 100000000; run++)
     {
        if (random.Next(0, 2) == 0)
        {
           position++;
        }
        else
        {
           position--;
        }
     }
     stopwatch.Stop();
     var elapsed = (double)stopwatch.ElapsedMilliseconds / 1000d;
     return "Position: " + position.ToString() + ", Time: " + elapsed.ToString();
  }
}

More...

Comments

Comment RSS