def _test_against_known_canonical_retriangulations():
    from snappy import Manifold
    for name, bytes_ in _known_canonical_retriangulations:
        M = Manifold(name); K = verified_canonical_retriangulation(M)
        L = Manifold('empty'); L._from_bytes(bytes_)
        if not len(K.isomorphisms_to(L)):
            raise Exception('%s failed' % name)
Example #2
0
def get_volume_data(man_nms, engine = 'magma', max_secs = 20, retrieve = True, sln = 2, max_itf_degree = MAX_ITF):
    """ Returns a VolumeData object containing exotic volumes for manifolds with the given names
Volumes' precision is based on pari, so set it there
set retrieve = False to skip retrieving ptolemy data from files
set engine = None to skip computing ptolemy data in an engine
set max_secs to specify how long we will spend computing a given manifolds' data before killing the engine and moving on;
  specifying None means we will never give up (unless something crashes)
if the engine given crashes, so will IDLE and SnapPy; to avoid this, run this command only from within python scripts.
Manifolds with more than floor(max_itf_degree/2) distinct volumes to an obstruction class
will have their data for that obstruction class removed, since this demonstrates an invariant trace field with too high ncp
Set to None and it will be ignored.""" 

#TODO: special case max_secs=None to not bother with processes

    if engine:
        def _use_engine(v,p):   # this function will be called in a second process to facilitate time limits
            p.send(v.compute_solutions(engine = engine))
    recs = dict()
    for nm in man_nms:
        try:
            sols = None
            var = Manifold(nm).ptolemy_variety(sln,'all')
            try:
                if retrieve:
                    sols = var.retrieve_decomposition()
                else:
                    raise Exception("Go on and compute")
            except Exception as e: # try using engine
                if engine:
                    mine, theirs = Pipe(duplex = False)
                    p = Process(target=_use_engine,args=[var,theirs])
                    p.daemon = True
                    p.start()
                    if mine.poll(max_secs): # Here is the time limit stuff
                        sols = mine.recv()
                        p.terminate()
                    else:
                        p.terminate()   # give up on this one
                        print 'Computation took too long; skipping '+nm
                        continue
                else:
                    print 'No engine and no data retrieved; skipping '+nm
                    continue
            if sols:
                data = [(c.number_field(),c.solutions(numerical = True).volume_numerical()) for c in sols.flatten()]
                for cl_idx in xrange(len(data)):
                    if data[cl_idx]: # TODO may be trivial since no check here
                        for v in data[cl_idx][1]:
                            recs.setdefault(str(data[cl_idx][0]),dict()).setdefault(str(v),list()).append((nm,cl_idx))
            else:
                print 'Got no solutions; skipping '+nm
        except Exception as e:
            print(str(e))+'; skipping '+nm
            continue
    for p in recs.keys():
        for v in recs[p].keys():
            recs[p][v] = list(set(recs[p][v]))
    return VolumeData(data = recs)
Example #3
0
def link_exterior_tri(DT_code, starts=4, random=4):
    tris = []
    for s in range(starts):
        M = Manifold('DT[%s]' % DT_code)
        for r in range(random + 1):
            tris.append(M.copy())
            for i in range(r):
                M.randomize()
    return min(tris, key=triangulation_sort_key)
Example #4
0
def helper_test_by_dehn_filling(M):
    from snappy import Manifold

    M_filled = M.filled_triangulation()

    for ignore_cusp_ordering in [False, True]:
        for ignore_curve_orientations in [False, True]:
            isosig = M.triangulation_isosig(
                decorated=True,
                ignore_cusp_ordering=ignore_cusp_ordering,
                ignore_curve_orientations=ignore_curve_orientations)
            N = Manifold(isosig)
            N_filled = N.filled_triangulation()

            helper_are_isometric(M, N)
Example #5
0
def check_certified_intervals():
    for n in [
            'm009', 'm015', 't02333', 't02333(1,2)', 'm129(2,3)',
            'm129(2,3)(3,4)'
    ]:
        M = Manifold(n)
        high_prec = M.tetrahedra_shapes('rect', bits_prec=1000)

        intervals = M.tetrahedra_shapes('rect', bits_prec=100, intervals=True)

        for z, interval in zip(high_prec, intervals):
            if not abs(interval.center() - z) < 1e-10:
                raise Exception

            if not z in interval:
                raise Exception
Example #6
0
 def __init__(self,
              manifold,
              order=128,
              offset=0.001,
              elevation=None,
              base_dir='PR_base_fibers',
              hint_dir='PR_hints',
              ignore_saved=False):
     self.base_dir = base_dir
     if not isinstance(manifold, (Manifold, ManifoldHP)):
         manifold = Manifold(manifold)
     self.offset = offset
     self.order = order
     if elevation is None:
         self.elevation = LineElevation(manifold,
                                        order=order,
                                        offset=offset,
                                        base_dir=base_dir,
                                        hint_dir=hint_dir,
                                        ignore_saved=ignore_saved)
     else:
         self.elevation = elevation
     # Save the manifold here, because it may have been replaced by a saved manifold.
     self.manifold = self.elevation.manifold
     self.elevation.tighten()
     print('Building arcs, rep kinds, and long trans...')
     self.build_arcs()
     print('Done!')
