I have a question about the running time of the accept/reject method to sample from discrete distributions.
I'm sampling from two distributions built like this:
draw $n_{outcomes}$ number from an exponential distribution (Pareto with $\alpha = 2$ in the second case)
compute the sum $Z$
divide each number by $Z$
That is $p_i = \frac{R_i}{\sum_i R_i}$, $R_i$ random number drawn from Exponential or Pareto distribution.
For the exponential case:
def create_discrete_dist_exp(n_items):
# creates a collection of floats drawn
# from an exponential distribution
# 1-rand() to avoid log(0), since rand()
# returns a float in [0, 1[
collection = -np.log(1 - np.random.rand(n_items))
# compute the normalization
Z = sum(collection)
#return the discrete distribution
return collection/Z
For the Pareto case:
def create_discrete_dist_sqrt(n_items):
# create a collection of floats
# distributed following a Pareto
collection = 1/np.sqrt(1-np.random.rand(n_items))
# compute the normalization
Z = sum(collection)
# return the distribution
return collection/Z
The accept/reject method consists in taking the max of these $p_i$ and build a rectangle of width $n_{outcomes}$, height $\max_i p_i$. Then draw a random point in the rectangle and see if it is under the probability distribution, in that case accept, otherwise reject.
def accept_reject(prob, n):
height = np.amax(prob)
width = len(prob)
samples = []
for i in xrange(0, n):
while(True):
x = np.random.rand()*width
y = np.random.rand()*height
# cast to int to avoid warnings
# because vector index is a float
ix = int(np.floor(x))
if prob[ix] > y:
samples.append(ix)
break
return samples
The question is how does the running time increase with $n_{outcomes}$?
A clue is that the largest number obtained by sampling N numbers from an exp distribution is $O(\log N)$, so my reasoning is: the largest number is $O(\log N)$, the others will be small, since the exponential distribution drops pretty quickly, therefore I can approximate the difference between the highest rectangle and the others with $O(\log N)$, which is also my guess for the rejection probability, therefore the running time will be $\sim \log N$. But:
• I'm not completely convinced by this reasoning
• I don't know what's the estimate for the largest number sampled in N iterations from a Pareto.
EDIT
running time (RT) and rejection rate (rr) in function of $n_{outcomes}$
fit of $\max p(x)$ with $f(x)=a*\log x + b$