Example #1
0
def printRealNumberAsFixed(r):

    assert isinstance(r, mpmath.mpf)
    
    if lessThanMaxErr(r):
        return '0'
    else:
        maxErrDigits = globalsettings.getSetting("maximalErrorDigits")
        s = mpmath.nstr(r,
                        maxErrDigits,
                        min_fixed = -mpmath.inf, max_fixed = mpmath.inf)
        a, b = s.split('.')

        # mpmath chops 1.2000000 to 1.2, so we are adding '0' to b

        alen = len(a)
        if a[0] in '+-':
            alen -= 1
        
        b += (maxErrDigits - alen + len(b)) * '0'

        # b should never be more than maximalErrorDigits

        b = b[:maxErrDigits - alen]

        return a + '.' + b
Example #2
0
def binarySearchIndex(listOfDicts, key, value):
    return _binarySearchIndex(
        listOfDicts,
        key,
        value=value + globalsettings.getSetting("maximalError"),
        firstIndex=0,
        lastIndex=len(listOfDicts),
    )
Example #3
0
def _solutionCheck(dict1, dict2):
    
    maxErr = globalsettings.getSetting("maximalError")

    assert set(dict1.keys()) == set(dict2.keys())

    for k in dict1.keys():
       if not abs(dict1[k] - dict2[k]) < maxErr:
           return False
    return True
Example #4
0
def binarySearch(listOfDicts, key, value):

    index = binarySearchIndex(listOfDicts, key, value)

    maxError = globalsettings.getSetting("maximalError")

    if index < len(listOfDicts) and abs(listOfDicts[index][key] - value) < maxError:

        return listOfDicts[index]

    return None
Example #5
0
def logOfSquare(c):
    return mpmath.log(c)

    csquare = c * c

    maxErr = globalsettings.getSetting("maximalError")

    if not ((csquare.real > 0 or
             abs(csquare.imag) > maxErr)):
        raise NumericalError(c, msg = "logOfSqaure near branch cut")

    return mpmath.log(csquare) / 2
Example #6
0
        def pqCandidates(z, w = w):

            PiI = mpmath.pi * 1j

            if abs(1 - z) < globalsettings.getSetting("maximalError"):
                return (z, 0, 0), 1

            p = mpmathRoundToInt( (w.w0 - mpmath.log(  z)) / PiI)
            q = mpmathRoundToInt( (w.w1 + mpmath.log(1-z)) / PiI)
            err = abs(w.w2 + mpmath.log(z) - mpmath.log(1-z) + p * PiI + q * PiI)

            return (z, p, q), err
Example #7
0
def matchingRowIndices(listOfDicts, key, value):

    index = binarySearchIndex(listOfDicts, key, value) + 1
    firstIndex = index
    lastIndex = index

    maxError = globalsettings.getSetting("maximalError")

    while firstIndex > 0 and abs(listOfDicts[firstIndex - 1][key] - value) < maxError:
        firstIndex -= 1

    return firstIndex, lastIndex
Example #8
0
    def __init__(self, P, no_check = False):
        assert isinstance(P, PtolemyCochain)
        self.sign = P.sign

        self.ptolemy_index = P.ptolemy_index
        self.tet_index = P.tet_index

        self.w0 = logOfSquare(P.c03) + logOfSquare(P.c12) - logOfSquare(P.c02) - logOfSquare(P.c13)
        self.w1 = logOfSquare(P.c02) + logOfSquare(P.c13) - logOfSquare(P.c01) - logOfSquare(P.c23)

        if no_check:
            self.w2 = - (self.w0 + self.w1)
            return

        self.w2 = logOfSquare(P.c01) + logOfSquare(P.c23) - logOfSquare(P.c03) - logOfSquare(P.c12)

        w0_e = mpmath.exp(self.w0)
        w1_e = mpmath.exp(-self.w1)

        errs = [abs(1 - w0_e - w1_e),
                abs(1 + w0_e - w1_e),
                abs(1 - w0_e + w1_e),
                abs(1 + w0_e + w1_e)]

        if not (errs[0] < globalsettings.getSetting("maximalError") or
                errs[1] < globalsettings.getSetting("maximalError") or
                errs[2] < globalsettings.getSetting("maximalError") or
                errs[3] < globalsettings.getSetting("maximalError")):
            raise NumericalError(val = errs,
                                 msg = "w triple (%s,%s,%s) from %s %s %s %s %s %s" % 
                                 (self.w0, self.w1, self.w2, P.c01, P.c02, P.c03, P.c12, P.c13, P.c23))
            
        if not abs(self.w0+self.w1+self.w2) < globalsettings.getSetting("maximalError"):
            raise NumericalError(val = (self.w0+self.w1+self.w2).abs(),
                                 msg = "w triple (%s,%s,%s) not sum to 0 from %s %s %s %s %s %s" % 
                                 (self.w0, self.w1, self.w2, P.c01, P.c02, P.c03, P.c12, P.c13, P.c23))
