def test_cmi_no_cond_correlated_gaussians():
    """Test estimators on correlated Gaussian data without conditional."""
    expected_mi, source, source_uncorr, target = _get_gauss_data()

    # Run OpenCL estimator.
    settings = {'debug': True}
    ocl_est = OpenCLKraskovCMI(settings=settings)
    mi_ocl, dist, n_range_var1, n_range_var2 = ocl_est.estimate(source, target)

    mi_ocl = mi_ocl[0]
    # Run JIDT estimator.
    jidt_est = JidtKraskovCMI(settings={})
    mi_jidt = jidt_est.estimate(source, target)

    cov_effective = np.cov(np.squeeze(source), np.squeeze(target))[1, 0]
    expected_mi = math.log(1 / (1 - math.pow(cov_effective, 2)))
    print('JIDT MI result: {0:.4f} nats; OpenCL MI result: {1:.4f} nats; '
          'expected to be close to {2:.4f} nats for correlated '
          'Gaussians.'.format(mi_jidt, mi_ocl, expected_mi))
    assert np.isclose(mi_jidt, expected_mi, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'JIDT estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl, expected_mi, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl, mi_jidt, atol=0.0001), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
Exemplo n.º 2
0
def test_analytical_surrogates():
    # Test generation of analytical surrogates.
    # Generate data and discretise it such that we can use analytical
    # surrogates.
    expected_mi, source1, source2, target = _get_gauss_data(covariance=0.4)
    settings = {'discretise_method': 'equal', 'n_discrete_bins': 5}
    est = JidtDiscreteCMI(settings)
    source_dis, target_dis = est._discretise_vars(var1=source1, var2=target)
    data = Data(np.hstack((source_dis, target_dis)),
                dim_order='sp',
                normalise=False)
    settings = {
        'cmi_estimator': 'JidtDiscreteCMI',
        'n_discrete_bins': 5,  # alphabet size of the variables analysed
        'n_perm_max_stat': 100,
        'n_perm_min_stat': 21,
        'n_perm_omnibus': 21,
        'n_perm_max_seq': 21,
        'max_lag_sources': 5,
        'min_lag_sources': 1,
        'max_lag_target': 5
    }
    nw = MultivariateTE()
    res = nw.analyse_single_target(settings, data, target=1)
    # Check if generation of analytical surrogates is documented in the
    # settings.
    assert res.settings.analytical_surrogates, (
        'Surrogates were not created analytically.')
def test_insufficient_no_points():
    """Test if estimation aborts for too few data points."""
    expected_mi, source1, source2, target = _get_gauss_data(n=4)

    settings = {
        'kraskov_k': 4,
        'theiler_t': 0,
        'history': 1,
        'history_target': 1,
        'lag_mi': 1,
        'source_target_delay': 1}

    # Test first settings combination with k==N
    est = OpenCLKraskovMI(settings)
    with pytest.raises(RuntimeError): est.estimate(source1, target)
    est = OpenCLKraskovCMI(settings)
    with pytest.raises(RuntimeError): est.estimate(source1, target, target)

    # Test a second combination with a Theiler-correction != 0
    settings['theiler_t'] = 1
    settings['kraskov_k'] = 2
    est = OpenCLKraskovMI(settings)
    with pytest.raises(RuntimeError): est.estimate(source1, target)
    est = OpenCLKraskovCMI(settings)
    with pytest.raises(RuntimeError): est.estimate(source1, target, target)
def test_insufficient_no_points():
    """Test if estimation aborts for too few data points."""
    expected_mi, source1, source2, target = _get_gauss_data(n=4)

    settings = {
        'kraskov_k': 4,
        'theiler_t': 0,
        'history': 1,
        'history_target': 1,
        'lag_mi': 1,
        'source_target_delay': 1
    }

    # Test first settings combination with k==N
    est = OpenCLKraskovMI(settings)
    with pytest.raises(RuntimeError):
        est.estimate(source1, target)
    est = OpenCLKraskovCMI(settings)
    with pytest.raises(RuntimeError):
        est.estimate(source1, target, target)

    # Test a second combination with a Theiler-correction != 0
    settings['theiler_t'] = 1
    settings['kraskov_k'] = 2
    est = OpenCLKraskovMI(settings)
    with pytest.raises(RuntimeError):
        est.estimate(source1, target)
    est = OpenCLKraskovCMI(settings)
    with pytest.raises(RuntimeError):
        est.estimate(source1, target, target)
def test_cmi_correlated_gaussians():
    """Test estimators on correlated Gaussian data with conditional."""
    expected_mi, source, source_uncorr, target = _get_gauss_data()

    # Run OpenCL estimator.
    settings = {'debug': True, 'return_counts': True}
    ocl_est = OpenCLKraskovCMI(settings=settings)
    (mi_ocl, dist, n_range_var1, n_range_var2,
     n_range_cond) = ocl_est.estimate(source, target, source_uncorr)

    mi_ocl = mi_ocl[0]
    # Run JIDT estimator.
    jidt_est = JidtKraskovCMI(settings={})
    mi_jidt = jidt_est.estimate(source, target, source_uncorr)

    print('JIDT MI result: {0:.4f} nats; OpenCL MI result: {1:.4f} nats; '
          'expected to be close to {2:.4f} nats for correlated '
          'Gaussians.'.format(mi_jidt, mi_ocl, expected_mi))
    assert np.isclose(
        mi_jidt, expected_mi,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'JIDT estimator failed (error larger 0.05).')
    assert np.isclose(
        mi_ocl, expected_mi,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(
        mi_ocl, mi_jidt,
        atol=0.0001), ('MI estimation for uncorrelated Gaussians using the '
                       'OpenCL estimator failed (error larger 0.05).')
def test_cmi_correlated_gaussians():
    """Test estimators on correlated Gaussian data with conditional."""
    expected_mi, source, source_uncorr, target = _get_gauss_data()

    # Run OpenCL estimator.
    settings = {'debug': True}
    ocl_est = OpenCLKraskovCMI(settings=settings)
    (mi_ocl, dist, n_range_var1,
     n_range_var2, n_range_cond) = ocl_est.estimate(source, target,
                                                    source_uncorr)

    mi_ocl = mi_ocl[0]
    # Run JIDT estimator.
    jidt_est = JidtKraskovCMI(settings={})
    mi_jidt = jidt_est.estimate(source, target, source_uncorr)

    print('JIDT MI result: {0:.4f} nats; OpenCL MI result: {1:.4f} nats; '
          'expected to be close to {2:.4f} nats for correlated '
          'Gaussians.'.format(mi_jidt, mi_ocl, expected_mi))
    assert np.isclose(mi_jidt, expected_mi, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'JIDT estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl, expected_mi, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl, mi_jidt, atol=0.0001), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
def test_multi_gpu():
    """Test use of multiple GPUs."""
    expected_mi, source, source_uncorr, target = _get_gauss_data()
    settings = {'debug': True, 'return_counts': True}

    # Get no. available devices on current platform.
    device_list, _, _ = OpenCLKraskovCMI()._get_device(gpuid=0)
    print(device_list)
    n_devices = len(device_list)

    # Try initialising estimator with unavailable GPU ID
    with pytest.raises(RuntimeError):
        settings['gpuid'] = n_devices + 1
        OpenCLKraskovCMI(settings=settings)

    # Run OpenCL estimator on available device with highest available ID.
    settings['gpuid'] = n_devices - 1
    ocl_est = OpenCLKraskovCMI(settings=settings)

    (mi_ocl, dist, n_range_var1, n_range_var2,
     n_range_cond) = ocl_est.estimate(source, target, source_uncorr)

    mi_ocl = mi_ocl[0]
    print('Expected MI: {0:.4f} nats; OpenCL MI result: {1:.4f} nats; '
          'expected to be close to 0 nats for uncorrelated '
          'Gaussians.'.format(expected_mi, mi_ocl))
    assert np.isclose(
        mi_ocl, expected_mi,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'OpenCL estimator failed (error larger 0.05).')
Exemplo n.º 8
0
def test_calculate_cmi_all_links():
    """Test if the CMI is estimated correctly."""
    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, target)), dim_order='sp', normalise=False)
    res_0 = pickle.load(
        open(os.path.join(os.path.dirname(__file__), 'data/mute_results_0.p'),
             'rb'))

    comp_settings = {
        'cmi_estimator': 'JidtKraskovCMI',
        'n_perm_max_stat': 50,
        'n_perm_min_stat': 50,
        'n_perm_omnibus': 200,
        'n_perm_max_seq': 50,
        'tail': 'two',
        'n_perm_comp': 6,
        'alpha_comp': 0.2,
        'stats_type': 'dependent'
    }
    comp = NetworkComparison()
    comp._initialise(comp_settings)
    comp._create_union(res_0)
    # Set selected variable to the source, one sample in the past of the
    # current_value (1, 5).
    comp.union._single_target[1]['selected_vars_sources'] = [(0, 4)]
    cmi = comp._calculate_cmi_all_links(data)
    print('correlated Gaussians: TE result {0:.4f} bits; expected to be '
          '{1:0.4f} bit for the copy'.format(cmi[1][0], expected_mi))
    assert np.isclose(cmi[1][0], expected_mi, atol=0.05), (
        'Estimated TE {0:0.6f} differs from expected TE {1:0.6f}.'.format(
            cmi[1][0], expected_mi))
