Random sampling of sorted numbers within range

Hi there,

I need your brains again for what I thought was a simple problem but turns out to be more complicated than I thought…

What I need is to be able to draw N numbers between 0 and 1, and they need to be sorted (any way). The following apparently works:

wtot = 1
b = pm.Dirichlet(‘b’, a=np.ones(n_sectors))
w = [pm.Deterministic(‘w_s{}’.format(i), wtot*b[i]) for i in range(n_sectors)]
for s in np.arange(1, n_sectors):
pm.Potential(‘prior_w_s{}’.format(s), pm.Uniform.dist(lower=0).logp(w[s-1]-w[s]))

(wtot is in case we wanna draw up to any number below 1, and it can be a random variable too, here I just set it to 1)

But I have 2 questions:

  • I would assume the use of potential slows down how fast draws are accepted/rejected, is that right? In which case:
  • Is there a better solution?

Thanks for your help!
Cheers,
MV

You might find some previous discussion helpful here:

TL;dr:

tr = pm.transforms
Order = tr.Ordered()
Logodd = tr.LogOdds()
chain_tran = tr.Chain([Logodd, Order])

n = 5
with pm.Model() as m0:
    x = pm.Uniform("x", 0.0, 1.0, shape=n, transform=chain_tran,
                   testval=np.linspace(.1, .9, n))  # test value need to be ordered
    trace = pm.sample()
1 Like

Thanks! Right now I can’t make the Ordered transform work with Dirichlet (sum!=1) but that’s a really useful example for Uniform.

Cheers,
MV