def test_mbar_computeOverlap(): # tests with identical states, which gives analytical results. d = len(N_k) even_O_k = 2.0*np.ones(d) even_K_k = 0.5*np.ones(d) even_N_k = 100*np.ones(d) name, test = generate_ho(O_k = even_O_k, K_k = even_K_k) x_n, u_kn, N_k_output, s_n = test.sample(even_N_k, mode='u_kn') mbar = MBAR(u_kn, even_N_k) overlap_scalar, eigenval, O = mbar.computeOverlap() reference_matrix = np.matrix((1.0/d)*np.ones([d,d])) reference_eigenvalues = np.zeros(d) reference_eigenvalues[0] = 1.0 reference_scalar = np.float64(1.0) eq(O, reference_matrix, decimal=precision) eq(eigenval, reference_eigenvalues, decimal=precision) eq(overlap_scalar, reference_scalar, decimal=precision) # test of more straightforward examples for system_generator in system_generators: name, test = system_generator() x_n, u_kn, N_k_output, s_n = test.sample(N_k, mode='u_kn') mbar = MBAR(u_kn, N_k) overlap_scalar, eigenval, O = mbar.computeOverlap() # rows of matrix should sum to one sumrows = np.array(np.sum(O,axis=1)) eq(sumrows, np.ones(np.shape(sumrows)), decimal=precision) eq(eigenval[0], np.float64(1.0), decimal=precision)
def test_mbar_computeOverlap(): # tests with identical states, which gives analytical results. d = len(N_k) even_O_k = 2.0 * np.ones(d) even_K_k = 0.5 * np.ones(d) even_N_k = 100 * np.ones(d) name, test = generate_ho(O_k=even_O_k, K_k=even_K_k) x_n, u_kn, N_k_output, s_n = test.sample(even_N_k, mode='u_kn') mbar = MBAR(u_kn, even_N_k) overlap_scalar, eigenval, O = mbar.computeOverlap() reference_matrix = np.matrix((1.0 / d) * np.ones([d, d])) reference_eigenvalues = np.zeros(d) reference_eigenvalues[0] = 1.0 reference_scalar = np.float64(1.0) eq(O, reference_matrix, decimal=precision) eq(eigenval, reference_eigenvalues, decimal=precision) eq(overlap_scalar, reference_scalar, decimal=precision) # test of more straightforward examples for system_generator in system_generators: name, test = system_generator() x_n, u_kn, N_k_output, s_n = test.sample(N_k, mode='u_kn') mbar = MBAR(u_kn, N_k) overlap_scalar, eigenval, O = mbar.computeOverlap() # rows of matrix should sum to one sumrows = np.array(np.sum(O, axis=1)) eq(sumrows, np.ones(np.shape(sumrows)), decimal=precision) eq(eigenval[0], np.float64(1.0), decimal=precision)
def run_mbar(self, test_overlap = True): r"""Runs MBAR free energy estimate """ MBAR_obj = MBAR(self._u_kln, self._N_k, verbose=True) self._f_k = MBAR_obj.f_k try: (deltaF_ij, dDeltaF_ij, theta_ij) = MBAR_obj.getFreeEnergyDifferences() except: (deltaF_ij, dDeltaF_ij, theta_ij) = MBAR_obj.getFreeEnergyDifferences(return_theta=True) self._deltaF_mbar = deltaF_ij[0, self._lambda_array.shape[0]-1] self._dDeltaF_mbar = dDeltaF_ij[0, self._lambda_array.shape[0]-1] self._pmf_mbar = numpy.zeros(shape=(self._lambda_array.shape[0], 3)) self._pmf_mbar[:, 0] = self._lambda_array self._pmf_mbar[:, 1] = self._f_k self._pmf_mbar[:,2] = dDeltaF_ij[0] self._pairwise_F = numpy.zeros(shape=(self._lambda_array.shape[0]-1,4)) self._pairwise_F[:,0] = self._lambda_array[:-1] self._pairwise_F[:,1] = self._lambda_array[1:] self._pairwise_F[:,2] = numpy.diag(deltaF_ij,1) self._pairwise_F[:,3] = numpy.diag(dDeltaF_ij,1) ##testing data overlap: if test_overlap: overlap_matrix = MBAR_obj.computeOverlap() self._overlap_matrix = overlap_matrix[2]
class MBAR(BaseEstimator): """Multi-state Bennett acceptance ratio (MBAR). Parameters ---------- maximum_iterations : int, optional Set to limit the maximum number of iterations performed. relative_tolerance : float, optional Set to determine the relative tolerance convergence criteria. initial_f_k : np.ndarray, float, shape=(K), optional Set to the initial dimensionless free energies to use as a guess (default None, which sets all f_k = 0). method : str, optional, default="hybr" The optimization routine to use. This can be any of the methods available via scipy.optimize.minimize() or scipy.optimize.root(). verbose : bool, optional Set to True if verbose debug output is desired. Attributes ---------- delta_f_ : DataFrame The estimated dimensionless free energy difference between each state. d_delta_f_ : DataFrame The estimated statistical uncertainty (one standard deviation) in dimensionless free energy differences. theta_ : DataFrame The theta matrix. states_ : list Lambda states for which free energy differences were obtained. """ def __init__(self, maximum_iterations=10000, relative_tolerance=1.0e-7, initial_f_k=None, method='hybr', verbose=False): self.maximum_iterations = maximum_iterations self.relative_tolerance = relative_tolerance self.initial_f_k = initial_f_k self.method = [dict(method=method)] self.verbose = verbose # handle for pymbar.MBAR object self._mbar = None def fit(self, u_nk): """ Compute overlap matrix of reduced potentials using multi-state Bennett acceptance ratio. Parameters ---------- u_nk : DataFrame u_nk[n,k] is the reduced potential energy of uncorrelated configuration n evaluated at state k. """ # sort by state so that rows from same state are in contiguous blocks u_nk = u_nk.sort_index(level=u_nk.index.names[1:]) groups = u_nk.groupby(level=u_nk.index.names[1:]) N_k = [(len(groups.get_group(i)) if i in groups.groups else 0) for i in u_nk.columns] self._mbar = MBAR_(u_nk.T, N_k, maximum_iterations=self.maximum_iterations, relative_tolerance=self.relative_tolerance, initial_f_k=self.initial_f_k, solver_protocol=self.method, verbose=self.verbose) self.states_ = u_nk.columns.values.tolist() # set attributes out = self._mbar.getFreeEnergyDifferences(return_theta=True) attrs = [ pd.DataFrame(i, columns=self.states_, index=self.states_) for i in out ] (self.delta_f_, self.d_delta_f_, self.theta_) = attrs return self def predict(self, u_ln): pass @property def overlap_matrix(self): r"""MBAR overlap matrix. The estimated state overlap matrix :math:`O_{ij}` is an estimate of the probability of observing a sample from state :math:`i` in state :math:`j`. The :attr:`overlap_matrix` is computed on-the-fly. Assign it to a variable if you plan to re-use it. See Also --------- pymbar.mbar.MBAR.computeOverlap """ return self._mbar.computeOverlap()['matrix']
for k in range(nstates): [nequil, g, Neff_max] = timeseries.detectEquilibration(u_kln[k, k, :]) indices = timeseries.subsampleCorrelatedData(u_kln[k, k, :], g=g) N_k[k] = len(indices) u_kln[k, :, 0:N_k[k]] = u_kln[k, :, indices].T # Compute free energy differences and statistical uncertainties mbar = MBAR(u_kln, N_k) [DeltaF_ij, dDeltaF_ij, Theta_ij] = mbar.getFreeEnergyDifferences(return_theta=True) #results = mbar.getFreeEnergyDifferences(return_dict=True,return_theta=True) #DeltaF_ij = results['Delta_f'] #dDeltaF_ij = results['dDelta_f'] #Theta_ij = results['Theta'] ODeltaF_ij = mbar.computeOverlap()['matrix'] # Print results f = open(Savename, 'w') for i in range(nstates): f.writelines("%.2f: %9.4f +- %.4f\n" % (l[i], DeltaF_ij[i, 0] * kT, dDeltaF_ij[i, 0] * kT)) f.close() # Plot Overlap fig1, ax1 = plt.subplots() plt.imshow(ODeltaF_ij[2]) plt.set_cmap('bone') cbar = plt.colorbar() cbar.set_label("Overlap", fontsize=12) ax1.xaxis.tick_top()
print("Analytical estimator of %s is" % (observe)) print(A_k_analytical[observe][nth]) print("MBAR estimator of the %s is" % (observe)) print(A_k_estimated) print("MBAR estimators differ by X standard deviations") stdevs = numpy.abs(A_k_error / dA_k_estimated) print(stdevs) print("============================================") print(" Testing computeOverlap ") print("============================================") results = mbar.computeOverlap() O = results['scalar'] O_i = results['eigenvalues'] O_ij = results['matrix'] print("Overlap matrix output") print(O_ij) for k in range(K): print("Sum of row %d is %f (should be 1)," % (k, numpy.sum(O_ij[k, :])), end=' ') if (numpy.abs(numpy.sum(O_ij[k, :]) - 1) < 1.0e-10): print("looks like it is.") else: print("but it's not.")
print "Analytical estimator of %s is" % (observe) print A_k_analytical[observe][nth] print "MBAR estimator of the %s is" % (observe) print A_k_estimated print "MBAR estimators differ by X standard deviations" stdevs = numpy.abs(A_k_error/dA_k_estimated) print stdevs print "============================================" print " Testing computeOverlap " print "============================================" O_ij = mbar.computeOverlap(output='matrix') print "Overlap matrix output" print O_ij for k in range(K): print "Sum of row %d is %f (should be 1)," % (k,numpy.sum(O_ij[k,:])), if (numpy.abs(numpy.sum(O_ij[k,:])-1)<1.0e-10): print "looks like it is." else: print "but it's not." O_i = mbar.computeOverlap(output='eigenvalues') print "Overlap eigenvalue output" print O_i O = mbar.computeOverlap(output='scalar') print "Overlap scalar output"
print "Analytical estimator of %s is" % (observe) print A_k_analytical[observe][nth] print "MBAR estimator of the %s is" % (observe) print A_k_estimated print "MBAR estimators differ by X standard deviations" stdevs = numpy.abs(A_k_error / dA_k_estimated) print stdevs print "============================================" print " Testing computeOverlap " print "============================================" O_ij = mbar.computeOverlap(output='matrix') print "Overlap matrix output" print O_ij for k in range(K): print "Sum of row %d is %f (should be 1)," % (k, numpy.sum(O_ij[k, :])), if (numpy.abs(numpy.sum(O_ij[k, :]) - 1) < 1.0e-10): print "looks like it is." else: print "but it's not." O_i = mbar.computeOverlap(output='eigenvalues') print "Overlap eigenvalue output" print O_i O = mbar.computeOverlap(output='scalar') print "Overlap scalar output"
print "Analytical estimator of %s is" % (observe) print A_k_analytical[observe][nth] print "MBAR estimator of the %s is" % (observe) print A_k_estimated print "MBAR estimators differ by X standard deviations" stdevs = numpy.abs(A_k_error/dA_k_estimated) print stdevs print "============================================" print " Testing computeOverlap " print "============================================" O, O_i, O_ij = mbar.computeOverlap() print "Overlap matrix output" print O_ij for k in range(K): print "Sum of row %d is %f (should be 1)," % (k,numpy.sum(O_ij[k,:])), if (numpy.abs(numpy.sum(O_ij[k,:])-1)<1.0e-10): print "looks like it is." else: print "but it's not." print "Overlap eigenvalue output" print O_i
print("Analytical estimator of %s is" % (observe)) print(A_k_analytical[observe][nth]) print("MBAR estimator of the %s is" % (observe)) print(A_k_estimated) print("MBAR estimators differ by X standard deviations") stdevs = numpy.abs(A_k_error/dA_k_estimated) print(stdevs) print("============================================") print(" Testing computeOverlap ") print("============================================") results = mbar.computeOverlap() O = results['scalar'] O_i = results['eigenvalues'] O_ij = results['matrix'] print("Overlap matrix output") print(O_ij) for k in range(K): print("Sum of row %d is %f (should be 1)," % (k,numpy.sum(O_ij[k,:])), end=' ') if (numpy.abs(numpy.sum(O_ij[k,:])-1)<1.0e-10): print("looks like it is.") else: print("but it's not.") print("Overlap eigenvalue output")
print("Analytical estimator of %s is" % (observe)) print(A_k_analytical[observe][nth]) print("MBAR estimator of the %s is" % (observe)) print(A_k_estimated) print("MBAR estimators differ by X standard deviations") stdevs = numpy.abs(A_k_error/dA_k_estimated) print(stdevs) print("============================================") print(" Testing computeOverlap ") print("============================================") results = mbar.computeOverlap(return_dict=True) O = results['scalar'] O_i = results['eigenvalues'] O_ij = results['matrix'] print("Overlap matrix output") print(O_ij) for k in range(K): print("Sum of row %d is %f (should be 1)," % (k,numpy.sum(O_ij[k,:])), end=' ') if (numpy.abs(numpy.sum(O_ij[k,:])-1)<1.0e-10): print("looks like it is.") else: print("but it's not.") print("Overlap eigenvalue output")