Example #9
0
    def checkConsistency(self):
        
        c01c23 = self.c01 * self.c23
        c02c13 = self.c02 * self.c13
        c03c12 = self.c03 * self.c12

        maxErr = globalsettings.getSetting("maximalError")

        if not ( (abs(- c03c12 - c01c23 + c02c13) < maxErr) or
                 (abs(- c03c12 + c01c23 + c02c13) < maxErr) or
                 (abs(  c03c12 - c01c23 + c02c13) < maxErr) or
                 (abs(  c03c12 + c01c23 + c02c13) < maxErr)):

            raise NumericalError(
                val=[ (- c03c12 - c01c23 + c02c13).abs(),
                      (- c03c12 + c01c23 + c02c13).abs(),
                      (c03c12 - c01c23 + c02c13).abs(),
                      (  c03c12 + c01c23 + c02c13).abs()],
                msg = "PtolemyCochain(%s,%s,%s,%s,%s,%s)" %
                ( self.c01, self.c02, self.c03,
                  self.c12, self.c13, self.c23))
Example #10
0
def check_solution_on_gluing_equations(t, N, solution, cohomology_class = None):

    maxErr = globalsettings.getSetting("maximalError")

    if cohomology_class:
        cohomology_coefficients = (
            cohomology_2_rel_boundary_class_to_coeffs(t,cohomology_class))

    for tet in t.tet_list:
        i = tet.index
        if cohomology_class:
            signs = cohomology_coefficients[tet.index]
            
            sign_01 = Z2_to_sign(signs[2] + signs[3])
            sign_12 = Z2_to_sign(signs[0] + signs[3])

        else:
            sign_01 = +1
            sign_12 = +1

        for coord in simplex_coords_with_fixed_sum(4, N-2):

            err = (
                - sign_01 *
                  solution[c_parameter_var(coord+(1,0,0,1),i)] *
                  solution[c_parameter_var(coord+(0,1,1,0),i)]
                - sign_12 *
                  solution[c_parameter_var(coord+(1,1,0,0),i)] *
                  solution[c_parameter_var(coord+(0,0,1,1),i)]
                + solution[c_parameter_var(coord+(1,0,1,0),i)] *
                  solution[c_parameter_var(coord+(0,1,0,1),i)])

            if abs(err) > maxErr:
                raise NumericalError(
                    val = err,
                    msg = "in verify gluing equations")
Example #11
0
def lessThanMaxErr(r):
    return abs(r) < globalsettings.getSetting("maximalError")
