A better approach would be instead of directly generating a sample from a log-uniform, you should create the log-uniform density.
In statistics speak, that is a reciprocal distribution which is already in SciPy: scipy.stats.reciprocal
. For example, to build a sample that is 10^{x~U[-1,1]}
, you would do:
rv = scipy.stats.reciprocal(a=0.1,b=10)
x = rv.rvs(N)
Alternatively, I wrote and use the following code to take the log-transform of any scipy.stats
-like (frozen) random-variable
class LogTransformRV(scipy.stats.rv_continuous):
def __init__(self,rv,base=10):
self.rv = rv
self.base = np.e if base in {'e','E'} else base
super(LogTransformRV, self).__init__()
self.a,self.b = self.base ** self.rv.ppf([0,1])
def _pdf(self,x):
return self.rv.pdf(self._log(x))/(x*np.log(self.base)) # Chain rule
def _cdf(self,x):
return self.rv.cdf(self._log(x))
def _ppf(self,y):
return self.base ** self.rv.ppf(y)
def _log(self,x):
return np.log(x)/np.log(self.base)