Source code for dit.other.disequilibrium

"""
Disequilibrium, as measured by `Intensive entropic non-triviality measure` by
P.W. Lamberti, M.T. Martin, A. Plastino, O.A. Rosso.
"""

from __future__ import division

import numpy as np

from ..divergences.pmf import jensen_shannon_divergence as JSD
from ..helpers import RV_MODES
from ..shannon import entropy

__all__ = ['disequilibrium',
           'LMPR_complexity',
          ]


[docs]def disequilibrium(dist, rvs=None, rv_mode=None): """ Compute the (normalized) disequilibrium as measured the Jensen-Shannon divergence from an equilibrium distribution. Parameters ---------- dist : Distribution Distribution to compute the disequilibrium of. rvs : list, None The indexes of the random variable used to calculate the diseqilibrium. If None, then the disequilibrium is calculated over all random variables. This should remain `None` for ScalarDistributions. rv_mode : str, None Specifies how to interpret the elements of `rvs`. Valid options are: {'indices', 'names'}. If equal to 'indices', then the elements of `rvs` are interpreted as random variable indices. If equal to 'names', the the elements are interpreted as random variable names. If `None`, then the value of `dist._rv_mode` is consulted. Returns ------- D : float The disequilibrium. """ if dist.is_joint(): if rvs is None: # Set to entropy of entire distribution rvs = list(range(dist.outcome_length())) rv_mode = RV_MODES.INDICES d = dist.marginal(rvs, rv_mode=rv_mode) else: d = dist d = d.copy(base='linear') d.make_dense() pmf = d.pmf Pe = np.ones_like(pmf)/pmf.size Pu = np.zeros_like(pmf); Pu[0] = 1 J = JSD(np.vstack([pmf, Pe])) Q = JSD(np.vstack([Pe, Pu])) D = J/Q return D
[docs]def LMPR_complexity(dist, rvs=None, rv_mode=None): """ Compute the LMPR complexity. Parameters ---------- dist : Distribution Distribution to compute the LMPR complexity of. rvs : list, None The indexes of the random variable used to calculate the LMPR complexity. If None, then the LMPR complexity is calculated over all random variables. This should remain `None` for ScalarDistributions. rv_mode : str, None Specifies how to interpret the elements of `rvs`. Valid options are: {'indices', 'names'}. If equal to 'indices', then the elements of `rvs` are interpreted as random variable indices. If equal to 'names', the the elements are interpreted as random variable names. If `None`, then the value of `dist._rv_mode` is consulted. Returns ------- C : float The LMPR complexity. """ d = dist.copy() d.make_dense() D = disequilibrium(d, rvs, rv_mode) H = entropy(d, rvs, rv_mode)/np.log2(len(d.outcomes)) return D*H