Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluate only desired branch in log1mexp_numpy #4428

Merged
merged 3 commits into from
Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Release Notes

## PyMC3 vNext (on deck)

### Breaking Changes

### New Features

### Maintenance
- `math.log1mexp_numpy` no longer raises RuntimeWarning when given very small inputs. These were commonly observed during NUTS sampling (see [#4428](https://github.com/pymc-devs/pymc3/pull/4428)).

## PyMC3 3.11.0 (21 January 2021)

This release breaks some APIs w.r.t. `3.10.0`. It also brings some dreadfully awaited fixes, so be sure to go through the (breaking) changes below.
Expand Down
8 changes: 7 additions & 1 deletion pymc3/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,13 @@ def log1mexp_numpy(x):
For details, see
https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf
"""
return np.where(x < 0.6931471805599453, np.log(-np.expm1(-x)), np.log1p(-np.exp(-x)))
x = np.asarray(x)
out = np.empty_like(x)
mask = x < 0.6931471805599453 # log(2)
out[mask] = np.log(-np.expm1(-x[mask]))
mask = ~mask
out[mask] = np.log1p(-np.exp(-x[mask]))
return out


def flatten_list(tensors):
Expand Down
10 changes: 10 additions & 0 deletions pymc3/tests/test_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def test_log1pexp():

def test_log1mexp():
vals = np.array([-1, 0, 1e-20, 1e-4, 10, 100, 1e20])
vals_ = vals.copy()
# import mpmath
# mpmath.mp.dps = 1000
# [float(mpmath.log(1 - mpmath.exp(-x))) for x in vals]
Expand All @@ -151,6 +152,15 @@ def test_log1mexp():
npt.assert_allclose(actual, expected)
actual_ = log1mexp_numpy(vals)
npt.assert_allclose(actual_, expected)
# Check that input was not changed in place
npt.assert_allclose(vals, vals_)


def test_log1mexp_numpy_no_warning():
"""Assert RuntimeWarning is not raised for very small numbers"""
with pytest.warns(None) as record:
log1mexp_numpy(1e-25)
assert not record


class TestLogDet(SeededTest):
Expand Down