Example #1
0
    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()}
Example #2
0
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