Example #12
0
    def __init__(self, w, no_check = False):
        assert isinstance(w, w_triple)
        self.sign = w.sign

        self.ptolemy_index = w.ptolemy_index
        self.tet_index = w.tet_index
        
        def pqCandidates(z, w = w):

            PiI = mpmath.pi * 1j

            if abs(1 - z) < globalsettings.getSetting("maximalError"):
                return (z, 0, 0), 1

            p = mpmathRoundToInt( (w.w0 - mpmath.log(  z)) / PiI)
            q = mpmathRoundToInt( (w.w1 + mpmath.log(1-z)) / PiI)
            err = abs(w.w2 + mpmath.log(z) - mpmath.log(1-z) + p * PiI + q * PiI)

            return (z, p, q), err

        candidate1, err1 = pqCandidates(z =   mpmath.exp(w.w0))
        candidate2, err2 = pqCandidates(z = - mpmath.exp(w.w0))

        if err1 < err2:
            candidate, err = candidate1, err1
        else:
            candidate, err = candidate2, err2

        if err > globalsettings.getSetting("maximalError"):
            raise NumericalError(val = err,
                                 msg = "err1 %s %s" % (candidate, err))

        self.z, self.p, self.q = candidate

        self.zp = 1 / (1 - self.z)
        self.zpp = 1 - 1 / self.z

        return

        if abs(w.w0) < globalsettings.getSetting("maximalError"):
            err1 = 1
        else:
            z1 = mpmath.exp(w.w0)
            p1 = int( ((w.w0 - mpmath.log(z1)) / PiI).real )
            q1 = int( ((w.w1 + mpmath.log(1 - z1)) / PiI).real )
            err1 = abs((w.w2 + mpmath.log(z1) - mpmath.log(1 - z1) + p1 * PiI + q1 * PiI))

        z2 = - mpmath.exp(w.w0)
        p2 = int( ((w.w0 - mpmath.log(z2)) / PiI).real )
        q2 = int( ((w.w1 + mpmath.log(1 - z2)) / PiI).real )
        err2 = abs((w.w2 + mpmath.log(z2) - mpmath.log(1 - z2) + p2 * PiI + q2 * PiI))

        if err1 < err2:
            if not err1 < globalsettings.getSetting("maximalError"):
                raise NumericalError(val = err1,
                                     msg = "err1 %s %s %s %s %s %s" % (
                        z1, p1, q1, w.w0, w.w1, w.w2))
            self.z = z1
            self.p = p1
            self.q = q1
        else:
            if not err2 < globalsettings.getSetting("maximalError"):
                raise NumericalError(val = err2,
                                     msg = "err1 %s %s %s %s %s %s" % (
                        z2, p2, q2, w.w0, w.w1, w.w2))
            self.z = z2
            self.p = p2
            self.q = q2
Example #13
0
from csvUtilities.readCensusTable import readCensusTable
import globalsettings
import mpmath
from linearCombinations import binarySearch, filterRepresentativeMfds, twoTerms
from linearCombinations.formatLinearCombination import formatLinearCombination

mpmath.mp.dps = 70
globalsettings.setSetting("maximalError", mpmath.mpf("0.1") ** 50)
globalsettings.setSetting("maximalErrorDigits", 50)

testCensusTablePath = globalsettings.getSetting("testCensusTablePath")
censusTableFile = testCensusTablePath + "/exampleCensusTable.csv"
censusTable = readCensusTable(censusTableFile, sortKey="Volume")

representatives = filterRepresentativeMfds.filterRepresentativeMfds(censusTable.listOfDicts)


def checkBinarySearchResult(vol, resultNames):

    if isinstance(vol, str):
        vol = mpmath.mpf(vol)

    rows = binarySearch.matchingRows(censusTable.listOfDicts, "Volume", vol)
    names = [row["Name"] for row in rows]

    assert set(resultNames) == set(names), Exception("Expected: %s\nGot %s" % (resultNames, names))