Example #7
0
 def _get_saved_data(self):
     base_fiber_file = os.path.join(self.base_dir,
                                    self.manifold.name() + '.base')
     ask_save = False
     try:
         with open(base_fiber_file) as datafile:
             data = eval(datafile.read())
         self._print('Loaded the base fiber from %s' % base_fiber_file)
         M = Manifold(data['manifold'])
         if not M == self.manifold:
             if self.verbose:
                 self._print(
                     'The saved base fiber uses a different triangulation of %s!'
                     % M)
                 response = user_input(
                     'Would you like to \n'
                     '(a) use the saved triangulation; or\n'
                     '(b) recompute the base fiber\n'
                     '? ')
                 while response.lower() not in ('a', 'b'):
                     response = user_input('Please type "a" or "b": ')
                 if response.lower() == 'a':
                     self.manifold = M
                 elif response == 'b':
                     ask_save = True
                     data = {}
             else:
                 data = {}
     except IOError:
         data = {}
     return data, ask_save
     raise ValueError('Only subclasses of Elevation can be instantiated.')
Example #8
0
def setup_extended_db(dbfile):
    if os.path.exists(dbfile):
        os.remove(dbfile)
    connection = sqlite3.connect(dbfile)
    create_extended_tables(connection)
    make_extended_views(connection)
    # Add the poor missing trefoil
    M = Manifold('3_1')
    M.set_name('K3a1')
    insert_cusped_manifold(connection,
                           'HT_links',
                           M,
                           is_link=True,
                           DTcode='cacbca')
    connection.commit()
    connection.close()
Example #9
0
def test_induced_sl4_representation():
    M = Manifold("m004")

    z_gl2 = ptolemy.CrossRatios.from_snappy_manifold(M)
    z_gl4 = z_gl2.induced_representation(4)

    G = M.fundamental_group()

    mat = z_gl4.evaluate_word(G.relators()[0], G)

    for i, row in enumerate(mat):
        for j, entry in enumerate(row):
            if i == j:
                assert abs(entry - 1) < 1e-9
            else:
                assert abs(entry) < 1e-9
Example #10
0
 def __init__(self,
              manifold,
              order=169,
              radius=1.02,
              elevation=None,
              base_dir='PE_base_fibers',
              hint_dir='hints',
              ignore_saved=False):
     # The default order is 13^2 because 13th roots of 1 are rarely singularities.
     self.base_dir = base_dir
     if not isinstance(manifold, (Manifold, ManifoldHP)):
         manifold = Manifold(manifold)
     self.radius = radius
     self.order = order
     if elevation is None:
         self.elevation = CircleElevation(manifold,
                                          order=order,
                                          radius=radius,
                                          base_dir=base_dir,
                                          hint_dir=hint_dir,
                                          ignore_saved=ignore_saved)
     else:
         self.elevation = elevation
     # Save the manifold here, because it may have been replaced by a saved manifold.
     self.manifold = self.elevation.manifold
     self.elevation.tighten()
Example #11
0
def bytes_n_cobs(mfld):
    """
    Return a bytestring encoding of the manifold and a list of basis
    changes that convert the combinatorial basis of the decoded
    bytestring back to the original peripheral basis of the manifold,
    and a permutation to be applied to the cusp indices.
    """
    cobs = mfld.set_peripheral_curves('combinatorial', return_matrices=True)
    bytestring = mfld._to_bytes()
    encoded_perm = 0
    N = Manifold('empty')
    N._from_bytes(bytestring)
    N.set_peripheral_curves('combinatorial')
    mfld.set_peripheral_curves(cobs)  # put it back the way it was
    isoms = mfld.isomorphisms_to(N)
    abcd = False
    while isoms:
        pick_one = isoms.pop()
        abcd = tuples(pick_one)
        if abcd:
            break
    if not abcd:
        print('No orientation preserving isometries????')
        return bytestring, cobs, 0
    perm = pick_one.cusp_images()
    for n in range(mfld.num_cusps()):
        a, b, c, d = abcd[n]
        cobs[perm[n]] = [[a, c], [b, d]]
        encoded_perm |= (n << (perm[n] << 2))
    return bytestring, cobs, encoded_perm
def draw_ladders_and_geometric_boundary_for_veering_isosig(sig, args={}):
    if args == {}:
        args = {
            'draw_boundary_triangulation': True,
            'draw_triangles_near_poles': False,
            'ct_depth': -1,
            'ct_epsilon': 0.03,
            'global_drawing_scale': 4,
            'delta': 0.2,
            'ladder_width': 10.0,
            'ladder_height': 20.0,
            'draw_labels': True
        }

    out_dir_ladders = 'Images/Ladders'
    out_dir_geometric = 'Images/Geometric'

    output_filename = sig + '.pdf'
    tri, angle = isosig_to_tri_angle(sig)

    M = Manifold(tri)
    tet_shapes = M.tetrahedra_shapes()
    tet_shapes = [complex(shape["rect"]) for shape in tet_shapes]
    args['tet_shapes'] = tet_shapes

    B = generate_boundary_triangulation(tri,
                                        angle,
                                        args=args,
                                        output_filename=output_filename)
    args_ladder = args.copy()
    args_ladder['style'] = 'ladders'
    output_filename_ladders = out_dir_ladders + '/' + output_filename
    B.draw(output_filename_ladders, args=args_ladder)

    args_geometric = args.copy()
    args_geometric['style'] = 'geometric'
    output_filename_geometric = out_dir_geometric + '/' + output_filename
    B.draw(output_filename_geometric, args=args_geometric)
Example #13
0
def testGeometricRep(compute_solutions):

    from snappy.ptolemy import geometricRep

    M = Manifold("m019")
    if compute_solutions:
        sol = geometricRep.compute_geometric_solution(M)
    else:
        from urllib.request import pathname2url
        url = pathname2url(os.path.abspath(testing_files_directory))
        sol = geometricRep.retrieve_geometric_solution(M, data_url=url)

    # Make sure this is of type Ptolemy
    sol['c_0011_2']

    assert any(
        [abs(vol - 2.9441064867) < 1e-9 for vol in sol.volume_numerical()])
