Skip to content

Commit

Permalink
Merge pull request kelltom#139 from AdamAtPurpose/main
Browse files Browse the repository at this point in the history
Add chisquared distribution to Random Util
  • Loading branch information
kelltom committed Mar 12, 2023
2 parents 3ebcd79 + 3038208 commit 639c1a5
Showing 1 changed file with 53 additions and 3 deletions.
56 changes: 53 additions & 3 deletions src/utilities/random_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import random
import secrets
from datetime import datetime
from typing import List
from typing import List, Union

import numpy as np

Expand Down Expand Up @@ -158,6 +158,30 @@ def fancy_normal_sample(lower_bound, upper_bound) -> float:
return truncated_normal_sample(lower_bound, upper_bound, mean=mean)


def chisquared_sample(df: int, min: float = 0, max: float = np.inf) -> float:
"""
Generate a random sample from a Chisquared distribution. Contraining the maximum will produce abnormal means.
Args:
df: Degrees of freedom (approximately the average result).
min: Minimum allowable output (default is 0)
max: Maximum allowable output (default is infinity).
Returns:
A random float from a Chisquared distribution.
Examples:
For 100,000 samples of chisquared_sample(average = 25, min = 3):
- Average = 24.98367264407156
- Maximum = 67.39469215530804
- Minimum = 3.636904524316633
- Graphed: https://i.imgur.com/9re2ezf.png
"""
if max is None:
max = np.inf
while True:
x = np.random.chisquare(df)
if x >= min and x <= max:
return x


def random_chance(probability: float) -> bool:
"""
Returns true or false based on a probability.
Expand All @@ -177,8 +201,34 @@ def random_chance(probability: float) -> bool:
if __name__ == "__main__":
import matplotlib.pyplot as plt

samples = [truncated_normal_sample(0, 600) for _ in range(100000)]
# Truncated normal distribution
samples = [truncated_normal_sample(lower_bound=0, upper_bound=100) for _ in range(100000)]
print("Truncated normal distribution")
print(f"Average output = {sum(samples) / len(samples)}")
print(f"Maximum output = {max(samples)}")
print(f"Minimum output = {min(samples)}")
print()
plt.hist(samples, bins=600)
plt.title("Truncated normal distribution")
plt.show()

# Fancy normal distribution
samples = [fancy_normal_sample(lower_bound=0, upper_bound=100) for _ in range(100000)]
print("Truncated normal distribution")
print(f"Average output = {sum(samples) / len(samples)}")
print(f"Maximum output = {max(samples)}")
print(f"Minimum output = {min(samples)}")
print()
plt.hist(samples, bins=600)
plt.title("Fancy normal distribution")
plt.show()

# plot the samples
# Chi-squared distribution
samples = [chisquared_sample(df=25) for _ in range(100000)]
print("Chi-squared distribution")
print(f"Average output = {sum(samples) / len(samples)}")
print(f"Maximum output = {max(samples)}")
print(f"Minimum output = {min(samples)}")
plt.hist(samples, bins=600)
plt.title("Chi-squared distribution")
plt.show()

0 comments on commit 639c1a5

Please sign in to comment.