Distributions
Distribution is the core class in dit. It represents a
probability distribution over discrete random variables as an xarray DataArray: each dimension is a
random variable, the coordinates along that dimension are the variable’s
alphabet, and the array values are probabilities.
The class tracks which dimensions are free (being described) versus given (conditioned on). A joint \(p(X,Y,Z)\) has three free variables and no given variables; a conditional \(p(Z \mid X,Y)\) has free variable \(Z\) and given variables \(X,Y\). That metadata is what makes the chain-rule algebra in Algebra work.
By default, unnamed variables are called X0, X1, … . Call
set_rv_names() to give them readable names.
Walkthrough
Construct the exclusive-or distribution, name its variables, take a marginal, and condition:
In [1]: from dit import Distribution
In [2]: d = Distribution(['000', '011', '101', '110'], [1/4]*4)
In [3]: d.set_rv_names('XYZ')
In [4]: print(d)
Class: Distribution
Alphabet: (('0', '1'), ('0', '1'), ('0', '1'))
Base: linear
x p(X,Y,Z)
('0', '0', '0') 0.25
('0', '1', '1') 0.25
('1', '0', '1') 0.25
('1', '1', '0') 0.25
In [5]: print(d.marginal('X', 'Y'))
Class: Distribution
Alphabet: (('0', '1'), ('0', '1'))
Base: linear
x p(X,Y)
('0', '0') 0.25
('0', '1') 0.25
('1', '0') 0.25
('1', '1') 0.25
In [6]: print(d.condition_on('X', 'Y'))
Class: Distribution
Alphabet: (('0', '1'), ('0', '1'), ('0', '1'))
Base: linear
x p(Z|X,Y)
('0', '0', '0') 1.0
('0', '1', '1') 1.0
('1', '0', '1') 1.0
('1', '1', '0') 1.0
The header p(Z|X,Y) is the distribution’s notation: free variables before
the bar, given variables after. Native condition_on()
returns that single conditional, not a list of slices.
See also the Symbolic page for sympy-valued probabilities.