Currently, float numbers cannot be used to define probabilities. OK, this is Lea’s design to work with integer probability weights; changing
Lea.fromValFreqs to accept float requires special care to be sure that the sum of probabilities is exactly equal to 1 (see maybe a forthcoming ticket). However, an easier objective should narrow down Boolean distributions : the given float probability can be converted to a fraction n/d using Python Fractions module; then, the probability weights of (True, False) can be trivially calculated as (n, d - n).
To be general, the proposition is to change
Lea.BoolProb method (aliased as
B in Lea 2.2.0) so as to accept the same argument interfaces as Python’s Fraction class, including float, decimals and strings. For example, the following expressions should be strictly equivalent to define an event having a probability of 1/2:
flip = B(1,2) flip = B(0.5) flip = B('0.5') flip = B('1/2') flip = B(Fraction(1,2)) flip = B(Decimal(0.5))
This could even be extended with percentage notation:
flip = B('50%')
Warning : since float number literals can be different from their mathematical equivalent, the method inherits the same behavior as the Fraction class :
flip2 = B(0.2) # displayed as # False : 14411518807585587/18014398509481984 # True : 3602879701896397/18014398509481984
This is a bit weird but unavoidable. However, the drawback is mainly the display; this is not a big accuracy problem since the “error” made is not worst than the rounding errors obtained with float. This can be seen by checking for example that
Pf(B(0.2)) == 0.2. Note that this effect can be avoided by using strings, decimals or fractions, assuming that the given probabilities are provided in these flavors.
flip3 = B('0.2') flip3 = B(Decimal('0.2')) flip3 = B(Fraction(2,10)) # all these expressions give: # False : 4/5 # True : 1/5