161 lines
5.4 KiB
Python
161 lines
5.4 KiB
Python
"""
|
|
Created on Fri Feb 12 10:42:00 2021
|
|
|
|
Author: Josef Perktold
|
|
License: BSD-3
|
|
|
|
"""
|
|
|
|
import numpy as np
|
|
from numpy.testing import assert_allclose, assert_equal
|
|
from scipy import stats
|
|
import statsmodels.distributions.tools as dt
|
|
|
|
|
|
def test_grid():
|
|
# test bivariate independent beta
|
|
k1, k2 = 3, 5
|
|
xg1 = np.arange(k1) / (k1 - 1)
|
|
xg2 = np.arange(k2) / (k2 - 1)
|
|
|
|
# histogram values for distribution
|
|
distr1 = stats.beta(2, 5)
|
|
distr2 = stats.beta(4, 3)
|
|
cdf1 = distr1.cdf(xg1)
|
|
cdf2 = distr2.cdf(xg2)
|
|
prob1 = np.diff(cdf1, prepend=0)
|
|
prob2 = np.diff(cdf2, prepend=0)
|
|
cd2d = cdf1[:, None] * cdf2
|
|
pd2d = prob1[:, None] * prob2
|
|
|
|
probs = dt.cdf2prob_grid(cd2d)
|
|
cdfs = dt.prob2cdf_grid(pd2d)
|
|
|
|
assert_allclose(cdfs, cd2d, atol=1e-12)
|
|
assert_allclose(probs, pd2d, atol=1e-12)
|
|
|
|
# check random sample
|
|
nobs = 1000
|
|
np.random.seed(789123)
|
|
rvs = np.column_stack([distr1.rvs(size=nobs), distr2.rvs(size=nobs)])
|
|
hist = np.histogramdd(rvs, [xg1, xg2])
|
|
assert_allclose(probs[1:, 1:], hist[0] / len(rvs), atol=0.02)
|
|
|
|
|
|
def test_average_grid():
|
|
x1 = np.arange(1, 4)
|
|
x2 = np.arange(4)
|
|
y = x1[:, None] * x2
|
|
|
|
res1 = np.array([[0.75, 2.25, 3.75],
|
|
[1.25, 3.75, 6.25]])
|
|
|
|
res0 = dt.average_grid(y, coords=[x1, x2])
|
|
assert_allclose(res0, res1, rtol=1e-13)
|
|
res0 = dt.average_grid(y, coords=[x1, x2], _method="slicing")
|
|
assert_allclose(res0, res1, rtol=1e-13)
|
|
res0 = dt.average_grid(y, coords=[x1, x2], _method="convolve")
|
|
assert_allclose(res0, res1, rtol=1e-13)
|
|
|
|
res0 = dt.average_grid(y, coords=[x1 / x1.max(), x2 / x2.max()])
|
|
assert_allclose(res0, res1 / x1.max() / x2.max(), rtol=1e-13)
|
|
res0 = dt.average_grid(y, coords=[x1 / x1.max(), x2 / x2.max()],
|
|
_method="convolve")
|
|
assert_allclose(res0, res1 / x1.max() / x2.max(), rtol=1e-13)
|
|
|
|
|
|
def test_grid_class():
|
|
|
|
res = {'k_grid': [3, 5],
|
|
'x_marginal': [np.array([0., 0.5, 1.]),
|
|
np.array([0., 0.25, 0.5, 0.75, 1.])],
|
|
'idx_flat.T': np.array([
|
|
[0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 2., 2., 2., 2., 2.],
|
|
[0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4.]])
|
|
}
|
|
gg = dt._Grid([3, 5])
|
|
assert_equal(gg.k_grid, res["k_grid"])
|
|
assert gg.x_marginal, res["x_marginal"]
|
|
assert_allclose(gg.idx_flat, res["idx_flat.T"].T, atol=1e-12)
|
|
assert_allclose(gg.x_flat, res["idx_flat.T"].T / [2, 4], atol=1e-12)
|
|
|
|
gg = dt._Grid([3, 5], eps=0.001)
|
|
assert_allclose(gg.x_flat.min(), 0.001, atol=1e-12)
|
|
assert_allclose(gg.x_flat.max(), 0.999, atol=1e-12)
|
|
xmf = np.concatenate(gg.x_marginal)
|
|
assert_allclose(xmf.min(), 0.001, atol=1e-12)
|
|
assert_allclose(xmf.max(), 0.999, atol=1e-12)
|
|
|
|
# 1-dim
|
|
gg = dt._Grid([5], eps=0.001)
|
|
res = {'k_grid': [5],
|
|
'x_marginal': [np.array([0.001, 0.25, 0.5, 0.75, 0.999])],
|
|
'idx_flat.T': np.array([[0., 1., 2., 3., 4.]])
|
|
}
|
|
assert_equal(gg.k_grid, res["k_grid"])
|
|
assert gg.x_marginal, res["x_marginal"]
|
|
assert_allclose(gg.idx_flat, res["idx_flat.T"].T, atol=1e-12)
|
|
# x_flat is 2-dim even if grid is 1-dim, TODO: maybe change
|
|
assert_allclose(gg.x_flat, res["x_marginal"][0][:, None], atol=1e-12)
|
|
|
|
# 3-dim
|
|
gg = dt._Grid([3, 3, 2], eps=0.)
|
|
res = {'k_grid': [3, 3, 2],
|
|
'x_marginal': [np.array([0., 0.5, 1.]),
|
|
np.array([0., 0.5, 1.]),
|
|
np.array([0., 1.])],
|
|
'idx_flat.T': np.array([
|
|
[0., 0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 1., 2., 2., 2., 2.,
|
|
2., 2.],
|
|
[0., 0., 1., 1., 2., 2., 0., 0., 1., 1., 2., 2., 0., 0., 1., 1.,
|
|
2., 2.],
|
|
[0., 1., 0., 1., 0., 1., 0., 1., 0., 1., 0., 1., 0., 1., 0., 1.,
|
|
0., 1.]])
|
|
}
|
|
assert_equal(gg.k_grid, res["k_grid"])
|
|
assert gg.x_marginal, res["x_marginal"]
|
|
assert_allclose(gg.idx_flat, res["idx_flat.T"].T, atol=1e-12)
|
|
assert_allclose(gg.x_flat, res["idx_flat.T"].T / [2, 2, 1], atol=1e-12)
|
|
|
|
|
|
def test_bernstein_1d():
|
|
k = 5
|
|
xg1 = np.arange(k) / (k - 1)
|
|
xg2 = np.arange(2 * k) / (2 * k - 1)
|
|
# verify linear coefficients are mapped to themselves
|
|
res_bp = dt._eval_bernstein_1d(xg2, xg1)
|
|
assert_allclose(res_bp, xg2, atol=1e-12)
|
|
|
|
res_bp = dt._eval_bernstein_1d(xg2, xg1, method="beta")
|
|
assert_allclose(res_bp, xg2, atol=1e-12)
|
|
|
|
res_bp = dt._eval_bernstein_1d(xg2, xg1, method="bpoly")
|
|
assert_allclose(res_bp, xg2, atol=1e-12)
|
|
|
|
|
|
def test_bernstein_2d():
|
|
k = 5
|
|
xg1 = np.arange(k) / (k - 1)
|
|
cd2d = xg1[:, None] * xg1
|
|
# verify linear coefficients are mapped to themselves
|
|
for evalbp in (dt._eval_bernstein_2d, dt._eval_bernstein_dd):
|
|
k_x = 2 * k
|
|
# create flattened grid of bivariate values
|
|
x2d = np.column_stack(
|
|
np.unravel_index(np.arange(k_x * k_x), (k_x, k_x))
|
|
).astype(float)
|
|
x2d /= x2d.max(0)
|
|
|
|
res_bp = evalbp(x2d, cd2d)
|
|
assert_allclose(res_bp, np.prod(x2d, axis=1), atol=1e-12)
|
|
|
|
# check univariate margins
|
|
x2d = np.column_stack((np.arange(k_x) / (k_x - 1), np.ones(k_x)))
|
|
res_bp = evalbp(x2d, cd2d)
|
|
assert_allclose(res_bp, x2d[:, 0], atol=1e-12)
|
|
|
|
# check univariate margins
|
|
x2d = np.column_stack((np.ones(k_x), np.arange(k_x) / (k_x - 1)))
|
|
res_bp = evalbp(x2d, cd2d)
|
|
assert_allclose(res_bp, x2d[:, 1], atol=1e-12)
|