Reputation: 11
I am trying to do the inverse method for a discrete variable, but I don't get anything (if I print the sample I get only one number, not a sample). How do I make this work correctly?
import numpy as np
import numpy.random as rd
import matplotlib.pyplot as plt
def inversao_discreto(p,M):
amostra=np.zeros(M)
acum=np.zeros(len(p))
acum[:]=p
for i in range(1, len(acum)):
acum[i]+=acum[i-1]
r=rd.random_sample(M)
for i in range(M):
i=0
k=0
while(r[k]>acum[i]):
i+=1
amostra=i
return amostra
model=np.array([0.1,0.2,0.1,0.2,0.4])
sample=inversao_discreto(model,10000)
Upvotes: 1
Views: 592
Reputation: 2460
As far as I could understand, you want to implement the Inverse transform sampling for discrete variables, which works like this:
Given a probability distribution `p`
Given a number of samples `M`
Calculate the cumulative probability distribution function `acum` from `p`
Generate `M` uniformly distributed samples and store into `r`
For each sample `r[i]`
Get the index where the cumulative distribution `acum` is larger or equal to the sample `r[i]`
Store this value into `amostra[i]`
If my understanding is correct, then your code is almost there. Your mistake is only in the last for
loop. Your variable i
is tracking the position of your samples stored in r
. Then, k
will keep track of where in the accumulator acum
you are comparing r
to. Here is the pseudo-code:
For each sample `r[i]`
Start with `k = 0`
While `r[i] > acum[k]`
Increment `k`
Now that `r[i] <= acum[k]`, store `k` into `amostra[i]`
Translating it to Python:
for i in range(M):
k = 0
while (r[i] > acum[k]):
k += 1
amostra[i] = k
So here is the code fixed:
import numpy as np
import numpy.random as rd
def inversao_discreto(p, M):
amostra = np.zeros(M)
acum = np.zeros(len(p))
acum[:] = p
for i in range(1, len(acum)):
acum[i] += acum[i - 1]
r = rd.random_sample(M)
for i in range(M):
k = 0
while (r[i] > acum[k]):
k += 1
amostra[i] = k
return amostra
model = np.array([0.1, 0.2, 0.1, 0.2, 0.4])
sample = inversao_discreto(model, 10000)
I tried to change as little code as possible to make it work since you are relatively new to Python. Most of the changes I implemented were based on this Style Guide for Python Code, which I recommend you to take a look at since will improve your code, visually speaking.
Upvotes: 1