def __init__(self, potential, coords, temperature, stepsize, niter, hEmin=0, hEmax=100, hbinsize=0.01, radius=2.5, acceptance=0.5, adjustf=0.9, adjustf_niter=1e4, adjustf_navg=100, bdim=3, single=False, seeds=None): #construct base class super(Metropolis_MCrunner, self).__init__(potential, coords, temperature, niter) #get/set seeds if not seeds: i32max = np.iinfo(np.int32).max seeds = dict(takestep=np.random.randint(i32max), metropolis=np.random.randint(i32max)) self.seeds = seeds #construct takestep: random step self.step = RandomCoordsDisplacement(self.seeds['takestep'], stepsize, report_interval=adjustf_navg, factor=adjustf, min_acc_ratio=acceptance, max_acc_ratio=acceptance, single=single, nparticles=int( len(coords) / bdim), bdim=bdim) #construct early configuration test: check within spherical container self.conftest = CheckSphericalContainer(radius, bdim) #construct accept test: Metropolis self.metropolis = MetropolisTest(self.seeds['metropolis']) #construct action: energy histogram self.binsize = hbinsize self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize, adjustf_niter) #set up pele:MC self.set_takestep(self.step) self.set_report_steps( adjustf_niter ) #set number of iterations for which steps are adapted self.add_accept_test(self.metropolis) self.add_conf_test(self.conftest) self.add_action(self.histogram)
def __init__(self, potential, coords, temperature, stepsize, niter, hEmin=0, hEmax=100, hbinsize=0.01, radius=2.5, acceptance=0.5, adjustf=0.9, adjustf_niter = 1e4, adjustf_navg = 100, bdim=3): #construct base class super(Metropolis_MCrunner,self).__init__(potential, coords, temperature, stepsize, niter) #construct test/action classes i32max = np.iinfo(np.int32).max self.binsize = hbinsize self.histogram = RecordEnergyHistogram(hEmin,hEmax,self.binsize, adjustf_niter) self.adjust_step = AdjustStep(acceptance, adjustf, adjustf_niter, adjustf_navg) self.step = RandomCoordsDisplacement(42) #self.step = RandomCoordsDisplacement(np.random.randint(i32max)) self.metropolis = MetropolisTest(44) #self.metropolis = MetropolisTest(np.random.randint(i32max)) self.conftest = CheckSphericalContainer(radius, bdim) #set up pele:MC self.set_takestep(self.step) self.add_accept_test(self.metropolis) self.add_conf_test(self.conftest) self.add_action(self.histogram) self.add_action(self.adjust_step)
def setUp(self): self.box_dimension = 3 self.nr_particles = 10 self.k = 42 self.nr_dof = self.box_dimension * self.nr_particles self.origin = np.zeros(self.nr_dof) self.potential = Harmonic(self.origin, self.k, bdim=self.box_dimension, com=True) self.temp = 1 self.nr_steps = 6e4 self.mc = MC(self.potential, self.origin, self.temp, self.nr_steps) self.take_step_A = RandomCoordsDisplacement(42, 4, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2) self.take_step_B = RandomCoordsDisplacement(44, 0.1, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2) self.step = TakeStepProbabilities(46) self.weight_A = 22 self.weight_B = 78 self.step.add_step(self.take_step_A, self.weight_A) self.step.add_step(self.take_step_B, self.weight_B) self.mc.set_takestep(self.step) self.frequency_step_A = self.weight_A / (self.weight_A + self.weight_B) self.frequency_step_B = self.weight_B / (self.weight_A + self.weight_B) self.metropolis = MetropolisTest(50) self.mc.add_accept_test(self.metropolis) self.hist_min = 0 self.hist_max = 1e4 self.eq_steps = self.nr_steps / 2 self.mc.set_report_steps(self.eq_steps) self.measure_energy = RecordEnergyHistogram(self.hist_min, self.hist_max, (self.hist_max - self.hist_min)/14, self.eq_steps) self.mc.add_action(self.measure_energy) self.true_energy = self.box_dimension * (self.nr_particles - 1) / 2
def __init__( self, potential, coords, temperature, stepsize, niter, hEmin=0, hEmax=100, hbinsize=0.01, radius=2.5, acceptance=0.5, adjustf=0.9, adjustf_niter=1e4, adjustf_navg=100, bdim=3, single=False, seeds=None, ): # construct base class super(Metropolis_MCrunner, self).__init__(potential, coords, temperature, niter) # get/set seeds if not seeds: i32max = np.iinfo(np.int32).max seeds = dict(takestep=np.random.randint(i32max), metropolis=np.random.randint(i32max)) self.seeds = seeds # construct takestep: random step self.step = RandomCoordsDisplacement( self.seeds["takestep"], stepsize, report_interval=adjustf_navg, factor=adjustf, min_acc_ratio=acceptance, max_acc_ratio=acceptance, single=single, nparticles=int(len(coords) / bdim), bdim=bdim, ) # construct early configuration test: check within spherical container self.conftest = CheckSphericalContainer(radius, bdim) # construct accept test: Metropolis self.metropolis = MetropolisTest(self.seeds["metropolis"]) # construct action: energy histogram self.binsize = hbinsize self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize, adjustf_niter) # set up pele:MC self.set_takestep(self.step) self.set_report_steps(adjustf_niter) # set number of iterations for which steps are adapted self.add_accept_test(self.metropolis) self.add_conf_test(self.conftest) self.add_action(self.histogram)
class TestTakeStepProbabilityHarmoinc(unittest.TestCase): def setUp(self): self.box_dimension = 3 self.nr_particles = 10 self.k = 42 self.nr_dof = self.box_dimension * self.nr_particles self.origin = np.zeros(self.nr_dof) self.potential = Harmonic(self.origin, self.k, bdim=self.box_dimension, com=True) self.temp = 1 self.nr_steps = 6e4 self.mc = MC(self.potential, self.origin, self.temp, self.nr_steps) self.take_step_A = RandomCoordsDisplacement(42, 4, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2) self.take_step_B = RandomCoordsDisplacement(44, 0.1, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2) self.step = TakeStepProbabilities(46) self.weight_A = 22 self.weight_B = 78 self.step.add_step(self.take_step_A, self.weight_A) self.step.add_step(self.take_step_B, self.weight_B) self.mc.set_takestep(self.step) self.frequency_step_A = self.weight_A / (self.weight_A + self.weight_B) self.frequency_step_B = self.weight_B / (self.weight_A + self.weight_B) self.metropolis = MetropolisTest(50) self.mc.add_accept_test(self.metropolis) self.hist_min = 0 self.hist_max = 1e4 self.eq_steps = self.nr_steps / 2 self.mc.set_report_steps(self.eq_steps) self.measure_energy = RecordEnergyHistogram(self.hist_min, self.hist_max, (self.hist_max - self.hist_min)/14, self.eq_steps) self.mc.add_action(self.measure_energy) self.true_energy = self.box_dimension * (self.nr_particles - 1) / 2 def test_basic_harmonic(self): self.mc.run() self.assertAlmostEqual(self.frequency_step_A, self.take_step_A.get_count() / self.nr_steps, delta=1e-2) self.assertAlmostEqual(self.frequency_step_B, self.take_step_B.get_count() / self.nr_steps, delta=1e-2) self.assertAlmostEqual(self.take_step_A.get_stepsize(), self.take_step_B.get_stepsize(), delta=1e-2) mean_energy, var_energy = self.measure_energy.get_mean_variance() self.assertAlmostEqual(mean_energy, self.true_energy, delta=3e-1)
class Metropolis_MCrunner(_BaseMCRunner): """This class is derived from the _base_MCrunner abstract method and performs Metropolis Monte Carlo. This particular implementation of the algorithm: * runs niter steps per run call * takes steps by sampling a random vector in a n dimensional hypersphere (n is the number of coordinates); * adjust the step size for the first adjustf_niter steps (averaging the acceptance for adjust_navg steps and adjusting the stepsize by a factor of 'adjustf') to meet some target acceptance 'acceptance'. * configuration test: accept if within a spherical box of radius 'radius' * acceptance test: metropolis for some particular temperature * record energy histogram (the energy histogram is resizable, but the bounds are defined by hEmin and hEmax, furthermore the bin size is set with hbinsize. Care must be taken because the array is resizable, if the step size is small and extremely high or low energies are sampled the memory for the histogram will be reallocated and this might cause a badalloc error, if trying to allocate a huge array. If you are sampling unwanted extremely high or low energies then you might want to add a pele::EnergyWindow test that guarantees to keep you within a specific energy range and/or make the stepsize larger or you might want to re-think about your simulation. Generally you shouldn't be spanning energies that differ by several orders of magnitude, if that is the case, resizable or not resizable arrays are not the problem, you'd be incurring in memory issues no matter what you do, unless you write to disk at every iteration) * NOTE: some of the modules (e.g. take step and acceptance tests) require to be seeded. Users are free to do this as they think * is best, here we generate a random integer in [0,i32max) where i32max is the largest signed integer, for each seed. Each module * has a separate rng engine, therefore it's best if each receives a different randomly sampled seed """ def __init__(self, potential, coords, temperature, stepsize, niter, hEmin=0, hEmax=100, hbinsize=0.01, radius=2.5, acceptance=0.5, adjustf=0.9, adjustf_niter=1e4, adjustf_navg=100, bdim=3, single=False, seeds=None): #construct base class super(Metropolis_MCrunner, self).__init__(potential, coords, temperature, niter) #get/set seeds if not seeds: i32max = np.iinfo(np.int32).max seeds = dict(takestep=np.random.randint(i32max), metropolis=np.random.randint(i32max)) self.seeds = seeds #construct takestep: random step self.step = RandomCoordsDisplacement(self.seeds['takestep'], stepsize, report_interval=adjustf_navg, factor=adjustf, min_acc_ratio=acceptance, max_acc_ratio=acceptance, single=single, nparticles=int( len(coords) / bdim), bdim=bdim) #construct early configuration test: check within spherical container self.conftest = CheckSphericalContainer(radius, bdim) #construct accept test: Metropolis self.metropolis = MetropolisTest(self.seeds['metropolis']) #construct action: energy histogram self.binsize = hbinsize self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize, adjustf_niter) #set up pele:MC self.set_takestep(self.step) self.set_report_steps( adjustf_niter ) #set number of iterations for which steps are adapted self.add_accept_test(self.metropolis) self.add_conf_test(self.conftest) self.add_action(self.histogram) def set_control(self, T): """set temperature, canonical control parameter""" self.temperature = T self.set_temperature(T) def get_stepsize(self): return self.step.get_stepsize() def dump_histogram(self, fname): """write histogram to fname""" Emin, Emax = self.histogram.get_bounds_val() histl = self.histogram.get_histogram() hist = np.array(histl) Energies, step = np.linspace(Emin, Emax, num=len(hist), endpoint=False, retstep=True) assert (abs(step - self.binsize) < self.binsize / 100) np.savetxt(fname, np.column_stack((Energies, hist)), delimiter='\t') mean, variance = self.histogram.get_mean_variance() return mean, variance def get_histogram(self): """returns a energy list and a histogram list""" Emin, Emax = self.histogram.get_bounds_val() histl = self.histogram.get_histogram() hist = np.array(histl) Energies, step = np.linspace(Emin, Emax, num=len(hist), endpoint=False, retstep=True) mean, variance = self.histogram.get_mean_variance() assert (abs(step - self.binsize) < self.binsize / 100) return Energies, hist, mean, variance def show_histogram(self): """shows the histogram""" hist = self.histogram.get_histogram() val = [i * self.binsize for i in xrange(len(hist))] plt.hist(val, weights=hist, bins=len(hist)) plt.show()
class Metropolis_MCrunner(_BaseMCRunner): """This class is derived from the _base_MCrunner abstract method and performs Metropolis Monte Carlo. This particular implementation of the algorithm: * runs niter steps per run call * takes steps by sampling a random vector in a n dimensional hypersphere (n is the number of coordinates); * adjust the step size for the first adjustf_niter steps (averaging the acceptance for adjust_navg steps and adjusting the stepsize by a factor of 'adjustf') to meet some target acceptance 'acceptance'. * configuration test: accept if within a spherical box of radius 'radius' * acceptance test: metropolis for some particular temperature * record energy histogram (the energy histogram is resizable, but the bounds are defined by hEmin and hEmax, furthermore the bin size is set with hbinsize. Care must be taken because the array is resizable, if the step size is small and extremely high or low energies are sampled the memory for the histogram will be reallocated and this might cause a badalloc error, if trying to allocate a huge array. If you are sampling unwanted extremely high or low energies then you might want to add a pele::EnergyWindow test that guarantees to keep you within a specific energy range and/or make the stepsize larger or you might want to re-think about your simulation. Generally you shouldn't be spanning energies that differ by several orders of magnitude, if that is the case, resizable or not resizable arrays are not the problem, you'd be incurring in memory issues no matter what you do, unless you write to disk at every iteration) * NOTE: some of the modules (e.g. take step and acceptance tests) require to be seeded. Users are free to do this as they think * is best, here we generate a random integer in [0,i32max) where i32max is the largest signed integer, for each seed. Each module * has a separate rng engine, therefore it's best if each receives a different randomly sampled seed """ def __init__( self, potential, coords, temperature, stepsize, niter, hEmin=0, hEmax=100, hbinsize=0.01, radius=2.5, acceptance=0.5, adjustf=0.9, adjustf_niter=1e4, adjustf_navg=100, bdim=3, single=False, seeds=None, ): # construct base class super(Metropolis_MCrunner, self).__init__(potential, coords, temperature, niter) # get/set seeds if not seeds: i32max = np.iinfo(np.int32).max seeds = dict(takestep=np.random.randint(i32max), metropolis=np.random.randint(i32max)) self.seeds = seeds # construct takestep: random step self.step = RandomCoordsDisplacement( self.seeds["takestep"], stepsize, report_interval=adjustf_navg, factor=adjustf, min_acc_ratio=acceptance, max_acc_ratio=acceptance, single=single, nparticles=int(len(coords) / bdim), bdim=bdim, ) # construct early configuration test: check within spherical container self.conftest = CheckSphericalContainer(radius, bdim) # construct accept test: Metropolis self.metropolis = MetropolisTest(self.seeds["metropolis"]) # construct action: energy histogram self.binsize = hbinsize self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize, adjustf_niter) # set up pele:MC self.set_takestep(self.step) self.set_report_steps(adjustf_niter) # set number of iterations for which steps are adapted self.add_accept_test(self.metropolis) self.add_conf_test(self.conftest) self.add_action(self.histogram) def set_control(self, T): """set temperature, canonical control parameter""" self.temperature = T self.set_temperature(T) def get_stepsize(self): return self.step.get_stepsize() def dump_histogram(self, fname): """write histogram to fname""" Emin, Emax = self.histogram.get_bounds_val() histl = self.histogram.get_histogram() hist = np.array(histl) Energies, step = np.linspace(Emin, Emax, num=len(hist), endpoint=False, retstep=True) assert abs(step - self.binsize) < self.binsize / 100 np.savetxt(fname, np.column_stack((Energies, hist)), delimiter="\t") mean, variance = self.histogram.get_mean_variance() return mean, variance def get_histogram(self): """returns a energy list and a histogram list""" Emin, Emax = self.histogram.get_bounds_val() histl = self.histogram.get_histogram() hist = np.array(histl) Energies, step = np.linspace(Emin, Emax, num=len(hist), endpoint=False, retstep=True) mean, variance = self.histogram.get_mean_variance() assert abs(step - self.binsize) < self.binsize / 100 return Energies, hist, mean, variance def show_histogram(self): """shows the histogram""" hist = self.histogram.get_histogram() val = [i * self.binsize for i in xrange(len(hist))] plt.hist(val, weights=hist, bins=len(hist)) plt.show()