pymc-devs / pymc2

THIS IS THE **OLD** PYMC PROJECT (VERSION 2). PLEASE USE PYMC INSTEAD:
http://pymc-devs.github.com/pymc/
Other
879 stars 229 forks source link

Creating a TruncatedNormal causes a divide by zero in log in utils.normcdf() #142

Closed mar-ses closed 7 years ago

mar-ses commented 7 years ago

Hello, I managed to find what seems to be a repeatable bug. I'm creating a truncated normal, here it is:

M[i] = pymc.TruncatedNormal('M_%i'%i, mu=mob[i], tau=1/(mst[i]**2), 
                            a=0.0, b=20.0, value=init_val)

I went into pdb to isolate what the input values were which cause the error, they are below:

(Pdb) mob[i]
0.92000000000000004
(Pdb) mst[i]
0.029999999999999999
(Pdb) M[i].value                 #i.e the init_val
array(0.8989278713856176)

As far as I can tell, nothing that I've entered is questionable, and yet I get the following error:

/home/username/anaconda3/lib/python3.5/site-packages/pymc/utils.py:436: RuntimeWarning: divide by zero encountered in log
  return np.where(y > 0, np.log(y), -np.inf)

I put a pdb.set_trace() in the above location, and indeed, y is zero for some reason.

(Pdb) y
array([ 0.])

I usually create a bunch of such truncated normals, all with similar input values (I can't tell what's special about this one, and I don't think it's the same one that triggers the error every time), and most of them don't trigger the error. Only one does. And I have no idea why.

mar-ses commented 7 years ago

I tried to repeat the error, here is exactly my input and the results:

In [1]: import numpy as np

In [2]: import pymc

In [3]: M = np.empty(1, dtype=object)

In [4]: mob = np.array([0.92000000000000004])

In [5]: mst = np.array([0.029999999999999999])

In [6]: val = np.array([0.8989278713856176])

In [8]: M[0] = pymc.TruncatedNormal('M_%i'%(0), mu=mob[0], tau=1/(mst[0]**2), a=
   ...: 0.0, b=20.0, value=val)
> /home/username/anaconda3/lib/python3.5/site-packages/pymc/utils.py(436)normcdf()
-> return np.where(y > 0, np.log(y), -np.inf)
(Pdb) y
array([ 0.])
(Pdb) c
/home/username/anaconda3/lib/python3.5/site-packages/pymc/utils.py:436: RuntimeWarning: divide by zero encountered in log
  return np.where(y > 0, np.log(y), -np.inf)
> /home/marko/anaconda3/lib/python3.5/site-packages/pymc/utils.py(436)normcdf()
-> return np.where(y > 0, np.log(y), -np.inf)
(Pdb) y
array([ 1.])
(Pdb) c

As you can see, I still have thepdb.set_trace() in normcdf, and normcdf gets called twice during the creation of the TruncatedNormal, the first time triggering the divide by zero with y=array([ 0.]), the second time with y=array([ 1.])

fonnesbeck commented 7 years ago

The PR above will fix this. I will merge it when tests pass.