def set_partitions(): print("Set partitions example.\n-----------------------\n") # In this examples, we ... L = LAtomSampler() Set = SetSampler def eval_P(x): return math.exp(math.exp(x) - 1) def expected_size(x): return x * math.exp(x) grammar = DecompositionGrammar({'P': Set(0, Set(1, L))}) grammar.init() oracle = EvaluationOracle({'x': 2.0}) BoltzmannSamplerBase.oracle = oracle # partition = grammar.sample('P', 'x', 'y') partition = grammar.sample_iterative('P', 'x', 'y') partition.assign_random_labels() print("expected size of set: {}\n".format(expected_size(oracle.get('x')))) print(partition) print("(size {})".format(partition.l_size))
def other_oldtest(): # some shortcuts to make the grammar more readable Z = ZeroAtomSampler() L = LAtomSampler() U = UAtomSampler() Tree = AliasSampler('Tree') Bla = AliasSampler('Bla') Blub = AliasSampler('Blub') Blob = AliasSampler('Blob') test_grammar = DecompositionGrammar() test_grammar.add_rules({ # tree is either a leaf or inner node with two children which are trees 'Tree': L + Tree * L * Blub, 'Blub': USubsSampler(Bla, Blob), 'Blob': L + U + Z, 'Bla': LSubsSampler(Blub, Blob), }) test_grammar.init() other_test_oracle = EvaluationOracle({ 'x0': 0.4999749994, 'y0': 1.0, # this is not needed here 'Tree(x0,y0)': 0.99005 }) # inject the oracle into the samplers BoltzmannSamplerBase.oracle = other_test_oracle print(test_grammar.recursive_rules) print() print(test_grammar._collect_oracle_queries('Bla', 'x', 'y'))
def __init__(self, n, epsilon=0.1, require_connected=True, with_embedding=True, allow_multiproc=False): # Handle invalid arguments. if n < 3: raise ValueError("n must be an integer greater or equal than 3") self._n = n if epsilon > 1 or epsilon < 0: raise ValueError("epsilon must be a real number in [0,1]") self._eps = epsilon # Compute interval of accepted sizes. self._lower = math.ceil(n * (1 - epsilon)) self._upper = math.floor(n * (1 + epsilon)) self._require_connected = require_connected self._with_embedding = with_embedding self._allow_parallel = allow_multiproc if allow_multiproc: self.sample = self._sample_multiproc else: self.sample = self._sample_single_proc # Set up the oracle and grammar for sampling. # BoltzmannSamplerBase.oracle = \ # EvaluationOracle.get_best_oracle_for_size(n, planar_graph_evals) # TODO Implement the choice of values. BoltzmannSamplerBase.oracle = EvaluationOracle(my_evals_1000) self._grammar = planar_graph_grammar() self._grammar.init() self._grammar._precompute_evals('G_dx_dx_dx', 'x', 'y')
def test_distribution_K_l_1(num_samples=100): """Unrooted binary trees (class K) with one black node.""" BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = binary_tree_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'K' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) # There are only 2 possibilities. graphs_labs = [ (nx.path_graph(2), 1, 4), (nx.path_graph(3), 2, 5), # TODO here something looks wrong when you run it. ] test_distribution_for_l_size( grammar, sampled_class, symbolic_x, symbolic_y, 1, # l-size graphs_labs, num_samples)
def binary_tree_oldtest_V2(): binary_tree_test_oracle = EvaluationOracle({ 'x': 0.0475080992953792, 'y': 1.0, # 'R_b_as(x,y)': 1, # 'R_w_as(x,y)': 1, 'R_w(x,y)': 1, 'R_b(x,y)': 1, # 'R_b_head(x,y)': 0.000001, # 'R_w_head(x,y)': 0.9 }) BoltzmannSamplerBase.oracle = binary_tree_test_oracle # BoltzmannSampler.oracle = EvaluationOracle(planar_graph_evals_n100) grammar = binary_tree_grammar() grammar.init() symbolic_x = 'x' symbolic_y = 'y' # [print(query) for query in sorted(binary_tree_grammar.collect_oracle_queries('K_dy', symbolic_x, symbolic_y))] tree = grammar.sample('K_dy', symbolic_x, symbolic_y) # print(tree) print(tree.base_class_object().get_attribute('numblacknodes'), end="\t") print(tree.base_class_object().get_attribute('numwhitenodes'), end="\t") print(tree.base_class_object().get_attribute('numtotal'), end="\t") return tree.base_class_object()
def run_profiler(): oracle = EvaluationOracle(my_evals_10000) BoltzmannSamplerBase.oracle = oracle BoltzmannSamplerBase.debug_mode = False grammar = planar_graph_grammar() grammar.init() symbolic_x = 'x' symbolic_y = 'y' sampled_class = 'G_dx_dx_dx' # symbolic_x = 'x*G_1_dx(x,y)' # symbolic_y = 'D(x*G_1_dx(x,y),y)' # sampled_class = 'K_dx_dx' # print(grammar.collect_oracle_queries(sampled_class, symbolic_x, symbolic_y)) grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) # random.seed(0) # boltzmann_framework_random_gen.seed(13) l_sizes = [] i = 0 samples = 1 while i < samples: obj = grammar.sample_iterative(sampled_class, symbolic_x, symbolic_y) l_sizes.append(obj.l_size) print(obj.l_size) i += 1 print() print("avg. size: {}".format(sum(l_sizes) / len(l_sizes)))
def test_distribution_K_l_2(num_samples=100): BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = binary_tree_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'K' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) star_path_1 = nx.star_graph(3) star_path_1.add_edge(1, 4) star_path_2 = nx.star_graph(3) star_path_2.add_edge(1, 4) star_path_2.add_edge(4, 5) other = nx.Graph(star_path_1) other.add_edge(4, 5) other.add_edge(4, 6) # The first factor is due to the position of the leaves and the second are the labellings. graphs_labs_u_size = [(nx.path_graph(3), 1 * 2, 5), (nx.path_graph(4), 4 * 2, 6), (nx.path_graph(5), 4 * 2, 7), (star_path_1, 2 * 2, 7), (star_path_2, 4 * 2, 8), (other, 1 * 2, 9)] test_distribution_for_l_size( grammar, sampled_class, symbolic_x, symbolic_y, 2, # l-size graphs_labs_u_size, num_samples)
def natural_numbers(): print("Natural numbers example.\n------------------------\n") # Define some shortcuts to make the grammar more readable. One = UAtomSampler() Zero = ZeroAtomSampler() N = AliasSampler('N') # Define the grammar and initialize. grammar = DecompositionGrammar({ # A natural number is either zero or the successor (+1) of another natural number. 'N': Zero + One * N }) grammar.init() y = 0.999 N = 1 / (1 - y) N_dy = 1 / (1 - y)**2 oracle = EvaluationOracle({'y': y, 'N(x,y)': N}) BoltzmannSamplerBase.oracle = oracle grammar._precompute_evals('N', 'x', 'y') print("expected number: {}".format(y * N_dy / N)) num_samples = 10 numbers = [ grammar.sample_iterative('N', 'x', 'y') for _ in range(num_samples) ]
def test_distribution_G_3_arrow_l_3(num_samples=100): BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = three_connected_graph_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'G_3_arrow' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) cycle_with_midpoint = nx.cycle_graph(4) cycle_with_midpoint.add_edges_from([(0, 4), (1, 4), (2, 4), (3, 4)]) fully_triangulated = nx.complete_graph(4) fully_triangulated.add_edges_from([(0, 4), (1, 4), (2, 4)]) other = nx.cycle_graph(4) other.add_edges_from([(0, 4), (1, 4), (2, 4)]) # See p. 12 (2) and p. 16. # The number of labellings come from deriving the generating function G_3 by y and then multiplying by 2. # The l-size is 2 less for edge rooted graphs, so we divide by 4*5 to get the form x³/3! * ... graphs_labs_u_size = [(cycle_with_midpoint, 2 * 8 * 15 / (4 * 5), 7), (fully_triangulated, 2 * 9 * 10 / (4 * 5), 8)] test_distribution_for_l_size( grammar, sampled_class, symbolic_x, symbolic_y, 3, # l-size graphs_labs_u_size, num_samples=num_samples)
def test_distribution_R_b_l_1(num_samples=100): BoltzmannSamplerBase.oracle = EvaluationOracle(planar_graph_evals_n100) grammar = binary_tree_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'R_b' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) # In this case the labs column does not correspond to actual labelings # but to distinction because of the root. graphs_labs_u_size = [ (nx.path_graph(1), 1, 2), (nx.path_graph(2), 2, 3), (nx.path_graph(3), 1, 4), ] test_distribution_for_l_size( grammar, sampled_class, symbolic_x, symbolic_y, 1, # l-size graphs_labs_u_size, num_samples)
def integer_partitions(): print("Integer partitions example.\n---------------------------\n") # Define some shortcuts to make the grammar more readable. U = UAtomSampler Set = SetSampler USubs = USubsSampler Bij = BijectionSampler Rule = AliasSampler class Partition(SetClass): def __init__(self, numbers): super(Partition, self).__init__(numbers) @property def u_size(self): return sum(iter(self)) def to_partition(p): return Partition([n.u_size for n in p]) # Define the grammar and initialize. grammar = DecompositionGrammar({ # A natural number is either zero or the successor (+1) of another natural number. 'N': U() + U() * Rule('N'), 'P': Bij(USubs(Set(1, U()), Rule('N')), to_partition) }) grammar.init() print("Needed oracle entries for sampling: {}\n".format( grammar._collect_oracle_queries('P', 'x', 'y'))) y = 0.56 N = y / (1 - y) P = math.exp(N) - 1 P_dy = math.exp(N) / (1 - y)**2 oracle = EvaluationOracle({ 'y': y, 'N(x,y)': N, }) BoltzmannSamplerBase.oracle = oracle print("expected number: {}\n".format(y * P_dy / P)) target_size = 4 num_samples = 100 partitions = [] while len(partitions) < num_samples: p = grammar.sample('P', 'x', 'y') if p.u_size == target_size: partitions.append(p) for i in range(1, 5): print("number of partitions into {} numbers: {}".format( i, len([p for p in partitions if len(p) == i])))
def test_distribution_G_3_arrow_l_4(num_samples=100): BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = three_connected_graph_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'G_3_arrow' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) # TODO we do not have enough data here to make this test g9 = nx.Graph() g9.add_edges_from([(0, 1), (0, 3), (0, 5), (1, 3), (1, 4), (2, 3), (2, 5), (2, 4), (4, 5)]) g10_1 = nx.Graph() g10_1.add_edges_from([(0, 1), (0, 3), (0, 2), (0, 5), (1, 2), (1, 4), (1, 5), (2, 3), (3, 4), (4, 5)]) g10_2 = nx.Graph() g10_2.add_edges_from([(0, 1), (0, 2), (0, 3), (1, 2), (1, 5), (2, 3), (2, 5), (2, 4), (3, 4), (4, 5)]) g11_1 = nx.Graph() g11_1.add_edges_from([(0, 1), (0, 5), (0, 4), (0, 3), (1, 4), (1, 5), (1, 2), (2, 3), (2, 5), (3, 5), (3, 4)]) g11_2 = nx.Graph() g11_2.add_edges_from([(0, 1), (0, 3), (0, 2), (0, 5), (0, 4), (1, 2), (1, 5), (1, 3), (2, 3), (3, 4), (4, 5)]) g12_1 = nx.Graph() g12_1.add_edges_from([(0, 1), (0, 2), (0, 3), (0, 5), (0, 4), (1, 2), (1, 4), (2, 3), (2, 4), (2, 5), (3, 5), (4, 5)]) g12_2 = nx.Graph() g12_2.add_edges_from([(0, 1), (0, 2), (0, 3), (0, 5), (1, 2), (1, 4), (1, 5), (2, 3), (2, 4), (3, 4), (3, 5), (4, 5)]) # ... graphs_labs_u_size = [ (g9, 2 * 9 * 60 / (6 * 5), 8), (g10_1, 2 * 10 * 432 / (6 * 5), 9), (g10_2, 2 * 10 * 0 / (6 * 5), 9), # Don't know how many there are with 10 edges (g11_1, 2 * 11 * 540 / (6 * 5), 10), (g11_2, 2 * 11 * 0 / (6 * 5), 10), # Same as above ... (g12_1, 2 * 12 * 195 / (6 * 5), 11), (g12_2, 2 * 12 * 0 / (6 * 5), 11) # Same as above ... ] test_distribution_for_l_size(grammar, sampled_class, symbolic_x, symbolic_y, 4, graphs_labs_u_size, num_samples=num_samples)
def irreducible_dissection_oldtest(): from planar_graph_sampler.grammar.irreducible_dissection_decomposition import irreducible_dissection_grammar symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' BoltzmannSamplerBase.oracle = EvaluationOracle(planar_graph_evals_n100) grammar = irreducible_dissection_grammar() grammar.init() dissection = grammar.sample('J', symbolic_x, symbolic_y) print(dissection) return dissection
def dummy_sampling(): print("Dummy sampling example.\n-----------------------\n") L = LAtomSampler() Tree = AliasSampler('Tree') tree_grammar = DecompositionGrammar() tree_grammar.rules = { # Tree is either a leaf or inner node with two children which are trees. 'Tree': L + L * Tree**2, } # init the grammar tree_grammar.init() tree_grammar.dummy_sampling_mode() def get_x_for_size(n): return math.sqrt(n**2 - 1) / (2 * n) def eval_T(x): return (math.sqrt(1 - 4 * x**2) + 1) / (2 * x) def eval_T_dx(x): return (1 / (math.sqrt(1 - 4 * x**2)) + 1) / (2 * x**2) target_size = 10 x = get_x_for_size(target_size) T = eval_T(x) T_dx = eval_T_dx(x) tree_oracle = EvaluationOracle({ 'x': x, 'Tree(x,y)': T, 'Tree_dx(x,y)': T_dx }) # Inject the oracle into the samplers. BoltzmannSamplerBase.oracle = tree_oracle print(tree_grammar._collect_oracle_queries('Tree', 'x', 'y')) num_samples = 10 while True: try: trees = [ tree_grammar.sample('Tree', 'x', 'y') for _ in range(num_samples) ] break except RecursionError: pass print(sum([tree.l_size for tree in trees]) / len(trees))
def binary_tree_oldtest(): binary_tree_test_oracle = EvaluationOracle({ 'x': 0.0475080992953792, 'y': 1.0, # 'R_b_as(x,y)': 1, # 'R_w_as(x,y)': 1, 'R_w(x,y)': 1, 'R_b(x,y)': 1, # 'R_b_head(x,y)': 0.000001, # 'R_w_head(x,y)': 0.9 }) # BoltzmannSampler.oracle = binary_tree_test_oracle BoltzmannSamplerBase.oracle = EvaluationOracle(planar_graph_evals_n100) grammar = binary_tree_grammar() grammar.init() # symbolic_x = 'x' symbolic_x = 'x*G_1_dx(x,y)' # symbolic_y = 'y' symbolic_y = 'D(x*G_1_dx(x,y),y)' print("Needed oracle entries:") [ print(query) for query in sorted( grammar._collect_oracle_queries('K_dy', symbolic_x, symbolic_y)) ] tree = grammar.sample('R_b', symbolic_x, symbolic_y) print("Black nodes: {}".format(tree.black_nodes_count)) print("White nodes: {}".format(tree.white_nodes_count)) print("Total nodes: {}".format(tree.black_nodes_count + tree.white_nodes_count)) print("Total leaves: {}".format(tree.leaves_count)) return tree
def test_distribution_G_1_dx_l_2(num_samples=100): """Test if connected planar graphs with exactly 4 nodes have the right distribution.""" BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = one_connected_graph_grammar() grammar.init() graphs_labs = [(nx.path_graph(3), 3, 2), (nx.complete_graph(3), 1, 3)] test_distribution_for_l_size(grammar, 'G_1_dx', 'x', 'y', 2, graphs_labs, num_samples=num_samples)
def network_oldtest(): BoltzmannSamplerBase.oracle = EvaluationOracle(planar_graph_evals_n100) grammar = two_connected_graph_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'y' [ print(query) for query in sorted( grammar._collect_oracle_queries('D', symbolic_x, symbolic_y)) ] network = grammar.sample('D', symbolic_x, symbolic_y) print(network.vertices_list) print(network.edges_list) print(network.root_half_edge) return network
def test_distribution_G_3_arrow_l_2(num_samples=100): BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = three_connected_graph_grammar() grammar.init() symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'G_3_arrow' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) # There is only 1 possibility, this test is sort of boring. graphs_labs_u_size = [(nx.complete_graph(4), 1, 5)] test_distribution_for_l_size( grammar, sampled_class, symbolic_x, symbolic_y, 2, # l-size graphs_labs_u_size, num_samples=num_samples)
def one_connected_oldtest(): from planar_graph_sampler.grammar.two_connected_decomposition import two_connected_graph_grammar from planar_graph_sampler.operations.block_decomposition import BlockDecomposition symbolic_x = 'x*G_1_dx(x,y)' symbolic_y = 'y' BoltzmannSamplerBase.oracle = EvaluationOracle(planar_graph_evals_n100) grammar = two_connected_graph_grammar() grammar.init() # Create list of L-der two connected graphs list_l_der_two_connected = [] for i in range(2): two_connected = grammar.sample('G_2_dx', symbolic_x, symbolic_y) list_l_der_two_connected.append(two_connected) decomp_worker = BlockDecomposition() decomp_worker.merge_set_of_l_der_two_connected_graphs( list_l_der_two_connected)
def test_distribution_G_2_dx_dx_l_3(num_samples=100): """Test if 2-connected planar graphs with exactly 4 nodes have the right distribution.""" BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = two_connected_graph_grammar() grammar.init() # grammar.precompute_evals('G_2_dx', 'x*G_1_dx(x,y)', 'y') # All two-connected planar graphs with 4 nodes and the number of their labellings. # See p.15, Fig. 5. cycle_with_chord = nx.cycle_graph(4) cycle_with_chord.add_edge(0, 2) graphs_labs = [(nx.cycle_graph(4), 3, 4), (cycle_with_chord, 6, 5), (nx.complete_graph(4), 1, 6)] test_distribution_for_l_size(grammar, 'G_2_dx_dx', 'x*G_1_dx(x,y)', 'y', 2, graphs_labs, num_samples=num_samples)
def test_distribution_G_1_dx_dx_l_2(num_samples=100): """Test if connected planar graphs with exactly 4 nodes have the right distribution.""" BoltzmannSamplerBase.oracle = EvaluationOracle(reference_evals) grammar = one_connected_graph_grammar() grammar.init() # All one-connected planar graphs with 4 nodes and the number of their labellings. # See p.15, Fig. 5. cycle_with_chord = nx.cycle_graph(4) cycle_with_chord.add_edge(0, 2) graphs_labs = [(nx.path_graph(4), 12, 3), (nx.star_graph(3), 4, 3), (nx.lollipop_graph(3, 1), 12, 4), (nx.cycle_graph(4), 3, 4), (cycle_with_chord, 6, 5), (nx.complete_graph(4), 1, 6)] test_distribution_for_l_size(grammar, 'G_1_dx_dx', 'x', 'y', 2, graphs_labs, num_samples=num_samples)
def sample_graphs_and_count(sampled_class, x, y, counting_seq, offset=1, factor=5): """Samples and graphs of given sizes and counts them.""" # Make evals hard coded for now - we are going to apply this test to small sizes only anyway. oracle = EvaluationOracle(my_evals_10) BoltzmannSamplerBase.oracle = oracle grammar = planar_graph_grammar() grammar.init(sampled_class, x, y) # The result will be a dictionary of graph count dicts keyed by number of nodes. result = {offset + i: {} for i in range(0, len(counting_seq))} sample_count = len(counting_seq) * [0] target_count = [factor * i for i in counting_seq] start = timer() while any(map(lambda pair: pair[0] < pair[1], zip(sample_count, target_count))): obj = grammar.sample_iterative(sampled_class).underive_all() if isinstance(obj, SetClass): obj = SetClass([he_graph.underive_all() for he_graph in obj]) n = obj.l_size if offset <= n < offset + len(counting_seq): if isinstance(obj, SetClass): G = comps_to_nx_graph(obj) else: assert isinstance(obj, HalfEdgeGraph) G = obj.to_networkx_graph(relabel=True) G_found = False for G_key in result[n]: if are_equal(G, G_key): result[n][G_key] += 1 G_found = True if not G_found: result[n][G] = 1 sample_count[n - offset] += 1 end = timer() print("time: {}".format(end - start)) return result
def ___sample_combinatorial_class(name, comb_class, symbolic_x, symbolic_y, size, exact=True, derived=0): start_sampling = timer() number_trials = 0 BoltzmannSamplerBase.oracle = EvaluationOracle.get_best_oracle_for_size( size, planar_graph_evals) grammar = None if name is "binary_tree": grammar = binary_tree_grammar() elif name is "three_connected": grammar = three_connected_graph_grammar() elif name is "two_connected": grammar = two_connected_graph_grammar() elif name is "one_connected": grammar = one_connected_graph_grammar() elif name is "planar_graph": grammar = planar_graph_grammar() else: raise Exception("No such graph class") assert (grammar is not None) grammar.init() node_num = 0 if exact: while node_num != size: number_trials += 1 graph = grammar.sample_iterative(comb_class, symbolic_x, symbolic_y) if derived == 0 and name is not "planar_graph" and name is not "one_connected": node_num = graph.number_of_nodes else: node_num = graph.l_size + derived else: graph = grammar.sample_iterative(comb_class, symbolic_x, symbolic_y) if derived == 0 and name is not "planar_graph" and name is not "one_connected": node_num = graph.number_of_nodes else: node_num = graph.l_size + derived if derived == 0 and name is not "planar_graph" and name is not "one_connected": edge_num = graph.number_of_edges else: edge_num = graph.u_size end_sampling = timer() time_needed = end_sampling - start_sampling data = (node_num, edge_num, number_trials, time_needed) ___save_graph_in_file(graph, name) return data, graph
def binary_trees(): print("Binary tree example.\n--------------------\n") def height(tree): if isinstance(tree, LAtomClass): return 1 else: assert isinstance(tree, ProdClass) return max(height(tree._second._first), height( tree._second._second)) + 1 # Define the grammar. # Define some shortcuts for readability. L = LAtomSampler _ = AliasSampler # Initialize a grammar object and set the sampling rules (in this case just one single rule). tree_grammar = DecompositionGrammar({ # A binary tree is either a leaf or an inner node with two children that are binary trees. 'T': L() + L() * _('T')**2 }) # Set the builder information and initialize the grammar. # tree_grammar.set_builder(['T'], BinaryTreeBuilder()) tree_grammar.init() # Do the mathematical stuff. def get_x_for_size(n): return math.sqrt(n**2 - 1) / (2 * n) def eval_T(x): return (math.sqrt(1 - 4 * x**2) + 1) / (2 * x) def eval_T_dx(x): return (1 / (math.sqrt(1 - 4 * x**2)) + 1) / (2 * x**2) # TODO something is weird here ... target_size = 2 # x = get_x_for_size(target_size) x = 0.499999999 print(x) T = eval_T(x) print(x * T**2 / (x + x * T**2)) T_dx = eval_T_dx(x) tree_oracle = EvaluationOracle({'x': x, 'T(x,y)': T, 'T_dx(x,y)': T_dx}) # Set the newly created oracle as the active oracle. BoltzmannSamplerBase.oracle = tree_oracle print("expected size of the trees: {}\n".format( tree_oracle.get_expected_l_size('T', 'x', 'y'))) print(tree_grammar.sample_iterative('T', 'x', 'y')) print("needed oracle entries for sampling: {}\n".format( tree_grammar._collect_oracle_queries('T', 'x', 'y'))) num_samples = 10 while True: try: trees = [ tree_grammar.sample('T', 'x', 'y') for _ in range(num_samples) ] break except RecursionError: # print("Recursion error") pass avg_size = sum([tree.l_size for tree in trees]) / num_samples print("average size in {} trials: {}".format(num_samples, avg_size)) avg_height = sum([height(tree) for tree in trees]) / num_samples print("average height of trees: {}".format(avg_height)) print(2 * math.sqrt(math.pi * avg_size / 2))
grammar.set_builder([ 'R_b', 'R_b_head', 'R_b_as', 'R_w', 'R_w_head', 'R_w_as', 'R_b_dx', 'R_b_head_dx', 'R_b_as_dx', 'R_w_dx', 'R_w_head_dx', 'R_w_as_dx' ], ModifiedDummyBuilder(grammar)) return grammar if __name__ == "__main__": from pyboltzmann.evaluation_oracle import EvaluationOracle from planar_graph_sampler.evaluations_planar_graph import * from pyboltzmann.utils import boltzmann_framework_random_gen from timeit import default_timer as timer # oracle = EvaluationOracle(planar_graph_evals[10000]) oracle = EvaluationOracle(my_evals_100) BoltzmannSamplerBase.oracle = oracle BoltzmannSamplerBase.debug_mode = False grammar = dummy_sampling_grammar() grammar.init() # grammar.dummy_sampling_mode() # symbolic_x = 'x' symbolic_y = 'y' symbolic_x = 'x*G_1_dx(x,y)' # symbolic_y = 'D(x*G_1_dx(x,y),y)' sampled_class = 'D_dx_dx' grammar._precompute_evals(sampled_class, symbolic_x, symbolic_y) try: print("expected: {}\n".format(
def test_sampled_sizes(): all_evaluations = [reference_evals] for evaluations in all_evaluations: oracle = EvaluationOracle(evaluations) BoltzmannSamplerBase.oracle = oracle # grammar = three_connected_graph_grammar() grammar = dummy_sampling_grammar() grammar.init() grammar.dummy_sampling_mode() grammar._precompute_evals('K', 'x*G_1_dx(x,y)', 'D(x*G_1_dx(x,y),y)') classes_known_dx = [ 'G_3_arrow', #'K_dx', #'K_dy', #'J_a', #'D', #'D_dx', #'S', #'S_dx', #'P', #'P_dx', #'H', #'H_dx', #'G_2_dx', #'G_2_dx_dx', #'G_1_dx_dx', #'G_1', #'G_1_dx', #'G', #'G_dx', #'G_dx_dx' ] symbolic_x = [ 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x*G_1_dx(x,y)', 'x', 'x', 'x', 'x', 'x', 'x' ] symbolic_y = [ 'D(x*G_1_dx(x,y),y)', 'D(x*G_1_dx(x,y),y)', 'D(x*G_1_dx(x,y),y)', 'D(x*G_1_dx(x,y),y)', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' ] for index, label in enumerate(classes_known_dx): x = symbolic_x[index] y = symbolic_y[index] expected_size = oracle.get_expected_l_size(label, symbolic_x[index], symbolic_y[index]) num_samples = 10000 count = 0 sizes = [] rec_errors = 0 while count < num_samples: try: sizes.append(grammar.sample(label, x, y).l_size) count += 1 except RecursionError: rec_errors += 1 observed = sum(sizes) / len(sizes) print( "class: {} \t expected: {} \t observed: {} \t rec. errors: {} \t difference: {}" .format(label, expected_size, observed, rec_errors, observed / expected_size - 1)) print()