Exemplo n.º 1
0
def max_individual(input: dit.Distribution,
                   conditional: np.ndarray,
                   eps: float = 0.01,
                   minimal_entropy_idx=None):
    rvs = input.get_rv_names()
    conditional = conditional / conditional.sum()
    states = len(input.alphabet[0])
    if not minimal_entropy_idx == 0 and not minimal_entropy_idx:
        minimal_entropy_idx = np.argmin([
            entropy(input.marginal([rv], rv_mode='indices').pmf)
            for rv in range(len(rvs))
        ])

    non_minimal_rvs = rvs[:minimal_entropy_idx] + rvs[minimal_entropy_idx + 1:]
    non_minimal_marginal, minimal_conditional = input.condition_on(
        non_minimal_rvs)
    [d.make_dense() for d in minimal_conditional]
    # minimal_conditional = np.stack([d.pmf for d in minimal_conditional])
    # print("minimal_conditional:",minimal_conditional)
    indiv_shape = (len(minimal_conditional), len(minimal_conditional[0]))

    # minimal_conditional = minimal_conditional.flatten()
    nudge_vector = np.zeros(indiv_shape)
    rotated_conditional = R(conditional, minimal_entropy_idx, len(rvs), states)
    total_max_impact = 0
    # print(len(rvs), (eps / 2)/len(minimal_conditional))
    for i, mc_dist in enumerate(minimal_conditional):

        rows = rotated_conditional[i * states:(i + 1) * states, :]

        max_impact = 0
        for allignment in itertools.product(
            [-1, 1], repeat=rotated_conditional.shape[1]):
            allignment = np.array(allignment)
            if np.all(allignment == 1) or np.all(allignment == -1):
                continue
            scores = np.sum(allignment * rows, axis=1)

            # Add rotation of scores so that scores are well aligned.
            # Weigh scores using the non_minimal_marginal

            vector, impact = find_max_impact(scores, mc_dist.pmf, (eps / 2) /
                                             len(minimal_conditional))
            if impact > max_impact:
                nudge_vector[i, :] = vector
                max_impact = impact
        total_max_impact += max_impact
    return nudge_vector, total_max_impact, minimal_entropy_idx
Exemplo n.º 2
0
def max_local(input: dit.Distribution,
              conditional: np.ndarray,
              eps: float = 0.01):
    rvs = input.get_rv_names()
    sorted_rvs = np.argsort([
        entropy(input.marginal([rv], rv_mode='indices').pmf)
        for rv in range(len(rvs))
    ])
    nudge_vectors = np.zeros(
        (input.outcome_length(), int(len(input) / 3), 3)
    )  # For each random variable we get (hopefully) a different nudge vector of len the input size
    max_impacts = np.zeros(input.outcome_length())
    for rv in sorted_rvs:
        nudge_vectors[rv, :, :], max_impacts[rv], _ = max_individual(
            input, conditional, eps / len(sorted_rvs), rv)
    return nudge_vectors, max_impacts
Exemplo n.º 3
0
def test_to_string8():
    outcomes = ['00', '01', '10', '11']
    pmf = [1/4]*4
    d = Distribution(outcomes, pmf)
    d = d.marginal([0])
    s = d.to_string(show_mask='!')
    s_ = """Class:          Distribution
Alphabet:       ('0', '1') for all rvs
Base:           linear
Outcome Class:  str
Outcome Length: 1 (mask: 2)
RV Names:       None

x    p(x)
0!   0.5
1!   0.5"""
    assert_equal(s, s_)
Exemplo n.º 4
0
def test_to_string8():
    outcomes = ['00', '01', '10', '11']
    pmf = [1/4]*4
    d = Distribution(outcomes, pmf)
    d = d.marginal([0])
    s = d.to_string(show_mask='!')
    s_ = """Class:          Distribution
Alphabet:       ('0', '1') for all rvs
Base:           linear
Outcome Class:  str
Outcome Length: 1 (mask: 2)
RV Names:       None

x    p(x)
0!   0.5
1!   0.5"""
    assert s == s_
Exemplo n.º 5
0
def test_to_string4():
    # Basic with marginal
    outcomes = ['00', '01', '10', '11']
    pmf = [1/4]*4
    d = Distribution(outcomes, pmf)
    d = d.marginal([0])
    s = d.to_string()
    s_ = """Class:          Distribution
Alphabet:       ('0', '1') for all rvs
Base:           linear
Outcome Class:  str
Outcome Length: 1
RV Names:       None

x   p(x)
0   0.5
1   0.5"""
    assert_equal(s, s_)
Exemplo n.º 6
0
def test_to_string4():
    # Basic with marginal
    outcomes = ['00', '01', '10', '11']
    pmf = [1/4]*4
    d = Distribution(outcomes, pmf)
    d = d.marginal([0])
    s = d.to_string()
    s_ = """Class:          Distribution
Alphabet:       ('0', '1') for all rvs
Base:           linear
Outcome Class:  str
Outcome Length: 1
RV Names:       None

x   p(x)
0   0.5
1   0.5"""
    assert s == s_
Exemplo n.º 7
0
def test_to_string5():
    # Basic with marginal and mask
    outcomes = ['00', '01', '10', '11']
    pmf = [1 / 4] * 4
    d = Distribution(outcomes, pmf)
    d = d.marginal([0])
    s = d.to_string(show_mask=True)
    s_ = """Class:          Distribution
Alphabet:       ('0', '1') for all rvs
Base:           linear
Outcome Class:  str
Outcome Length: 1 (mask: 2)
RV Names:       None

x    p(x)
0*   0.5
1*   0.5"""
    assert_equal(s, s_)
Exemplo n.º 8
0
def max_local_nudge2(old_X: dit.Distribution,
                     YgivenX: np.ndarray,
                     eps: float = 0.01):
    if old_X.outcome_length() == 1:
        return max_global_nudge(old_X, YgivenX, eps)

    mask = old_X._mask
    base = old_X.get_base()
    new_X = old_X.copy(base=base)
    old_X.make_dense()
    rvs = old_X.get_rv_names()
    sorted_rvs = np.argsort([
        entropy(old_X.marginal([rv], rv_mode='indices').pmf)
        for rv in range(len(rvs))
    ])
    oldshape = len(old_X)
    outcomes = old_X.outcomes
    # print("before", new_X.pmf.shape)
    for i, rv in enumerate(sorted_rvs):
        nudges, _ = max_nudge(new_X.copy('linear'),
                              YgivenX,
                              eps=(eps / len(sorted_rvs)),
                              nudge_type='individual',
                              minimal_entropy_idx=rv)
        #        print("local eps",sum([sum(abs(nudge)) for nudge in nudges]), eps, old_X.outcome_length())
        new_X = do_max_individual_nudge(new_X, nudges, rv, True)
        # print("after {}".format(i), new_X.pmf.shape)
        new_X.make_dense()
        newshape = len(new_X)
    #  if oldshape != newshape:
    #      print(nudges)
    #   print("after {} and making dense".format(i), new_X.pmf.shape)
    dct = {o: new_X[o] if o in new_X.outcomes else 0.0 for o in outcomes}
    #print(outcomes, dct)
    new_X = dit.Distribution(dct)
    new_X.set_rv_names(rvs)
    new_X._mask = mask
    return new_X