def canonical_averages(ps, microcanonical_averages_arrays):
num_sites = microcanonical_averages_arrays['<STR_LIT:N>']<EOL>num_edges = microcanonical_averages_arrays['<STR_LIT:M>']<EOL>spanning_cluster = ('<STR_LIT>' in microcanonical_averages_arrays)<EOL>ret = dict()<EOL>ret['<STR_LIT>'] = ps<EOL>ret['<STR_LIT:N>'] = num_sites<EOL>ret['<STR_LIT:M>'] = num_edges<EOL>ret['<STR_LIT>'] = np.empty(ps.size)<EOL>ret['<STR_LIT>'] = np.empty((ps.size, <NUM_LIT:2>))<EOL>if spanning_cluster:<EOL><INDENT>ret['<STR_LIT>'] = np.empty(ps.size)<EOL>ret['<STR_LIT>'] = np.empty((ps.size, <NUM_LIT:2>))<EOL><DEDENT>ret['<STR_LIT>'] = np.empty((<NUM_LIT:5>, ps.size))<EOL>ret['<STR_LIT>'] = np.empty((<NUM_LIT:5>, ps.size, <NUM_LIT:2>))<EOL>for p_index, p in enumerate(ps):<EOL><INDENT>binomials = _binomial_pmf(n=num_edges, p=p)<EOL>for key, value in microcanonical_averages_arrays.items():<EOL><INDENT>if len(key) <= <NUM_LIT:1>:<EOL><INDENT>continue<EOL><DEDENT>if key in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>ret[key][p_index] = np.sum(binomials * value)<EOL><DEDENT>elif key in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>ret[key][p_index] = np.sum(<EOL>np.tile(binomials, (<NUM_LIT:2>, <NUM_LIT:1>)).T * value, axis=<NUM_LIT:0><EOL>)<EOL><DEDENT>elif key == '<STR_LIT>':<EOL><INDENT>ret[key][:, p_index] = np.sum(<EOL>np.tile(binomials, (<NUM_LIT:5>, <NUM_LIT:1>)) * value, axis=<NUM_LIT:1><EOL>)<EOL><DEDENT>elif key == '<STR_LIT>':<EOL><INDENT>ret[key][:, p_index] = np.sum(<EOL>np.rollaxis(np.tile(binomials, (<NUM_LIT:5>, <NUM_LIT:2>, <NUM_LIT:1>)), <NUM_LIT:2>, <NUM_LIT:1>) * value,<EOL>axis=<NUM_LIT:1><EOL>)<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError(<EOL>'<STR_LIT>'.format(value.ndim)<EOL>)<EOL><DEDENT><DEDENT><DEDENT>return ret<EOL>
Compute the canonical cluster statistics from microcanonical statistics

This is according to Newman and Ziff, Equation (2).
Note that we also simply average the bounds of the confidence intervals
according to this formula.

Parameters
----------

ps : iterable of float
   Each entry is a probability for which to form the canonical ensemble
   and compute the weighted statistics from the microcanonical statistics

microcanonical_averages_arrays
   Typically the output of :func:`microcanonical_averages_arrays`

Returns
-------

ret : dict
   Canonical ensemble cluster statistics

ret['ps'] : iterable of float
    The parameter `ps`

ret['N'] : int
    Total number of sites

ret['M'] : int
    Total number of bonds

ret['spanning_cluster'] : 1-D :py:class:`numpy.ndarray` of float
    The percolation probability:
    The normalized average number of runs that have a spanning cluster.

ret['spanning_cluster_ci'] : 2-D :py:class:`numpy.ndarray` of float, size 2
    The lower and upper bounds of the percolation probability.

ret['max_cluster_size'] : 1-D :py:class:`numpy.ndarray` of float
    The percolation strength:
    Average relative size of the largest cluster

ret['max_cluster_size_ci'] : 2-D :py:class:`numpy.ndarray` of float
    Lower and upper bounds of the normal confidence interval of the
    percolation strength.

ret['moments'] : 2-D :py:class:`numpy.ndarray` of float, shape (5, M + 1)
    Average raw moments of the (relative) cluster size distribution.

ret['moments_ci'] : 3-D :py:class:`numpy.ndarray` of float, shape (5, M + 1, 2)
    Lower and upper bounds of the normal confidence interval of the raw
    moments of the (relative) cluster size distribution.

See Also
--------

microcanonical_averages

microcanonical_averages_arrays