 # Defining non-standard likelihood

Hi, I am new to Pymc3, I am trying to sample from the posterior of a 1d parameter(phi) using Metropolis. The prior of the parameter is normal and the likelihood is a non-standard distribution. The likelihood is calculated on a vector of 1d residuals. I was following this discussion How to set up a custom likelihood function for two variables - #4 by junpenglao.

``````np.random.seed(123)

def Likelihood(phi,d,value):
logp = 0.0;
for val in value:
logp = logp + (d/2-1)*np.log(val) - 0.5*func1(val, phi)
return logp

def func1(value, phi):
if value <= phi:
return value
else :
return 2*np.sqrt(phi*value) - phi

with Model() as func_model:
# Priors for unknown model parameters
phi = Normal('phi', mu=3.0, sd=2.0)
like = DensityDist('like',Likelihood, observed=dict(phi = phi, d = 1, value = data))
#step1 = find_MAP(model = Huber_model)
step2 = Metropolis([phi])
trace = sample(10000, step= [step2], tune = true, tune_interval = 500, chains = 5)

``````

The error I am getting is

``````    if value <= phi:
File "/home/navlab-shounak/.local/lib/python3.8/site-packages/theano/tensor/var.py", line 67, in __bool__
raise TypeError("Variables do not support boolean operations.")
TypeError: Variables do not support boolean operations.

``````

You’ll need to use the conditionals made available in `theano.tensor` . You will also likely need to use scan rather than a python `for` loop.

Do I replace `value <= phi` by `tt.le(value, phi)` ?

For your `func1()`, you will probably end up using `tt.switch()` instead of the if/then. For your `likelihood()`, you can probably just calculate the logp of every datapoint in `value` and then `tt.sum()` the logps. No need to loop (I don’t think).

I changed that, but still getting this error

``````File "/home/pymc3 codes/pyenv/lib/python3.8/site-packages/theano/graph/fg.py", line 342, in import_var
raise MissingInputError("Undeclared input", variable=var)
theano.graph.fg.MissingInputError: Undeclared input
``````

I saw this was a version problem with pymc3 and theano. Currently I have
`python 3.8.12`
`pymc3 3.11.2`
`theano-pymc 1.1.2`

Can you post the code that is raising this error?

``````import numpy as np
import matplotlib.pyplot as plt
import pymc3 as pm
import arviz as az

# Intialize random number generator
np.random.seed(123)

def Likelihood(phi,d,value):
return (d/2-1)*pm.math.log(value) - 0.5*func1(value, phi)

def func1(value, phi):
b = pm.math.switch(value <= phi, value, 2*pm.math.sqrt(phi*value) - phi)
return b

with pm.Model() as model:
phi = pm.Normal('phi', mu=4.0, sd=1.0)
like = pm.DensityDist('like',Likelihood, observed=dict(phi = phi, d = 1, value = data))
trace = pm.sample(10000, return_inferencedata=False)

with model:
az.plot_trace(trace, var_names=['phi']);
plt.show()

``````

It looks like you may be mixing the Potential and DensityDist approaches outlined in Junpeng’s original post. Changing this line:

``````like = pm.DensityDist('like',
Likelihood,
observed=dict(phi = phi,
d = 1,
value = data)
)
``````

to this:

``````like = pm.Potential('like', Likelihood(phi, 1, data))
``````

at least gets it sampling. Is that what you intended?

1 Like

Yes,thank you ! It is working now.

1 Like