126 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 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
 | |
| 
 | |
| 
 | |
| # There are more tests of boxcox and boxcox1p in test_mpmath.py.
 | |
| 
 | |
| def test_boxcox_basic():
 | |
|     x = np.array([0.5, 1, 2, 4])
 | |
| 
 | |
|     # lambda = 0  =>  y = log(x)
 | |
|     y = boxcox(x, 0)
 | |
|     assert_almost_equal(y, np.log(x))
 | |
| 
 | |
|     # lambda = 1  =>  y = x - 1
 | |
|     y = boxcox(x, 1)
 | |
|     assert_almost_equal(y, x - 1)
 | |
| 
 | |
|     # lambda = 2  =>  y = 0.5*(x**2 - 1)
 | |
|     y = boxcox(x, 2)
 | |
|     assert_almost_equal(y, 0.5*(x**2 - 1))
 | |
| 
 | |
|     # x = 0 and lambda > 0  =>  y = -1 / lambda
 | |
|     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 < 0  =>  y = nan
 | |
|     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 and lambda <= 0  =>  y = -inf
 | |
|     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])
 | |
| 
 | |
|     # lambda = 0  =>  y = log(1+x)
 | |
|     y = boxcox1p(x, 0)
 | |
|     assert_almost_equal(y, np.log1p(x))
 | |
| 
 | |
|     # lambda = 1  =>  y = x
 | |
|     y = boxcox1p(x, 1)
 | |
|     assert_almost_equal(y, x)
 | |
| 
 | |
|     # lambda = 2  =>  y = 0.5*((1+x)**2 - 1) = 0.5*x*(2 + x)
 | |
|     y = boxcox1p(x, 2)
 | |
|     assert_almost_equal(y, 0.5*x*(2 + x))
 | |
| 
 | |
|     # x = -1 and lambda > 0  =>  y = -1 / lambda
 | |
|     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 < -1  =>  y = nan
 | |
|     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 and lambda <= 0  =>  y = -inf
 | |
|     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):
 | |
|     # test boxcox & inv_boxcox
 | |
|     y = boxcox(x, lmb)
 | |
|     assert np.isfinite(y)
 | |
|     x_inv = inv_boxcox(y, lmb)
 | |
|     assert_allclose(x, x_inv)
 | |
| 
 | |
|     # test boxcox1p & inv_boxcox1p
 | |
|     y1p = boxcox1p(x-1, lmb)
 | |
|     assert np.isfinite(y1p)
 | |
|     x1p_inv = inv_boxcox1p(y1p, lmb)
 | |
|     assert_allclose(x-1, x1p_inv)
 |