# Truncating a Zero Inflated Poisson distribution

Hi! I’m working on a dataset where observations are best described as zero-inflated, Poisson distributed, with an upper bound (that’s a relatively low number). I was hoping that I could simply apply `pm.Truncated` on `pm.ZeroInflatedPoisson`, along the lines of:

``````zeroinfl_dist = pm.ZeroInflatedPoisson.dist()
pm.Truncated("truncated_zipoisson", zeroinfl_dist, lower=0, upper=my_upper_limit)
``````

However, it seems that truncation is not implemented for this distribution (I get an error `NotImplementedError: Truncation not implemented for SymbolicRandomVariable MarginalMixtureRV{inline=True}`). What would be the best way to go around this limitation? Any hints would be much appreciated!

I think I figured it out myself - the ZeroInflatedPoisson distribution code was pretty easy to modify:

``````from pymc.distributions.discrete import _zero_inflated_mixture, Poisson

class ZeroInflatedPoissonTrunc:

def __new__(cls, name, psi, mu, upper_limit, **kwargs):
pois = Poisson.dist(mu=mu)
trunc_pois = pm.Truncated.dist(pois, lower=0, upper=upper_limit)
return _zero_inflated_mixture(
name=name, nonzero_p=psi, nonzero_dist=trunc_pois, **kwargs
)

@classmethod
def dist(cls, psi, mu, upper_limit, **kwargs):
pois = Poisson.dist(mu=mu)
trunc_pois = pm.Truncated.dist(pois, lower=0, upper=upper_limit)
return _zero_inflated_mixture(
name=None, nonzero_p=psi, nonzero_dist=trunc_pois, **kwargs
)
``````

Works like a charm!

That’s a neat solution, you can do it without the class as well

``````truncated_poisson = pm.Truncated.dist(pm.Poisson.dist(), lower=0, upper=upper_limit)
zero_inflation = pm.DiracDelta(0)
truncated_zip = pm.Mixture("truncated_zip", w=..., comp_dists([zero_inflation, truncated_poisson]))
``````
2 Likes