Esempio n. 1
0
def insert_rv(dist, idx, sigalg):
    """
    Returns a new distribution with a random variable inserted at index `idx`.

    The random variable is constructed according to its induced sigma-algebra.

    Parameters
    ----------
    dist : Distribution
        The distribution which defines the base sigma-algebra.
    idx : int
        The index at which to insert the random variable. To append, set `idx`
        to be equal to -1 or dist.outcome_length().
    sigalg : frozenset
        The sigma-algebra induced by the random variable.

    Returns
    -------
    d : Distribution
        The new distribution.

    """
    from itertools import chain

    if idx == -1:
        idx = dist.outcome_length()

    if not (0 <= idx <= dist.outcome_length()):
        raise IndexError('Invalid insertion index.')

    # Provide sane sorting of atoms
    atoms = atom_set(sigalg)
    atoms = [sorted(atom) for atom in atoms]
    atoms.sort(key=lexico_key)
    labels = range(len(atoms))
    if dist._outcome_class == str:
        # Then the labels for the new random variable must be strings.
        labels = map(str, labels)

    # Create an index from outcomes to atoms.
    atom_of = {}
    for label, atom in zip(labels, atoms):
        for outcome in atom:
            atom_of[outcome] = label

    if idx == dist.outcome_length():
        def new_outcome_ctor(outcome, ctor=dist._outcome_ctor):
            new_outcome = [ outcome, [atom_of[outcome]] ]
            return ctor(chain.from_iterable(new_outcome))
    elif idx == 0:
        def new_outcome_ctor(outcome, ctor=dist._outcome_ctor):
            new_outcome = [ [atom_of[outcome]], outcome ]
            return ctor(chain.from_iterable(new_outcome))
    else:
        def new_outcome_ctor(outcome, ctor=dist._outcome_ctor):
            new_outcome = [ outcome[:idx], [atom_of[outcome]], outcome[idx:] ]
            return ctor(chain.from_iterable(new_outcome))

    d = dit.modify_outcomes(dist, new_outcome_ctor)
    return d
Esempio n. 2
0
def test_product_with_rvs2():
    """
    Test product_distribution() with an rvs specification.
    """
    d = dit.example_dists.Xor()
    d_iid = dit.product_distribution(d, [[0, 1]])
    d_truth = dit.uniform_distribution(2, ['01'])
    d_truth = dit.modify_outcomes(d_truth, lambda x: ''.join(x))
    assert d_truth.is_approx_equal(d_iid)
Esempio n. 3
0
def test_product():
    """
    Smoke test for product_distribution().
    """
    d = dit.example_dists.Xor()
    d_iid = dit.product_distribution(d)
    d_truth = dit.uniform_distribution(3, ['01'])
    d_truth = dit.modify_outcomes(d_truth, lambda x: ''.join(x))
    assert d_truth.is_approx_equal(d_iid)
Esempio n. 4
0
def test_product_with_rvs2():
    """
    Test product_distribution() with an rvs specification.

    """
    d = dit.example_dists.Xor()
    d_iid = dit.product_distribution(d, [[0,1]])
    d_truth = dit.uniform_distribution(2, ['01'])
    d_truth = dit.modify_outcomes(d_truth, lambda x: ''.join(x))
    assert_true(d_truth.is_approx_equal(d_iid))
Esempio n. 5
0
def test_product():
    """
    Smoke test for product_distribution().

    """
    d = dit.example_dists.Xor()
    d_iid = dit.product_distribution(d)
    d_truth = dit.uniform_distribution(3, ['01'])
    d_truth = dit.modify_outcomes(d_truth, lambda x: ''.join(x))
    assert_true(d_truth.is_approx_equal(d_iid))
Esempio n. 6
0
def test_insert_rvf2():
    # Test multiple insertion.
    d = dit.uniform_distribution(2, 2)
    d = dit.modify_outcomes(d, lambda x: ''.join(map(str, x)))
    def xor(outcome):
        o = str(int(outcome[0] != outcome[1]))
        # Here we are returning 2 random variables
        return o*2
    # We are also inserting two times simultaneously.
    d2 = dit.insert_rvf(d, [xor, xor])
    outcomes = ('000000', '011111', '101111', '110000')
    assert_equal(d2.outcomes, outcomes)
Esempio n. 7
0
def test_insert_rvf2():
    # Test multiple insertion.
    d = dit.uniform_distribution(2, 2)
    d = dit.modify_outcomes(d, lambda x: ''.join(map(str, x)))
    def xor(outcome):
        o = str(int(outcome[0] != outcome[1]))
        # Here we are returning 2 random variables
        return o*2
    # We are also inserting two times simultaneously.
    d2 = dit.insert_rvf(d, [xor, xor])
    outcomes = ('000000', '011111', '101111', '110000')
    assert d2.outcomes == outcomes
Esempio n. 8
0
def test_coarsegrain():
    d = dit.example_dists.Xor()
    d2 = dit.modify_outcomes(d, lambda x: '1' if '1' in x else '0')
    assert_equal(d2.outcomes, ('0', '1'))
    np.testing.assert_allclose(d2.pmf, [.25, .75])
