class NestedSamplingSA(NestedSampling): """overload get_starting_configuration() in order to introduce sampling from known minima Parameters ---------- system : pele system object nreplicas : int number of replicas takestep : callable object to do the step taking. must be callable and have attribute takestep.stepsize minima : list of Minimum objects """ def __init__(self, system, nreplicas, mc_runner, minima, minprob=None, energy_offset=None, **kwargs): super(NestedSamplingSA, self).__init__(system, nreplicas, mc_runner, **kwargs) self.minima = minima self.bh_sampler = SASampler(self.minima, self.system.k) if minprob is None: raise ValueError("minprob cannot be None") self.minprob = minprob if energy_offset is None: self.energy_offset = 2.5 else: self.energy_offset = energy_offset self.count_sampled_minima = 0 def get_starting_configuration_minima_HA(self, Emax): """using the Harmonic Approximation sample a new configuration starting from a minimum sampled uniformly according to phase space volume Notes ----- displace minimum configuration along its eigenvectors """ m = self.bh_sampler.sample_minimum(Emax) x = self.bh_sampler.sample_coords_from_basin(m, Emax) pot = self.system.get_potential() e = pot.getEnergy(x) return x, e def get_starting_configuration_minima_single(self, Emax): """return a minimum sampled uniformly according to phase space volume""" m = self.bh_sampler.sample_minimum(Emax) x, e = m.coords, m.energy self.system.center_coords(x) if True: accept_tests = self.system.get_config_tests() for test in accept_tests: t = test(coords=x) if not t: print "warning: minimum from database failed configuration test", m._id, m.energy raise ConfigTestError() return x, e def get_starting_configuration_minima(self, Emax): """return a minimum sampled uniformly according to phase space volume Notes ----- some of the minima in the database don't satisfy the configuration checks. So we sample over and over again until we get one that passes """ self.count_sampled_minima += 1 while True: try: return self.get_starting_configuration_minima_single(Emax) except ConfigTestError: pass def onset_prob_func(self, Emax): """return the probability of sampling from a minimum The probability depends on Emax. For high Emax the probability is 0. the probability increases as Emax get's lower, reaching a maximum of self.minprob. value of Emax where the probabilty starts to get large is energy_max_database + energy_offset where energy_max_database is the maximum energy minimum in the database. This behavior can be adjusted with parameter energy_offset. parameter b determines the speed at which it turns on. """ if not hasattr(self, "_energy_max_database"): self._energy_max_database = float( max([m.energy for m in self.minima])) max_prob = float(self.minprob) energy_onset_width = 1. dE = self._energy_max_database + self.energy_offset - Emax f = dE / energy_onset_width if f > 100: onset_prob = 0. else: onset_prob = max_prob / (1. + np.exp(-f)) return onset_prob def get_starting_configurations(self, Emax): """this function overloads the function in NestedSampling""" # choose a replica randomly configs = self.get_starting_configurations_from_replicas() # replace each starting configuration with a one chosen # from the minima with probability prob onset_prob = self.onset_prob_func(Emax) prob = onset_prob / float(self.nreplicas) for i in range(len(configs)): if np.random.uniform(0, 1) < prob: x, energy = self.get_starting_configuration_minima(Emax) configs[i] = Replica(x, energy, from_random=False) if self.verbose: print "sampling from minima, E minimum:", energy, "with probability:", prob return configs
class NestedSamplingSA(NestedSampling): """overload get_starting_configuration() in order to introduce sampling from known minima Parameters ---------- system : pele system object nreplicas : int number of replicas takestep : callable object to do the step taking. must be callable and have attribute takestep.stepsize minima : list of Minimum objects """ def __init__(self, system, nreplicas, mc_runner, minima, minprob=None, energy_offset=None, **kwargs): super(NestedSamplingSA, self).__init__(system, nreplicas, mc_runner, **kwargs) self.minima = minima self.bh_sampler = SASampler(self.minima, self.system.k) if minprob is None: raise ValueError("minprob cannot be None") self.minprob = minprob if energy_offset is None: self.energy_offset = 2.5 else: self.energy_offset = energy_offset self.count_sampled_minima = 0 def get_starting_configuration_minima_HA(self, Emax): """using the Harmonic Approximation sample a new configuration starting from a minimum sampled uniformly according to phase space volume Notes ----- displace minimum configuration along its eigenvectors """ m = self.bh_sampler.sample_minimum(Emax) x = self.bh_sampler.sample_coords_from_basin(m, Emax) pot = self.system.get_potential() e = pot.getEnergy(x) return x, e def get_starting_configuration_minima_single(self, Emax): """return a minimum sampled uniformly according to phase space volume""" m = self.bh_sampler.sample_minimum(Emax) x, e = m.coords, m.energy self.system.center_coords(x) if True: accept_tests = self.system.get_config_tests() for test in accept_tests: t = test(coords=x) if not t: print "warning: minimum from database failed configuration test", m._id, m.energy raise ConfigTestError() return x, e def get_starting_configuration_minima(self, Emax): """return a minimum sampled uniformly according to phase space volume Notes ----- some of the minima in the database don't satisfy the configuration checks. So we sample over and over again until we get one that passes """ self.count_sampled_minima += 1 while True: try: return self.get_starting_configuration_minima_single(Emax) except ConfigTestError: pass def onset_prob_func(self, Emax): """return the probability of sampling from a minimum The probability depends on Emax. For high Emax the probability is 0. the probability increases as Emax get's lower, reaching a maximum of self.minprob. value of Emax where the probabilty starts to get large is energy_max_database + energy_offset where energy_max_database is the maximum energy minimum in the database. This behavior can be adjusted with parameter energy_offset. parameter b determines the speed at which it turns on. """ if not hasattr(self, "_energy_max_database"): self._energy_max_database = float(max([m.energy for m in self.minima])) max_prob = float(self.minprob) energy_onset_width = 1. dE = self._energy_max_database + self.energy_offset - Emax f = dE / energy_onset_width if f > 100: onset_prob = 0. else: onset_prob = max_prob / ( 1. + np.exp(-f)) return onset_prob def get_starting_configurations(self, Emax): """this function overloads the function in NestedSampling""" # choose a replica randomly configs = self.get_starting_configurations_from_replicas() # replace each starting configuration with a one chosen # from the minima with probability prob onset_prob = self.onset_prob_func(Emax) prob = onset_prob / float(self.nreplicas) for i in range(len(configs)): if np.random.uniform(0,1) < prob: x, energy = self.get_starting_configuration_minima(Emax) configs[i] = Replica(x, energy, from_random=False) if self.verbose: print "sampling from minima, E minimum:", energy, "with probability:", prob return configs