Beispiel #1
0
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]
    expected = np.array([
        np.nan,
        -np.inf,
        -46.051701859880914,
        -9.210390371559516,
        -4.540096037048921e-05,
        -3.720075976020836e-44,
        0.0,
    ])
    actual = at.log1mexp(-vals).eval()
    npt.assert_allclose(actual, expected)
    actual_ = log1mexp_numpy(-vals, negative_input=True)
    npt.assert_allclose(actual_, expected)
    # Check that input was not changed in place
    npt.assert_allclose(vals, vals_)
Beispiel #2
0
def log1mexp(x, *, negative_input=False):
    r"""Return log(1 - exp(-x)).

    This function is numerically more stable than the naive approach.

    For details, see
    https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf

    References
    ----------
    .. [Machler2012] Martin Mächler (2012).
       "Accurately computing `\log(1-\exp(- \mid a \mid))` Assessed by the Rmpfr package"

    """
    if not negative_input:
        warnings.warn(
            "pymc.math.log1mexp will expect a negative input in a future "
            "version of PyMC.\n To suppress this warning set `negative_input=True`",
            FutureWarning,
            stacklevel=2,
        )
        x = -x

    return at.log1mexp(x)
Beispiel #3
0
def logdiffexp(a, b):
    """log(exp(a) - exp(b))"""
    return a + at.log1mexp(b - a)
Beispiel #4
0
def test_log1mexp_numpy_integer_input():
    assert np.isclose(log1mexp_numpy(-2, negative_input=True),
                      at.log1mexp(-2).eval())