def __init__(self, surface_name, generators, automorph, MCG_must_contain, word_filter=basic_filter, manifold_filter=basic_filter, options=None): self.surface_name = surface_name self.generators = generators self.automorph = automorph self.MCG_must_contain = MCG_must_contain self.word_filter = word_filter self.manifold_filter = manifold_filter self.options = options if options is not None else Options() self.surfaces = SimpleNamespace( twister=snappy.twister.Surface(self.surface_name), flipper=flipper.load(self.surface_name), curver=curver.load(self.surface_name), ) self.word_generator = WordGenerator(self.generators, self.automorph, self.MCG_must_contain, self.word_filter, self.surfaces, self.options) for path in [ self.options.word_parts, self.options.properties_parts, self.options.word, self.options.properties, self.options.census ]: os.makedirs(os.path.dirname(path), exist_ok=True)
def test_closed_parallel_topological_type(self): S = curver.load(2, 1) a = S.triangulation([0, 2, 2, 2, 2, 0, 0, 0, 0]) b = S.triangulation([0, 0, 0, 0, 0, 2, 2, 2, 2]) self.assertEqual(a.topological_type(), b.topological_type()) self.assertEqual(a.topological_type(closed=True), b.topological_type(closed=True)) self.assertEqual((a+a).topological_type(), (b+b).topological_type()) self.assertEqual((a+a).topological_type(closed=True), (b+b).topological_type(closed=True)) self.assertNotEqual((a+a).topological_type(), (a+b).topological_type()) self.assertEqual((a+a).topological_type(closed=True), (a+b).topological_type(closed=True))
def test_dihedral(self, genus): S = curver.load(genus, 2) g = S('a_0.b_0.' + '.'.join('c_{}.b_{}'.format(i, i+1) for i in range(genus-1)) + '.p_1').simplify() h = S('(a_0.b_0.' + '.'.join('c_{}.b_{}'.format(i, i+1) for i in range(genus-1)) + ')^{}.S_1'.format(2*genus+1)).simplify() K = curver.kernel.FiniteSubgroup.from_generators({'g': g, 'h': h}) self.assertEqual(len(K), 4*(genus+1)) signature = [(Fraction(-genus, 2*(genus+1)), 1, [(False, 2, ['h'], 2*(genus+1)), (False, 2*(genus+1), ['hg'], 2), (True, 2*(genus+1), ['g' * (2*genus + 1)], 2)])] self.assertEqual(K.quotient_orbifold_signature(), signature)
def test_pair(self, g, p): assume(2 - 2 * g - p < 0) T = curver.load(g, p).triangulation self.assertTrue(T.is_connected()) surface = T.surface() self.assertEqual(len(surface), 1) S = list(surface.values())[0] self.assertEqual(S.g, g) self.assertEqual(S.p, p)
def main(args): if args.sig is not None: T = curver.triangulation_from_sig(args.sig) else: T = curver.load(args.genus, max(args.punctures, 1)).triangulation P = Polyhedron.from_triangulation(T, args.upper, zeros=args.zeros) num_integral_points = P.integral_points_count(triangulation='cddlib') print(P) try: print('Polytope dimension: {}'.format(P.as_sage().dimension())) except AttributeError: print('Polytope dimension: Unknown') print('Drawing from [0, {})'.format(num_integral_points)) common = dict(T=T, P=P, closed=args.punctures == 0) iterable = (dict(index=randrange(0, num_integral_points)) for _ in range(args.num)) process(from_index, common, iterable, cores=args.cores, path=args.output)
def index(request): error = None order = None classes = defaultdict(list) non_periodic = [] if request.method == 'POST': form = MappingClassForm(request.POST) if form.is_valid(): try: g = int(form.cleaned_data['genus']) p = int(form.cleaned_data['punctures']) words = form.cleaned_data['words'] S = curver.load(g, p) for word in re.split('[;,]+', words): h = S(word) order = h.order() if order == 0: non_periodic.append(word) else: signature = h.subgroup().quotient_orbifold_signature( )[0] signature = Orbifold( order, signature.euler_characteristic, tuple( sorted([ cone(cp, order) for cp in signature.cone_points ]))) classes[signature].append(word) except Exception as e: error = str(e) else: form = MappingClassForm() return render( request, 'quotient/index.html', { 'form': form, 'error': error, 'classes': dict(classes), 'non_periodic': non_periodic, 'version': curver.__version__ })
def main(args): if args.genus == 0 and args.punctures == 6: common = dict( T=curver.load(0, 6).triangulation, P=Polyhedron( eqns=[], ieqs=[ [0, 1, 0, 1, -2, 0, 0], # 1 + 3 - 4 - 4 [0, -1, 1, 0, 2, 0, 0], # -1 + 2 + 4 + 4 [0, 1, 1, 0, 0, 0, -1], # 1 + 2 - 6 [0, -1, 0, 0, 1, 0, 1], # 4 + 6 - 1 [args.upper, -4, -8, -5, -4, -5, -2], [-args.lower, 4, 8, 5, 4, 5, 2], ] + [[-1] + [0] * i + [1] + [0] * (6 - i - 1) for i in range(6)]), embedding=np.array([ [1, 0, 1, -1, 0, 0], [1, 0, 1, 0, 0, 0], [1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 1, -1], [1, 0, 1, -2, 0, 0], [-1, 1, 0, 2, 0, 0], [-1, 1, 0, 2, 1, 1], [0, 1, 0, 1, 1, 0], [0, 0, 0, 1, 0, 0], [0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 1], [-1, 0, 0, 1, 0, 1], ], dtype=object), closed=False, ) elif args.genus == 2 and args.punctures == 0: common = dict( T=curver.load(2, 1).triangulation, P=Polyhedron(eqns=[], ieqs=[ [-1, 1, 1, 1, 0, 0, -1], [-1, -1, -1, -1, 1, 1, 1], [args.upper, -7, -8, -7, -5, -5, -6], [-args.lower, 7, 8, 7, 5, 5, 6], ] + [[-1] + [0] * i + [1] + [0] * (6 - i - 1) for i in range(6)]), embedding=np.array([ [2, 2, 2, 0, 0, 0], [0, 0, 0, 1, 1, 2], [0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 1, 1], [0, 0, 0, 1, 0, 1], [1, 2, 1, 0, 0, 0], [1, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 0], [1, 1, 0, 0, 0, 0], ]), closed=True, ) elif args.genus == 2 and args.punctures == 1: common = dict( T=curver.load(2, 1).triangulation, P=Polyhedron( eqns=[], ieqs=[ [0, 1, 1, 0, -1, 0, 0, 0, 0], # 1 + 2 - 4 [0, 0, -1, 1, 1, 0, 0, 0, 0], # 3 + 4 - 2 [0, 0, 0, 0, 0, 1, 1, 0, -1], # 5 + 6 - 8 [0, 0, 0, 0, 0, 0, -1, 1, 1], # 7 + 8 - 6 [0, 0, 0, -1, -1, 0, 0, 1, 1], # 7 + 8 - 3 - 4 [0, 0, 0, 1, 1, 0, -1, 0, 1], # 3 + 4 + 8 - 6 [0, 0, 0, 1, 1, 0, 1, 0, -1], # 3 + 4 + 6 - 8 [args.upper, -11, -9, -9, -2, -9, -6, -6, -2], [-args.lower, 11, 9, 9, 2, 9, 6, 6, 2], ] + [[-1] + [0] * i + [1] + [0] * (8 - i - 1) for i in range(8)]), embedding=np.array( [ [0, 0, 2, 2, 0, 0, 0, 0], # 3 + 3 + 4 + 4 [0, 1, 1, 0, 0, 0, 0, 0], # 2 + 3 [0, -1, 1, 2, 0, 0, 0, 0], # 3 + 4 + 4 - 2 [1, 0, 1, 0, 0, 0, 0, 0], # 1 + 3 [1, 1, 0, 0, 0, 0, 0, 0], # 1 + 2 [0, 0, 0, 0, 0, 1, 1, 0], # 6 + 7 [0, 0, 0, 0, 0, -1, 1, 2], # 7 + 8 + 8 - 6 [0, 0, 0, 0, 1, 0, 1, 0], # 5 + 7 [0, 0, 0, 0, 1, 1, 0, 0], # 5 + 6 ], dtype=object), closed=False, ) elif args.genus == 3 and args.punctures == 0: common = dict( T=curver.load(3, 1).triangulation, P=Polyhedron( eqns=[], ieqs=[ # a1, b1, c1, a2, b2, c2, a3, b3, c3, x, y, z [-1, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, +1, +1], [-2, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, +1, +1], [-2, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, +1, +1], [-2, +2, +2, +2, 0, 0, 0, 0, 0, 0, 0, -1, -1], [-1, 0, 0, 0, 0, -1, -1, 0, 0, 0, +1, 0, +1], [-2, 0, 0, 0, 0, -2, 0, 0, 0, 0, +1, 0, +1], [-2, 0, 0, 0, 0, 0, -2, 0, 0, 0, +1, 0, +1], [-2, 0, 0, 0, +2, +2, +2, 0, 0, 0, -1, 0, -1], [-1, 0, 0, 0, 0, 0, 0, 0, -1, -1, +1, +1, 0], [-2, 0, 0, 0, 0, 0, 0, 0, -2, 0, +1, +1, 0], [-2, 0, 0, 0, 0, 0, 0, 0, 0, -2, +1, +1, 0], [-2, 0, 0, 0, 0, 0, 0, +2, +2, +2, -1, -1, 0], [ args.upper, -4, -2, -2, -4, -2, -2, -4, -2, -2, -6, -6, -6 ], [ -args.lower, +4, +2, +2, +4, +2, +2, +4, +2, +2, +6, +6, +6 ], ] + [[-1] + [0] * i + [1] + [0] * (12 - i - 1) for i in range(12)]), embedding=np.array([ #a1, b1, c1, a2, b2, c2, a3, b3, c3, x, y, z [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, +1], # 0 [0, -1, -1, 0, 0, 0, 0, 0, 0, 0, +1, +1], # 1 [0, +1, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 2 [+1, 0, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 3 [+1, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 4 [0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, +1], # 5 [0, 0, 0, 0, -1, -1, 0, 0, 0, +1, 0, +1], # 6 [0, 0, 0, 0, +1, +1, 0, 0, 0, 0, 0, 0], # 7 [0, 0, 0, +1, 0, +1, 0, 0, 0, 0, 0, 0], # 8 [0, 0, 0, +1, +1, 0, 0, 0, 0, 0, 0, 0], # 9 [0, 0, 0, 0, 0, 0, 0, 0, 0, +1, +1, 0], # 10 [0, 0, 0, 0, 0, 0, 0, -1, -1, +1, +1, 0], # 11 [0, 0, 0, 0, 0, 0, 0, +1, +1, 0, 0, 0], # 12 [0, 0, 0, 0, 0, 0, +1, 0, +1, 0, 0, 0], # 13 [0, 0, 0, 0, 0, 0, +1, +1, 0, 0, 0, 0], # 14 ]), closed=True, ) else: raise ValueError( f'Intrinsic coordinates not known for S_{args.genus},{args.punctures}' ) iterable = (dict() for _ in count()) process(func, common, iterable, cores=args.cores, path=args.output)
def memoized_load(*args): return curver.load(*args)
def test_correct_component_of_topological_type_marked(self): S = curver.load(2, 8) c = S.curves['p_1'] + S.curves['p_3'] + S.curves['p_5'] + S.curves['p_7'] + S.arcs['s_2'].boundary() + S.arcs['s_4'].boundary() + S.arcs['s_6'].boundary() + S.arcs['s_2'] d = S.curves['p_1'] + S.curves['p_3'] + S.curves['p_5'] + S.curves['p_7'] + S.arcs['s_2'].boundary() + S.arcs['s_4'].boundary() + S.arcs['s_6'].boundary() + S.arcs['s_4'] self.assertNotEqual(c.topological_type(), d.topological_type())
return curver.load(*args) @st.composite def mcgs(draw): g, p = draw(st.sampled_from(MCGS)) return memoized_load(g, p) @st.composite def mapping_classes(draw, triangulation=None, power_range=10): return draw(encodings(triangulation, power_range, distribution=[2, 3])) PERIODICS = [ curver.load(0, 6)('s_0.s_1.s_2.s_3.s_4'), curver.load(0, 6)('(s_0.s_1.s_2.s_3.s_4)^2'), curver.load(0, 6)('(s_0.s_1.s_2.s_3.s_4)^3'), curver.load(0, 6)('s_0.s_1.S_3.S_4'), curver.load(1, 1)('a_0.b_0'), curver.load(1, 1)('a_0.b_0.a_0'), curver.load(2, 1)('a_0.b_0.c_0.b_1'), curver.load(2, 1)('a_0.b_0.c_0.b_1.a_1'), curver.load(2, 2)('a_0.b_0.c_0.b_1.p_1'), ] @st.composite def periodic_mapping_classes(draw): return draw(st.sampled_from(PERIODICS))
import argparse parser = argparse.ArgumentParser(description='sample curves of at most a given weight') parser.add_argument('--num', '-n', type=int, default=1000, help='number of samples to take') parser.add_argument('--sig', '-s', type=str, help='signature of triangulation to use') parser.add_argument('--genus', '-g', type=int, default=2, help='genus of surface to work over') parser.add_argument('--punctures', '-p', type=int, default=0, help='num punctures of surface to work over') parser.add_argument('--weight', '-w', type=int, default=1000000, help='max weight of a curve') parser.add_argument('--zeros', '-z', type=int, default=35, help='which normal arcs to set to zero') parser.add_argument('--cores', '-c', type=int, default=1, help='number of cores to use') parser.add_argument('path', type=str, help='path to file to process') args = parser.parse_args() if args.sig is not None: T = curver.triangulation_from_sig(args.sig) else: T = curver.load(args.genus, max(args.punctures, 1)).triangulation P = get_polyhedron(T, args.weight, zeros=args.zeros) num_integral_points = P.integral_points_count(triangulation='cddlib') print(P) try: print('Polytope dimension: {}'.format(P.as_sage().dimension())) except AttributeError: print('Polytope dimension: Unknown') print('Drawing from [0, {})'.format(num_integral_points)) common = {'T': T, 'P': P, 'closed': args.punctures == 0, 'labels': [label for label in [i for i in range(T.zeta)] + [~i for i in range(T.zeta)][::-1]]} with open(args.path) as F: iterable = ({'geometric': eval(line)} for line in F) process(from_geometric, common, iterable, cores=args.cores)