Operations

There are several operations possible on joint random variables. Let’s consider the standard xor distribution:

In [1]: d = dit.Distribution(['000', '011', '101', '110'], [1/4]*4)

In [2]: d.set_rv_names('XYZ')

Marginal

dit supports two ways of selecting only a subset of random variables. marginal() returns a distribution containing only the random variables specified, whereas marginalize() return a distribution containing all random variables except the ones specified:

In [3]: print(d.marginal(['X', 'Y']))
Class:    Distribution
Alphabet: (('0', '1'), ('0', '1'))
Base:     linear

x            p(X,Y)
('0', '0')   1/4
('0', '1')   1/4
('1', '0')   1/4
('1', '1')   1/4

In [4]: print(d.marginalize(['X', 'Y']))
Class:    Distribution
Alphabet: (('0', '1'),)
Base:     linear

x        p(Z)
('0',)   1/2
('1',)   1/2
Distribution.marginal(*args)[source]

Marginalise to keep only the specified free variables.

Given (conditioned) variables are always kept.

Supports two call signatures:

  • marginal('X', 'Y') – positional variable names

  • marginal(['X', 'Y']) – list of names (or integer indices)

Parameters:

*args (str, or a single list/tuple) – The free variable names to keep. Integer indices are auto-resolved to dimension names.

Returns:

result

Return type:

Distribution

Distribution.marginalize(*args)[source]

Marginalise out (remove) the specified free variables.

Supports two call signatures:

  • marginalize('X') – positional variable names

  • marginalize(['X']) – list of names (or integer indices)

Parameters:

*args (str, or a single list/tuple) – The free variable names to remove.

Returns:

result

Return type:

Distribution

Conditional

We can also condition on a subset of random variables:

In [5]: marginal, cdists = d.condition_on(['X', 'Y'], rvs=['Z'])

In [6]: print(marginal)
Class:    Distribution
Alphabet: (('0', '1'), ('0', '1'))
Base:     linear

x            p(X,Y)
('0', '0')   1/4
('0', '1')   1/4
('1', '0')   1/4
('1', '1')   1/4

In [7]: print(cdists[0]) # XY = 00
Class:    Distribution
Alphabet: (('0', '1'),)
Base:     linear

x        p(Z)
('0',)   1

In [8]: print(cdists[1]) # XY = 01
Class:    Distribution
Alphabet: (('0', '1'),)
Base:     linear

x        p(Z)
('1',)   1

In [9]: print(cdists[2]) # XY = 10
Class:    Distribution
Alphabet: (('0', '1'),)
Base:     linear

x        p(Z)
('1',)   1

In [10]: print(cdists[3]) # XY = 11
Class:    Distribution
Alphabet: (('0', '1'),)
Base:     linear

x        p(Z)
('0',)   1
Distribution.condition_on(*cond_vars, rvs=None, crvs=None)[source]

Condition on the specified free variables.

Supports two call signatures:

  • Native: condition_on('X', 'Y') – positional var names. Returns a single conditional Distribution.

  • dit-compat: any of these forms triggers the dit-compatible return format (marginal, list_of_conditionals):

    • condition_on(crvs=['X'], rvs=['Y'])

    • condition_on(['X'], rvs=['Y']) (positional crvs)

    • condition_on(crvs=['X'])

    The returned list contains one Distribution per outcome of the conditioning variable.

Parameters:
  • *cond_vars (str, or a single list/tuple) – Variable names to condition on. If a single list/tuple is passed and rvs is provided, it is interpreted as crvs (dit-compat positional form).

  • rvs (list, optional) – Variables to keep in the conditional (dit-compat API).

  • crvs (list, optional) – Variables to condition on (dit-compat API).

Returns:

result – A single conditional distribution (native), or a (marginal, list_of_Distributions) tuple (dit-compat).

Return type:

Distribution or tuple

Examples

>>> p_xyz.condition_on('Z')   # native: returns p(X,Y|Z)
>>> p_xyz.condition_on('X', 'Y')  # native: returns p(Z|X,Y)
>>> marg, cdists = p_xyz.condition_on(crvs=['Z'])  # dit-compat
>>> marg, cdists = p_xyz.condition_on(['Z'], rvs=['X'])  # dit-compat

Join

We can construct the join of two random variables:

\[X \join Y = \min \{ V | V \imore X \land V \imore Y \}\]

Where \(\min\) is understood to be minimizing with respect to the entropy.

In [11]: from dit.algorithms.lattice import join

In [12]: print(join(d, ['XY']))
Class:    Distribution
Alphabet: (0, 1, 2, 3)
Base:     linear

x   p(x)
0   1/4
1   1/4
2   1/4
3   1/4
join(dist, rvs, int_outcomes=True)[source]

Returns the distribution of the join of random variables defined by rvs.

Parameters:
  • dist (Distribution) – The distribution which defines the base sigma-algebra.

  • rvs (list) – A list of lists. Each list specifies a random variable to be joined with the other lists. Each random variable can defined as a series of unique indexes. Multiple random variables can use the same index. For example, [[0, 1], [1, 2]].

  • int_outcomes (bool) – If True, then the outcomes of the join are relabeled as integers instead of as the atoms of the induced sigma-algebra.

Returns:

d – The distribution of the join.

Return type:

Distribution

insert_join(dist, idx, rvs, support_only=False)[source]

