Monday, 13 May 2013

std::enable_shared_from_this is ugly, ugly, ugly

I've just had to use the rather esoteric (but fundamental) std::enable_shared_from_this template base class from C++11. Now I feel rather depressed.

Thursday, 2 May 2013

Lies, damned lies, and Ayn Rand

Sometimes the talk pages of Wikipedia are more entertaining and informative than the articles themselves. Take the talk page for Ayn Rand's 1957 novel "Atlas Shrugged". It contains the following comments:
Is it worth mentioning that the most recent reference in popular culture is the 2007 video-game Bioshock? It explored many of the same themes and includes other references such as character names (Atlas, Andrew Ryan).

The BioShock franchise has released a total of 3 games by now, with aggregate sales of 9 million copies. These sales appear to be slightly above those for the book itself (8 million), secured over a shorter time span and without extensive give-aways by a well-healed nonprofit. The video games probably deserve their own (short) section. 
The game is currently mentioned (though scarcely) in the Wikipedia article itself, along with a reference to an Economist article pointing out recent peaks of Amazon sales of the novel. The print article suggests a link between negative financial news and spikes in the sales figures:


Perhaps it's just low-brow me, but no-one seems to have mentioned that the original BioShock game was released for Xbox 360/PC in August 2007 and Playstation 3 in October 2008. These dates spookily coincide with the spikes in sales of Ayn Rand's book. The Economist article doesn't even mention BioShock.

Heck, I even went out and bought "Atlas Shrugged" on the strength of playing and enjoying Bioshock. But then, I'm not an economist...

Wednesday, 9 January 2013

Gratuitous Aphorism #6

Constants invariably aren't.

Sunday, 23 December 2012

Typo T-Shirt


ty·po : /ˈtīpō/ (noun) An acronym for Take Your Pantries Off

Saturday, 15 September 2012

Movie Budgets

I've been fascinated by the movie business. Who invests such large amounts of cash up front to make a movie? How much of a gamble is it?

I've been looking at a movie budgets table published by The Numbers. It lists over 3600 (mainly US and British) movies and estimations of their budgets and grosses. It includes some unreleased and recently-released films for which the grosses are unavailable or unreliable. For the purposes of this discussion, I've excluded films before 1946 and after 2011, and those that have no income information whatsoever. That left me with 3512 movies.

I bucketed the films by logarithmic budget:

Budget
Movies
Losing Movies
Total Budget
Total Profit
ROI
Up to $9,999
7
2 (29%)
$40,100
$3,063,092
7739%
$10,000 to $99,999
33
9 (27%)
$1,102,000
$302,684,325
27567%
$100,000 to $999,999
155
57 (37%)
$66,670,000
$1,242,723,838
1964%
$1,000,000 to $9,999,999
858
309 (36%)
$3,876,788,054
$14,419,232,185
472%
$10,000,000 to $99,999,999
2256
781 (35%)
$78,584,771,638
$123,049,314,610
257%
$100,000,000 and over
203
26 (13%)
$28,762,300,000
$57,812,766,174
301%
Totals
3512
1184 (34%)
$111,292,671,792
$196,829,784,224
277%

Even from such a simple table, there are a number of interesting observations:
  1. Very few low-budget films make it to the cinema. Those that do generally make huge profits (speaking relatively).
  2. Only two-thirds of cinema releases recoup their budgets (modulo Hollywood accounting).
  3. The vast majority of releases are in the $10M to $100M bracket; but this has the lowest return on investment (ROI, calculated here as [Budget+Profit]÷Budget).
  4. Nine-figure budget movies are much less likely to lose money.
We can also plot ROI (y-axis) against budget (x-axis):


This produces some interesting outliers:
  • "A" is Paranormal Activity (2007) which supposedly cost $15,000 but grossed $200M worldwide. That's over one million percent ROI.
  • "B" is My Date with Drew (2004) which supposedly cost $1,100 to make, but grossed over $180,000. It's the cheapest movie I could find with a successful cinema release.
  • "C" is Pirates of the Caribbean: At World's End (2007), the most expensive film on the list at $300M. It grossed over $660M.
  • "D" is Evan Almighty (2007), the most expensive film ($175M) on the list that failed to make a profit, but only just.
  • "E" is Nomad (2005), a film in which the Kazakh government invested $40M. It only made $79,123 at the US box office. [Actually, these figures are slightly out-of-date: the film made $3M in international releases]
  • "F" is Ed and His Dead Mother (1993) which cost $1,800,000 but only made $673 (or $1097 depending on your sources) at the box office.
