I've got an algorithm for computing the probability of a candidate in the presidential election winning a certain number of elector votes that looks like this (in pseudo-code):
define fold-into (probs votes prob) for i from 538 downto 0 probs[i] = probs[i] * (1 - prob) if (votes <= i) probs[i] = probs[i] + (prob * probs[i - votes])
So far so good. Now I'd like to add this function which can back out the effects of a single state:
define back-out (probs votes prob) for i from 0 to 538 if (= prob 1) probs[i] (i + votes) < probs.length ? probs[i + votes] : 0 else if (votes <= i) probs[i] = probs[i] - probs[i - votes] * prob probs[i] = probs[i] / (1 - prob)
Mathematically this works--I've actually implemented this in Common Lisp and when I use arbitrary-precision rational numbers it works perfectly. But when I use floating point numbers the computations in back-out get wildly out of whack. As best as I can tell this is because small errors introduced because (x * y) / y isn't necessarily exactly x get propagated throughout the whole array of probabilities and perhaps amplified by inaccuracies in the subtraction. (I can't just use rationals because I'm actually implementing this in Javascript whose only numeric type is double float.)
Is there some obvious way to write this so I can still use floating point numbers but have back-out work properly. I'd be happy to trade some precision for reversibility.