Returns a new distribution with the join inserted at index idx.

The join of the random variables in rvs is constructed and then inserted into at index idx.

Parameters:
  • dist (Distribution) – The distribution which defines the base sigma-algebra.

  • idx (int) – The index at which to insert the join. To append the join, set idx to be equal to -1 or dist.outcome_length().

  • rvs (list) – A list of lists. Each list specifies a random variable to be met with the other lists. Each random variable can defined as a series of unique indexes. Multiple random variables can use the same index. For example, [[0, 1], [1, 2]].

  • support_only (bool) – If True, only consider outcomes with non-zero probability.

Returns:

d – The new distribution with the join at index idx.

Return type:

Distribution

Meet

We can construct the meet of two random variabls:

\[X \meet Y = \max \{ V | V \iless X \land V \iless Y \}\]

Where \(\max\) is understood to be maximizing with respect to the entropy.

In [13]: from dit.algorithms.lattice import meet

In [14]: outcomes = ['00', '01', '10', '11', '22', '33']

In [15]: d2 = dit.Distribution(outcomes, [1/8]*4 + [1/4]*2, sample_space=outcomes)

In [16]: d2.set_rv_names('XY')

In [17]: print(meet(d2, ['X', 'Y']))
Class:    Distribution
Alphabet: (0,)
Base:     linear

x   p(x)
0   1
meet(dist, rvs, int_outcomes=True)[source]

Returns the distribution of the meet of random variables defined by rvs.

Parameters:
  • dist (Distribution) – The distribution which defines the base sigma-algebra.

  • rvs (list) – A list of lists. Each list specifies a random variable to be met with the other lists. Each random variable can defined as a series of unique indexes. Multiple random variables can use the same index. For example, [[0, 1], [1, 2]].

  • int_outcomes (bool) – If True, then the outcomes of the meet are relabeled as integers instead of as the atoms of the induced sigma-algebra.

Returns:

d – The distribution of the meet.

Return type:

Distribution

insert_meet(dist, idx, rvs, support_only=False)[source]

Returns a new distribution with the meet inserted at index idx.

The meet of the random variables in rvs is constructed and then inserted into at index idx.

Parameters:
  • dist (Distribution) – The distribution which defines the base sigma-algebra.

  • idx (int) – The index at which to insert the meet. To append the meet, set idx to be equal to -1 or dist.outcome_length().

  • rvs (list) – A list of lists. Each list specifies a random variable to be met with the other lists. Each random variable can defined as a series of unique indexes. Multiple random variables can use the same index. For example, [[0,1],[1,2]].

  • support_only (bool) – If True, only consider outcomes with non-zero probability.

Returns:

d – The new distribution with the meet at index idx.

Return type:

Distribution

Minimal Sufficient Statistic

This method constructs the minimal sufficient statistic of \(X\) about \(Y\): \(X \mss Y\):

\[X \mss Y = \min \{ V | V \iless X \land \I{X:Y} = \I{V:Y} \}\]
In [18]: from dit.algorithms import insert_mss

In [19]: d2 = dit.Distribution(['00', '01', '10', '11', '22', '33'], [1/8]*4 + [1/4]*2)

In [20]: print(insert_mss(d2, -1, [0], [1]))
Class:    Distribution
Alphabet: (('0', '1', '2', '3'), ('0', '1', '2', '3'), (0, 1, 2))
Base:     linear

x               p(X0,X1,X2)
('0', '0', 2)   1/8
('0', '1', 2)   1/8
('1', '0', 2)   1/8
('1', '1', 2)   1/8
('2', '2', 0)   1/4
('3', '3', 1)   1/4

Again, \(\min\) is understood to be over entropies.

mss(dist, rvs, about=None, int_outcomes=True)[source]
Parameters:
  • dist (Distribution) – The distribution which defines the base sigma-algebra.

  • rvs (list) – A list of random variables to be compressed into a minimal sufficient statistic.

  • about (list) – A list of random variables for which the minimal sufficient static will retain all information about.

  • int_outcomes (bool) – If True, then the outcomes of the minimal sufficient statistic are relabeled as integers instead of as the atoms of the induced sigma-algebra.

Returns:

d – The distribution of the minimal sufficient statistic.

Return type:

Distribution

Examples

>>> d = Xor()
>>> print(mss(d, [0], [1, 2]))
Class:    Distribution
Alphabet: (0, 1)
Base:     linear
x   p(x)
0   0.5
1   0.5
insert_mss(dist, idx, rvs, about=None)[source]

Inserts the minimal sufficient statistic of rvs about about into dist at index idx.

Parameters:
  • dist (Distribution) – The distribution which defines the base sigma-algebra.

  • idx (int) – The location in the distribution to insert the minimal sufficient statistic.

  • rvs (list) – A list of random variables to be compressed into a minimal sufficient statistic.

  • about (list) – A list of random variables for which the minimal sufficient static will retain all information about.

Returns:

d – The distribution dist modified to contain the minimal sufficient statistic.

Return type:

Distribution

Examples

>>> d = Xor()
>>> print(insert_mss(d, -1, [0], [1, 2]))
Class:          Distribution
Alphabet:       ('0', '1') for all rvs
Base:           linear
Outcome Class:  str
Outcome Length: 4
RV Names:       None
x      p(x)
0000   0.25
0110   0.25
1011   0.25
1101   0.25