Thanks you, I'll check out the DE moves as you suggest.
I'm reluctant to transform priors from the range [0,1] as I have (among others) two priors a,b which must satisfy a>0, b>0, a+b<1. While I could reparameterize this as b=a*c this will cause parameter interactions between a and c. Therefore for the time being I am repeating proposals until they fit the prior, as below. As StretchMove doesn't contain any tuning I'm hoping this shouldn't affect the properties of the sample chain, though if the move is something that gets tuned I suppose it might?
class PriorRejectMoveWrapper(RedBlueMove):
def __init__(self,move,prior,maxattempts=30, **kwargs):
self.move = move
self.prior = prior
self.maxattempts = maxattempts
super(PriorRejectMoveWrapper,self).__init__(**kwargs)
def get_proposal(self,current_walkers,other_group,random):
proposals = []
factors = []
for walker in current_walkers:
for _ in range(self.maxattempts):
proposal,factor = self.move.get_proposal(np.array([walker]),other_group,random)
assert proposal.shape[0]==1
assert factor.shape==(1,)
if self.prior(proposal[0]) > -np.inf:
break
proposals += [proposal[0]]
factors += [factor[0]]
return np.array(proposals),np.array(factors)
# ... later ...
sampler = emcee.EnsembleSampler(n_walk, n_dim, ll_func, pool=pool, moves=PriorRejectMoveWrapper(StretchMove(),prior))
Crispin