Astronomy, astrophysics, computation and culture

October 24, 2009

My friend Sam had a hunch that he was suffering more suck-outs on the online poker site Full Tilt Poker than chance would predict. Fortunately, the Full Tilt client can be configured to store the history of every hand you see on the site into a series of text files. Over lunch, I wrote a quick-and-dirty Python script to parse through the log files and pull out situations of interest.

I've refined the script a little bit over the past day, and thought it would be worth sharing. Copy a whole bunch of Full Tilt hand history files (names like "FT20091024 - $<blahblahblah>.txt") into the same directory as the program, and run "python fulltilt.py > out.csv". It globs onto all .txt files in the current directory and searches them for hand history.

The program makes use of poker-eval and pypoker-eval, both of which must be installed correctly for it to work. These exist as packages for Debian, Red Hat, and several other Linux flavours. I got them to install on a Mac, with a little chicanery with .pc files. It also uses cPickle, which might not be included with really old versions of Python.

Our program only looks at hands where two players are entirely committed before the flop (ie: one player all-in, the other calls, and everyone else folds). In our testing data set, we have 832 such hands against which we've tested. The program will identify each of those hands, and compute the odds of a win/loss/tie for the favoured hand. It will also tell you the probability of the actual outcome and classify the hands into more generic categories (ie: 'Ah Kh' -> 'AK s') for sorting and analysis in your favorite spreadsheet.

cPickle is used to store the results of the odds evaluation. Basically, whenever I calculate the odds of a particular hand combination, I cache the results. I then save the cache to file and use it next time to improve performance. The improvement is substantial: our test set takes ~7.5 minutes on the first run and about 48 seconds on subsequent runs.

Sam is a quantum information theorist / serious mathematician and will be running a statistical analysis on our results so far. I'll link to that when it's published. So far, we have no opinion on the fairness of Full Tilt's shuffle.

If you're interested in this, we would love to have either your Full Tilt Hand History, or the results of running our program on your Hand History. More data will allow us to make a stronger statistical statement on the fairness of Full Tilt's shuffle. Please email me if you're interested: alf@freealf.com.

The program is released under a BSD license. That means you can do basically anything with it as long as you credit us, and that we provide no warranty. It could be easily adapted for hand history on other poker sites, for example.

February 24, 2009

So the SciPy package for Python is full of lots of goodness. Be very careful using the eigh() routine to get eigenvalues, though. There's a "gotcha" buried in it.

The syntax is:

(eigenvalues, eigenvectors) = eigh(matrix)

This returns an array of eigenvalues and a 2D array of eigenvectors (each eigenvector consists of many components).

And there's the gotcha. Let's say you want the nth eigenvalue and eigenvector. I would write:

eigenvalues[n]eigenvectors[n]

And I would be horribly wrong. The eigenvectors and eigenvalues do share an index, but the index on the eigenvector is SECOND column:

eigenvectors[:,n]

Seriously WTF.

Update: It turns out that this is due to eigh() being part of LAPACK, which is a non-Python library (Fortran?) that has a different internal storage model for 2D arrays. So possibly less WTF, but still dangerous as all hell.