Exemplo n.º 9
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."""
    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))
Exemplo n.º 11
0
def test_estimate_parallel():
    """Test estimate_parallel() against estimate()."""
    expected_mi, source1, source2, target = _get_gauss_data()

    source_chunks = np.vstack((source1, source1))
    target_chunks = np.vstack((target, target))

    # Compare MI-estimates from serial and parallel estimator.
    mi_estimator = JidtKraskovMI(settings={'noise_level': 0})
    mi = mi_estimator.estimate(source1, target)
    with pytest.raises(AssertionError):
        mi_estimator.estimate_parallel(
            n_chunks=2,
            var1=source_chunks,
            var2=target)
    mi_parallel1 = mi_estimator.estimate_parallel(
            n_chunks=2,
            re_use=['var2'],
            var1=source_chunks,
            var2=target)
    mi_parallel2 = mi_estimator.estimate_parallel(
            n_chunks=2,
            var1=source_chunks,
            var2=target_chunks)
    assert (mi_parallel1 == mi_parallel2).all(), (
        'Results for stacked ({0}) and re-used ({1}) target differ.'.format(
            mi_parallel1, mi_parallel2))
    assert mi_parallel1[0] == mi, (
        'Results for first chunk differ from serial estimate.')
    assert mi_parallel1[1] == mi, (
        'Results for second chunk differ from serial estimate.')
    assert np.isclose(mi, expected_mi, rtol=0.05), (
        'Estimated ({0}) and expected ({1}) MI differ.'.format(
            mi, expected_mi))

    # Check if a single chunk is returned if all variables are defined as
    # reusable.
    mi_parallel3 = mi_estimator.estimate_parallel(
            n_chunks=2,
            re_use=['var1', 'var2'],
            var1=source1,
            var2=target)
    assert len(mi_parallel3) == 1, (
        'Single chunk data returned more than one estimate.')
    assert np.isclose(mi_parallel3[0], expected_mi, rtol=0.05), (
        'Estimated ({0}) and expected ({1}) MI differ.'.format(
            mi_parallel3[0], expected_mi))

    # Check assertion for incorrect number of samples in data to be reused in
    # parallel estimator.
    with pytest.raises(AssertionError):
        mi_estimator.estimate_parallel(
                n_chunks=2,
                re_use=['var2'],
                var1=source_chunks,
                var2=target[:100])
Exemplo n.º 12
0
def test_estimate_parallel():
    """Test estimate_parallel() against estimate()."""
    expected_mi, source1, source2, target = _get_gauss_data()

    source_chunks = np.vstack((source1, source1))
    target_chunks = np.vstack((target, target))

    # Compare MI-estimates from serial and parallel estimator.
    mi_estimator = JidtKraskovMI(settings={'noise_level': 0})
    mi = mi_estimator.estimate(source1, target)
    with pytest.raises(AssertionError):
        mi_estimator.estimate_parallel(n_chunks=2,
                                       var1=source_chunks,
                                       var2=target)
    mi_parallel1 = mi_estimator.estimate_parallel(n_chunks=2,
                                                  re_use=['var2'],
                                                  var1=source_chunks,
                                                  var2=target)
    mi_parallel2 = mi_estimator.estimate_parallel(n_chunks=2,
                                                  var1=source_chunks,
                                                  var2=target_chunks)
    assert (mi_parallel1 == mi_parallel2).all(), (
        'Results for stacked ({0}) and re-used ({1}) target differ.'.format(
            mi_parallel1, mi_parallel2))
    assert mi_parallel1[0] == mi, (
        'Results for first chunk differ from serial estimate.')
    assert mi_parallel1[1] == mi, (
        'Results for second chunk differ from serial estimate.')
    assert np.isclose(
        mi, expected_mi,
        rtol=0.05), ('Estimated ({0}) and expected ({1}) MI differ.'.format(
            mi, expected_mi))

    # Check if a single chunk is returned if all variables are defined as
    # reusable.
    mi_parallel3 = mi_estimator.estimate_parallel(n_chunks=2,
                                                  re_use=['var1', 'var2'],
                                                  var1=source1,
                                                  var2=target)
    assert len(mi_parallel3) == 1, (
        'Single chunk data returned more than one estimate.')
    assert np.isclose(
        mi_parallel3[0], expected_mi,
        rtol=0.05), ('Estimated ({0}) and expected ({1}) MI differ.'.format(
            mi_parallel3[0], expected_mi))

    # Check assertion for incorrect number of samples in data to be reused in
    # parallel estimator.
    with pytest.raises(AssertionError):
        mi_estimator.estimate_parallel(n_chunks=2,
                                       re_use=['var2'],
                                       var1=source_chunks,
                                       var2=target[:100])
def test_amd_data_padding():
    """Test padding necessary for AMD devices."""
    expected_mi, source, source_uncorr, target = _get_gauss_data()

    settings = {'debug': True, 'return_counts': True}
    est_mi = OpenCLKraskovMI(settings=settings)
    est_cmi = OpenCLKraskovCMI(settings=settings)

    # Run OpenCL estimator for various data sizes.
    for n in [11, 13, 25, 64, 100, 128, 999, 10000, 3781, 50000]:
        for n_chunks in [1, 3, 10, 50, 99]:
            data_run_source = np.tile(source[:n], (n_chunks, 1))
            data_run_target = np.tile(target[:n], (n_chunks, 1))
            mi, dist, n_range_var1, n_range_var2 = est_mi.estimate(
                data_run_source, data_run_target, n_chunks=n_chunks)
            cmi, dist, n_range_var1, n_range_var2 = est_cmi.estimate(
                data_run_source, data_run_target, n_chunks=n_chunks)
    # Run OpenCL esitmator for various no. points and check result for
    # correctness. Note that for smaller sample sizes the error becomes too
    # large.
    n_chunks = 1
    for n in [832, 999, 10000, 3781, 50000]:
        data_run_source = np.tile(source[:n], (n_chunks, 1))
        data_run_target = np.tile(target[:n], (n_chunks, 1))
        mi, dist, n_range_var1, n_range_var2 = est_mi.estimate(
            data_run_source, data_run_target, n_chunks=n_chunks)
        cmi, dist, n_range_var1, n_range_var2 = est_cmi.estimate(
            data_run_source, data_run_target, n_chunks=n_chunks)
        print('{0} points, {1} chunks: OpenCL MI result: {2:.4f} nats; '
              'expected to be close to {3:.4f} nats for correlated '
              'Gaussians.'.format(n, n_chunks, mi[0], expected_mi))
        assert np.isclose(mi[0], expected_mi, atol=0.05), (
            'MI estimation for uncorrelated Gaussians using the OpenCL '
            'estimator failed (error larger 0.05).')
        print('OpenCL CMI result: {0:.4f} nats; expected to be close to '
              '{1:.4f} nats for correlated Gaussians.'.format(
                  cmi[0], expected_mi))
        assert np.isclose(cmi[0], expected_mi, atol=0.05), (
            'CMI estimation for uncorrelated Gaussians using the OpenCL '
            'estimator failed (error larger 0.05).')

    # Test debugging switched off
    settings = {'debug': False, 'return_counts': False}
    est_mi = OpenCLKraskovMI(settings=settings)
    est_cmi = OpenCLKraskovCMI(settings=settings)
    mi = est_mi.estimate(source, target)
    cmi = est_cmi.estimate(source, target)

    settings['local_values'] = True
    est_mi = OpenCLKraskovMI(settings=settings)
    est_cmi = OpenCLKraskovCMI(settings=settings)
    mi = est_mi.estimate(source, target)
    cmi = est_cmi.estimate(source, target)
Exemplo n.º 14
0
def test_gauss_data():
    """Test bivariate TE estimation from correlated Gaussians."""
    # Generate data and add a delay one one sample.
    expected_mi, source, source_uncorr, target = _get_gauss_data(seed=SEED)
    source = source[1:]
    source_uncorr = source_uncorr[1:]
    target = target[:-1]
    data = Data(np.hstack((source, source_uncorr, target)),
                dim_order='sp',
                normalise=False,
                seed=SEED)
    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': 1,
        'min_lag_sources': 1,
        'max_lag_target': 1
    }
    nw = BivariateTE()
    results = nw.analyse_single_target(settings,
                                       data,
                                       target=2,
                                       sources=[0, 1])
    te = results.get_single_target(2, fdr=False)['te'][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 BivarateTE() estimate to JIDT estimate.
    est = JidtKraskovTE({
        'history_target': 1,
        'history_source': 1,
        'source_target_delay': 1,
        'normalise': False
    })
    jidt_cmi = est.estimate(source=source, target=target)
    print('Estimated TE: {0:0.6f}, estimated TE using JIDT core estimator: '
          '{1:0.6f} (expected: ~ {2:0.6f}).'.format(te, jidt_cmi, expected_mi))
    assert np.isclose(te, jidt_cmi, atol=0.005), (
        'Estimated TE {0:0.6f} differs from JIDT estimate {1:0.6f} (expected: '
        'TE {2:0.6f}).'.format(te, jidt_cmi, expected_mi))
    assert np.isclose(te, expected_mi, atol=0.05), (
        'Estimated TE {0:0.6f} differs from expected TE {1:0.6f}.'.format(
            te, expected_mi))
Exemplo n.º 15
0
def test_amd_data_padding():
    """Test padding necessary for AMD devices."""
    expected_mi, source, source_uncorr, target = _get_gauss_data()

    settings = {'debug': True}
    est_mi = OpenCLKraskovMI(settings=settings)
    est_cmi = OpenCLKraskovCMI(settings=settings)

    # Run OpenCL estimator for various data sizes.
    for n in [11, 13, 25, 64, 100, 128, 999, 10000, 3781, 50000]:
        for n_chunks in [1, 3, 10, 50, 99]:
            data_run_source = np.tile(source[:n], (n_chunks, 1))
            data_run_target = np.tile(target[:n], (n_chunks, 1))
            mi, dist, n_range_var1, n_range_var2 = est_mi.estimate(
                data_run_source, data_run_target, n_chunks=n_chunks)
            cmi, dist, n_range_var1, n_range_var2 = est_cmi.estimate(
                data_run_source, data_run_target, n_chunks=n_chunks)
    # Run OpenCL esitmator for various no. points and check result for
    # correctness. Note that for smaller sample sizes the error becomes too
    # large.
    n_chunks = 1
    for n in [832, 999, 10000, 3781, 50000]:
        data_run_source = np.tile(source[:n], (n_chunks, 1))
        data_run_target = np.tile(target[:n], (n_chunks, 1))
        mi, dist, n_range_var1, n_range_var2 = est_mi.estimate(
            data_run_source, data_run_target, n_chunks=n_chunks)
        cmi, dist, n_range_var1, n_range_var2 = est_cmi.estimate(
            data_run_source, data_run_target, n_chunks=n_chunks)
        print('{0} points, {1} chunks: OpenCL MI result: {2:.4f} nats; '
              'expected to be close to {3:.4f} nats for correlated '
              'Gaussians.'.format(n, n_chunks, mi[0], expected_mi))
        assert np.isclose(mi[0], expected_mi, atol=0.05), (
            'MI estimation for uncorrelated Gaussians using the OpenCL '
            'estimator failed (error larger 0.05).')
        print('OpenCL CMI result: {0:.4f} nats; expected to be close to '
              '{1:.4f} nats for correlated Gaussians.'.format(
                    cmi[0], expected_mi))
        assert np.isclose(cmi[0], expected_mi, atol=0.05), (
            'CMI estimation for uncorrelated Gaussians using the OpenCL '
            'estimator failed (error larger 0.05).')

    # Test debugging switched off
    settings['debug'] = False
    mi = est_mi.estimate(source, target)
    cmi = est_cmi.estimate(source, target)

    settings['local_values'] = True
    mi = est_mi.estimate(source, target)
    cmi = est_cmi.estimate(source, target)
Exemplo n.º 16
0
def test_local_values():
    """Test estimation of local MI and CMI using OpenCL estimators."""
    # Get data
    n_chunks = 2
    expec_mi, source, source_uncorr, target = _get_gauss_data(n=20000,
                                                              seed=SEED)
    chunklength = int(source.shape[0] / n_chunks)

    # Estimate local values
    settings = {'local_values': True}
    est_cmi = OpenCLKraskovCMI(settings=settings)
    cmi = est_cmi.estimate(source, target, source_uncorr, n_chunks=n_chunks)

    est_mi = OpenCLKraskovMI(settings=settings)
    mi = est_mi.estimate(source, target, n_chunks=n_chunks)

    mi_ch1 = np.mean(mi[0:chunklength])
    mi_ch2 = np.mean(mi[chunklength:])
    cmi_ch1 = np.mean(cmi[0:chunklength])
    cmi_ch2 = np.mean(cmi[chunklength:])

    # Estimate non-local values for comparison
    settings = {'local_values': False}
    est_cmi = OpenCLKraskovCMI(settings=settings)
    mi = est_cmi.estimate(source, target, source_uncorr, n_chunks=n_chunks)

    est_mi = OpenCLKraskovMI(settings=settings)
    cmi = est_mi.estimate(source, target, n_chunks=n_chunks)

    # Report results
    print('OpenCL MI result: {0:.4f} nats (chunk 1); {1:.4f} nats (chunk 2) '
          'expected to be close to {2:.4f} nats for uncorrelated '
          'Gaussians.'.format(mi_ch1, mi_ch2, expec_mi))
    print('OpenCL CMI result: {0:.4f} nats (chunk 1); {1:.4f} nats (chunk 2) '
          'expected to be close to {2:.4f} nats for uncorrelated '
          'Gaussians.'.format(cmi_ch1, cmi_ch2, expec_mi))

    assert np.isclose(mi_ch1, expec_mi, atol=0.05)
    assert np.isclose(mi_ch2, expec_mi, atol=0.05)
    assert np.isclose(cmi_ch1, expec_mi, atol=0.05)
    assert np.isclose(cmi_ch2, expec_mi, atol=0.05)
    assert np.isclose(mi_ch1, mi_ch2, atol=0.05)
    assert np.isclose(mi_ch1, mi[0], atol=0.05)
    assert np.isclose(mi_ch2, mi[1], atol=0.05)
    assert np.isclose(cmi_ch1, cmi_ch2, atol=0.05)
    assert np.isclose(cmi_ch1, cmi[0], atol=0.05)
    assert np.isclose(cmi_ch2, cmi[1], atol=0.05)
Exemplo n.º 17
0
def test_local_values():
    """Test estimation of local MI and CMI using OpenCL estimators."""
    # Get data
    n_chunks = 2
    expec_mi, source, source_uncorr, target = _get_gauss_data(n=20000)
    chunklength = int(source.shape[0] / n_chunks)

    # Estimate local values
    settings = {'local_values': True}
    est_cmi = OpenCLKraskovCMI(settings=settings)
    cmi = est_cmi.estimate(source, target, source_uncorr, n_chunks=n_chunks)

    est_mi = OpenCLKraskovMI(settings=settings)
    mi = est_mi.estimate(source, target, n_chunks=n_chunks)

    mi_ch1 = np.mean(mi[0:chunklength])
    mi_ch2 = np.mean(mi[chunklength:])
    cmi_ch1 = np.mean(cmi[0:chunklength])
    cmi_ch2 = np.mean(cmi[chunklength:])

    # Estimate non-local values for comparison
    settings = {'local_values': False}
    est_cmi = OpenCLKraskovCMI(settings=settings)
    mi = est_cmi.estimate(source, target, source_uncorr, n_chunks=n_chunks)

    est_mi = OpenCLKraskovMI(settings=settings)
    cmi = est_mi.estimate(source, target, n_chunks=n_chunks)

    # Report results
    print('OpenCL MI result: {0:.4f} nats (chunk 1); {1:.4f} nats (chunk 2) '
          'expected to be close to {2:.4f} nats for uncorrelated '
          'Gaussians.'.format(mi_ch1, mi_ch2, expec_mi))
    print('OpenCL CMI result: {0:.4f} nats (chunk 1); {1:.4f} nats (chunk 2) '
          'expected to be close to {2:.4f} nats for uncorrelated '
          'Gaussians.'.format(cmi_ch1, cmi_ch2, expec_mi))

    assert np.isclose(mi_ch1, expec_mi, atol=0.05)
    assert np.isclose(mi_ch2, expec_mi, atol=0.05)
    assert np.isclose(cmi_ch1, expec_mi, atol=0.05)
    assert np.isclose(cmi_ch2, expec_mi, atol=0.05)
    assert np.isclose(mi_ch1, mi_ch2, atol=0.05)
    assert np.isclose(mi_ch1, mi[0], atol=0.05)
    assert np.isclose(mi_ch2, mi[1], atol=0.05)
    assert np.isclose(cmi_ch1, cmi_ch2, atol=0.05)
    assert np.isclose(cmi_ch1, cmi[0], atol=0.05)
    assert np.isclose(cmi_ch2, cmi[1], atol=0.05)
Exemplo n.º 18
0
def test_gauss_data():
    """Test bivariate TE 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,
        'max_lag_target': 1
    }
    nw = BivariateTE()
    results = nw.analyse_single_target(settings,
                                       data,
                                       target=2,
                                       sources=[0, 1])
    te = results.get_single_target(2, fdr=False)['te'][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 BivarateTE() estimate to JIDT estimate.
    current_value = (2, 2)
    source_vars = results.get_single_target(2, False)['selected_vars_sources']
    target_vars = results.get_single_target(2, False)['selected_vars_target']
    var1 = data.get_realisations(current_value, source_vars)[0]
    var2 = data.get_realisations(current_value, [current_value])[0]
    cond = data.get_realisations(current_value, target_vars)[0]
    est = JidtKraskovCMI({})
    jidt_cmi = est.estimate(var1=var1, var2=var2, conditional=cond)
    print('Estimated TE: {0:0.6f}, estimated TE using JIDT core estimator: '
          '{1:0.6f} (expected: {2:0.6f}).'.format(te, jidt_cmi, expected_mi))
    assert np.isclose(te, jidt_cmi, atol=0.005), (
        'Estimated TE {0:0.6f} differs from JIDT estimate {1:0.6f} (expected: '
        'TE {2:0.6f}).'.format(te, jidt_cmi, 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))
Exemplo n.º 20
0
def test_gauss_data():
    """Test bivariate TE 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,
        'max_lag_target': 1}
    nw = BivariateTE()
    results = nw.analyse_single_target(
        settings, data, target=2, sources=[0, 1])
    te = results.get_single_target(2, fdr=False)['te'][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 BivarateTE() estimate to JIDT estimate.
    current_value = (2, 2)
    source_vars = results.get_single_target(2, False)['selected_vars_sources']
    target_vars = results.get_single_target(2, False)['selected_vars_target']
    var1 = data.get_realisations(current_value, source_vars)[0]
    var2 = data.get_realisations(current_value, [current_value])[0]
    cond = data.get_realisations(current_value, target_vars)[0]
    est = JidtKraskovCMI({})
    jidt_cmi = est.estimate(var1=var1, var2=var2, conditional=cond)
    print('Estimated TE: {0:0.6f}, estimated TE using JIDT core estimator: '
          '{1:0.6f} (expected: {2:0.6f}).'.format(te, jidt_cmi, expected_mi))
    assert np.isclose(te, jidt_cmi, atol=0.005), (
        'Estimated TE {0:0.6f} differs from JIDT estimate {1:0.6f} (expected: '
        'TE {2:0.6f}).'.format(te, jidt_cmi, expected_mi))
Exemplo n.º 21
0
def test_mi_correlated_gaussians_two_chunks():
    """Test estimators on two chunks of correlated Gaussian data."""
    expected_mi, source, source_uncorr, target = _get_gauss_data(n=20000,
                                                                 seed=SEED)
    n_points = source.shape[0]

    # Run OpenCL estimator.
    n_chunks = 2
    settings = {'debug': True, 'return_counts': True}
    ocl_est = OpenCLKraskovMI(settings=settings)
    mi_ocl, dist, n_range_var1, n_range_var2 = ocl_est.estimate(
        source, target, n_chunks=n_chunks)

    # Run JIDT estimator.
    jidt_est = JidtKraskovMI(settings={})
    mi_jidt = jidt_est.estimate(source[0:int(n_points / 2), :],
                                target[0:int(n_points / 2), :])

    print('JIDT MI result: {0:.4f} nats; OpenCL MI result: [{1:.4f}, {2:.4f}] '
          'nats; expected to be close to {3:.4f} nats for correlated '
          'Gaussians.'.format(mi_jidt, mi_ocl[0], mi_ocl[1], expected_mi))
    assert np.isclose(
        mi_jidt, expected_mi,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'JIDT estimator failed (error larger 0.05).')
    assert np.isclose(
        mi_ocl[0], expected_mi,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(
        mi_ocl[0], mi_jidt,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(
        mi_ocl[1], mi_jidt,
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(
        mi_ocl[0], mi_ocl[1],
        atol=0.05), ('MI estimation for uncorrelated Gaussians using the '
                     'OpenCL estimator failed (error larger 0.05).')
Exemplo n.º 22
0
def test_compare_bivariate_and_multivariate_te():
    """Compare bivariate to multivariate TE estimation."""
    expected_mi, source, source_uncorr, target = _get_gauss_data(seed=SEED)
    source = source[1:]
    source_uncorr = source_uncorr[1:]
    target = target[:-1]
    data = Data(np.hstack((source, source_uncorr, target)),
                dim_order='sp',
                normalise=False,
                seed=SEED)
    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': 1,
        'min_lag_sources': 1,
        'max_lag_target': 1
    }
    nw_bivar = BivariateTE()
    results = nw_bivar.analyse_single_target(settings,
                                             data,
                                             target=2,
                                             sources=[0, 1])
    te_bivar = results.get_single_target(2, fdr=False)['te'][0]

    nw_multivar = MultivariateTE()
    results = nw_multivar.analyse_single_target(settings,
                                                data,
                                                target=2,
                                                sources=[0, 1])
    te_multivar = results.get_single_target(2, fdr=False)['te'][0]

    print('Estimated TE: {0:0.6f}, estimated TE using multivariate algorithm: '
          '{1:0.6f} (expected: ~ {2:0.6f}).'.format(te_bivar, te_multivar,
                                                    expected_mi))
    assert np.isclose(te_bivar, te_multivar, atol=0.005), (
        'Estimated TE {0:0.6f} differs from multivariate estimate {1:0.6f} '
        '(expected: TE {2:0.6f}).'.format(te_bivar, te_multivar, expected_mi))
Exemplo n.º 23
0
def test_mi_correlated_gaussians_two_chunks():
    """Test estimators on two chunks of correlated Gaussian data."""
    expected_mi, source, source_uncorr, target = _get_gauss_data(n=20000)
    n_points = source.shape[0]

    # Run OpenCL estimator.
    n_chunks = 2
    settings = {'debug': True}
    ocl_est = OpenCLKraskovMI(settings=settings)
    mi_ocl, dist, n_range_var1, n_range_var2 = ocl_est.estimate(
                                                            source, target,
                                                            n_chunks=n_chunks)

    # Run JIDT estimator.
    jidt_est = JidtKraskovMI(settings={})
    mi_jidt = jidt_est.estimate(source[0:int(n_points/2), :],
                                target[0:int(n_points/2), :])

    print('JIDT MI result: {0:.4f} nats; OpenCL MI result: [{1:.4f}, {2:.4f}] '
          'nats; expected to be close to {3:.4f} nats for correlated '
          'Gaussians.'.format(mi_jidt, mi_ocl[0], mi_ocl[1], expected_mi))
    assert np.isclose(mi_jidt, expected_mi, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'JIDT estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl[0], expected_mi, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl[0], mi_jidt, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl[1], mi_jidt, atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
    assert np.isclose(mi_ocl[0], mi_ocl[1], atol=0.05), (
                        'MI estimation for uncorrelated Gaussians using the '
                        'OpenCL estimator failed (error larger 0.05).')
def test_multivariate_te_corr_gaussian(estimator=None):
    """Test multivariate TE estimation on correlated Gaussians.

    Run the multivariate TE algorithm on two sets of random Gaussian data with
    a given covariance. The second data set is shifted by one sample creating
    a source-target delay of one sample. This example is modeled after the
    JIDT demo 4 for transfer entropy. The resulting TE can be compared to the
    analytical result (but expect some error in the estimate).

    The simulated delay is 1 sample, i.e., the algorithm should find
    significant TE from sample (0, 1), a sample in process 0 with lag/delay 1.
    The final target sample should always be (1, 1), the mandatory sample at
    lat 1, because there is no memory in the process.

    Note:
        This test runs considerably faster than other system tests.
        This produces strange small values for non-coupled sources.  TODO
    """
    if estimator is None:
        estimator = 'JidtKraskovCMI'

    cov = 0.4
    expected_mi, source1, source2, target = _get_gauss_data(covariance=cov)
    # n = 1000
    # source = [rn.normalvariate(0, 1) for r in range(n)]
    # target = [sum(pair) for pair in zip(
    #     [cov * y for y in source],
    #     [(1 - cov) * y for y in [rn.normalvariate(0, 1) for r in range(n)]])]
    # # Cast everything to numpy so the idtxl estimator understands it.
    # source = np.expand_dims(np.array(source), axis=1)
    # target = np.expand_dims(np.array(target), axis=1)

    data = Data(normalise=True)
    data.set_data(np.vstack((source1[1:].T, target[:-1].T)), 'ps')
    settings = {
        'cmi_estimator': estimator,
        'discretise_method': 'max_ent',
        'max_lag_sources': 5,
        'min_lag_sources': 1,
        'max_lag_target': 5,
        'n_perm_max_stat': 21,
        'n_perm_min_stat': 21,
        'n_perm_omnibus': 21,
        'n_perm_max_seq': 21,
        }
    random_analysis = MultivariateTE()
    results_max_ent = random_analysis.analyse_single_target(settings, data, 1)

    settings['discretise_method'] = 'equal'
    settings['n_discrete_bins'] = 5
    results_equal = random_analysis.analyse_single_target(settings, data, 1)

    # Assert that there are significant conditionals from the source for target
    # 1. For 500 repetitions I got mean errors of 0.02097686 and 0.01454073 for
    # examples 1 and 2 respectively. The maximum errors were 0.093841 and
    # 0.05833172 repectively. This inspired the following error boundaries.
    corr_expected = cov / (1 * np.sqrt(cov**2 + (1-cov)**2))
    expected_res = calculate_mi(corr_expected)
    estimated_res_max_ent = results_max_ent.get_single_target(1, fdr=False)['te'][0]
    estimated_res_equal = results_equal.get_single_target(1, fdr=False)['te'][0]
    diff_max_ent = np.abs(estimated_res_max_ent - expected_res)
    diff_equal = np.abs(estimated_res_equal - expected_res)
    print('Expected source sample: (0, 1)\nExpected target sample: (1, 1)')
    print(('Max. entropy binning - estimated TE: {0:5.4f}, analytical result: '
           '{1:5.4f}, error: {2:2.2f} % ').format(
               estimated_res_max_ent, expected_res, diff_max_ent / expected_res))
    print(('Equal binning - estimated TE: {0:5.4f}, analytical result: '
           '{1:5.4f}, error: {2:2.2f} % ').format(
               estimated_res_equal, expected_res, diff_equal / expected_res))
    assert diff_max_ent < 0.1, (
        'Multivariate TE calculation for correlated Gaussians using '
        'discretised data with max. entropy binning failed (error larger 0.1: '
        '{0}, expected: {1}, actual: {2}).'.format(
            diff_max_ent, expected_res, results_max_ent['cond_sources_te']))
    assert diff_equal < 0.1, (
        'Multivariate TE calculation for correlated Gaussians using '
        'discretised data with equal binning failed (error larger 0.1: {0}, '
        'expected: {1}, actual: {2}).'.format(
            diff_max_ent, expected_res, results_max_ent['cond_sources_te']))
Exemplo n.º 25
0
def test_calculate_single_link():
    """Test calculation of single link (conditional) MI and TE."""

    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')

    n = NetworkAnalysis()
    n._cmi_estimator = JidtKraskovCMI(settings={})
    n.settings = {'local_values': False}
    current_value = (2, 1)

    # Test single link estimation for a single and multiple sources for
    # cases: no target vars, source vars/no source vars (tests if the
    # conditioning set is built correctly for conditioning='full').
    source_realisations = data.get_realisations(current_value, [(0, 0)])[0]
    current_value_realisations = data.get_realisations(current_value,
                                                       [current_value])[0]
    expected_mi = n._cmi_estimator.estimate(current_value_realisations,
                                            source_realisations)
    # cond. on second source
    cond_realisations = data.get_realisations(current_value, [(1, 0)])[0]
    expected_mi_cond1 = n._cmi_estimator.estimate(current_value_realisations,
                                                  source_realisations,
                                                  cond_realisations)

    for sources in ['all', [0]]:
        for conditioning in ['full', 'target', 'none']:
            for source_vars in [[(0, 0)], [(0, 0), (1, 0)]]:
                mi = n._calculate_single_link(data,
                                              current_value,
                                              source_vars,
                                              target_vars=None,
                                              sources=sources,
                                              conditioning=conditioning)
                if mi.shape[0] > 1:  # array for source='all'
                    mi = mi[0]

                if source_vars == [(0, 0)]:  # no conditioning
                    assert np.isclose(mi, expected_mi, rtol=0.05), (
                        'Estimated single-link MI ({0}) differs from expected '
                        'MI ({1}).'.format(mi, expected_mi))
                else:
                    if conditioning == 'full':  # cond. on second source
                        assert np.isclose(mi, expected_mi_cond1, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi_cond1))
                    else:  # no conditioning
                        assert np.isclose(mi, expected_mi, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi))

        # Test single link estimation for a single and multiple sources for
        # cases: target vars/no target vars, source vars (tests if the
        # conditioning set is built correctly for conditioning='full').
        cond_realisations = np.hstack((  # cond. on second source and target
            data.get_realisations(current_value, [(1, 0)])[0],
            data.get_realisations(current_value, [(2, 0)])[0]))
        expected_mi_cond2 = n._cmi_estimator.estimate(
            current_value_realisations, source_realisations, cond_realisations)
        # cond. on target
        cond_realisations = data.get_realisations(current_value, [(2, 0)])[0]
        expected_mi_cond3 = n._cmi_estimator.estimate(
            current_value_realisations, source_realisations, cond_realisations)

        for target_vars in [None, [(2, 0)]]:
            for conditioning in ['full', 'target', 'none']:
                mi = n._calculate_single_link(data,
                                              current_value,
                                              source_vars=[(0, 0), (1, 0)],
                                              target_vars=target_vars,
                                              sources=sources,
                                              conditioning=conditioning)
                if mi.shape[0] > 1:  # array for source='all'
                    mi = mi[0]

                if conditioning == 'none':  # no conditioning
                    assert np.isclose(mi, expected_mi, rtol=0.05), (
                        'Estimated single-link MI ({0}) differs from expected '
                        'MI ({1}).'.format(mi, expected_mi))
                else:
                    # target only
                    if target_vars is not None and conditioning == 'target':
                        assert np.isclose(mi, expected_mi_cond3, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi_cond3))
                    # target and 2nd source
                    if target_vars is not None and conditioning == 'full':
                        assert np.isclose(mi, expected_mi_cond2, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi_cond2))
                    # target is None, condition on second target
                    else:
                        if conditioning == 'full':
                            assert np.isclose(
                                mi, expected_mi_cond1, rtol=0.05
                            ), ('Estimated single-link MI ({0}) differs from expected '
                                'MI ({1}).'.format(mi, expected_mi_cond1))

    # Test requested sources not in source vars
    with pytest.raises(RuntimeError):
        mi = n._calculate_single_link(data,
                                      current_value,
                                      source_vars=[(0, 0), (3, 0)],
                                      target_vars=None,
                                      sources=4,
                                      conditioning='full')
    # Test source vars not in data/processes
    with pytest.raises(IndexError):
        mi = n._calculate_single_link(data,
                                      current_value,
                                      source_vars=[(0, 0), (10, 0)],
                                      target_vars=None,
                                      sources='all',
                                      conditioning='full')
    # Test unknown conditioning
    with pytest.raises(RuntimeError):
        mi = n._calculate_single_link(data,
                                      current_value,
                                      source_vars=[(0, 0)],
                                      conditioning='test')
Exemplo n.º 26
0
def test_calculate_single_link():
    """Test calculation of single link (conditional) MI and TE."""

    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')

    n = NetworkAnalysis()
    n._cmi_estimator = JidtKraskovCMI(settings={})
    n.settings = {
        'local_values': False
    }
    current_value = (2, 1)

    # Test single link estimation for a single and multiple sources for
    # cases: no target vars, source vars/no source vars (tests if the
    # conditioning set is built correctly for conditioning='full').
    source_realisations = data.get_realisations(current_value, [(0, 0)])[0]
    current_value_realisations = data.get_realisations(
        current_value, [current_value])[0]
    expected_mi = n._cmi_estimator.estimate(
        current_value_realisations, source_realisations)
    # cond. on second source
    cond_realisations = data.get_realisations(current_value, [(1, 0)])[0]
    expected_mi_cond1 = n._cmi_estimator.estimate(
        current_value_realisations, source_realisations, cond_realisations)

    for sources in ['all', [0]]:
        for conditioning in ['full', 'target', 'none']:
            for source_vars in [[(0, 0)], [(0, 0), (1, 0)]]:
                mi = n._calculate_single_link(
                    data, current_value, source_vars, target_vars=None,
                    sources=sources, conditioning=conditioning)
                if mi.shape[0] > 1:  # array for source='all'
                    mi = mi[0]

                if source_vars == [(0, 0)]:  # no conditioning
                    assert np.isclose(mi, expected_mi, rtol=0.05), (
                        'Estimated single-link MI ({0}) differs from expected '
                        'MI ({1}).'.format(mi, expected_mi))
                else:
                    if conditioning == 'full':  # cond. on second source
                        assert np.isclose(mi, expected_mi_cond1, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi_cond1))
                    else:  # no conditioning
                        assert np.isclose(mi, expected_mi, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi))

        # Test single link estimation for a single and multiple sources for
        # cases: target vars/no target vars, source vars (tests if the
        # conditioning set is built correctly for conditioning='full').
        cond_realisations = np.hstack((  # cond. on second source and target
            data.get_realisations(current_value, [(1, 0)])[0],
            data.get_realisations(current_value, [(2, 0)])[0]
            ))
        expected_mi_cond2 = n._cmi_estimator.estimate(
            current_value_realisations, source_realisations, cond_realisations)
        # cond. on target
        cond_realisations = data.get_realisations(current_value, [(2, 0)])[0]
        expected_mi_cond3 = n._cmi_estimator.estimate(
            current_value_realisations, source_realisations, cond_realisations)

        for target_vars in [None, [(2, 0)]]:
            for conditioning in ['full', 'target', 'none']:
                mi = n._calculate_single_link(
                    data, current_value, source_vars=[(0, 0), (1, 0)],
                    target_vars=target_vars, sources=sources,
                    conditioning=conditioning)
                if mi.shape[0] > 1:  # array for source='all'
                    mi = mi[0]

                if conditioning == 'none':  # no conditioning
                    assert np.isclose(mi, expected_mi, rtol=0.05), (
                        'Estimated single-link MI ({0}) differs from expected '
                        'MI ({1}).'.format(mi, expected_mi))
                else:
                    # target only
                    if target_vars is not None and conditioning == 'target':
                        assert np.isclose(mi, expected_mi_cond3, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi_cond3))
                    # target and 2nd source
                    if target_vars is not None and conditioning == 'full':
                        assert np.isclose(mi, expected_mi_cond2, rtol=0.05), (
                            'Estimated single-link MI ({0}) differs from '
                            'expected MI ({1}).'.format(mi, expected_mi_cond2))
                    # target is None, condition on second target
                    else:
                        if conditioning == 'full':
                            assert np.isclose(mi, expected_mi_cond1, rtol=0.05), (
                                'Estimated single-link MI ({0}) differs from expected '
                                'MI ({1}).'.format(mi, expected_mi_cond1))

    # Test requested sources not in source vars
    with pytest.raises(RuntimeError):
        mi = n._calculate_single_link(
            data, current_value, source_vars=[(0, 0), (3, 0)],
            target_vars=None, sources=4, conditioning='full')
    # Test source vars not in data/processes
    with pytest.raises(IndexError):
        mi = n._calculate_single_link(
            data, current_value, source_vars=[(0, 0), (10, 0)],
            target_vars=None, sources='all', conditioning='full')
    # Test unknown conditioning
    with pytest.raises(RuntimeError):
        mi = n._calculate_single_link(
            data, current_value, source_vars=[(0, 0)], conditioning='test')