Reputation: 2103
In passing someone had suggested to me that I could use half normal distribution in python to set min and max points using 0 to infinity: halfnorm.rvs()
The 0 seems to cut off the min, however I have no idea what to do with the infinity.
I would like to do a number generator from 0 - 15 within a normal distribution, but having a hard time finding a function that doesn't go over the max or below the min due to the nature of distribution limits.
Upvotes: 2
Views: 3559
Reputation: 1
I recently ran in to a similar issue.
To get around this and keep my min/max in reasonable bounds I just created some if statements to catch any numbers that went above the real min and max.
if value <0:
value = abs(value)
elif value >15:
value - 15 = diff
value = 15-diff
This was close enough for me.
Upvotes: -1
Reputation: 4148
I had just answered similar question here. I'll copy answer here as I think this question title is much more informative:
You can use uniform distribution with boundaries "translated" from normal to uniform space (using error function) and convert it to normal distribution using inverse error function.
import matplotlib.pyplot as plt
import numpy as np
from scipy import special
mean = 0
std = 7
min_value = 0
max_value = 15
min_in_standard_domain = (min_value - mean) / std
max_in_standard_domain = (max_value - mean) / std
min_in_erf_domain = special.erf(min_in_standard_domain)
max_in_erf_domain = special.erf(max_in_standard_domain)
random_uniform_data = np.random.uniform(min_in_erf_domain, max_in_erf_domain, 10000)
random_gaussianized_data = (special.erfinv(random_uniform_data) * std) + mean
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].hist(random_uniform_data, 30)
axes[1].hist(random_gaussianized_data, 30)
axes[0].set_title('uniform distribution samples')
axes[1].set_title('erfinv(uniform distribution samples)')
plt.show()
Upvotes: 0
Reputation: 1914
I would try to use the beta-distribution: https://en.wikipedia.org/wiki/Beta_distribution. It's quite simple (e.g. to integrate) and capable of fitting typical reaction time distributions.
Now the question is how to sample this efficiently for fixed α and β parameters ... scipy
has done it for us: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.beta.html
Edit: Motivated by the comment and curiosity, here an example, plotting the histogram of 10 samples á 1000 values:
from scipy.stats import beta
from numpy import histogram
import pylab
max_time = 3
min_time = 0.5
a, b = 2, 7
dist = beta(a, b)
for _ in range(10):
sample = min_time + dist.rvs(size=1000) * (max_time - min_time)
his, bins = histogram(sample, bins=20, density=True)
pylab.plot(bins[:-1], his, ".")
pylab.xlabel("Reaction time [s]")
pylab.ylabel("Probability density [1/s]")
pylab.grid()
pylab.show()
Upvotes: 2