def log_average(psis, z, F, g1data, g2data=None, neighbors=None, iat_method=DEFAULT_IAT): """Estimates the asymptotic variance in the EMUS estimate of :math:`-log <g_1>/<g_2>`. If :math:`g_2` data is not provided, it estimates the asymptotic variance in the estimate of :math:`-log <g_1>/<g_2>`. Input and output is as in average_ratio. Note that if this is used for free energy differences, the result does not use the Boltzmann factor (i.e. :math:`k_B T=1`). In that case, resulting variances should be scaled by the Boltzmann factor *squared*. """ # Clean the input and set defaults L = len(psis) if neighbors is None: neighbors = np.outer(np.ones(L), range(L)).astype(int) g1data = [np.array(g1i).flatten() for g1i in g1data] if g2data is None: g2data = [np.ones(np.shape(g1data_i)) for g1data_i in g1data] # Compute average of functions in each window. g1star = emus._calculate_win_avgs(psis, z, g1data) g2star = emus._calculate_win_avgs(psis, z, g2data) g1avg = np.dot(g1star, z) g2avg = np.dot(g2star, z) # Compute partial derivatives gI = lm.groupInverse(np.eye(L) - F) for i in xrange(L): dBdF = np.outer(z, np.dot(gI, g1star / g1avg - g2star / g2avg)) dBdg1 = z / g1avg dBdg2 = -z / g2avg iats, variances = _calculate_acovar( psis, dBdF, (g1data, g2data), (dBdg1, dBdg2), neighbors=neighbors, iat_method=iat_method ) return iats, -np.log(g1avg / g2avg), variances
def average_ratio(psis, z, F, g1data, g2data=None, neighbors=None, iat_method=DEFAULT_IAT): """Estimates the asymptotic variance in the estimate of :math:`<g_1>/<g_2>`. If :math:`g_2` is not given, it just calculates the asymptotic variance associated with the average of :math:`g_1`. Parameters ---------- psis : 3D data structure The values of the bias functions evaluated each window and timepoint. See `datastructures <../datastructures.html#data-from-sampling>`__ for more information. z : 1D array Array containing the normalization constants F : 2D array Overlap matrix for the first EMUS iteration. g1data : 2D data structure Trajectory of observable in the numerator. First dimension corresponds to the window index and the second to the point in the trajectory. g2data : 2D data structure, optional Trajectory of observable in the denominator of the ratio. neighbors : 2D array, optional List showing which windows neighbor which. Element i,j is the j'th neighboring window of window i. iat_method : string, optional Method used to estimate autocorrelation time. Choices are 'acor', 'ipce', and 'icce'. Returns ------- iats : ndarray Array of length L (no. windows) where the i'th value corresponds to the iat for window i's contribution to the error. mean : scalar Estimate of the ratio variances : ndarray Array of length L (no. windows) where the i'th value corresponds to the autocovariance corresponding to window i's contribution to the error. The total autocavariance of the ratio can be calculated by summing over the array. """ # Clean the input and set defaults L = len(psis) if neighbors is None: neighbors = np.outer(np.ones(L), range(L)).astype(int) g1data = [np.array(g1i).flatten() for g1i in g1data] if g2data is None: g2data = [np.ones(np.shape(g1data_i)) for g1data_i in g1data] # Compute average of functions in each window. g1star = emus._calculate_win_avgs(psis, z, g1data) g2star = emus._calculate_win_avgs(psis, z, g2data) g1avg = np.dot(g1star, z) g2avg = np.dot(g2star, z) # Compute partial derivatives gI = lm.groupInverse(np.eye(L) - F) for i in xrange(L): dBdF = np.outer(z, np.dot(gI, g1star - g1avg / g2avg * g2star)) / g2avg dBdg1 = z / g2avg dBdg2 = -(g1avg / g2avg) * z / g2avg iats, variances = _calculate_acovar( psis, dBdF, (g1data, g2data), (dBdg1, dBdg2), neighbors=neighbors, iat_method=iat_method ) return iats, g1avg / g2avg, variances