I'm setting up an experiment that requires 10 variables to be uniformly distributed between -pi and pi. This should be fairly trivial, using scipy
.
Details: Python 3.8.16 NumPy 1.24.2 SciPy 1.10.1
Note: The Python version cannot exceed 3.8.16 due to the use of the module PsychoPy
which cannot operate on more recent versions of Python.
import numpy as np
from scipy.stats import uniform
uni = uniform(-np.pi, np.pi)
variables = uni.rvs(10)
This should return 10 values uniformly distributed between -pi and pi, however, it does not. It very rarely returns any values above 0, almost all of them are negative. For example:
>>> uni.rvs(10)
array([-0.03489156, -0.50000997, -2.98451371, -1.7355833 , -2.68861409,
-2.03613316, -2.33966294, -0.52913401, -0.47277852, -2.27422887])
For experimental purposes, I need some of these values to be above 0.4 in at least some iterations of uni.rvs(10)
.
But even when running:
i=0
while i <=0.4:
i = uni.rvs()
The loop just runs indefinitely. This suggests to me that the sampling occurring using rvs
is in fact not uniform at all. I'm not sure if this is an oversight on my part, or if the specific environment is forcing this problem.
I have tried to sample 10 values from a uniform distribution using scipy.stats.uniform
. However, the values returned do not appear to be sampled uniformly at all.
As per the documentation, you can pass loc
and scale
such that the sampling is on [loc, loc + scale]
. I believe the arguments you are passing are being interpreted as loc
and scale
, hence you are getting uniform sampling on [-np.pi, -np.pi + np.pi]
, i.e. [-np.pi, 0]
. Simply pass 2*np.pi
as your second argument.
import numpy as np
from scipy.stats import uniform
uni = uniform(loc=-np.pi, scale=2*np.pi)
variables = uni.rvs(20)
print(variables)
Output:
[-2.06319644 1.04916367 3.07400506 1.03832226 1.01205737 -0.57139507
2.80455874 3.10886192 -2.18827084 -1.49833546 -1.54547847 -3.06877181
1.15691104 1.48957702 1.36562556 2.69624898 0.03550638 -1.92457988
-0.32644606 -1.9145792 ]