def simplify(self): p = copy.deepcopy(self.productions) uf = UnionFind(list(p.keys())) while True: changed = False subs = {} to_add = {} to_delete = set() for k1, r1 in p.items(): for k2, r2 in p.items(): if k1 != k2 and k1 not in subs and k2 not in subs and r1 == r2: subs[k2] = k1 to_add[k1] = r2 to_delete.add(k2) uf.union(k1, k2) changed = True p = {**p, **to_add} for k in to_delete: del p[k] if not changed: break else: p = {k2: r2.substitute(subs) for k2, r2 in p.items()} return Grammar(productions=p), {k: uf.component(k) for k in p.keys()}
def sample_config(config, eta, N, no_colors, sites, param_name, curr_params, uf=None, cluster_constraints=None): if uf == None and not only_averages: '''Generate clusters from the assigned bonds (eta_edge)''' uf = UnionFind(sites) eta_edges = eta[1] for i in range(eta_edges.shape[0]): for j in range(eta_edges.shape[1]): for e in range(eta_edges.shape[2]): if eta_edges[i, j, e] == -1: continue if eta_edges[i, j, e] == 0: if e == 0: uf.union(site2str((i, j)), site2str((i + 1, j))) elif e == 1: uf.union(site2str((i, j)), site2str((i, j + 1))) '''For each cluster, find the site with strongest constraint (smallest eta_site) and assign that eta_site to the entire cluster ''' eta_sites = eta[2] cluster_constraints = {} cl_n = 0 cls = np.zeros((eta_sites.shape[0], eta_sites.shape[1]), dtype=np.uint16) # up to 255x255 box for cluster in uf.components(): cl_n += 1 min_constraint = no_colors cluster_root = '-1,-1' for site_str in cluster: site = str2site(site_str) if eta_sites[site[0], site[1]] <= min_constraint: min_constraint = eta_sites[site[0], site[1]] cluster_root = site_str cls[site[0], site[1]] = cl_n cluster_constraints[cluster_root] = min_constraint cluster_constraints[cl_n] = min_constraint if prt: print('clusters formed by bonds (eta_edge):') if prt: print(cls) # Case with no field and gamma > 0 if (curr_params['alpha'] == 0 and curr_params['gamma'] > 0): if prt: print('Case with no field and gamma > 0') '''Choose exactly how many colors to use in the configuration''' max_colors = eta[0] # eta_lambda prob_k = [] if only_averages: no_cl = N * N else: no_cl = len(uf.components()) for k in range(1, max_colors + 1): prob_k.append(P_exact_cols(no_colors, k, no_cl, S)) if prt: print('prob_k:', prob_k) prob_k = [pk / sum(prob_k) for pk in prob_k] prob_k = np.array(prob_k) if prt: print('prob_k:', prob_k) exact_k = np.random.choice((np.arange(1, max_colors + 1)), p=prob_k) if prt: print('exact number of colors to use in configuration:') if prt: print(exact_k) if only_averages: '''Only compute average in case with zero field and no interaction, but with gamma > 0, use an arbitray partition (avoid computing Bell polynomials) ''' chosen_colors = range(1, exact_k + 1) if exact_k == no_colors: chosen_partition = [exact_k] else: chosen_partition = [ exact_k - 1 ] + [0] * max(0, no_colors - exact_k - 1) + [1] part = [] for i in range(len(chosen_partition)): part += ([i + 1] * chosen_partition[i]) chosen_partition = part if prt: print('chosen partition:') if prt: print(chosen_partition) color_arr = [] for i in range(len(chosen_partition)): color_arr += [chosen_colors[i]] * chosen_partition[i] config = np.array(color_arr).reshape((N, N)) return config, None, None '''Sample a partition of the no. of clusters into k blocks using Bell polynomials''' partition_dict = {} if ((no_cl, exact_k) in bell_dict): partition_dict = bell_dict[(no_cl, exact_k)] if prt: print("Bell found", (no_cl, exact_k)) else: session.evaluate("subs = Array[x," + str(no_cl - exact_k + 1) + "]") partition_dict = session.evaluate( "Association@CoefficientRules[BellY[" + str(no_cl) + ", " + str(exact_k) + ", subs], subs]") bell_dict[(no_cl, exact_k)] = partition_dict if prt: print("Bell computed", (no_cl, exact_k)) if prt: print("partition_dict", partition_dict) partitions = [] partition_p = [] for partition in partition_dict: partitions.append(partition) partition_p.append(partition_dict[partition]) if prt: print('partition_p:', partition_p) partition_p = [pk / sum(partition_p) for pk in partition_p] parition_p = np.array(partition_p) if prt: print('partition_p:', partition_p) chosen_partition = partitions[np.random.choice( (np.arange(0, len(partitions))), p=partition_p)] if prt: print('chosen partition:') if prt: print(chosen_partition) # Transform to actual partition part = [] for i in range(len(chosen_partition)): part += ([i + 1] * chosen_partition[i]) chosen_partition = part if prt: print('chosen partition:') if prt: print(chosen_partition) '''Color each block in the partition randomly without replacement''' # Choose the colors to be used chosen_colors = np.random.choice((np.arange(1, no_colors + 1)), len(chosen_partition), replace=False) # Choose a random permutation of the given word color_arr = [] for i in range(len(chosen_partition)): color_arr += [chosen_colors[i]] * chosen_partition[i] color_arr = np.array(color_arr) color_arr = np.random.permutation(color_arr) if prt: print('colors for clusters:') if prt: print(color_arr) '''Color each cluster with the assigned color''' i = 0 for root in cluster_constraints: cluster_color = color_arr[i] for site_str in uf.component(root): site = str2site(site_str) config[site[0], site[1]] = cluster_color i += 1 # Case with field and gamma > 0 or case with gamma = 0 else: '''Randomly sample a color for each cluster''' if prt: print('Case with field and gamma > 0 or case with gamma = 0') config = brute_force_sample(cluster_constraints, cls, uf, config) return config, uf, cluster_constraints