An alternative to binopdf using the NAG toolbox for MATLAB

March 1st, 2010 | Categories: math software, matlab, NAG Library, programming | Tags:

The Problem

A MATLAB user came to me with a complaint recently.  He had a piece of code that made use of the MATLAB Statistics toolbox but couldn’t get reliable access to  a stats toolbox license from my employer’s server.  You see, although we have hundreds of licenses for MATLAB itself, we only have a few dozen licenses for the statistics toolbox.  This has always served us well in the past but use of this particular toolbox is on the rise and so we sometimes run out which means that users are more likely to get the following error message these days

??? License checkout failed.
License Manager Error -4
Maximum number of users for Statistics_Toolbox reached.
Try again later.
To see a list of current users use the lmstat utility or contact your License Administrator.

The user had some options if he wanted to run his code via our shared network licenses for MATLAB (rather than rewrite in a free language or buy his own, personal license for MATLAB):

  • Wait until a license became free.
  • Wait until we found funds for more licenses.
  • Buy an additional license token for himself and add it to the network (235 pounds +VAT currently)
  • Allow me to gave a look at his code and come up with another way

He went for the final option.  So, I sat with a colleague of mine and we looked through the code.  It turned out that there was only one line in the entire program that used the Statistics toolbox and all that line did was call binopdf.  That one function call almost cost him 235 quid!

Now, binopdf() simply evaluates the binomial probability density function and the definition doesn’t look too difficult so you may wonder why I didn’t just cook up my own version of binopdf for him?  Quite simply, I don’t trust myself to do as good a job as The Mathworks.  There’s bound to be gotchas and I am bound to not know them at first.  What would you rather use, binpodf.m from Mathworks or binopdf.m from ‘Dodgy Sysadmin’s Functions Inc.’?  Your research depends upon this function remember…

NAG to the rescue!

I wanted to use a version of this function that was written by someone I trust so my mind immediately turned to NAG (Numerical Algorithms Group) and their MATLAB toolbox which my employer has a full site license for.  The NAG Toolbox for MATLAB has a function called g01bj which does what we need and a whole lot more.  The basic syntax is

[plek, pgtk, peqk, ifail] = g01bj(n, p, x)

From the NAG documentation: Let X denote a random variable having a binomial distribution with parameters n and p. g01bj calculates the following probabilities

  • plek = Prob{X<=x}
  • pgtk = Prob{X > x}
  • peqk = Prob{X = x}

MATLAB’s binopodf only calculates Prob(X=x) so the practical upshot is that for the following MATLAB code

n=200;
x=0;
p=0.02;
y=binopdf(x,n,p)

the corresponding NAG Toolbox code (on a 32bit machine) is

n=int32(200);
x=int32(0);
p=0.02;
[plek, pgtk, y, ifail] = g01bj(n, p, x);

both of these code snippets gives

y =
    0.0176

Further tests show that NAG’s and MATLAB’s results agree either exactly or to within what is essentially numerical noise for a range of values. The only thing that remained was to make NAG’s function look more ‘normal’ for the user in question which meant creating a file called nag_binopdf.m which contained the following

function pbin = nag_binopdf(x,n,p)
   x=int32(x);
   n=int32(n);
   [~,~,pbin,~] = g01bj(n,p,x);
end

Now the user had a function called nag_binopdf that behaved just like the Statistics toolbox’s binopdf, for his particular application, argument order and everything.

It’s not all plain sailing though!

As good as the NAG toolbox is, it’s not perfect.  Note that I placed particular emphasis on the fact that we had come up with a suitable, drop-in replacement for binopdf for this user’s particular application.  The salient points of his application are:

  • His input argument, x, is just a single value – not a vector of values. The NAG library wasn’t written with MATLAB in mind, it’s written in Fortran, and so many of its functions are not vectorised (some of them are though).  In Fortran this is no problem at all but in MATLAB it’s a pain.  I could, of course, write a nag_binopodf that looks like it’s vectorised by putting g01bj in a loop hidden away from the user but I’d soon get found out because the performance would suck.  To better support MATLAB users, NAG needs to write properly vectorised versions of its functions.
  • He only wanted to run his code on 32bit machines. If he had wanted to run it on a 64bit machine then he would have to change all of those int32() calls to int64().  I agree that this is no big deal but it’s something that he wouldn’t have to worry about if he had coughed up the cash for a Mathworks statistics license.

Final thoughts

I use the NAG toolbox for MATLAB to do this sort of thing all the time and have saved researchers at my university several thousand pounds over the last year or so through unneeded Mathworks toolbox licenses.  As well as statistics, the NAG toolbox is also good for optimisation (local and global), curve fitting, splines, wavelets, finance,partial differential equations and probably more.  Not everyone likes this approach and it is not always suitable but when it works, it works well.  Sometimes, you even get a significant speed boost into the bargain (check out my interp1 article for example).

Comments are, as always, welcomed.

Blog posts similar to this one

  1. Matt
    March 23rd, 2010 at 21:15
    Reply | Quote | #1

    Just discovered your blog. Looks interesting — I’m gonna start following.

    Loved the line “What would you rather use, binpodf.m from Mathworks or binopdf.m from ‘Dodgy Sysadmin’s Functions Inc.’?”