I am developing an equity calculator and using free Equilab for algorithmic inspiration. I noticed an algorithmic quirk in Equilab that I cannot explain and was hoping you guys might have some ideas.
This is using the "Enumerate all" radio button. Start by setting the first range to a particular hand (eg AsKd) and the second range to "random", then click Evaluate. Notice the instant evaluation time. This is clearly using a precalculated lookup table for heads up preflop equity between various hand groups.
There are two easy ways to make Equilab unable to use this lookup table. One is to set a dead card. If you set one dead card (requires View->Dead cards) and click Evaluate, notice that this takes quite a long time, ~25sec on my machine. This makes sense as Equilab must now iterate all 2million+ possible boards and evaluate the ranges on each one.
However, another way to short circuit the lookup table is to add a 3rd range set to a fixed particular hand, say QhJc. Evaluating this scenario is much faster than with dead cards, taking about one second on my machine. It's clearly doing SOME work (compared to using the lookup table), but it's much faster than calculating with a dead card. Adding the dead card back in slows it to a crawl once again. And of course two dead cards are just as slow.
This does not make sense to me. Naively, calculating equities with two dead cards or with two cards used up in a 3rd range should take essentially the same amount of time since you would have to iterate the same boards and ranges in both situations, and yet we see that with Equilab's implementation, these situations have vastly different performance characteristics. This implies that Equilab is using some algorithmic trickery to speed up enumerating a random range against two fixed hands in some way that becomes invalidated as soon as a dead card is introduced. I suspected some sort of further lookup table scheme that still functions mulitway (indeed, setting any number of remaining seats with fixed hands is still fast), but I can't imagine how such a thing might work. Any ideas?
Another idea is that perhaps the developers were just lazy and did not update the dead card code path along the way, so it is missing some key optimizations that were added to the mainline enumeration path during development. I've noticed some odd bugs and quirks in Equilab, so it wouldn't surprise me if this was the explanation. But if some highly optimized multiway equity algorithm really exists that depends on having no dead cards, I want to know about it!