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
예제 #2
0
 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()
예제 #3
0
    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
예제 #4
0
    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)
예제 #5
0
    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]