def _compute_coarse_sets(self, user_sets): r"""Computes the sets to coarse-grain the tpt flux to. Parameters ---------- tpt_sets : list of int-iterables sets of states that shall be distinguished in the coarse-grained flux. Returns ------- sets : list of int-iterables sets to compute tpt on. These sets still respect the boundary between A, B and the intermediate tpt states. Notes ----- Given the sets that the user wants to distinguish, the algorithm will create additional sets if necessary * If states are missing in user_sets, they will be put into a separate set * If sets in user_sets are crossing the boundary between A, B and the intermediates, they will be split at these boundaries. Thus each set in user_sets can remain intact or be split into two or three subsets """ # set-ify everything setA = set(self.A) setB = set(self.B) setI = set(self.I) raw_sets = [set(user_set) for user_set in user_sets] # anything missing? Compute all listed states set_all = set(range(self.nstates)) set_all_user = [] for user_set in raw_sets: set_all_user += user_set set_all_user = set(set_all_user) # ... and add all the unlisted states in a separate set set_rest = set_all - set_all_user if len(set_rest) > 0: raw_sets.append(set_rest) # split sets Asets = [] Isets = [] Bsets = [] for raw_set in raw_sets: s = raw_set.intersection(setA) if len(s) > 0: Asets.append(s) s = raw_set.intersection(setI) if len(s) > 0: Isets.append(s) s = raw_set.intersection(setB) if len(s) > 0: Bsets.append(s) tpt_sets = Asets + Isets + Bsets Aindexes = list(range(0, len(Asets))) Bindexes = list(range(len(Asets) + len(Isets), len(tpt_sets))) return tpt_sets, Aindexes, Bindexes
def I(self): r"""Returns the set of intermediate states """ return list(set(range(self.nstates)) - set(self._A) - set(self._B))