def test_zero_lag(): """Test analysis for 0 lag.""" expected_mi, source, source_uncorr, target = _get_gauss_data() data = Data(np.hstack((source, target)), dim_order='sp', normalise=False) settings = { 'cmi_estimator': 'JidtKraskovCMI', 'n_perm_max_stat': 21, 'n_perm_min_stat': 21, 'n_perm_max_seq': 21, 'n_perm_omnibus': 21, 'tau_sources': 0, # this is not required, but shouldn't throw an error if provided 'max_lag_sources': 0, 'min_lag_sources': 0 } nw = MultivariateMI() results = nw.analyse_single_target(settings, data, target=1, sources='all') mi_estimator = JidtKraskovMI(settings={'normalise': False}) jidt_mi = mi_estimator.estimate(source, target) omnibus_mi = results.get_single_target(1, fdr=False).omnibus_mi print('Estimated omnibus MI: {0:0.6f}, estimated MI using JIDT core ' 'estimator: {1:0.6f} (expected: {2:0.6f}).'.format( omnibus_mi, jidt_mi, expected_mi)) assert np.isclose(omnibus_mi, jidt_mi, atol=0.005), ( 'Zero-lag omnibus MI ({0:0.6f}) differs from JIDT estimate ' '({1:0.6f}).'.format(omnibus_mi, jidt_mi)) assert np.isclose( omnibus_mi, expected_mi, atol=0.05), ('Zero-lag omnibus MI ({0:0.6f}) differs from expected MI ' '({1:0.6f}).'.format(omnibus_mi, expected_mi))
def test_zero_lag(): """Test analysis for 0 lag.""" covariance = 0.4 n = 10000 source = np.random.normal(0, 1, size=n) target = (covariance * source + (1 - covariance) * np.random.normal(0, 1, size=n)) # expected_corr = covariance / (np.sqrt(covariance**2 + (1-covariance)**2)) corr = np.corrcoef(source, target)[0, 1] expected_mi = -0.5 * np.log(1 - corr**2) data = Data(np.vstack((source, target)), dim_order='ps', normalise=False) settings = { 'cmi_estimator': 'JidtKraskovCMI', 'n_perm_max_stat': 21, 'n_perm_min_stat': 21, 'n_perm_max_seq': 21, 'n_perm_omnibus': 21, 'max_lag_sources': 0, 'min_lag_sources': 0 } nw = MultivariateMI() results = nw.analyse_single_target(settings, data, target=1, sources='all') mi_estimator = JidtKraskovMI(settings={}) jidt_mi = mi_estimator.estimate(source, target) omnibus_mi = results.get_single_target(1, fdr=False).omnibus_mi print('Estimated omnibus MI: {0:0.6f}, estimated MI using JIDT core ' 'estimator: {1:0.6f} (expected: {2:0.6f}).'.format( omnibus_mi, jidt_mi, expected_mi)) assert np.isclose(omnibus_mi, jidt_mi, rtol=0.05), ( 'Zero-lag omnibus MI ({0:0.6f}) differs from JIDT estimate ({1:0.6f}).' .format(omnibus_mi, jidt_mi)) assert np.isclose(omnibus_mi, expected_mi, rtol=0.05), ( 'Zero-lag omnibus MI ({0:0.6f}) differs from expected MI ({1:0.6f}).'. format(omnibus_mi, expected_mi))
def test_discrete_input(): """Test multivariate MI estimation from discrete data.""" # Generate Gaussian test data covariance = 0.4 data = _get_discrete_gauss_data(covariance=covariance, n=10000, delay=1, normalise=False, seed=SEED) corr_expected = covariance / (1 * np.sqrt(covariance**2 + (1 - covariance)**2)) expected_mi = calculate_mi(corr_expected) settings = { 'cmi_estimator': 'JidtDiscreteCMI', 'discretise_method': 'none', 'n_discrete_bins': 5, # alphabet size of the variables analysed 'n_perm_max_stat': 21, 'n_perm_omnibus': 30, 'n_perm_max_seq': 30, 'min_lag_sources': 1, 'max_lag_sources': 2 } nw = MultivariateMI() res = nw.analyse_single_target(settings=settings, data=data, target=1) assert np.isclose( res._single_target[1].omnibus_mi, expected_mi, atol=0.05), ( 'Estimated MI for discrete variables is not correct. Expected: ' '{0}, Actual results: {1}.'.format(expected_mi, res['selected_sources_te'][0]))
def test_gauss_data(): """Test bivariate MI estimation from correlated Gaussians.""" # Generate data and add a delay one one sample. expected_mi, source, source_uncorr, target = _get_gauss_data() source = source[1:] source_uncorr = source_uncorr[1:] target = target[:-1] data = Data(np.hstack((source, source_uncorr, target)), dim_order='sp') settings = { 'cmi_estimator': 'JidtKraskovCMI', 'n_perm_max_stat': 21, 'n_perm_min_stat': 21, 'n_perm_max_seq': 21, 'n_perm_omnibus': 21, 'max_lag_sources': 2, 'min_lag_sources': 1} nw = MultivariateMI() results = nw.analyse_single_target( settings, data, target=2, sources=[0, 1]) mi = results.get_single_target(2, fdr=False)['mi'][0] sources = results.get_target_sources(2, fdr=False) # Assert that only the correlated source was detected. assert len(sources) == 1, 'Wrong no. inferred sources: {0}.'.format( len(sources)) assert sources[0] == 0, 'Wrong inferred source: {0}.'.format(sources[0]) # Compare BivarateMI() estimate to JIDT estimate. est = JidtKraskovMI({'lag_mi': 1}) jidt_mi = est.estimate(var1=source, var2=target) print('Estimated MI: {0:0.6f}, estimated MI using JIDT core estimator: ' '{1:0.6f} (expected: {2:0.6f}).'.format(mi, jidt_mi, expected_mi)) assert np.isclose(mi, jidt_mi, atol=0.005), ( 'Estimated MI {0:0.6f} differs from JIDT estimate {1:0.6f} (expected: ' 'MI {2:0.6f}).'.format(mi, jidt_mi, expected_mi))
def test_zero_lag(): """Test analysis for 0 lag.""" covariance = 0.4 n = 10000 source = np.random.normal(0, 1, size=n) target = (covariance * source + (1 - covariance) * np.random.normal(0, 1, size=n)) # expected_corr = covariance / (np.sqrt(covariance**2 + (1-covariance)**2)) corr = np.corrcoef(source, target)[0, 1] expected_mi = -0.5 * np.log(1 - corr**2) data = Data(np.vstack((source, target)), dim_order='ps', normalise=False) settings = { 'cmi_estimator': 'JidtKraskovCMI', 'n_perm_max_stat': 21, 'n_perm_min_stat': 21, 'n_perm_max_seq': 21, 'n_perm_omnibus': 21, 'max_lag_sources': 0, 'min_lag_sources': 0} nw = MultivariateMI() results = nw.analyse_single_target( settings, data, target=1, sources='all') mi_estimator = JidtKraskovMI(settings={}) jidt_mi = mi_estimator.estimate(source, target) omnibus_mi = results.get_single_target(1, fdr=False).omnibus_mi print('Estimated omnibus MI: {0:0.6f}, estimated MI using JIDT core ' 'estimator: {1:0.6f} (expected: {2:0.6f}).'.format( omnibus_mi, jidt_mi, expected_mi)) assert np.isclose(omnibus_mi, jidt_mi, rtol=0.05), ( 'Zero-lag omnibus MI ({0:0.6f}) differs from JIDT estimate ({1:0.6f}).'.format( omnibus_mi, jidt_mi)) assert np.isclose(omnibus_mi, expected_mi, rtol=0.05), ( 'Zero-lag omnibus MI ({0:0.6f}) differs from expected MI ({1:0.6f}).'.format( omnibus_mi, expected_mi))
def test_gauss_data(): """Test multivariate MI estimation from correlated Gaussians.""" # Generate data and add a delay one one sample. expected_mi, source, source_uncorr, target = _get_gauss_data() source = source[1:] source_uncorr = source_uncorr[1:] target = target[:-1] data = Data(np.hstack((source, source_uncorr, target)), dim_order='sp', normalise=False) settings = { 'cmi_estimator': 'JidtKraskovCMI', 'n_perm_max_stat': 21, 'n_perm_min_stat': 21, 'n_perm_max_seq': 21, 'n_perm_omnibus': 21, 'max_lag_sources': 2, 'min_lag_sources': 1 } nw = MultivariateMI() results = nw.analyse_single_target(settings, data, target=2, sources=[0, 1]) mi = results.get_single_target(2, fdr=False)['mi'][0] sources = results.get_target_sources(2, fdr=False) # Assert that only the correlated source was detected. assert len(sources) == 1, 'Wrong no. inferred sources: {0}.'.format( len(sources)) assert sources[0] == 0, 'Wrong inferred source: {0}.'.format(sources[0]) # Compare BivarateMI() estimate to JIDT estimate. Mimick realisations used # internally by the algorithm. est = JidtKraskovMI({'lag_mi': 0, 'normalise': False}) jidt_mi = est.estimate(var1=source[1:-1], var2=target[2:]) print('Estimated MI: {0:0.6f}, estimated MI using JIDT core estimator: ' '{1:0.6f} (expected: {2:0.6f}).'.format(mi, jidt_mi, expected_mi)) assert np.isclose(mi, jidt_mi, atol=0.005), ( 'Estimated MI {0:0.6f} differs from JIDT estimate {1:0.6f} (expected: ' 'MI {2:0.6f}).'.format(mi, jidt_mi, expected_mi)) assert np.isclose(mi, expected_mi, atol=0.05), ( 'Estimated MI {0:0.6f} differs from expected MI {1:0.6f}.'.format( mi, expected_mi))
def test_discrete_input(): """Test multivariate MI estimation from discrete data.""" # Generate Gaussian test data covariance = 0.4 n = 10000 delay = 1 source = np.random.normal(0, 1, size=n) target = (covariance * source + (1 - covariance) * np.random.normal(0, 1, size=n)) corr_expected = covariance / (1 * np.sqrt(covariance**2 + (1 - covariance)**2)) expected_mi = calculate_mi(corr_expected) source = source[delay:] target = target[:-delay] # Discretise data settings = {'discretise_method': 'equal', 'n_discrete_bins': 5} est = JidtDiscreteCMI(settings) source_dis, target_dis = est._discretise_vars(var1=source, var2=target) data = Data(np.vstack((source_dis, target_dis)), dim_order='ps', normalise=False) settings = { 'cmi_estimator': 'JidtDiscreteCMI', 'discretise_method': 'none', 'n_discrete_bins': 5, # alphabet size of the variables analysed 'n_perm_max_stat': 21, 'n_perm_omnibus': 30, 'n_perm_max_seq': 30, 'min_lag_sources': 1, 'max_lag_sources': 2 } nw = MultivariateMI() res = nw.analyse_single_target(settings=settings, data=data, target=1) assert np.isclose( res._single_target[1].omnibus_mi, expected_mi, atol=0.05), ( 'Estimated MI for discrete variables is not correct. Expected: ' '{0}, Actual results: {1}.'.format(expected_mi, res['selected_sources_te'][0]))
def test_discrete_input(): """Test multivariate MI estimation from discrete data.""" # Generate Gaussian test data covariance = 0.4 n = 10000 delay = 1 source = np.random.normal(0, 1, size=n) target = (covariance * source + (1 - covariance) * np.random.normal(0, 1, size=n)) corr_expected = covariance / ( 1 * np.sqrt(covariance**2 + (1-covariance)**2)) expected_mi = calculate_mi(corr_expected) source = source[delay:] target = target[:-delay] # Discretise data settings = {'discretise_method': 'equal', 'n_discrete_bins': 5} est = JidtDiscreteCMI(settings) source_dis, target_dis = est._discretise_vars(var1=source, var2=target) data = Data(np.vstack((source_dis, target_dis)), dim_order='ps', normalise=False) settings = { 'cmi_estimator': 'JidtDiscreteCMI', 'discretise_method': 'none', 'n_discrete_bins': 5, # alphabet size of the variables analysed 'n_perm_max_stat': 21, 'n_perm_omnibus': 30, 'n_perm_max_seq': 30, 'min_lag_sources': 1, 'max_lag_sources': 2} nw = MultivariateMI() res = nw.analyse_single_target(settings=settings, data=data, target=1) assert np.isclose( res._single_target[1].omnibus_mi, expected_mi, atol=0.05), ( 'Estimated MI for discrete variables is not correct. Expected: ' '{0}, Actual results: {1}.'.format( expected_mi, res['selected_sources_te'][0]))
def test_return_local_values(): """Test estimation of local values.""" max_lag = 5 data = Data() data.generate_mute_data(500, 5) settings = { 'cmi_estimator': 'JidtKraskovCMI', 'noise_level': 0, 'local_values': True, # request calculation of local values 'n_perm_max_stat': 21, 'n_perm_min_stat': 21, 'n_perm_max_seq': 21, 'n_perm_omnibus': 21, 'max_lag_sources': max_lag, 'min_lag_sources': 4, 'max_lag_target': max_lag } target = 3 sources = [0, 4] mi = MultivariateMI() results = mi.analyse_single_target(settings, data, target=target, sources=sources) settings['local_values'] = False results_avg = mi.analyse_single_target(settings, data, target=target, sources=sources) # Test if any sources were inferred. If not, return (this may happen # sometimes due to too few samples, however, a higher no. samples is not # feasible for a unit test). if results.get_single_target(target, fdr=False)['mi'] is None: return if results_avg.get_single_target(target, fdr=False)['mi'] is None: return lmi = results.get_single_target(target, fdr=False)['mi'] n_sources = len(results.get_target_sources(target, fdr=False)) assert type(lmi) is np.ndarray, ( 'LMI estimation did not return an array of values: {0}'.format(lmi)) assert lmi.shape[0] == n_sources, ( 'Wrong dim (no. sources) in LMI estimate: {0}'.format(lmi.shape)) assert lmi.shape[1] == data.n_realisations_samples( (0, max_lag)), ('Wrong dim (no. samples) in LMI estimate: {0}'.format( lmi.shape)) assert lmi.shape[2] == data.n_replications, ( 'Wrong dim (no. replications) in LMI estimate: {0}'.format(lmi.shape)) # Check if average and mean local values are the same. Test each source # separately. Inferred sources and variables may differ between the two # calls to analyse_single_target() due to low number of surrogates used in # unit testing. mi_single_link = results_avg.get_single_target(target, fdr=False)['mi'] sources_local = results.get_target_sources(target, fdr=False) sources_avg = results_avg.get_target_sources(target, fdr=False) for s in list(set(sources_avg).intersection(sources_local)): i1 = np.where(sources_avg == s)[0][0] i2 = np.where(sources_local == s)[0][0] # Skip comparison if inferred variables differ between links. vars_local = [ v for v in results.get_single_target( target, fdr=False).selected_vars_sources if v[0] == s ] vars_avg = [ v for v in results_avg.get_single_target( target, fdr=False).selected_vars_sources if v[0] == s ] if vars_local != vars_avg: continue print('Compare average ({0:.4f}) and local values ({1:.4f}).'.format( mi_single_link[i1], np.mean(lmi[i2, :, :]))) assert np.isclose( mi_single_link[i1], np.mean(lmi[i2, :, :]), rtol=0.00005), ( 'Single link average MI ({0:.6f}) and mean LMI ({1:.6f}) ' ' deviate.'.format(mi_single_link[i1], np.mean(lmi[i2, :, :])))
def test_multivariate_mi_init(): """Test instance creation for MultivariateMI class.""" # Test error on missing estimator settings = { 'n_perm_max_stat': 21, 'n_perm_omnibus': 30, 'max_lag_sources': 7, 'min_lag_sources': 2 } nw = MultivariateMI() with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=Data(), target=1) # Test setting of min and max lags settings['cmi_estimator'] = 'JidtKraskovCMI' data = Data() data.generate_mute_data(n_samples=10, n_replications=5) # Invalid: min lag sources bigger than max lag settings['min_lag_sources'] = 8 settings['max_lag_sources'] = 7 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: tau bigger than lags settings['min_lag_sources'] = 2 settings['max_lag_sources'] = 4 settings['tau_sources'] = 10 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: negative lags or taus settings['tau_sources'] = 1 settings['min_lag_sources'] = 1 settings['max_lag_sources'] = -7 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['max_lag_sources'] = 7 settings['min_lag_sources'] = -4 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['min_lag_sources'] = 4 settings['tau_sources'] = -1 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: lags or taus are no integers settings['min_lag_sources'] = 1.5 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['min_lag_sources'] = 1 settings['max_lag_sources'] = 1.5 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['max_lag_sources'] = 7 settings['tau_sources'] = 1.5 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: sources or target is no int with pytest.raises(RuntimeError): # no int nw.analyse_single_target(settings=settings, data=data, target=1.5) with pytest.raises(RuntimeError): # negative nw.analyse_single_target(settings=settings, data=data, target=-1) with pytest.raises(RuntimeError): # not in data nw.analyse_single_target(settings=settings, data=data, target=10) with pytest.raises(RuntimeError): # wrong type nw.analyse_single_target(settings=settings, data=data, target={}) with pytest.raises(RuntimeError): # negative nw.analyse_single_target(settings=settings, data=data, target=0, sources=-1) with pytest.raises(RuntimeError): # negative nw.analyse_single_target(settings=settings, data=data, target=0, sources=[-1]) with pytest.raises(RuntimeError): # not in data nw.analyse_single_target(settings=settings, data=data, target=0, sources=20) with pytest.raises(RuntimeError): # not in data nw.analyse_single_target(settings=settings, data=data, target=0, sources=[20])
def test_multivariate_mi_init(): """Test instance creation for MultivariateMI class.""" # Test error on missing estimator settings = { 'n_perm_max_stat': 21, 'n_perm_omnibus': 30, 'max_lag_sources': 7, 'min_lag_sources': 2} nw = MultivariateMI() with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=Data(), target=1) # Test setting of min and max lags settings['cmi_estimator'] = 'JidtKraskovCMI' data = Data() data.generate_mute_data(n_samples=10, n_replications=5) # Invalid: min lag sources bigger than max lag settings['min_lag_sources'] = 8 settings['max_lag_sources'] = 7 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: tau bigger than lags settings['min_lag_sources'] = 2 settings['max_lag_sources'] = 4 settings['tau_sources'] = 10 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: negative lags or taus settings['tau_sources'] = 1 settings['min_lag_sources'] = 1 settings['max_lag_sources'] = -7 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['max_lag_sources'] = 7 settings['min_lag_sources'] = -4 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['min_lag_sources'] = 4 settings['tau_sources'] = -1 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: lags or taus are no integers settings['min_lag_sources'] = 1.5 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['min_lag_sources'] = 1 settings['max_lag_sources'] = 1.5 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) settings['max_lag_sources'] = 7 settings['tau_sources'] = 1.5 with pytest.raises(RuntimeError): nw.analyse_single_target(settings=settings, data=data, target=1) # Invalid: sources or target is no int with pytest.raises(RuntimeError): # no int nw.analyse_single_target(settings=settings, data=data, target=1.5) with pytest.raises(RuntimeError): # negative nw.analyse_single_target(settings=settings, data=data, target=-1) with pytest.raises(RuntimeError): # not in data nw.analyse_single_target(settings=settings, data=data, target=10) with pytest.raises(RuntimeError): # wrong type nw.analyse_single_target(settings=settings, data=data, target={}) with pytest.raises(RuntimeError): # negative nw.analyse_single_target(settings=settings, data=data, target=0, sources=-1) with pytest.raises(RuntimeError): # negative nw.analyse_single_target(settings=settings, data=data, target=0, sources=[-1]) with pytest.raises(RuntimeError): # not in data nw.analyse_single_target(settings=settings, data=data, target=0, sources=20) with pytest.raises(RuntimeError): # not in data nw.analyse_single_target(settings=settings, data=data, target=0, sources=[20])