Now, the question is how to loop the p1 , p2,… part so that I don’t have to explicitly write down all the binomial sampling steps (I obviously would like to have an arbitrary number of these)?
The idea is to simulate a finite population evolving under genetic drift for several generations. You have a population of N individuals, of which initially n_0 have a certain gene (so, with frequency p_0 = n_0/N). Every new generation, a binomial sample of the previous generation is drawn, resulting in a new gene frequency p_{t} = n_{t}/N, where n_t \sim Bin(N,p_{t-1}).
the model that I presented in the original post is a simplification to illustrate my difficulty. The actual idea is to use information from sub-samples of the initial and final population to estimate parameters of a slightly more complicated model that I have not included here (namely, selection, which would change the way we calculate p_{t+1}.
thanks @twiecki. Although I am not sure this would solve it: What I would like is a series of binomial samples for which the p parameter of each draw depends on the previous draw. Because of this, I thought scan() would be right way of going about it.
This is something that is not well supported in PyMC just yet. In the next major release it will be straightforward to use Scans to specify such kind of models.
Thanks @ricardoV94 . Looign forward to the new version. In any case, I ended up doing it without scan(), just creating a list of variables in a for loop. It’s probably much slower than the scan solution, as it ends up creating many variables that will be estimated, but it works.
I am leaving it here or reference, as it may help others:
ps =[ pm.Binomial("n0",popsize,p0_,shape=data.shape[0])/popsize ]
for n in range(1,24):
nextp = ps[n-1]
ps.append(pm.Binomial("n"+str(n),popsize,nextp,shape=data.shape[0])/popsize )
Importantly, you need to specify the shape, when you use Binomials like this…
The issue with that approach is that you can only do a very limited number of steps due to theano recursion limit. You can try to do that loop for 500 steps and you’ll see it (I think the limit is way less than 500).