def test_combo_bias(self): #TODO: we don't support this yet, but we need to at some point # test what happens if you have more than one sample in the change # if you do a multi-step bias (in the same direction), then it seems # to me that the total bias should be the same as if it were a # one-step. This is *not* true if hops are in different directions. # Then it depends on the product of the "upstream" hops ensembles = self.network.transitions[(self.stateA, self.stateB)].ensembles # all downstream move move_012 = paths.SequentialMover([ paths.EnsembleHopMover(ensembles[0], ensembles[1]), paths.EnsembleHopMover(ensembles[1], ensembles[2]) ]) change_012 = move_012.move(self.sample_set) # all upstream move move_210 = paths.SequentialMover([ paths.EnsembleHopMover(ensembles[2], ensembles[1]), paths.EnsembleHopMover(ensembles[1], ensembles[0]) ]) change_210 = move_210.move(self.sample_set) # assert_almost_equal( # self.bias.probability_old_to_new(change_210, self.sample_set), 1.0 # ) # assert_almost_equal( # self.bias.probability_new_to_old(change_210, self.sample_set), 0.2 # ) raise SkipTest
def test_build_balance_partners_no_partner(self): ensA = self.scheme.network.sampling_transitions[0].ensembles[0] ensB = self.scheme.network.sampling_transitions[0].ensembles[1] hopAB = paths.EnsembleHopMover(ensemble=ensA, target_ensemble=ensB) hopBA = paths.EnsembleHopMover(ensemble=ensB, target_ensemble=ensA) self.scheme.movers['hop'] = [hopAB] self.scheme.append(strategies.OrganizeByMoveGroupStrategy()) root = self.scheme.move_decision_tree() self.scheme.build_balance_partners()
def make_movers(self, scheme): signatures = [ m.ensemble_signature for m in scheme.movers[self.from_group] ] # a KeyError here indicates that there is no existing group of that # name: build scheme.movers[self.from_group] before trying to use it! self.check_for_hop_repex_validity(signatures) hop_list = [] for sig in signatures: n_ens = len(sig[0]) if n_ens == 2: hop_list.extend([[sig[0][0], sig[0][1]], [sig[0][1], sig[0][0]]]) elif n_ens == 1: hop_list.extend([[sig[0][0], sig[1][0]]]) hops = [] for hop in hop_list: if self.bias is not None: bias = self.bias.bias_probability(hop[0], hop[1]) else: bias = None hopper = paths.EnsembleHopMover(hop[0], hop[1], bias=bias) hopper.named("EnsembleHop " + str(hop[0].name) + "->" + str(hop[1].name)) hops.append(hopper) return hops
def __init__(self, bias=None, shooters=None, ensembles=None): """ Parameters ---------- bias : None not used yet, only for API consistency and later implementation shooters : list of ShootingMovers list of ShootingMovers for each ensemble ensembles : list of Ensembles list of ensembles the move should act on Notes ----- The bootstrapping will use the ensembles sequentially so it requires that all ensembles have a reasonable overlab using shooting moves. """ self.shooters = shooters self.bias = bias self.ensembles = ensembles initialization_logging(logger=init_log, obj=self, entries=['bias', 'shooters', 'ensembles']) ens_pairs = [[self.ensembles[i], self.ensembles[i+1]] for i in range(len(self.ensembles)-1)] # Bootstrapping sets numeric replica IDs. If the user wants it done # differently, the user can change it. self._ensemble_dict = {ens : rep for rep, ens in enumerate(ensembles) } # Create all possible hoppers so we do not have to recreate these # every time which will result in more efficient storage mover = paths.LastAllowedMover([ # writing an algorithm this convoluted can get you shot in Texas paths.PartialAcceptanceSequentialMover( movers=[ shoot, paths.EnsembleHopMover( ensemble=enss[0], target_ensemble=enss[1], change_replica=self._ensemble_dict[enss[1]] ) ] ) for (enss, shoot) in zip(ens_pairs, shooters) ]) super(BootstrapPromotionMove, self).__init__(mover)
def make_movers(self, scheme): signatures = [ m.ensemble_signature for m in scheme.movers[self.from_group] ] # a KeyError here indicates that there is no existing group of that # name: build scheme.movers[self.from_group] before trying to use it! self.check_for_hop_repex_validity(signatures) hop_list = [] for sig in signatures: n_ens = len(sig[0]) if n_ens == 2: hop_list.extend([[sig[0][0], sig[0][1]], [sig[0][1], sig[0][0]]]) elif n_ens == 1: hop_list.extend([[sig[0][0], sig[1][0]]]) hops = [ paths.EnsembleHopMover(hop[0], hop[1], bias=self.bias) for hop in hop_list ] return hops
def setup(self): # create the network paths.InterfaceSet._reset() xval = paths.FunctionCV(name="xA", f=lambda s: s.xyz[0][0]) self.stateA = paths.CVDefinedVolume(xval, -1.0, -0.5).named("A") self.stateB = paths.CVDefinedVolume(xval, 0.5, float("inf")).named("B") ifacesA = paths.VolumeInterfaceSet(xval, float(-1.0), [-0.5, -0.4, -0.3, -0.2]) self.network = paths.MISTISNetwork([(self.stateA, ifacesA, self.stateB) ]) transition = self.network.transitions[(self.stateA, self.stateB)] ensembles = transition.ensembles self.xval = xval self.ifacesA = ifacesA # create the biases bias_table = {} bias_table[ensembles[0]] = 1.0 bias_table[ensembles[1]] = 0.5 bias_table[ensembles[2]] = 0.2 self.bias = BiasEnsembleTable.ratios_from_dictionary(bias_table) # samples, moves, changes traj = make_1d_traj( [-0.55, -0.45, -0.35, -0.25, -0.15, -0.26, -0.36, -0.46, -0.56]) s0 = paths.Sample(replica=0, ensemble=ensembles[0], trajectory=traj) s1 = paths.Sample(replica=1, ensemble=ensembles[1], trajectory=traj) s2 = paths.Sample(replica=2, ensemble=ensembles[2], trajectory=traj) self.sample_set = paths.SampleSet([s0, s1, s2]) self.sample_set.sanity_check() move_01 = paths.EnsembleHopMover(ensembles[0], ensembles[1]) move_02 = paths.EnsembleHopMover(ensembles[0], ensembles[2]) move_12 = paths.EnsembleHopMover(ensembles[1], ensembles[2]) move_21 = paths.EnsembleHopMover(ensembles[2], ensembles[1]) move_20 = paths.EnsembleHopMover(ensembles[2], ensembles[0]) move_10 = paths.EnsembleHopMover(ensembles[1], ensembles[0]) # NOTE: all changes here are accepted self.change_01 = move_01.move(self.sample_set) self.change_02 = move_02.move(self.sample_set) self.change_12 = move_12.move(self.sample_set) self.change_21 = move_21.move(self.sample_set) self.change_20 = move_20.move(self.sample_set) self.change_10 = move_10.move(self.sample_set) # convenience lists for changes going outward vs. inward self.out_changes = [self.change_01, self.change_02, self.change_12] self.in_changes = [self.change_10, self.change_20, self.change_21]