Esempio n. 9
0
def insert_rv(dist, idx, sigalg):
    """
    Returns a new distribution with a random variable inserted at index `idx`.

    The random variable is constructed according to its induced sigma-algebra.

    Parameters
    ----------
    dist : Distribution
        The distribution which defines the base sigma-algebra.
    idx : int
        The index at which to insert the random variable. To append, set `idx`
        to be equal to -1 or dist.outcome_length().
    sigalg : frozenset
        The sigma-algebra induced by the random variable.

    Returns
    -------
    d : Distribution
        The new distribution.

    """
    from itertools import chain

    if idx == -1:
        idx = dist.outcome_length()

    if not 0 <= idx <= dist.outcome_length():
        raise IndexError('Invalid insertion index.')

    # Provide sane sorting of atoms
    atoms = atom_set(sigalg)
    atoms = [sorted(atom) for atom in atoms]
    atoms.sort(key=quasilexico_key)
    if dist._outcome_class == str:
        # Then the labels for the new random variable must be strings.
        from string import ascii_letters, digits
        labels = (digits + ascii_letters)[:len(atoms)]
    else:
        labels = range(len(atoms))

    # Create an index from outcomes to atoms.
    atom_of = {}
    for label, atom in zip(labels, atoms):
        for outcome in atom:
            atom_of[outcome] = label

    if idx == dist.outcome_length():
        def new_outcome_ctor(outcome, ctor=dist._outcome_ctor):
            """The end of the outcome"""
            new_outcome = [outcome, [atom_of[outcome]]]
            return ctor(chain.from_iterable(new_outcome))
    elif idx == 0:
        def new_outcome_ctor(outcome, ctor=dist._outcome_ctor):
            """The beginning of the outcome"""
            new_outcome = [[atom_of[outcome]], outcome]
            return ctor(chain.from_iterable(new_outcome))
    else:
        def new_outcome_ctor(outcome, ctor=dist._outcome_ctor):
            """In the middle of the outcome"""
            new_outcome = [outcome[:idx], [atom_of[outcome]], outcome[idx:]]
            return ctor(chain.from_iterable(new_outcome))

    d = dit.modify_outcomes(dist, new_outcome_ctor)
    return d
Esempio n. 10
0
"""
Tests for dit.multivariate.secret_key_agreement.trivial_bounds.
"""
from __future__ import division

import pytest

import dit
from dit.multivariate import (upper_intrinsic_total_correlation,
                              upper_intrinsic_dual_total_correlation,
                              upper_intrinsic_caekl_mutual_information,
                              )


dist = dit.modify_outcomes(dit.example_dists.giant_bit(4, 2).__matmul__(dit.example_dists.n_mod_m(4, 2)),
                           lambda o: tuple(a+b for a, b in zip(o[:4], o[4:])))


def test_uitc1():
    """
    Test against known value.
    """
    value = upper_intrinsic_total_correlation(dist, dist.rvs[:-1], dist.rvs[-1])
    assert value == pytest.approx(1.0)


def test_uidtc1():
    """
    Test against known value.
    """
    value = upper_intrinsic_dual_total_correlation(dist, dist.rvs[:-1], dist.rvs[-1])
Esempio n. 11
0
def test_coarsegrain():
    d = dit.example_dists.Xor()
    d2 = dit.modify_outcomes(d, lambda x: '1' if '1' in x else '0')
    assert_equal(d2.outcomes, ('0', '1'))
    np.testing.assert_allclose(d2.pmf, [.25, .75])
Esempio n. 12
0
"""
Tests for dit.multivariate.secret_key_agreement.trivial_bounds.
"""

import pytest

import dit
from dit.multivariate import (
    upper_intrinsic_total_correlation,
    upper_intrinsic_dual_total_correlation,
    upper_intrinsic_caekl_mutual_information,
)

dist = dit.modify_outcomes(
    dit.example_dists.giant_bit(4,
                                2).__matmul__(dit.example_dists.n_mod_m(4, 2)),
    lambda o: tuple(a + b for a, b in zip(o[:4], o[4:])))


def test_uitc1():
    """
    Test against known value.
    """
    value = upper_intrinsic_total_correlation(dist, dist.rvs[:-1],
                                              dist.rvs[-1])
    assert value == pytest.approx(1.0)


def test_uidtc1():
    """
    Test against known value.
Esempio n. 13
0
def test_coarsegrain():
    d = dit.example_dists.Xor()
    d2 = dit.modify_outcomes(d, lambda x: '1' if '1' in x else '0')
    assert d2.outcomes == ('0', '1')
    assert np.allclose(d2.pmf, [0.25, 0.75])
Esempio n. 14
0
def test_coarsegrain():
    d = dit.example_dists.Xor()
    d2 = dit.modify_outcomes(d, lambda x: '1' if '1' in x else '0')
    assert d2.outcomes == ('0', '1')
    assert np.allclose(d2.pmf, [.25, .75])