def _flatten_structures(self): c_specs, self.edges, self.weights, self.einstrs, self.einpaths = [], [], [], [], [] ks = {} # handle n=1 case specially c_specs.append([1,0,0,0,0,1,1,0]) self.edges.append(()) self.weights.append(()) self.einstrs.append(self.einstrs_d[(1,0)][0]) self.einpaths.append(self.einpaths_d[(1,0)][0]) for ne in sorted(self.edges_d.keys()): n, e = ne z = zip(self.edges_d[ne], self.weights_d[ne], self.chis_d[ne], self.einstrs_d[ne], self.einpaths_d[ne]) for edgs, ws, c, es, ep in z: for w in ws: d = sum(w) k = ks.setdefault((n,d), 0) ks[(n,d)] += 1 vs = valencies(EFPElem(edgs, weights=w).edges).values() v = max(vs) h = Counter(vs)[1] c_specs.append([n, e, d, v, k, c, 1, h]) self.edges.append(edgs) self.weights.append(w) self.einstrs.append(es) self.einpaths.append(ep) self.c_specs = np.asarray(c_specs)
def __init__(self, edges, measure='hadr', beta=1, kappa=1, normed=True, coords=None, check_input=True, np_optimize='greedy'): """ **Arguments** - **edges** : _list_ - Edges of the EFP graph specified by pairs of vertices. - **measure** : {`'hadr'`, `'hadrdot'`, `'ee'`} - The choice of measure. See [Measures](../measures) for additional info. - **beta** : _float_ - The parameter $\\beta$ appearing in the measure. Must be greater than zero. - **kappa** : {_float_, `'pf'`} - If a number, the energy weighting parameter $\\kappa$. If `'pf'`, use $\\kappa=v-1$ where $v$ is the valency of the vertex. - **normed** : _bool_ - Controls normalization of the energies in the measure. - **coords** : {`'ptyphim'`, `'epxpypz'`, `None`} - Controls which coordinates are assumed for the input. See [Measures](../measures) for additional info. - **check_input** : _bool_ - Whether to check the type of the input each time or assume the first input type. - **np_optimize** : {`True`, `False`, `'greedy'`, `'optimal'`} - The `optimize` keyword of `numpy.einsum_path`. """ # initialize EFPBase super(EFP, self).__init__(measure, beta, kappa, normed, coords, check_input) # store these edges as an EFPElem self.efpelem = EFPElem(edges) self._np_optimize = np_optimize # setup ve for standard efp compute (self.efpelem.einstr, self.efpelem.einpath, self.chi) = VariableElimination(np_optimize).einspecs( self.simple_graph, self.n)
def __init__(self, *args, **kwargs): r"""EFPSet can be initialized in one of three ways (in order of precedence): 1. **Default** - Use the ($d\le10$) EFPs that come installed with the `EnergFlow` package. 2. **Generator** - Pass in a custom `Generator` object as the first positional argument. 3. **Custom File** - Pass in the name of a `.npz` file saved with a custom `Generator`. To control which EFPs are included, `EFPSet` accepts an arbitrary number of specifications (see [`sel`](#sel)) and only EFPs meeting each specification are included in the set. **Arguments** - ***args** : _arbitrary positional arguments_ - If the first positional argument is a `Generator` instance, it is used for initialization. The remaining positional arguments must be valid arguments to `sel`. - **filename** : _string_ - Path to a `.npz` file which has been saved by a valid `energyflow.Generator`. - **measure** : {`'hadr'`, `'hadr-dot'`, `'ee'`} - See [Measures](../measures) for additional info. - **beta** : _float_ - The parameter $\\beta$ appearing in the measure. Must be greater than zero. - **kappa** : {_float_, `'pf'`} - If a number, the energy weighting parameter $\\kappa$. If `'pf'`, use $\\kappa=v-1$ where $v$ is the valency of the vertex. - **normed** : _bool_ - Controls normalization of the energies in the measure. - **coords** : {`'ptyphim'`, `'epxpypz'`, `None`} - Controls which coordinates are assumed for the input. See [Measures](../measures) for additional info. - **check_input** : _bool_ - Whether to check the type of the input each time or assume the first input type. - **verbose** : _bool_ - Controls printed output when initializing EFPSet. """ default_kwargs = { 'filename': None, 'measure': 'hadr', 'beta': 1, 'kappa': 1, 'normed': True, 'coords': None, 'check_input': True, 'verbose': False } measure_kwargs = [ 'measure', 'beta', 'kappa', 'normed', 'coords', 'check_input' ] # process arguments for k, v in default_kwargs.items(): if k not in kwargs: kwargs[k] = v if k not in measure_kwargs: setattr(self, k, kwargs.pop(k)) kwargs_check('__init__', kwargs, allowed=measure_kwargs) # initialize EFPBase super(EFPSet, self).__init__(*[kwargs[k] for k in measure_kwargs]) # handle different methods of initialization maxs = ['nmax', 'emax', 'dmax', 'cmax', 'vmax', 'comp_dmaxs'] elemvs = ['edges', 'weights', 'einstrs', 'einpaths'] if len(args) >= 1 and isinstance(args[0], Generator): constructor_attrs = maxs + elemvs + [ 'cols', 'c_specs', 'disc_specs', 'disc_formulae' ] gen = {attr: getattr(args[0], attr) for attr in constructor_attrs} args = args[1:] elif self.filename is not None: self.filename += '.npz' if not self.filename.endswith( '.npz') else '' gen = np.load(self.filename, allow_pickle=True) else: gen = np.load(DEFAULT_EFP_FILE, allow_pickle=True) # compile regular expression for use in sel() self.SEL_RE = SEL_RE # put column headers and indices into namespace self._cols = gen['cols'] self._set_col_inds() # put gen maxs into dict self.gen_maxs = {m: gen[m] for m in maxs} # get disc formulae and disc mask orig_disc_specs = gen['disc_specs'] disc_mask = self.sel(*args, specs=orig_disc_specs) self.disc_formulae = gen['disc_formulae'][disc_mask] # get connected specs and full specs orig_c_specs = gen['c_specs'] c_mask = self.sel(*args, specs=orig_c_specs) self._cspecs = orig_c_specs[c_mask] self._specs = concat_specs(self._cspecs, orig_disc_specs[disc_mask]) # make EFPElem list z = zip(*([gen[v] for v in elemvs] + [orig_c_specs[:, self.k_ind]])) self.efpelems = [ EFPElem(*args) for m, args in enumerate(z) if c_mask[m] ] # union over all weights needed self.__weight_set = frozenset(w for efpelem in self.efpelems for w in efpelem.weight_set) # get col indices for disconnected formulae connected_ndk = { efpelem.ndk: i for i, efpelem in enumerate(self.efpelems) } self.disc_col_inds = [] for formula in self.disc_formulae: try: self.disc_col_inds.append( [connected_ndk[factor] for factor in formula]) except KeyError: warnings.warn( 'connected efp needed for {} not found'.format(formula)) # handle printing if self.verbose: print('Originally Available EFPs:') self.print_stats(specs=concat_specs(orig_c_specs, orig_disc_specs), lws=2) if len(args) > 0: print('Currently Stored EFPs:') self.print_stats(lws=2)