Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d222134

Browse files
authored
Minor accuracy improvements in statistics (gh-157380)
1 parent 3308360 commit d222134

1 file changed

Lines changed: 15 additions & 17 deletions

File tree

Lib/statistics.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,15 @@
138138
from decimal import Decimal
139139
from itertools import compress, count, groupby, repeat
140140
from bisect import bisect_left, bisect_right
141-
from math import hypot, sqrt, fabs, exp, erfc, tau, log, fsum, sumprod
142-
from math import isfinite, isinf, pi, cos, sin, tan, cosh, asin, atan, acos
141+
from math import hypot, sqrt, fabs, exp, erfc, log, fsum, sumprod
142+
from math import isfinite, isinf, pi, sin, cosh
143+
from math import sinpi, cospi, tanpi, asinpi, acospi, atanpi
143144
from functools import reduce
144145
from operator import itemgetter
145146
from collections import Counter, namedtuple, defaultdict
146147

147148
_SQRT2 = sqrt(2.0)
148-
_SQRT2PI = sqrt(tau)
149+
_SQRT2PI = float.fromhex('0x1.40d931ff62706p+1') # Correctly rounded sqrt(2*pi)
149150
_random = random
150151

151152
## Exceptions ##############################################################
@@ -820,8 +821,8 @@ def deco(builder):
820821

821822
@register('normal', 'gauss')
822823
def normal_kernel():
823-
sqrt2pi = sqrt(2 * pi)
824-
neg_sqrt2 = -sqrt(2)
824+
sqrt2pi = _SQRT2PI
825+
neg_sqrt2 = -_SQRT2
825826
pdf = lambda t: exp(-1/2 * t * t) / sqrt2pi
826827
cdf = lambda t: 1/2 * erfc(t / neg_sqrt2)
827828
invcdf = lambda t: _normal_dist_inv_cdf(t, 0.0, 1.0)
@@ -840,12 +841,10 @@ def logistic_kernel():
840841
@register('sigmoid')
841842
def sigmoid_kernel():
842843
# (2/pi) / (exp(t) + exp(-t))
843-
c1 = 1 / pi
844-
c2 = 2 / pi
845-
c3 = pi / 2
846-
pdf = lambda t: c1 / cosh(t)
847-
cdf = lambda t: c2 * atan(exp(t))
848-
invcdf = lambda p: log(tan(p * c3))
844+
recip_pi = 1 / pi
845+
pdf = lambda t: recip_pi / cosh(t)
846+
cdf = lambda t: 2.0 * atanpi(exp(t))
847+
invcdf = lambda p: log(tanpi(p * 0.5))
849848
support = None
850849
return pdf, cdf, invcdf, support
851850

@@ -869,7 +868,7 @@ def triangular_kernel():
869868
def parabolic_kernel():
870869
pdf = lambda t: 3/4 * (1.0 - t * t)
871870
cdf = lambda t: sumprod((-1/4, 3/4, 1/2), (t**3, t, 1.0))
872-
invcdf = lambda p: 2.0 * cos((acos(2.0*p - 1.0) + pi) / 3.0)
871+
invcdf = lambda p: 2.0 * cospi((acospi(2.0 * p - 1.0) + 1.0) / 3.0)
873872
support = 1.0
874873
return pdf, cdf, invcdf, support
875874

@@ -906,7 +905,7 @@ def _triweight_invcdf_estimate(p):
906905
sign, p = (1.0, p) if p <= 1/2 else (-1.0, 1.0 - p)
907906
x = (2.0 * p) ** 0.3400218741872791 - 1.0
908907
if 0.00001 < p < 0.499:
909-
x -= 0.033 * sin(1.07 * tau * (p - 0.035))
908+
x -= 0.033 * sinpi(2.14 * (p - 0.035))
910909
return x * sign
911910

912911
@register('triweight')
@@ -921,10 +920,9 @@ def triweight_kernel():
921920
@register('cosine')
922921
def cosine_kernel():
923922
c1 = pi / 4
924-
c2 = pi / 2
925-
pdf = lambda t: c1 * cos(c2 * t)
926-
cdf = lambda t: 1/2 * sin(c2 * t) + 1/2
927-
invcdf = lambda p: 2.0 * asin(2.0 * p - 1.0) / pi
923+
pdf = lambda t: c1 * cospi(0.5 * t)
924+
cdf = lambda t: 1/2 * sinpi(0.5 * t) + 1/2
925+
invcdf = lambda p: 2.0 * asinpi(2.0 * p - 1.0)
928926
support = 1.0
929927
return pdf, cdf, invcdf, support
930928

0 commit comments

Comments
 (0)