Getting Mass matrix contains zeros on the diagonal

Sorry, still very green learning how to use PYMC3. I know this has been asked before but after reading through quite a few posts, I still cannot figure out why I am getting the following error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/pymc3/parallel_sampling.py", line 137, in run
    self._start_loop()
  File "/usr/local/lib/python3.7/dist-packages/pymc3/parallel_sampling.py", line 191, in _start_loop
    point, stats = self._compute_point()
  File "/usr/local/lib/python3.7/dist-packages/pymc3/parallel_sampling.py", line 216, in _compute_point
    point, stats = self._step_method.step(self._point)
  File "/usr/local/lib/python3.7/dist-packages/pymc3/step_methods/arraystep.py", line 276, in step
    apoint, stats = self.astep(array)
  File "/usr/local/lib/python3.7/dist-packages/pymc3/step_methods/hmc/base_hmc.py", line 147, in astep
    self.potential.raise_ok(self._logp_dlogp_func._ordering.vmap)
  File "/usr/local/lib/python3.7/dist-packages/pymc3/step_methods/hmc/quadpotential.py", line 272, in raise_ok
    raise ValueError("\n".join(errmsg))
ValueError: Mass matrix contains zeros on the diagonal. 
The derivative of RV `a_bin`.ravel()[5] is zero.
The derivative of RV `a_bin`.ravel()[6] is zero.
The derivative of RV `a_bin`.ravel()[7] is zero.
The derivative of RV `sd_bin_log__`.ravel()[0] is zero.
The derivative of RV `b_up_log__`.ravel()[0] is zero.

This the model I am trying to run is:

with pm.Model() as _model:
    a = pm.Normal('a', mu=3, sd=.75)
    b_up = pm.Exponential('b_up', 1) 
    b_down = pm.Exponential('b_down', 1/0.5)
    swp = pm.Normal('swp', 1, sigma=7)
    sd_bin = pm.Exponential('sd_bin', 3) 
    a_bin = pm.Normal('a_bin', 0, sd_bin, shape=num_bins) 
    sigma  = pm.Exponential('sigma', 1) 

    def get_mu(price):
        price_sc = price / 100

        _b = tt.switch(
            tt.lt(price_sc, swp),
            b_up, # rise
            -b_down # fall
        )

        return a + _b * (price_sc - swp) # scaled for: log(value) / price ratio  

    mu_i = get_mu(prices) + a_bin[bin_index] 
    lk = pm.Lognormal.dist(mu_i, sigma)

    pm.Potential('obs', freq*lk.logp(values))
    post = pm.sample(tune=5000, draws=1000, chains=2)

To debug, I’ve tried:

  • Setting the priors to static numbers and then adding in priors as distributions one at a time. I end up just getting the above error message with different RVs
  • Smoothing the piecewise function
  • Doing prior predictive sampling to make sure the mu_i values are reasonable
  • Adjusting the init setting in the sample method
  • Removing the hierarchical component

Not sure what to try next. Again, not sure exactly if what I am doing is even reasonable for the model definition. Any help would be greatly appreciated. Thank you!!

This might not be the main issue but you need to make sure swp (prior) is between the min and max of price_sc. If it goes outside the range, the piecewise will be wasted.

Thanks Dirk. I did try to set the values of swp to be tighter so that it doesn’t fall outside the range of price_sc but still no luck. But I will verify again.