Skip to content

Minor code cleanups for statistics #19873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 3, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 7 additions & 76 deletions Lib/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,13 @@ def _normal_dist_inv_cdf(p, mu, sigma):
return mu + (x * sigma)


# If available, use C implementation
try:
from _statistics import _normal_dist_inv_cdf
except ImportError:
pass


class NormalDist:
"Normal distribution of a random variable"
# https://en.wikipedia.org/wiki/Normal_distribution
Expand Down Expand Up @@ -1111,79 +1118,3 @@ def __hash__(self):

def __repr__(self):
return f'{type(self).__name__}(mu={self._mu!r}, sigma={self._sigma!r})'

# If available, use C implementation
try:
from _statistics import _normal_dist_inv_cdf
except ImportError:
pass


if __name__ == '__main__':

# Show math operations computed analytically in comparsion
# to a monte carlo simulation of the same operations

from math import isclose
from operator import add, sub, mul, truediv
from itertools import repeat
import doctest

g1 = NormalDist(10, 20)
g2 = NormalDist(-5, 25)

# Test scaling by a constant
assert (g1 * 5 / 5).mean == g1.mean
assert (g1 * 5 / 5).stdev == g1.stdev

n = 100_000
G1 = g1.samples(n)
G2 = g2.samples(n)

for func in (add, sub):
print(f'\nTest {func.__name__} with another NormalDist:')
print(func(g1, g2))
print(NormalDist.from_samples(map(func, G1, G2)))

const = 11
for func in (add, sub, mul, truediv):
print(f'\nTest {func.__name__} with a constant:')
print(func(g1, const))
print(NormalDist.from_samples(map(func, G1, repeat(const))))

const = 19
for func in (add, sub, mul):
print(f'\nTest constant with {func.__name__}:')
print(func(const, g1))
print(NormalDist.from_samples(map(func, repeat(const), G1)))

def assert_close(G1, G2):
assert isclose(G1.mean, G1.mean, rel_tol=0.01), (G1, G2)
assert isclose(G1.stdev, G2.stdev, rel_tol=0.01), (G1, G2)

X = NormalDist(-105, 73)
Y = NormalDist(31, 47)
s = 32.75
n = 100_000

S = NormalDist.from_samples([x + s for x in X.samples(n)])
assert_close(X + s, S)

S = NormalDist.from_samples([x - s for x in X.samples(n)])
assert_close(X - s, S)

S = NormalDist.from_samples([x * s for x in X.samples(n)])
assert_close(X * s, S)

S = NormalDist.from_samples([x / s for x in X.samples(n)])
assert_close(X / s, S)

S = NormalDist.from_samples([x + y for x, y in zip(X.samples(n),
Y.samples(n))])
assert_close(X + Y, S)

S = NormalDist.from_samples([x - y for x, y in zip(X.samples(n),
Y.samples(n))])
assert_close(X - Y, S)

print(doctest.testmod())