Enable defining Boolean distribution with float

Issue #35 closed
Pierre Denis
repo owner created an issue

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

Comments (8)

  1. Log in to comment