Example #14
0
    def flipper_bundle_data(self):
        """ Return the flipper triangulation, flip sequence and edge closer defined by following this TautStructure. """

        # How to wrap from the bottom edge back to the top.
        top = dict((arrow.Tetrahedron.Index, index)
                   for index, starts in enumerate(self.tops)
                   for arrow in starts)
        bottom = dict((arrow.Tetrahedron.Index, index)
                      for index, ends in enumerate(self.bottoms)
                      for arrow in ends)
        edge_advance = dict(
            ((loci,
              sum(self.surface.weights[face_index(arrow)]
                  for arrow in self.branch_loci[loci][0]) - 1), (top[tet], 0))
            for tet, loci in bottom.items())

        S0, E0 = self.surface.connected_component(
        )  # Get a component and its edges.
        E_curr = E0
        flips = []
        while True:
            flips += [
                i for i, edge in enumerate(E_curr) if edge in edge_advance
            ]  # Find the edges where we are not moving directly across.
            E_curr = [
                edge_advance.get((loci, sheet), (loci, sheet + 1))
                for loci, sheet in E_curr
            ]  # Move across.
            if sorted(E_curr) == E0:
                break

        F = S0.flipper_triangulation()
        M0 = self.manifold.snappy_manifold()
        image_edge = E0.index(E_curr[0])
        for edge in [image_edge, ~image_edge]:
            try:
                h = F.encode_flips_and_close(flips, 0, edge)
                B = h.bundle(veering=False, _safety=False)
                if M0.is_isometric_to(Manifold(B)):
                    return F, flips, edge
            except (flipper.AssumptionError, AssertionError):
                pass

        raise RuntimeError(
            "Neither sister triangulations are the starting triangulation")
    def get_manifold(text = text):
        triangulation_text = utilities.join_long_lines(
            find_unique_section(text, "TRIANGULATION"))

        if triangulation_text[:15] == '% Triangulation':

            from snappy import Manifold

            return Manifold(triangulation_text)
        
        if ('<?xml' in triangulation_text and
            '<reginadata' in triangulation_text and 
            '<packet' in triangulation_text):

            from reginaWrapper import NTriangulationForPtolemy

            return NTriangulationForPtolemy.from_xml(triangulation_text)

        raise Exception("Triangulation format not supported: %s..." % 
                        triangulation_text[:20])
Example #16
0
def run_perf_test(): 
    gui = InsideManifoldGUI(Manifold("m004"))

    PerfTest(gui.main_widget)
"""
Run this in Sage and SnapPy and see that the last line of the result differs dramatically.

If we multiply two numbers with different precisions, we expect the result to be
of the lower precision. This is consistent between Sage and SnapPy.
However, if we cast the low precision to a type of higher precision and then multiply, we
expect the result to be of the type of the higher precision.
This works in Sage, but it doesn't work for SnapPy Numbers.

This affects the code computing cusp translations, look for "_SnapPyNumberHack".
"""

from snappy import Manifold
M = Manifold("m004")

# Let's take a real 53bit precision number
v = M.cusp_neighborhood().volume(0)
# And a complex 1000bit precision number
z = M.tetrahedra_shapes('rect', bits_prec = 1000)[0]
# High precision real field
RF = z.real().parent()

print("Expect low precision number: ", v)
print("Expect high precision number:", z)
print("Product, expect low precision number:", v * z)
print("Casting to high precision:", RF(v))
print("Product again, this time it should be high precision (!!!):", RF(v) * z)