Also of note:
  • Mars Needs Moms (2011) which only recouped $40M of its estimated $150M costs, making it the greatest absolute dollar loser on the list.
  • Avatar (2009) made a profit of $2547M on its costs of $237M.
  • Rocky (1976) which made $225M off of its $1M costs. This the best ROI for a movie costing at least $1M.
The naive conclusion seems to be either (i) make lots of movies for about $100,000 in the hopes that one of them is a huge success; or (ii) persuade people to give you more than $100,000,000 thereby guaranteeing a sure-fire success.

Friday, 7 September 2012

Map Demo 3.0

For several years on-and-off, I've been working on a demo to showcase compression techniques and to try to sate my curiosity in cartography and country-based statistics. I've just uploaded the latest incarnation: Version 3.0.


This is a bog-standard 32-bit Windows application with all the data embedded within it. Compiling the supplied source code with Visual C 2008 produces an executable of just 118KB; compressing this with UPX brings it down to 84KB, mainly through instruction-stream compression.

The pertinent features are: 
  1. Coastline and border data for 214 countries (including South Sudan and Montenegro);
  2. Over one hundred statistics and codes for each country;
  3. Vector-drawn flags for each country;
  4. 128 map projections;
  5. Choropleth statistically mapping;
  6. The ability to save the data table as a CSV file (significantly larger than the executable!); and
  7. The ability to save maps and flags as Windows Enhanced Metafiles.

Monday, 20 August 2012

RGB/HCL in HLSL

The HCL colour space by M. Sarifuddin and Rokia Missaoui (not to be confused with CIELCH) is another colour space that tries to improve on HSL and HSV. It is a cylindrical space which means that, for an accurate implementation, trigonometric functions are necessary. One interesting feature is that it tries to adjust the hue metric to be more perceptually meaningful using piecewise linear interpolation.

Here's the optimised HLSL code to convert from linear RGB:

float HCLgamma = 3;
float HCLy0 = 100;
// HCLmaxL == exp(HCLgamma / HCLy0) - 0.5
float HCLmaxL = 0.530454533953517;

float3 RGBtoHCL(in float3 RGB)
{
  float3 HCL;
  float H = 0;
  float U, V;
#if NO_ASM
  U = -min(RGB.r, min(RGB.g, RGB.b));
  V = max(RGB.r, max(RGB.g, RGB.b));
#else
  float4 RGB4 = RGB.rgbr;
  asm { max4 U, -RGB4 };
  asm { max4 V, RGB4 };
#endif
  float Q = HCLgamma / HCLy0;
  HCL.y = V + U;
  if (HCL.y != 0)
  {
    H = atan2(RGB.g - RGB.b, RGB.r - RGB.g) / PI;
    Q *= -U / V;
  }
  Q = exp(Q);
  HCL.x = frac(H / 2 - min(frac(H), frac(-H)) / 6);
  HCL.y *= Q;
  HCL.z = lerp(U, V, Q) / (HCLmaxL * 2);
}


All components are scaled to fit into the expected [0,1] range.

The weird-looking statement with "frac()" terms is performing the piecewise adjustment of hue.

I'm very happy with this code as it is considerably faster than a simplistic transliteration of the reference code that Sarifuddin Madenda was good enough to send me.

However, the reverse transformation is far from perfect and needs more work to reduce the branching nature of the algorithm:

float HCLtoRGB(in float3 HCL)
{
  float3 RGB = 0;
  if (HCL.z != 0)
  {
    float H = HCL.x;
    float C = HCL.y;
    float L = HCL.z * HCLmaxL;
    float Q = exp((1 - C / (2 * L)) * (HCLgamma / HCLy0));
    float U = (2 * L - C) / (2 * Q - 1);
    float V = C / Q;
    float T = tan((H + min(frac(2 * H) / 4, frac(-2 * H) / 8)) * PI * 2);
    H *= 6;
    if (H <= 1)
    {
      RGB.r = 1;
      RGB.g = T / (1 + T);
    }
    else if (H <= 2)
    {
      RGB.r = (1 + T) / T;
      RGB.g = 1;
    }
    else if (H <= 3)
    {
      RGB.g = 1;
      RGB.b = 1 + T;
    }
    else if (H <= 4)
    {
      RGB.g = 1 / (1 + T);
      RGB.b = 1;
    }
    else if (H <= 5)
    {
      RGB.r = -1 / T;
      RGB.b = 1;
    }
    else
    {
      RGB.r = 1;
      RGB.b = -T;
    }
  }
  return RGB * V + U;
}


The multiple if-statements could be rationalised (binary search style) but I can't help thinking there's some simple trigonometric identity that can be utilised to eradicate them completely.