Optimizations and Improvements
To compute the correct CDF values execute the following commands:
round(float(cdf(0.004, 1)), 2)
0.95
cdf(0.004, 1).limit_denominator(100)
Fraction(94, 99)
round(float(cdf(10.83, 1)), 3)
0.001
cdf(10.83, 1).limit_denominator(1000)
Fraction(1, 1000)
round(float(cdf(3.94, 10)), 2)
0.95
cdf(3.94, 10).limit_denominator(100)
Fraction(19, 20)
round(float(cdf(29.59, 10)), 3)
0.001
cdf(29.59, 10).limit_denominator(10000)
Fraction(8, 8005)
Given X^2 and a number of degrees of freedom, our CDF function produces the same
results as a widely used table of values.
Here's an entire row from a X^2 table, computed with a simple generator expression:
chi2= [0.004, 0.02, 0.06, 0.15, 0.46, 1.07, 1.64, 2.71, 3.84,
6.64, 10.83]
act= [round(float(x), 3) for x in map(cdf, chi2, [1]*len(chi2))]
act
[0.95, 0.888, 0.806, 0.699, 0.498, 0.301, 0.2, 0.1, 0.05, 0.01,
0.001]
The expected values are as follows:
[0.95, 0.90, 0.80, 0.70, 0.50, 0.30, 0.20, 0.10, 0.05, 0.01, 0.001]
We have some tiny discrepancies in the third decimal place.
What we can do with this is get a probability from a X^2 value. From our example
shown previously, the 0.05 probability for six degrees of freedom has a X^2 value
12.5916
round(float(cdf(12.5916, 6)), 2)
0.05