|
import numpy as np |
|
from numpy.testing import assert_equal, assert_almost_equal, assert_allclose |
|
from scipy.special import boxcox, boxcox1p, inv_boxcox, inv_boxcox1p |
|
import pytest |
|
|
|
|
|
|
|
|
|
def test_boxcox_basic(): |
|
x = np.array([0.5, 1, 2, 4]) |
|
|
|
|
|
y = boxcox(x, 0) |
|
assert_almost_equal(y, np.log(x)) |
|
|
|
|
|
y = boxcox(x, 1) |
|
assert_almost_equal(y, x - 1) |
|
|
|
|
|
y = boxcox(x, 2) |
|
assert_almost_equal(y, 0.5*(x**2 - 1)) |
|
|
|
|
|
lam = np.array([0.5, 1, 2]) |
|
y = boxcox(0, lam) |
|
assert_almost_equal(y, -1.0 / lam) |
|
|
|
def test_boxcox_underflow(): |
|
x = 1 + 1e-15 |
|
lmbda = 1e-306 |
|
y = boxcox(x, lmbda) |
|
assert_allclose(y, np.log(x), rtol=1e-14) |
|
|
|
|
|
def test_boxcox_nonfinite(): |
|
|
|
x = np.array([-1, -1, -0.5]) |
|
y = boxcox(x, [0.5, 2.0, -1.5]) |
|
assert_equal(y, np.array([np.nan, np.nan, np.nan])) |
|
|
|
|
|
x = 0 |
|
y = boxcox(x, [-2.5, 0]) |
|
assert_equal(y, np.array([-np.inf, -np.inf])) |
|
|
|
|
|
def test_boxcox1p_basic(): |
|
x = np.array([-0.25, -1e-20, 0, 1e-20, 0.25, 1, 3]) |
|
|
|
|
|
y = boxcox1p(x, 0) |
|
assert_almost_equal(y, np.log1p(x)) |
|
|
|
|
|
y = boxcox1p(x, 1) |
|
assert_almost_equal(y, x) |
|
|
|
|
|
y = boxcox1p(x, 2) |
|
assert_almost_equal(y, 0.5*x*(2 + x)) |
|
|
|
|
|
lam = np.array([0.5, 1, 2]) |
|
y = boxcox1p(-1, lam) |
|
assert_almost_equal(y, -1.0 / lam) |
|
|
|
|
|
def test_boxcox1p_underflow(): |
|
x = np.array([1e-15, 1e-306]) |
|
lmbda = np.array([1e-306, 1e-18]) |
|
y = boxcox1p(x, lmbda) |
|
assert_allclose(y, np.log1p(x), rtol=1e-14) |
|
|
|
|
|
def test_boxcox1p_nonfinite(): |
|
|
|
x = np.array([-2, -2, -1.5]) |
|
y = boxcox1p(x, [0.5, 2.0, -1.5]) |
|
assert_equal(y, np.array([np.nan, np.nan, np.nan])) |
|
|
|
|
|
x = -1 |
|
y = boxcox1p(x, [-2.5, 0]) |
|
assert_equal(y, np.array([-np.inf, -np.inf])) |
|
|
|
|
|
def test_inv_boxcox(): |
|
x = np.array([0., 1., 2.]) |
|
lam = np.array([0., 1., 2.]) |
|
y = boxcox(x, lam) |
|
x2 = inv_boxcox(y, lam) |
|
assert_almost_equal(x, x2) |
|
|
|
x = np.array([0., 1., 2.]) |
|
lam = np.array([0., 1., 2.]) |
|
y = boxcox1p(x, lam) |
|
x2 = inv_boxcox1p(y, lam) |
|
assert_almost_equal(x, x2) |
|
|
|
|
|
def test_inv_boxcox1p_underflow(): |
|
x = 1e-15 |
|
lam = 1e-306 |
|
y = inv_boxcox1p(x, lam) |
|
assert_allclose(y, x, rtol=1e-14) |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"x, lmb", |
|
[[100, 155], |
|
[0.01, -155]] |
|
) |
|
def test_boxcox_premature_overflow(x, lmb): |
|
|
|
y = boxcox(x, lmb) |
|
assert np.isfinite(y) |
|
x_inv = inv_boxcox(y, lmb) |
|
assert_allclose(x, x_inv) |
|
|
|
|
|
y1p = boxcox1p(x-1, lmb) |
|
assert np.isfinite(y1p) |
|
x1p_inv = inv_boxcox1p(y1p, lmb) |
|
assert_allclose(x-1, x1p_inv) |
|
|