def internal_san_checker(): sys.stderr.write( "Starting internal sanity check with {} classes.\n".format( len(classes))) ProgressBar.create(len(classes)) for clas in classes: if len(clas) < 2: continue print('Sanity checking the class %s' % str(clas)) for l in range(1, check_len + 1): for p in PermSet(l): last = None for i in clas: if last is None: last = p.avoids(MeshPatt.unrank(classpatt, mps[i])) continue av = p.avoids(MeshPatt.unrank(classpatt, mps[i])) if av != last: print('Noooooooooooooooo') print(MeshPatt.unrank(classpatt, mps[i - 1])) print('') print(mps[i]) return last = av ProgressBar.progress() ProgressBar.finish() print("Sanity check completed.")
def test_length_one_meshpatts_emptyness(self): for equivalent_shading in ([], [(0, 0)], [(1, 0)], [(0, 1), (1, 1)]): mp = MeshPatt(Perm((0,)), equivalent_shading) assert Cell(frozenset({mp}), frozenset()).is_empty() for nonequivalent_shading in ([(0, 0), (1, 1)], [(0, 1), (1, 0)]): mp = MeshPatt(Perm((0,)), nonequivalent_shading) assert not Cell(frozenset({mp}), frozenset()).is_empty()
def test_mixed_sorting(self): p1 = Perm((0, 2, 1)) mp1 = MeshPatt(p1, [(i, i) for i in range(4)]) p2 = Perm((1, 0)) mp2 = MeshPatt(p2, [(2 - i, 2 - i) for i in range(3)]) assert list(Utils.sorted({p1, mp1, p2, mp2})) == [p2, p1, mp2, mp1]
def setUp(self): self.mp_31c2 = MeshPatt(Perm((2, 0, 1)), ((2, 0), (2, 1), (2, 2), (2, 3))) self.mp_cell = Cell(frozenset({self.mp_31c2}), frozenset()) self.mixed_av_co_cell = Cell( frozenset({ Perm((0, 2, 1)), MeshPatt(Perm((1, 0)), [(0, 0), (1, 1), (2, 2)]) }), frozenset({Perm((0, 1))}) )
def test_cleaning_av_123_with_shaded_column(self): p = Perm((0, 1, 2)) shading = [(1, 0), (1, 1), (1, 2), (1, 3)] mp = MeshPatt(p, shading) sub_mesh_patts = { mp.sub_mesh_pattern(indices) for indices in combinations(range(len(mp)), 2) } assert Utils.clean_patts( {}, sub_mesh_patts) == {MeshPatt(Perm((0, 1)), [])} assert Utils.clean_patts( {Perm((0, 1))}, sub_mesh_patts) == {Perm((0, 1))}
def stat_descriptor_single(stats): """Return all single mesh patterns that describe stats.""" #Find first non-zero stat to determine underlying permutation for perm, stat in stats: if stat > 0: p = perm break meshpatts = [MeshPatt(p)] while not all(all(occs(p, m) == s for p, s in stats) for m in meshpatts): new_meshpatts = [] for mp in meshpatts: unusable = False green = [] red = [] for perm, stat in stats: loccs = list(mp.occurrences_in(perm)) s = len(loccs) if s < stat: unusable = True break if s == stat: green.extend(smart_shade(perm, mp, loccs)) if s > stat: red.append(smart_shade(perm, mp, loccs)) if not unusable: ps = pick_shade(green, red) new_meshpatts.extend([mp.shade(boxes) for boxes in ps]) meshpatts = set(new_meshpatts) return meshpatts
def setUp(self): self.p_312 = Perm((2, 0, 1)) self.mp_31c2 = MeshPatt(self.p_312, ((2, 0), (2, 1), (2, 2), (2, 3))) self.mp_1c2 = self.mp_31c2.sub_mesh_pattern([1, 2]) self.root_mp_cell = Cell(frozenset({self.mp_31c2}), frozenset()) self.sub_mp_cell = Cell(frozenset({self.mp_1c2}), frozenset()) self.empty_mt = MeshTiling() self.any_mt = MeshTiling({(0, 0): MeshTiling.anything_cell}) self.root_mt = MeshTiling({ (0, 0): self.root_mp_cell, }) self.sub_mt = MeshTiling({ (0, 0): self.root_mp_cell, (1, 1): MeshTiling.point_cell, (2, 0): self.sub_mp_cell, })
def __str__(self): if self.is_empty() or self.is_point() or self.is_anything(): return repr(self) else: # String representation of mesh patts are a (2N + 1) x (2N + 1) # matrix where N is the length of the underlying permutation height = 1 + 2 * max( len(patt) for patt in chain(self.obstructions, self.requirements)) Av_strings = [ Utils.pad_string_to_rectangle( str(patt if isinstance(patt, MeshPatt ) else MeshPatt(patt, [])), 1 + 2 * len(patt), height).split("\n") for patt in Utils.sorted(self.obstructions) ] Co_strings = [ Utils.pad_string_to_rectangle( str(patt if isinstance(patt, MeshPatt ) else MeshPatt(patt, [])), 1 + 2 * len(patt), height).split("\n") for patt in Utils.sorted(self.requirements) ] lines = ["" for _ in range(height)] for row in range(height): middle_row = (row == (height - 1) / 2) if middle_row: prefix, delim, postfix = "{}( ", " , ", " )" else: prefix, delim, postfix = " ", " ", " " if self.is_avoiding(): lines[row] += prefix.format("Av") + delim.join( av_str[row] for av_str in Av_strings) + postfix if self.is_containing(): if self.is_avoiding(): lines[row] += " and " if middle_row else " " lines[row] += prefix.format("Co") + delim.join( co_str[row] for co_str in Co_strings) + postfix return "\n".join(line for line in lines)
def __init__(self, patts, classical_pattern, active): self.idmap = dict() self.pattrank = patts self.adj = [[] for _ in range(len(patts))] self.patts = [MeshPatt.unrank(classical_pattern, n) for n in patts] self.len = len(patts) self.active = active for patt in patts: if patt not in self.idmap: self.idmap[patt] = len(self.idmap) else: msg = "Element twice in class list: {}".format(patt) raise ValueError(msg)
def test_string_padding_to_rectangle(self): mp = MeshPatt(Perm((2, 0, 1)), ((2, 0), (2, 1), (2, 2), (2, 3))) mp_str = str(mp) for w, h in product(range(7), range(7)): with pytest.raises(ValueError): Utils.pad_string_to_rectangle(mp_str, w, h) assert Utils.pad_string_to_rectangle(mp_str, 7, 7) == mp_str padded_lines = Utils.pad_string_to_rectangle(mp_str, 9, 11).split("\n") for i, unpadded_line in enumerate(mp_str.split("\n"), start=2): assert unpadded_line.center(9) == padded_lines[i]
def test_cleaning_all_length_one_mesh_patt(self): p = Perm((0,)) perms = {p} mesh_patts = { MeshPatt(p, shading) for shading in [ list((n % 2, n // 2) for n, b in enumerate(c) if b) for c in product([True, False], repeat=4) ] } output = Utils.clean_patts(perms, mesh_patts) assert len(output) == 4 for patt in output: assert patt in perms or patt in mesh_patts
def main(): logging.getLogger().setLevel(logging.INFO) perm = Perm((2, 0, 1)) mesh_patt = MeshPatt(perm, ((2, 0), (2, 1), (2, 2), (2, 3))) mesh_tiling = MeshTiling({ (0, 0): Cell(obstructions=frozenset({mesh_patt}), requirements=frozenset()), }) mesh_tiling.MAX_COLUMN_DIMENSION = 3 mesh_tiling.MAX_ROW_DIMENSION = 2 mesh_tiling.MAX_ACTIVE_CELLS = 3 max_elmnt_size = 5 comb_cov = CombCov(mesh_tiling, max_elmnt_size) comb_cov.print_outcome()
def __init__(self, n, patt=None): self.n = n self.patt = patt self.mps = [] self.idx = {} sys.stderr.write('Generating mesh patterns\n') ProgressBar.create(2**((n + 1) * (n + 1)) * (factorial(n) if patt is None else 1)) for i, mp in enumerate(gen_meshpatts(n, patt)): ProgressBar.progress() self.mps.append(mp) self.idx[mp] = i assert MeshPatt.unrank(patt, i) == mp ProgressBar.finish()
right, top, left, bottom = patt.has_anchored_point() in_bound = set() if not right and not left and not top and not bottom: return False if right: in_bound.add(len(patt) - 1) if left: in_bound.add(0) if top: in_bound.add(inv[len(patt) - 1]) if bottom: in_bound.add(inv[0]) uf = UnionFind(len(patt)) for i in range(1, len(patt)): if all((i, j) in patt.shading for j in range(len(patt) + 1)): uf.unite(i - 1, i) if all((j, i) in patt.shading for j in range(len(patt) + 1)): uf.unite(inv[i - 1], inv[i]) # print(uf.leaders) return uf.leaders == set(uf.find(b) for b in in_bound) # cpatt = Perm(map(int, sys.stdin.readline().split())) cpatt = Perm(map(int, sys.argv[1])) mpatts = map(int, sys.stdin.readlines()) for p in mpatts: patt = MeshPatt.unrank(cpatt, p) if not is_boundary_anchored(patt) and len(patt.shading) < 10: print(patt) print()
class MeshTilingTest(unittest.TestCase): def setUp(self): self.p_312 = Perm((2, 0, 1)) self.mp_31c2 = MeshPatt(self.p_312, ((2, 0), (2, 1), (2, 2), (2, 3))) self.mp_1c2 = self.mp_31c2.sub_mesh_pattern([1, 2]) self.root_mp_cell = Cell(frozenset({self.mp_31c2}), frozenset()) self.sub_mp_cell = Cell(frozenset({self.mp_1c2}), frozenset()) self.empty_mt = MeshTiling() self.any_mt = MeshTiling({(0, 0): MeshTiling.anything_cell}) self.root_mt = MeshTiling({ (0, 0): self.root_mp_cell, }) self.sub_mt = MeshTiling({ (0, 0): self.root_mp_cell, (1, 1): MeshTiling.point_cell, (2, 0): self.sub_mp_cell, }) def test_is_instance_of_Rule(self): assert isinstance(self.sub_mt, Rule) assert isinstance(self.root_mt, Rule) assert isinstance(self.empty_mt, Rule) def test_padding_removal(self): padded_sub_mt = MeshTiling({ (1, 1): self.root_mp_cell, (2, 2): MeshTiling.point_cell, (3, 1): self.sub_mp_cell, }) assert padded_sub_mt == self.sub_mt def test_any_mt(self): any_tiling = self.any_mt.tiling assert len(any_tiling) == 1 assert any_tiling[0] == MeshTiling.anything_cell def test_number_to_coordinates_conversions(self): assert self.sub_mt.convert_linear_number_to_coordinates(0) == (0, 0) assert self.sub_mt.convert_linear_number_to_coordinates(1) == (1, 0) assert self.sub_mt.convert_linear_number_to_coordinates(2) == (2, 0) assert self.sub_mt.convert_linear_number_to_coordinates(3) == (0, 1) assert self.sub_mt.convert_linear_number_to_coordinates(4) == (1, 1) assert self.sub_mt.convert_linear_number_to_coordinates(5) == (2, 1) for number in (-1, 6): with pytest.raises(IndexError): self.sub_mt.convert_linear_number_to_coordinates(number) def test_coordinates_to_number_conversions(self): assert self.sub_mt.convert_coordinates_to_linear_number(0, 0) == 0 assert self.sub_mt.convert_coordinates_to_linear_number(1, 0) == 1 assert self.sub_mt.convert_coordinates_to_linear_number(2, 0) == 2 assert self.sub_mt.convert_coordinates_to_linear_number(0, 1) == 3 assert self.sub_mt.convert_coordinates_to_linear_number(1, 1) == 4 assert self.sub_mt.convert_coordinates_to_linear_number(2, 1) == 5 for (col, row) in [(-1, 0), (0, -1), (3, 0), (0, 2)]: with pytest.raises(IndexError): self.sub_mt.convert_coordinates_to_linear_number(col, row) def test_make_tiling(self): tiling = self.sub_mt.tiling correct_tiling = [ Cell(frozenset({self.mp_31c2}), frozenset()), MeshTiling.empty_cell, Cell(frozenset({self.mp_1c2}), frozenset()), MeshTiling.empty_cell, MeshTiling.point_cell, MeshTiling.empty_cell ] assert tiling == correct_tiling def test_invalid_obstruction(self): invalid_cell = Cell(frozenset({"not a mesh patt"}), frozenset()) invalid_mt = MeshTiling({(0, 0): invalid_cell}) with pytest.raises(ValueError): list(invalid_mt.get_subrules()) def test_extra_empty_cell(self): root_mt_with_extra_empty_cell = MeshTiling({ (0, 0): self.root_mp_cell, (1, 1): MeshTiling.empty_cell }) assert self.root_mt == root_mt_with_extra_empty_cell def test_get_elmnts_of_size_Av21_cell(self): mt = MeshTiling({ (0, 0): Cell(frozenset({Perm((1, 0))}), frozenset()), (1, 1): MeshTiling.point_cell }) for size in range(1, 5): expected_perms = set(Av([Perm((1, 0))]).of_length(size)) mt_perms = mt.get_elmnts(of_size=size) assert (len(set(mt_perms)) == len(list(mt_perms))) assert (set(mt_perms) == expected_perms) def test_get_elmnts_of_size_point_cell(self): mt = MeshTiling({ (0, 0): MeshTiling.point_cell }) for size in range(1, 5): expected_perms = {Perm((0,))} if size == 1 else set() mt_perms = mt.get_elmnts(of_size=size) assert (len(set(mt_perms)) == len(list(mt_perms))) assert (set(mt_perms) == expected_perms) def test_subrules(self): self.root_mt.MAX_COLUMN_DIMENSION = 3 self.root_mt.MAX_ROW_DIMENSION = 2 self.root_mt.MAX_ACTIVE_CELLS = 3 subrules = list(self.root_mt.get_subrules()) assert all(isinstance(rule, Rule) for rule in subrules) assert (self.empty_mt in subrules) assert (self.any_mt in subrules) assert (self.root_mt in subrules) assert (self.sub_mt in subrules) def test_subrules_too_small_dimensions(self): self.root_mt.MAX_COLUMN_DIMENSION = 2 self.root_mt.MAX_ROW_DIMENSION = 2 self.root_mt.MAX_ACTIVE_CELLS = 3 subrules = list(self.root_mt.get_subrules()) assert all(isinstance(rule, Rule) for rule in subrules) assert (self.empty_mt in subrules) assert (self.any_mt in subrules) assert (self.root_mt in subrules) assert (self.sub_mt not in subrules) def test_dimensions(self): assert (self.empty_mt.get_dimension() == (1, 1)) assert (self.any_mt.get_dimension() == (1, 1)) assert (self.root_mt.get_dimension() == (1, 1)) assert (self.sub_mt.get_dimension() == (3, 2)) def test_length(self): assert (len(self.empty_mt) == 1) assert (len(self.any_mt) == 1) assert (len(self.root_mt) == 1) assert (len(self.sub_mt) == 6) def test_is_hashable(self): self.empty_mt.__hash__() self.any_mt.__hash__() self.root_mt.__hash__() self.sub_mt.__hash__() def test_repr(self): assert repr(self.empty_mt) == "(1x1) MeshTiling [ ]" assert repr(self.any_mt) == "(1x1) MeshTiling [S]" sub_mt_rep = repr(self.sub_mt) assert sub_mt_rep.startswith("(3x2) MeshTiling") assert repr(self.mp_1c2) in sub_mt_rep assert repr(self.mp_31c2) in sub_mt_rep def test_str(self): assert str(self.empty_mt) == "\n" + ( " --- \n" "| |\n" " --- \n") assert str(self.any_mt) == "\n" + ( " --- \n" "| S |\n" " --- \n") assert str(self.sub_mt) == "\n" + ( " --------------------------------- \n" "| | o | |\n" "|---------------+---+-------------|\n" "| | |#| | | |\n" "| -2-+-+- | | |#| |\n" "| | |#| | | -+-1- |\n" "| Av( -+-+-1- ) | | Av( |#| ) |\n" "| | |#| | | -0-+- |\n" "| -+-0-+- | | |#| |\n" "| | |#| | | |\n" " --------------------------------- \n")
def test_cleaning_av_12_perm_and_mesh_patts(self): p = Perm((0, 1)) mesh_patts = {MeshPatt(p, ()), MeshPatt(p, [(1, 0), (1, 1), (1, 2)])} perms = {p} expected_output = {p} assert Utils.clean_patts(perms, mesh_patts) == expected_output
def sdm_bivincular(stats, priors=[], maxpatts=4, maxlen=3): """Find one or more lists of mesh patterns (bivincular patterns) that describe stats, if possible. Args: stats: The statistic for which to find a description. List of tuples (p,s) where p is a permutation and s is an integer. priors: List of mesh patterns previously selected for the description. maxpatts: The maximum number of patterns allowed in a description. maxlen: The maximum length of patterns allowed in a description. Returns list of lists of mesh patterns (bivincular patterns) that describe the given statistic. """ tsp = tuple(sorted(priors)) if tsp in memo_b: return [] if len(priors) > maxpatts: memo_b[tsp] = [] return [] if priors == []: for perm, stat in stats: if stat > 0: p = perm break if len(p) > maxlen: memo_b[tsp] = priors return [] meshpatts = [[MeshPatt(p)]] else: meshpatts = [priors] if len(priors) == maxpatts and any( occsum(p, priors) < s for p, s in stats): memo_b[tsp] = [] return [] i = 0 while i < 10 and not all( all(occsum(p, m) <= s for p, s in stats) for m in meshpatts): new_meshpatts = [] for mp in meshpatts: green = [] red = [] for perm, stat in stats: st = occsum(perm, mp) if st > stat: red.append(smshbiv_list(perm, mp)) ps = pick_shade(green, red) new_meshpatts.extend([shbiv_list(mp, boxes) for boxes in ps]) meshpatts = new_meshpatts i += 1 f = [] for mp in meshpatts: new_stats = [(p, s - occsum(p, mp)) for p, s in stats] if all(s == 0 for _, s in new_stats): f.append(mp) elif all(s >= 0 for _, s in new_stats): for perm, stat in new_stats: if stat > 0: p = perm break if len(p) <= maxlen: f.extend( sdm_bivincular(stats, mp + [MeshPatt(p)], maxpatts, maxlen)) if len(f) == 0: memo_b[tsp] = [] return [] minlen = min([len(l) for l in f]) ff = set([tuple(sorted(l)) for l in f if len(l) == minlen]) memo_b[tsp] = ff return ff