I am trying to create a custom distribution for zero truncated Poisson by specifying the log probability function and then using the pm.DensityDist method as below. However I get these errors:
TypeError: don't know how to convert scalar number to int
k = np.array([1,2, 48,1])
def log_fact(a):
return np.array([ np.sum([np.log(i) for i in range(1, x)]) for x in np.nditer(a, ['refs_ok']) ]).reshape(a.shape)
print(log_fact(k))
lam = 1
def ztp_logp(k):
return ( k * np.log(lam) - np.log(np.exp(lam) - 1) - log_fact(k) ).sum()
ztp_logp(k)
with pm.Model() as ztp_model:
zp_poisson = pm.DensityDist('zp_poisson', ztp_logp, observed=k)
TypeErrorTraceback (most recent call last)
<ipython-input-66-43b7242eea0e> in <module>()
1 with pm.Model() as ztp_model:
----> 2 zp_poisson = pm.DensityDist('zp_poisson', ztp_logp, observed=k)
/Users/vmullachery/anaconda/envs/dl2.7/lib/python2.7/site-packages/pymc3/distributions/distribution.pyc in __new__(cls, name, *args, **kwargs)
35 total_size = kwargs.pop('total_size', None)
36 dist = cls.dist(*args, **kwargs)
---> 37 return model.Var(name, dist, data, total_size)
38 else:
39 raise TypeError("Name needs to be a string but got: {}".format(name))
/Users/vmullachery/anaconda/envs/dl2.7/lib/python2.7/site-packages/pymc3/model.pyc in Var(self, name, dist, data, total_size)
780 var = ObservedRV(name=name, data=data,
781 distribution=dist,
--> 782 total_size=total_size, model=self)
783 self.observed_RVs.append(var)
784 if var.missing_values:
/Users/vmullachery/anaconda/envs/dl2.7/lib/python2.7/site-packages/pymc3/model.pyc in __init__(self, type, owner, index, name, data, distribution, total_size, model)
1228
1229 self.missing_values = data.missing_values
-> 1230 self.logp_elemwiset = distribution.logp(data)
1231 # The logp might need scaling in minibatches.
1232 # This is done in `Factor`.
<ipython-input-64-5d9727a596ae> in ztp_logp(k)
4 from scipy.special import factorial
5 def ztp_logp(k):
----> 6 return ( k * np.log(lam) - np.log(np.exp(lam) - 1) - log_fact(k) ).sum()
7
8 ztp_logp(k)
<ipython-input-63-03136e096fc4> in log_fact(a)
1 k = np.array([1,2, 48,1])
2 def log_fact(a):
----> 3 return np.array([ np.sum([np.log(i) for i in range(1, x)]) for x in np.nditer(a, ['refs_ok']) ]).reshape(a.shape)
4
5 print(log_fact(k))
TypeError: don't know how to convert scalar number to int