def testBinarySearch():

    checkBinarySearchResult(
def solvePolynomialEquations(polys,
                             polynomialSolver,
                             free_dim = 0,
                             with_poly_history = False,
                             poly_history="",
                             variable_dict = { },
                             non_linear_equation_encountered=False):
    
#    polys = [polynomial.convertCoefficients(number) for polynomial in polys]

    if globalsettings.getSetting("solvePolynomialEquationsLog"):
        poly_history += '\n\n\n\n'+'\n'.join(map(_printPoly,polys))+'\n\n============\n'

    if not polys:
        assert free_dim == 0
        if with_poly_history:
            return [(variable_dict,poly_history)]
        else:
            return [variable_dict]
    solutions=[]
    for i in polys:
        assert isinstance(i,Polynomial)
        
    univariate_polys = [ poly for poly in polys if poly.isUnivariate() ]

    if globalsettings.getSetting("solvePolynomialEquationsLog"):
        poly_history=poly_history+'\n\n'+str(map(_printPoly,univariate_polys))+'\n'
    
    if univariate_polys:
        univariate_poly = univariate_polys[0]
        #    print univariate_poly
        variable_name = univariate_poly.variables()[0]
        if globalsettings.getSetting("solvePolynomialEquationsLog"):
            poly_history = poly_history + '\n\nSolving for %s\n' % variable_name

        try:
            sol = polynomialSolver(univariate_poly)
            if globalsettings.getSetting("solvePolynomialEquationsLog"):
                poly_history = poly_history+'\n'+str(sol)+'\n'
        except Exception as e:
            raise SolverException("Error in find_complex_roots when solving: " +
                                  str(univariate_poly) + " " + repr(e),
                                  poly_history)

        assert len(sol)==univariate_poly.degree()
        #if not len(sol)==1:
        #    if non_linear_equation_encountered:
        #        raise SolverException(
        #            "Encountered second non linear equation: " +
        #            str(univariate_poly),
        #            poly_history)
        #    
        #    non_linear_equation_encountered = True
    else:
        if free_dim == 0:
            raise SolverException("No univariate polynomial left",
                                  poly_history)
        else:
            univariate_poly = None
            variable_name = polys[-1].variables()[0]
            sol = [random_complex_modulos()]
            if globalsettings.getSetting("solvePolynomialEquationsLog"):
                poly_history += "In pick random solution for %s:\n %s\n\n" % (variable_name, sol)

            free_dim = free_dim - 1
        
    for value in sol:
        new_variable_dict = dict(variable_dict)
        new_variable_dict[variable_name] = value
        new_polys = [
            poly.substitute(
                { variable_name : Polynomial.constantPolynomial(value) })
            for poly in polys if not poly is univariate_poly]
        new_solutions = solvePolynomialEquations(
            new_polys,
            polynomialSolver = polynomialSolver,
            free_dim = free_dim,
            with_poly_history = with_poly_history,
            poly_history = poly_history,
            variable_dict = new_variable_dict)
        solutions = solutions + new_solutions
        
    return solutions
def get_complex_volumes_and_cross_ratios(t, N, c, primeIdeal, not_paranoid = False):

    # Find the points in the variety
    # solvePolynomialEquations assumes that prime_ideal is given
    # in Groebner basis

    all_cvols = []
    all_cross_ratios = []

    sys.stderr.write("Solving numerically the old way...\n")

    def conversionFunction(c):
        if isinstance(c, Fraction):
            return mpmath.mpc(c.numerator) / mpmath.mpc(c.denominator)
        else:
            return mpmath.mpc(c)

    primeIdealFloatCoeff = primeIdeal.convertCoefficients(conversionFunction)
    solutions = solvePolynomialEquations(
        primeIdealFloatCoeff,
        polynomialSolver = algebra.mpmathFunctions.PolynomialSolver)

    # Solutions is a list with one element per Galois conjugate
    if not len(solutions) == primeIdeal.numberOfPoints:
        raise NumericalError("Number of solutions doesn't match")

    sys.stderr.write("Solved numerically the old way\n")

    # make Nf contain the error message !

    try:
        class SolverThread(threading.Thread):
            def __init__(self, ideal):
                threading.Thread.__init__(self)
                self.ideal = ideal
                self.solution = None
                self.nf = None
                self.event = threading.Event()
                self.done = False
            def run(self):
                try:
                    self.solution, self.nf = (
                        solvePolynomialEquationsExactly(self.ideal, timeout = "process"))
                    self.done = True
                except:
                    pass
                self.event.set()

        sys.stderr.write("Solving exactly...\n")

        thread = SolverThread(primeIdeal)
        thread.start()

        if not thread.event.wait(1200.0):
            thread._Thread__stop()
            raise pari.TimeoutAlarm

        if not thread.done:
            raise pari.PariError

        sys.stderr.write("Solved exactly.\n")
        solution, nf = thread.solution, thread.nf

        nfDegree = 1
        if nf:
            nfDegree = nf.degree()

        if not nfDegree == primeIdeal.numberOfPoints:
            print nf, nfDegree, primeIdeal.numberOfPoints
            raise Exception, "points not matching"

        if nf:
            print "Number field", nf.printMagma()

        sys.stderr.write("Solving numerically the new way...\n")

        solutionsNew = exactSolutionsToNumerical(
            solution, nf,
            coeffConversion = conversionFunction,
            polynomialSolver = algebra.mpmathFunctions.PolynomialSolver)

        sys.stderr.write("Solved numerically the new way.\n")

        sys.stderr.write("Checking against other solutions...\n")

        try:
            solutionCheck(solutionsNew, solutions)

            sys.stderr.write("Checked against other solution.\n")
        except:
            nf = "Error: Solutions not matching"

    except pari.TimeoutAlarm:
        nf = "Error: Timeout"

    except Exception as e: 
        print e
        nf = "Error: unknown"

    id_c_parms = manifold.slN.get_identified_c_parameters(t, N)
    if N % 2 == 0:
        H = manifold.slN.get_all_obstruction_classes(t)
        h = H[c]
    else:
        h = None

    # Each element in solutions is a dictionary
    # mapping the variable name to the numerical value
    for solution in solutions:
        # the Ptolemy coordinates are projective
        # We multiply all Ptolemy coordinates by the same random number
        # to avoid taking the logarithm of a negative real number
        solution = manifold.slN.multiply_solution_by_constant(
            solution, 
            mpmath.mpc("1.0","0.32433234644"))

        # We assign a value to each Ptolemy coordinate based on the 
        # solution
        c_parms = manifold.slN.map_solution_to_c_parameters(solution,
                                                            id_c_parms)
        # Consistency check
        if not not_paranoid:
            manifold.slN.check_solution_identification(t, N, c_parms)

        # Consistency check
        manifold.slN.check_solution_on_gluing_equations(
            t, N, c_parms, h)

        # Get Ptolemy cochain
        # P consists of Ptolemy_cochain objects which encapsulate
        #   a sign for orientation and 6 edge parameters c
        P = manifold.slN.get_Ptolemy_cochain(t, N, c_parms, no_check = not_paranoid)

        # convert the 6 edge parameters into an element of the
        # extended Bloch group represented by (w0,w1,w2)
        ws = [manifold.bloch_group.w_triple(x, no_check = not_paranoid) for x in P]

        # convert the triples (w0,w1,w2) into [z;p,q]
        # a different representation of an extended Bloch group element
        zpqs = [manifold.bloch_group.zpq_triple(x, no_check = not_paranoid) for x in ws]

        cross_ratios = {}
        for zpq_triple in zpqs:
            for k, v in zpq_triple.cross_ratios().items():
                cross_ratios[k] = v

        all_cross_ratios.append(cross_ratios)
                
        #for i in zpqs:
        #    print i
        

        # Compute the volume function and sum for all [z;p,q]
        vols = [x.volume() for x in zpqs]
        vol = sum(vols)

        # Compute the L function and sum for all [z;p,q]
        cvols = [x.L_function() for x in zpqs]
        cvol = sum(cvols) / 1j

        sys.stderr.write("   %s\n" % (
            utilities.printNumbers.printComplexNumberAsFixed(cvol)))

        # Consistency check
        maxErr = globalsettings.getSetting("maximalError")

        if not abs(vol - cvol.real) < maxErr:
            raise NumericalError(val = [vol, cvol], 
                                 msg = "Vol and Complex Vol not matching")
        all_cvols.append(cvol)
    return all_cvols, nf, all_cross_ratios