Here it is. The CustomDist doesn’t explicitly forbid negative values but the prior predictive plot shows that there are no sampled negative values.

```
import numpy as np
import plotly.express as px
import pymc as pm
def dist_beta(a, b, loc, scale,size):
return pm.Beta.dist(a, b, size=size) * scale + loc
def dist_gamma(a,b,loc,size):
return pm.Gamma.dist(a, b, size = size) + loc
def logp_beta(x, a, b, loc, scale):
return (x - loc)/scale
def logp_gamma(x, a, b, loc):
return x - loc
sd_mult = 0.01
with pm.Model() as m:
# Left beta
left_a = pm.Normal('left_a', 1.70, 1.70 * sd_mult )
left_b = pm.Normal('left_b', 1.11, 1.11 * sd_mult )
left_loc = pm.Normal('left_loc', 2.0e6, 2.0e6 * sd_mult )
left_scale = pm.Normal('left_scale', 1.57e5, 1.57e5 * sd_mult )
# Middle beta
middle_a = pm.Normal('middle_a', 0.75, 0.75 * sd_mult )
middle_b = pm.Normal('middle_b', 1.11, 1.11 * sd_mult )
middle_loc = pm.Normal('middle_loc', 2.16e6, 2.16e6 * sd_mult )
middle_scale = pm.Normal('middle_scale', 8.6e4, 8.6e4 * sd_mult )
gamma_a = pm.Normal('gamma_a', 344.92, 344.92 * sd_mult )
gamma_b = pm.Normal('gamma_b', 1 / 1045, (1 / 1045) * sd_mult )
gamma_loc = pm.Normal('gamma_loc', 1.92e6, 1.92e6 * sd_mult)
left_beta = pm.CustomDist.dist(
left_a,
left_b,
left_loc,
left_scale,
dist=dist_beta,
logp = logp_beta,
class_name='left_beta'
)
middle_beta = pm.CustomDist.dist(
middle_a,
middle_b,
middle_loc,
middle_scale,
dist=dist_beta,
logp = logp_beta,
class_name='middle_beta'
)
right = pm.CustomDist.dist(
gamma_a,
gamma_b,
gamma_loc,
dist=dist_gamma,
logp = logp_gamma,
class_name='gamma'
)
w = pm.Dirichlet('w', np.ones(3))
data = np.array([2.207e6, 2.064e6, 2.156e6, 2.057e6, 2.089e6, 2.205e6])
resp = pm.Mixture('resp', w = w, comp_dists=[left_beta, middle_beta, right], observed=data)
trace = pm.sample()
with m:
prior = pm.sample_prior_predictive()
post = pm.sample_posterior_predictive(trace)
```

Prior predictive samples look good:

```
px.histogram(prior.prior_predictive.resp.to_numpy().reshape(-1))
```

But the posteriors are strange:

```
px.histogram(post.posterior_predictive.resp.to_numpy().reshape(-1))
```