|
import pytest |
|
from pytest import raises as assert_raises, warns as assert_warns |
|
|
|
import numpy as np |
|
from numpy.testing import assert_approx_equal, assert_allclose, assert_equal |
|
|
|
from scipy.spatial.distance import cdist |
|
from scipy import stats |
|
|
|
class TestMGCErrorWarnings: |
|
""" Tests errors and warnings derived from MGC. |
|
""" |
|
def test_error_notndarray(self): |
|
|
|
x = np.arange(20) |
|
y = [5] * 20 |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, y) |
|
assert_raises(ValueError, stats.multiscale_graphcorr, y, x) |
|
|
|
def test_error_shape(self): |
|
|
|
x = np.arange(100).reshape(25, 4) |
|
y = x.reshape(10, 10) |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, y) |
|
|
|
def test_error_lowsamples(self): |
|
|
|
x = np.arange(3) |
|
y = np.arange(3) |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, y) |
|
|
|
def test_error_nans(self): |
|
|
|
x = np.arange(20, dtype=float) |
|
x[0] = np.nan |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, x) |
|
|
|
y = np.arange(20) |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, y) |
|
|
|
def test_error_wrongdisttype(self): |
|
|
|
x = np.arange(20) |
|
compute_distance = 0 |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, x, |
|
compute_distance=compute_distance) |
|
|
|
@pytest.mark.parametrize("reps", [ |
|
-1, |
|
'1', |
|
]) |
|
def test_error_reps(self, reps): |
|
|
|
x = np.arange(20) |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, x, reps=reps) |
|
|
|
def test_warns_reps(self): |
|
|
|
x = np.arange(20) |
|
reps = 100 |
|
assert_warns(RuntimeWarning, stats.multiscale_graphcorr, x, x, reps=reps) |
|
|
|
def test_error_infty(self): |
|
|
|
x = np.arange(20) |
|
y = np.ones(20) * np.inf |
|
assert_raises(ValueError, stats.multiscale_graphcorr, x, y) |
|
|
|
|
|
class TestMGCStat: |
|
""" Test validity of MGC test statistic |
|
""" |
|
def _simulations(self, samps=100, dims=1, sim_type=""): |
|
|
|
if sim_type == "linear": |
|
x = np.random.uniform(-1, 1, size=(samps, 1)) |
|
y = x + 0.3 * np.random.random_sample(size=(x.size, 1)) |
|
|
|
|
|
elif sim_type == "nonlinear": |
|
unif = np.array(np.random.uniform(0, 5, size=(samps, 1))) |
|
x = unif * np.cos(np.pi * unif) |
|
y = (unif * np.sin(np.pi * unif) + |
|
0.4*np.random.random_sample(size=(x.size, 1))) |
|
|
|
|
|
elif sim_type == "independence": |
|
u = np.random.normal(0, 1, size=(samps, 1)) |
|
v = np.random.normal(0, 1, size=(samps, 1)) |
|
u_2 = np.random.binomial(1, p=0.5, size=(samps, 1)) |
|
v_2 = np.random.binomial(1, p=0.5, size=(samps, 1)) |
|
x = u/3 + 2*u_2 - 1 |
|
y = v/3 + 2*v_2 - 1 |
|
|
|
|
|
else: |
|
raise ValueError("sim_type must be linear, nonlinear, or " |
|
"independence") |
|
|
|
|
|
if dims > 1: |
|
dims_noise = np.random.normal(0, 1, size=(samps, dims-1)) |
|
x = np.concatenate((x, dims_noise), axis=1) |
|
|
|
return x, y |
|
|
|
@pytest.mark.xslow |
|
@pytest.mark.parametrize("sim_type, obs_stat, obs_pvalue", [ |
|
("linear", 0.97, 1/1000), |
|
("nonlinear", 0.163, 1/1000), |
|
("independence", -0.0094, 0.78) |
|
]) |
|
def test_oned(self, sim_type, obs_stat, obs_pvalue): |
|
np.random.seed(12345678) |
|
|
|
|
|
x, y = self._simulations(samps=100, dims=1, sim_type=sim_type) |
|
|
|
|
|
stat, pvalue, _ = stats.multiscale_graphcorr(x, y) |
|
assert_approx_equal(stat, obs_stat, significant=1) |
|
assert_approx_equal(pvalue, obs_pvalue, significant=1) |
|
|
|
@pytest.mark.xslow |
|
@pytest.mark.parametrize("sim_type, obs_stat, obs_pvalue", [ |
|
("linear", 0.184, 1/1000), |
|
("nonlinear", 0.0190, 0.117), |
|
]) |
|
def test_fived(self, sim_type, obs_stat, obs_pvalue): |
|
np.random.seed(12345678) |
|
|
|
|
|
x, y = self._simulations(samps=100, dims=5, sim_type=sim_type) |
|
|
|
|
|
stat, pvalue, _ = stats.multiscale_graphcorr(x, y) |
|
assert_approx_equal(stat, obs_stat, significant=1) |
|
assert_approx_equal(pvalue, obs_pvalue, significant=1) |
|
|
|
@pytest.mark.xslow |
|
def test_twosamp(self): |
|
np.random.seed(12345678) |
|
|
|
|
|
x = np.random.binomial(100, 0.5, size=(100, 5)) |
|
y = np.random.normal(0, 1, size=(80, 5)) |
|
|
|
|
|
stat, pvalue, _ = stats.multiscale_graphcorr(x, y) |
|
assert_approx_equal(stat, 1.0, significant=1) |
|
assert_approx_equal(pvalue, 0.001, significant=1) |
|
|
|
|
|
y = np.random.normal(0, 1, size=(100, 5)) |
|
|
|
|
|
stat, pvalue, _ = stats.multiscale_graphcorr(x, y, is_twosamp=True) |
|
assert_approx_equal(stat, 1.0, significant=1) |
|
assert_approx_equal(pvalue, 0.001, significant=1) |
|
|
|
@pytest.mark.xslow |
|
def test_workers(self): |
|
np.random.seed(12345678) |
|
|
|
|
|
x, y = self._simulations(samps=100, dims=1, sim_type="linear") |
|
|
|
|
|
stat, pvalue, _ = stats.multiscale_graphcorr(x, y, workers=2) |
|
assert_approx_equal(stat, 0.97, significant=1) |
|
assert_approx_equal(pvalue, 0.001, significant=1) |
|
|
|
@pytest.mark.xslow |
|
def test_random_state(self): |
|
|
|
x, y = self._simulations(samps=100, dims=1, sim_type="linear") |
|
|
|
|
|
stat, pvalue, _ = stats.multiscale_graphcorr(x, y, random_state=1) |
|
assert_approx_equal(stat, 0.97, significant=1) |
|
assert_approx_equal(pvalue, 0.001, significant=1) |
|
|
|
@pytest.mark.xslow |
|
def test_dist_perm(self): |
|
np.random.seed(12345678) |
|
|
|
x, y = self._simulations(samps=100, dims=1, sim_type="nonlinear") |
|
distx = cdist(x, x, metric="euclidean") |
|
disty = cdist(y, y, metric="euclidean") |
|
|
|
stat_dist, pvalue_dist, _ = stats.multiscale_graphcorr(distx, disty, |
|
compute_distance=None, |
|
random_state=1) |
|
assert_approx_equal(stat_dist, 0.163, significant=1) |
|
assert_approx_equal(pvalue_dist, 0.001, significant=1) |
|
|
|
@pytest.mark.fail_slow(20) |
|
@pytest.mark.slow |
|
def test_pvalue_literature(self): |
|
np.random.seed(12345678) |
|
|
|
|
|
x, y = self._simulations(samps=100, dims=1, sim_type="linear") |
|
|
|
|
|
_, pvalue, _ = stats.multiscale_graphcorr(x, y, random_state=1) |
|
assert_allclose(pvalue, 1/1001) |
|
|
|
@pytest.mark.xslow |
|
def test_alias(self): |
|
np.random.seed(12345678) |
|
|
|
|
|
x, y = self._simulations(samps=100, dims=1, sim_type="linear") |
|
|
|
res = stats.multiscale_graphcorr(x, y, random_state=1) |
|
assert_equal(res.stat, res.statistic) |
|
|