Example #18
0
class Apoly(object):
    """
    The A-polynomial of a SnapPy manifold.

    Constructor: Apoly(mfld, order=128, gluing_form=False, denom=None, multi=False,
                       use_hints=True, verbose=True)

    <mfld>           is a manifold name recognized by SnapPy, or a Manifold instance.
    <gluing_form>    (True/False) indicates whether to find a "standard"
                     A-polynomial, or the gluing variety variant.
    <order>          must be at least twice the M-degree.  Try doubling this
                     if the coefficients seem to be wrapping.
    <denom>          Denominator for leading coefficient.  This should be
                     a string, representing a polynomial expression in H,
                     the meridian holonomy.  e.g. denom='((H-1)**3)*((H+1)**4)'
    <multi>          If True, multiple copies of lifts are not removed, so
                     multiplicities of factors of the polynomial are computed.
    <use_hints>      Whether to check for and use hints from a hint file.
    <verbose>        Whether to print information about the computation.
    <precision>      Specify 'double'(default), or a number of bits.

    Methods:

    An Apoly object A is callable:  A(x,y) returns the value at (x,y).
    A.as_string(exp='^') returns a string suitable for input to a generic symbolic
                      algebra program which uses the symbol exp for exponentiation.
    A.sage()          returns a Sage polynomial with parent ring ZZ['M', 'L']
    A.show(text=False) shows the newton polygon with dots.  The text
                      flag shows the coefficients.
    A.show_R_longitude_evs() uses matplotlib to graph the L-projections of
                      arcs of the elevation of the circle of radius R in the M-plane.
    A.show_T_longitude_evs() uses matplotlib to graph the L-projections
                      of components of the inverse image of the tightened
                      circle of radius T in the M-plane.
    A.boundary_slopes() returns the boundary slopes detected by the character
                      variety.
    A.save(basename=None, dir='polys', with_hint=True, twist=0)
                      Saves the polynomial in a .apoly or .gpoly text file for
                      input to a symbolic computation program.  The directory
                      can be overridden by specifying dir. Saves the parameters
                      in a .hint file unless with_hint==False.  Assumes that the
                      preferred longitude is LM^twist, where L,M are the SnapPea
                      meridian and longitued
    A.verify() runs various consistency checks on the polynomial.

    An Apoly object prints itself as a matrix of coefficients.
  """
    def __init__(self, mfld, order=128, gluing_form=False,
                 radius=1.02, denom=None, multi=False, use_hints=True, verbose=True,
                 apoly_dir='apolys', gpoly_dir='gpolys', base_dir='PE_base_fibers',
                 hint_dir='hints', dict_dir='apoly_dicts', precision='double',
                 phc_rescue=False):
        if isinstance(mfld, Manifold):
            self.manifold = mfld
            self.mfld_name = mfld.name()
        else:
            self.mfld_name = mfld
            self.manifold = Manifold(mfld)
        self.viewer= None
        self.gluing_form = gluing_form
        self.verbose = verbose
        self.apoly_dir = apoly_dir
        self.gpoly_dir = gpoly_dir
        self.base_dir = base_dir
        self.hint_dir = hint_dir
        self.dict_dir = dict_dir
        options = {'order'        : order,
                   'denom'        : denom,
                   'multi'        : multi,
                   'radius'       : radius,
                   'precision'    : precision,
                   'phc_rescue'   : phc_rescue
                   }
                   # 'apoly_dir'   : apoly_dir,
                   # 'gpoly_dir'   : gpoly_dir,
                   # 'base_dir'    : base_dir,
                   # 'hint_dir'    : hint_dir}
                   # 'dict_dir'    : dict_dir}
        if use_hints:
            self._print("Checking for hints ... ", end='')
            hintfile = os.path.join(self.hint_dir, self.mfld_name+'.hint')
            if os.path.exists(hintfile):
                self._print("yes!")
                exec(open(hintfile).read())
                options.update(hint)
                prec = options['precision']
            else:
                print("nope.")
        self.order = N = options['order']
        self._denom = options['denom']
        self.multi = options['multi']
        self.radius = options['radius']
        self.precision = precision = options['precision']
        if precision != 'double':
            self.precision = int(precision) # avoid Sage Integers
            self.fft_obj = ComplexFFT(self.order)
        self.phc_rescue = phc_rescue
        filename = self.manifold.name()+'.base'
        saved_base_fiber = os.path.join(self.base_dir, filename)
        prec = 53 if self.precision == 'double' else self.precision
        msg = 'Using: radius=%g; order=%d; denom=%s; precision=%d bits.'%(
            options['radius'], options['order'], options['denom'], prec)
        self.elevation = CircleElevation(
            self.manifold,
            order=self.order,
            radius=self.radius,
            base_dir=self.base_dir,
            phc_rescue=self.phc_rescue,
            verbose=self.verbose,
            msg=msg
        )
        if self.elevation.failed:
            print("Warning: Failed to elevate the R-circle.  This Apoly is incomplete.")
            return
        if self.gluing_form:
            vals = array([track for track in self.elevation.R_longitude_holos])
        else:
            if isinstance(self.precision, int):
                self.elevation.polish_R_longitude_vals(precision=self.precision)
                vals = array(self.elevation.polished_R_longitude_evs)
            else:
                vals = array(self.elevation.R_longitude_evs)
        self.degree = len(vals)
        if multi == False:
            self.multiplicities, vals = self.demultiply(vals)
        self.reduced_degree = len(vals)
        self._compute_all(vals)
        self._print('done.')

    def __call__(self, M, L):
        result = 0
        rows, cols = self.coefficients.shape
        for i in range(rows):
            Lresult = 0
            for j in range(cols):
                Lresult = Lresult*L + self.coefficients[-1-i][-1-j]
            result = result*M + Lresult
        return result

    def __repr__(self):
        return 'A-polynomial of %s'%self.mfld_name

    def __str__(self):
        digits = 2 + int(ceil(log(self.height)/log(10)))
        width = len(self.coefficients[0])
        format = '[' + ('%' + str(digits) + '.0f')*width + ']\n'
        result = ''
        for row in self.coefficients:
            result += format%tuple(row + 0.)
        return result

    def _print(self, *args, **kwargs):
        if self.verbose:
            print(*args, **kwargs)

    @staticmethod
    def _rounded_real(z):
        if is_ComplexNumber(z):
            return z.real().round()
        elif isinstance(z, complex):
            return round(z.real)
        else:
            raise ValueError('Unknown type %s.'%type(z))

    @staticmethod
    def realpart(z):
        if is_ComplexNumber(z):
            return z.real()
        else:
            return z.real

    @property
    def denom(self):
        return self._denom

    def find_denom(self, base_index=None, row=None):
        # Look for a short integer vector K such that the convolution
        # of a row of normalized coefficients with K has a long block
        # of zeros starting at the base index.  This function only
        # looks for one zero, but it could be used with different base
        # indices or rows to corroborate the result. Also note that
        # the denominator should be a product of cyclotomic
        # polynomials.
        # The base index and row default to the middle.
        if base_index is None:
            assert self.order%2 == 0
            base_index = self.order // 2
        max_size = self.order - base_index
        if row is None:
            row = self.normalized_coeffs.shape[0] // 2
        X = array([float(self.realpart(z)) for z in self.normalized_coeffs[row]])
        # Find the shortest block with a non-trivial relation.
        M = None
        for n in range(max_size):
            N = array([X[base_index+i:base_index+i+n] for i in range(n)])
            r = matrix_rank(N)
            if r == n - 1:
                M = N
            if n > r + 5: # looks like the rank has stabilized ...
                break
        if M is None:
            raise RuntimeError("Failed to find a denominator.")
        # Now M should be square with a null space of dimension 1.
        U, S, V = svd(M)
        K = V[-1] # unit vector in the null space of M
        coeffs = [int(round(x)) for x in K/K[-1]]
        # Perhaps we should remove powers of H and verify that we
        # are left with a product of cyclotomics.
        return PolynomialRing(ZZ, 'H')(coeffs)

    @denom.setter
    def denom(self, denom_string):
        assert denom_string is None or isinstance(denom_string, str)
        self._denom = denom_string
        if self.precision != 'double':
            self._compute_all(array(self.elevation.polished_R_longitude_evs))
        else:
            self._compute_all(array(self.elevation.R_longitude_evs))

    def _compute_all(self, vals):
        """
        Use a discrete Fourier transform to compute the A-polynomial from the
        longitude eigenvalues (or holonomies).  We are viewing the A-polynomial
        as a polynomial in L with coefficients in QQ[M].  For a number z on the
        R-circle, we find a monic polynomial in L vanishing on the values taken
        by L at those points of the A-curve where M takes the value z.  Thus we
        get a polynomial in L whose coefficients are polynomials in M vanishing
        on the A-curve.  To compute the integer coefficients of these
        M-polynomials we renormalize to the unit circle and use the inverse FFT.
        (Note: this produces a monic polynomial in L, but the A-polynomial is
        not monic when there is an ideal point of the character variety which
        is associated with a meridian boundary slope.  The denom parameter is
        used to resolve this issue.)
        """
        self.sampled_roots = vals
        self.sampled_coeffs = self.symmetric_funcs(vals)
        if isinstance(self.precision, int):
            radius = RealField(self.precision)(self.radius)
            ifft = self.fft_obj.ifft
            def real(z):
                return z.real()
        else:
            radius = self.radius
            ifft = fft.ifft
            def real(z):
                return z.real
        self._print("Interpolating with IFFT.")
        if self._denom:
            exec('denom_function = lambda H : %s'%self._denom)
            if isinstance(self.precision, int):
                circle = [radius*U1Q(-n, self.order, precision=self.precision)
                          for n in range(self.order)]
                D = array([denom_function(z) for z in circle])
            else:
                D = array([denom_function(z) for z in self.elevation.R_path])
            self.raw_coeffs = array([ifft(x*D) for x in self.sampled_coeffs])
        else:
            self.raw_coeffs = array([ifft(x) for x in self.sampled_coeffs])
        # Renormalize the coefficients, to adjust for the circle radius.
        N = self.order
        if N%2 == 0:
            powers = -array(list(range(1+N//2))+list(range(1-N//2, 0)))
        else:
            powers = -array(list(range(1+N//2))+list(range(-(N//2), 0)))
        renorm = array([radius**n for n in powers])
        self.normalized_coeffs = self.raw_coeffs*renorm
        self.int_coeffs = array([map(self._rounded_real, x) for x in self.normalized_coeffs],
                                dtype='O')
        #self.int_coeffs = array([[self. for z in row]
        #                              for row in self.normalized_coeffs], dtype='O')
        self.height = int(max([max(abs(x)) for x in self.int_coeffs]))
        self.bits_height = int(ceil(log(float(self.height))/log(2)))
        #self.bits_height = log(self.height, 2)
        self.noise = (array([[real(z) for z in row] for row in self.normalized_coeffs], dtype='O') -
                      self.int_coeffs)
        self.max_noise = [max(abs(x)) for x in self.noise]
        self.shift = self.find_shift()
        self._print('Shift is %d.'%self.shift)
        if self.shift is None:
            raise ValueError('Could not compute the shift. '
                             'Coefficients may be wrapping.  '
                             'If so, a larger order might help.')
        C = self.int_coeffs.transpose()
        coefficient_array = take(C, arange(len(C))-self.shift, axis=0)
        rows, cols = coefficient_array.shape
        while rows > 0:
            if max(abs(coefficient_array[rows-1])) > 0:
                break
            rows -= 1
        self.coefficients = coefficient_array[:rows]
        self._print('log_2(height) is %s'%self.bits_height)
        self._print("Noise levels: ")
        for level in self.max_noise:
            self._print(level)
        if max(self.max_noise) > 0.2:
            self._print('Failed to find integer coefficients with tolerance 0.2')
            return
        self._print('Computing the Newton polygon.')
        self.compute_newton_polygon()

    def compute_newton_polygon(self):
        power_scale = (1, 1) if self.gluing_form else (1, 2)
        self.newton_polygon = NewtonPolygon(self.as_dict(), power_scale)

    def recompute(self):
        """
        Recompute A after changing attributes.
        """
        self._compute_all(array(self.elevation.R_longitude_evs))

    def help(self):
        print(self.__doc__)

    def symmetric_funcs(self, evs):
        """
        Given a numpy 2D array whose rows are L-eigenvalues sampled on a circle,
        return a 2D array whose rows are the elementary symmetric functions of
        the roots.

        Before computing the elementary symmetric functions, each column is
        sorted in descending size, to avoid 'catastrophic cancellation'. This
        means, for example (using decimal floating point with 3 digits) that
        we want to compute
           .101E3 - .100E3 - .999E0 = .1E-2 == .001
        rather than
           .101E3 - .999E0 - .100E3 "=" .1E1 == 1.0
        """
        for n in range(evs.shape[1]):
            evs[:, n] = sorted(evs[:, n], key=lambda x: -abs(x))
        coeffs = [0, ones(evs[0].shape, evs.dtype)]
        for root in evs:
            for i in range(1, len(coeffs)):
                coeffs[-i] = -root*coeffs[-i] + coeffs[-1-i]
            coeffs.append(ones(evs[0].shape, evs.dtype))
        return coeffs[1:]

    def demultiply(self, eigenvalues):
        multiplicities = []
        sdr = [] #system of distinct representatives
        multis = [1]*len(eigenvalues)
        for i in range(len(eigenvalues)):
            unique = True
            for j in range(i+1,len(eigenvalues)):
                # If this row is the same as a lower row, do not
                # put it in the sdr.  Just increment the multiplicity
                # of the lower row.
                if max(abs(eigenvalues[i] - eigenvalues[j])) < 1.0E-6:
                    unique = False
                    multis[j] += multis[i]
                    break
            if unique:
                sdr.append(i)
                multiplicities.append((i, multis[i]))
        return multiplicities, take(eigenvalues, sdr, 0)

    def find_shift(self):
       rows, cols = self.normalized_coeffs.shape
       shifts = [0]
       #start from the top and search for the last row above the middle
       #whose left-most non-zero entry is +-1.
       for i in range(rows):
          for j in range(1, 1 + cols//2):
             if abs(abs(self.normalized_coeffs[i][-j]) - 1.) < .01:
                 shifts.append(j)
       return max(shifts)

# Should have a monomial class, and generate a list of monomials here not a string
    def monomials(self):
        rows, cols = self.coefficients.shape
        monomials = []
        for j in range(cols):
            for i in range(rows):
                if self.gluing_form:
                    m,n = 2*i, 2*j
                else:
                    m,n = 2*i, j
                a = int(self.coefficients[i][j])
                if a != 0:
                    if i > 0:
                        if j > 0:
                            monomial = '%d*(M^%d)*(L^%d)'%(a,m,n)
                        else:
                            monomial = '%d*(M^%d)'%(a,m)
                    else:
                        if j > 0:
                            monomial = '%d*(L^%d)'%(a,n)
                        else:
                            monomial = '%d'%a
                    monomials.append(monomial)
        return monomials

# Should use the list of monomials to generate the dict
    def as_dict(self):
        rows, cols = self.coefficients.shape
        result = {}
        for j in range(cols):
            for i in range(rows):
                if self.gluing_form:
                    m,n = 2*i, 2*j
                else:
                    m,n = 2*i, j
                coeff = int(self.coefficients[i][j])
                if coeff:
                    result[(m,n)] = coeff
        return result

    def break_line(self, line):
        marks = [0]
        start = 60
        while True:
            mark = line.find('+', start)
            if mark == -1:
                break
            marks.append(mark)
            start = mark+60
        lines = []
        for i in range(len(marks) - 1):
            lines.append(line[marks[i]:marks[i+1]])
        lines.append(line[marks[-1]:])
        return '\n    '.join(lines)

    def as_string(self, exp='^'):
        polynomial_string = ('+'.join(self.monomials())).replace('+-','-')
        return polynomial_string.replace('^', exp)

    def sage(self):
        return sage_poly_ring(self.as_dict())

    # could do this by sorting the monomials
    def as_Lpolynomial(self, name='A', twist=0):
        terms = []
        rows, cols = self.coefficients.shape
        #We are taking the true longitude to be L*M^twist.
        #So we change variables by L -> M^(-twist)*L.
        #Then renormalize so the minimal power of M is 0.
        minexp = 2*rows
        for j in range(cols):
            for i in range(rows):
                if self.coefficients[i][j]:
                    break
            minexp = min(2*i - j*twist, minexp)
        for j in range(cols):
            if self.gluing_form:
                n = 2*j
            else:
                n = j
            monomials = []
            for i in range(rows):
                m = 2*i
                a = int(self.coefficients[i][j])
                if a != 0:
                    if i > 0:
                        monomial = '%d*M^%d'%(a,m)
                    else:
                        monomial = '%d'%a
                    monomials.append(monomial.replace('^1 ',' '))
            if monomials:
                p = - n*twist - minexp
                if p:
                    P = '%d'%p
                    if p < 0:
                        P = '('+P+')'
                    if n > 0:
                        term = '+ (L^%d*M^%s)*('%(n,P) + ' + '.join(monomials) + ')'
                    else:
                        term = '(M^%s)*('%P + ' + '.join(monomials) + ')'
                else:
                    if n > 0:
                        term = '+ (L^%d)*('%n + ' + '.join(monomials) + ')'
                    else:
                        term = '(' + ' + '.join(monomials) + ')'
                term = self.break_line(term)
                terms.append(term.replace('+ -','- '))
        return name + ' :=\n' + '\n'.join(terms)

    def save(self, basename=None, dir=None, with_hint=True, twist=0):
        if dir == None:
            if self.gluing_form:
                poly_dir = self.gpoly_dir
                hint_dir = self.hint_dir
                ext = '.gpoly'
            else:
                poly_dir = self.apoly_dir
                hint_dir = self.hint_dir
                ext = '.apoly'
        dict_dir = self.dict_dir
        for dir in (poly_dir, hint_dir, dict_dir):
            if not os.path.exists(dir):
                cwd = os.path.abspath(os.path.curdir)
                newdir = os.path.join(cwd,dir)
                response = user_input("May I create a directory %s?(y/n)"%newdir)
                if response.lower() != 'y':
                    sys.exit(0)
                os.mkdir(newdir)
        if basename == None:
            basename = self.mfld_name
        polyfile_name = os.path.join(poly_dir, basename + ext)
        hintfile_name = os.path.join(hint_dir, basename + '.hint')
        dictfile_name = os.path.join(dict_dir, basename + '.dict')
        if self.gluing_form:
            lhs = 'G_%s'%basename
        else:
            lhs = 'A_%s'%basename
        with open(polyfile_name,'wb') as polyfile:
            polyfile.write(self.as_Lpolynomial(name=lhs, twist=twist))
            polyfile.write(';\n')
        with open(dictfile_name, 'wb') as dictfile:
            dictfile.write('%s = {\n'%lhs)
            polydict = self.as_dict()
            for key in sorted(polydict.keys()):
                dictfile.write(' %s : %s,\n'%(key, polydict[key]))
            dictfile.write('}\n')
        if with_hint:
            self.elevation.save_hint(
                directory=self.hint_dir,
                extra_options={
                    'denom': self._denom,
                    'multi': self.multi,
                    'precision': self.precision
                })

    def boundary_slopes(self):
        return [s.sage() for s in self.newton_polygon.lower_slopes]

    def show_R_longitude_evs(self):
        self.elevation.show_R_longitude_evs()

    def show_T_longitude_evs(self):
        if not self.elevation.T_circle:
            self.tighten()
        self.elevation.show_T_longitude_evs()

    def show_coefficients(self):
        plot = Plot([[self.realpart(z) for z in row]
                     for row in self.normalized_coeffs.real], number_type=float)

    def show_noise(self):
        plot = Plot(self.noise, number_type=float)

    def show_imag_noise(self):
        plot = Plot(self.normalized_coeffs.imag, number_type=float)

    def show(self, text=False):
        self.viewer= V = PolyViewer(self.newton_polygon, title=self.mfld_name)
        if text:
            V.show_text()
        else:
            V.show_dots()
        V.show_sides()

    def show_R_volumes(self):
        H = self.elevation
        Plot(H.volumes(H.R_fibers), number_type=float)

    def show_T_volumes(self):
        H = self.elevation
        Plot(H.volumes(H.T_fibers), number_type=float)

    def tighten(self, T=1.0):
        self.elevation.tighten(T)

    def verify(self):
        noise_ok = True
        symmetry = True
        sign = None
        self._print('Checking max noise level: ', end=' ')
        self._print(max(self.max_noise))
        if max(self.max_noise) > 0.2:
            noise_ok = False
            self._print('Failed')
        self._print('Checking for reciprocal symmetry ... ', end=' ')
        if max(abs(self.coefficients[0] - self.coefficients[-1][-1::-1]))==0:
            sign = -1.0
        elif max(abs(self.coefficients[0] + self.coefficients[-1][-1::-1]))==0:
            sign = 1.0
        else:
            self._print('Failed!')
            symmetry = False
        if sign:
            for i in range(len(self.coefficients)):
                maxgap = max(abs(self.coefficients[i] +
                              sign*self.coefficients[-i-1][-1::-1]))
                if maxgap > 0:
                    self._print('Failed! gap = %d'%maxgap)
                    symmetry = False
        if symmetry:
            self._print('OK.')
        result = noise_ok and symmetry
        if result:
            self._print('Passed!')
        return result
Example #19
0
 def __init__(self, mfld, order=128, gluing_form=False,
              radius=1.02, denom=None, multi=False, use_hints=True, verbose=True,
              apoly_dir='apolys', gpoly_dir='gpolys', base_dir='PE_base_fibers',
              hint_dir='hints', dict_dir='apoly_dicts', precision='double',
              phc_rescue=False):
     if isinstance(mfld, Manifold):
         self.manifold = mfld
         self.mfld_name = mfld.name()
     else:
         self.mfld_name = mfld
         self.manifold = Manifold(mfld)
     self.viewer= None
     self.gluing_form = gluing_form
     self.verbose = verbose
     self.apoly_dir = apoly_dir
     self.gpoly_dir = gpoly_dir
     self.base_dir = base_dir
     self.hint_dir = hint_dir
     self.dict_dir = dict_dir
     options = {'order'        : order,
                'denom'        : denom,
                'multi'        : multi,
                'radius'       : radius,
                'precision'    : precision,
                'phc_rescue'   : phc_rescue
                }
                # 'apoly_dir'   : apoly_dir,
                # 'gpoly_dir'   : gpoly_dir,
                # 'base_dir'    : base_dir,
                # 'hint_dir'    : hint_dir}
                # 'dict_dir'    : dict_dir}
     if use_hints:
         self._print("Checking for hints ... ", end='')
         hintfile = os.path.join(self.hint_dir, self.mfld_name+'.hint')
         if os.path.exists(hintfile):
             self._print("yes!")
             exec(open(hintfile).read())
             options.update(hint)
             prec = options['precision']
         else:
             print("nope.")
     self.order = N = options['order']
     self._denom = options['denom']
     self.multi = options['multi']
     self.radius = options['radius']
     self.precision = precision = options['precision']
     if precision != 'double':
         self.precision = int(precision) # avoid Sage Integers
         self.fft_obj = ComplexFFT(self.order)
     self.phc_rescue = phc_rescue
     filename = self.manifold.name()+'.base'
     saved_base_fiber = os.path.join(self.base_dir, filename)
     prec = 53 if self.precision == 'double' else self.precision
     msg = 'Using: radius=%g; order=%d; denom=%s; precision=%d bits.'%(
         options['radius'], options['order'], options['denom'], prec)
     self.elevation = CircleElevation(
         self.manifold,
         order=self.order,
         radius=self.radius,
         base_dir=self.base_dir,
         phc_rescue=self.phc_rescue,
         verbose=self.verbose,
         msg=msg
     )
     if self.elevation.failed:
         print("Warning: Failed to elevate the R-circle.  This Apoly is incomplete.")
         return
     if self.gluing_form:
         vals = array([track for track in self.elevation.R_longitude_holos])
     else:
         if isinstance(self.precision, int):
             self.elevation.polish_R_longitude_vals(precision=self.precision)
             vals = array(self.elevation.polished_R_longitude_evs)
         else:
             vals = array(self.elevation.R_longitude_evs)
     self.degree = len(vals)
     if multi == False:
         self.multiplicities, vals = self.demultiply(vals)
     self.reduced_degree = len(vals)
     self._compute_all(vals)
     self._print('done.')
Example #20
0
def run_perf_test(): 
    gui = InsideViewer(Manifold("m004"))

    PerfTest(gui.widget)
Example #21
0
    def handle_return(self, event):
        if self.state == 'ready':
            self.choose()
        else:
            self.show_covers()

    def choose(self, event=None):
        self.result = [
            self.cover_list[self.covers.index(x)]
            for x in self.covers.selection()
        ]
        self.root.destroy()

    def cancel(self):
        self.result = []
        self.root.destroy()

    def go(self):
        self.root.grab_set()
        self.root.wait_window()


if __name__ == '__main__':
    from snappy import Manifold
    root = Tk_.Tk()
    root.withdraw()
    browser1 = Browser(Manifold('m125'), root)
    browser2 = Browser(Manifold('12n345'))
    root.wait_window(browser1.window)
    root.wait_window(browser2.window)
Example #22
0
    pos_c2 = [weights[to_index(face_class[2])] for face_class in face_classes]
    neg_c2 = [weights[to_index(face_class[3])] for face_class in face_classes]

    for p, n in zip(pos_c2, neg_c2):
        if p != -n:
            raise Exception("Not matching")

    for row in trig._ptolemy_equations_boundary_map_2()[0]:
        if len(row) != len(pos_c2):
            raise Exception("Not matching")
        s = sum([e * p for e, p in zip(row, pos_c2)])
        if s != 0:
            raise Exception("Not in kernel")


if __name__ == '__main__':
    print(sys.argv)

    if sys.argv[1] == 'perf':
        run_perf_test()
    else:
        trig = Manifold(sys.argv[1])

        weights = None
        if len(sys.argv) == 3:
            weights = eval(sys.argv[2])

            check_weights(trig, weights)

        main(trig, weights)
Example #23
0
def run_perf_test():
    gui = ViewerWindow(InsideViewer, Manifold("m004"))

    PerfTest(gui.view.widget)
Example #24
0
def run_perf_test(): 
    from snappy import Manifold

    gui = RaytracingWidget(Manifold("m004"))

    PerfTest(gui.main_widget)
Example #25
0
from __future__ import print_function
from builtins import range
"""
We decorate Regina's triangulation isomorphism signature (isosig) to
record the peripheral structure of a cusped manifold M, that is, the
cusp labels and the peripheral curves on each cusp. The basic idea is
to store these relative to SnapPy's combinatorial defaults for the
triangulation created from the bare isosig.

Specifically, if M has n cusps, we append a permutation on {0,...,n-1}
as well as n change-of-basis matrices, represented as a sequence of 5n
integers and encoded as a string of isosig characters. This decoration
string is appended to the isosig string, after first appending a
separator character which is not a valid isosig character.  To save
space, the permutation may be omitted when it is equal to the identity
permutation; this is indicated by the fact that the length of the
decoration is 4n rather than 5n.

Currently, only oriented manifolds are supported.

A simple valid decorated isosig for a two-cusped manifold is::

    eLPkbdcddhgggb_abBaaBBaaB

Here, the bare isosig is what precedes the underscore; what follows is
an encoded version of the 5n integers mentioned above.  This decorated
isosig is equivalent to

    eLPkbdcddhgggb_BaaBBaaB

where the permutation part has been elided since the permutation is
Example #26
0
def cross_ratios(M):
    return [ptolemys.cross_ratios() for ptolemys in ptolemy_coordinates(M)]


if __name__ == '__main__':
    from snappy import Manifold
    import sys

    if len(sys.argv) != 2:
        print("Usage: sage -python printMatrices.py CLOSED_MFD")
        print()
        print('Example: sage -python printMatrices.py "m004(2,3)"')
        sys.exit(1)

    M = Manifold(sys.argv[1])
    G = M.fundamental_group()
    list_z = cross_ratios(M)
    for i, z in enumerate(list_z):
        print("Solution %d:" % i)
        nf = z['z_0000_0'].parent()
        print("    Number field:", nf.defining_polynomial())
        print("    Exact values:")
        for g in G.generators():
            print("        Generator %s:" % g)
            print(z.evaluate_word(g, G))

        for z_numerical in evaluate_at_roots(nf, z, precision=100):
            print("    Numerical values:")
            d = CrossRatios(z_numerical, manifold_thunk=lambda: M)
Example #27
0
 def ManifoldGetter(name):
     return NTriangulationForPtolemy(
         NTriangulation(Manifold(name)._to_string()))
Example #28
0
def run_perf_test():
    from snappy import Manifold

    gui = InsideViewer(Manifold("m004"))

    PerfTest(gui.widget)
Example #29
0
# Import raytracing directly from SnapPy source so that we can quickly
# iterate on shaders without the need to build/install SnapPy every time.

snappy_path, dir_name = os.path.split(os.getcwd())

sys.path.append(os.path.join(snappy_path, 'python'))

from raytracing.inside_viewer import *

def run_perf_test(): 
    gui = InsideViewer(Manifold("m004"))

    PerfTest(gui.widget)

def main(manifold):
    if sys.platform == 'darwin':
        print(darwinTkMsg)

    gui = InsideViewer(manifold)
    gui.widget.focus_set()
    gui.container.mainloop()
    
if __name__ == '__main__':
    print(sys.argv)

    if sys.argv[1] == 'perf':
        run_perf_test()
    else:
        main(Manifold(sys.argv[1]))
Example #30
0
def run_perf_test():
    from snappy import Manifold

    gui = FiniteViewer(Manifold("m004(3,2)"))

    PerfTest(gui.widget)
Example #31
0
 def ManifoldGetter(name):
     return Manifold(name)