def get_overconvergent_class_matrices(p,E,prec, sign_at_infinity,use_ps_dists = False,use_sage_db = False,parallelize = False,progress_bar = False):
    # If the moments are pre-calculated, will load them. Otherwise, calculate and
    # save them to disk.
    if use_ps_dists == False:
        raise NotImplementedError, 'Must use distributions from Pollack-Stevens code in the split case'

    sgninfty = 'plus' if sign_at_infinity == 1 else 'minus'
    dist_type = 'ps' if use_ps_dists == True else 'fm'
    fname = 'moments_%s_%s_%s_%s_%s.sobj'%(p,E.cremona_label(),sgninfty,prec,dist_type)
    if use_sage_db:
        try:
            Phi = db(fname)
            return Phi
        except IOError: pass
    phi0 = E.pollack_stevens_modular_symbol()
    if sign_at_infinity == 1:
        phi0 = phi0.plus_part()
    elif sign_at_infinity == -1:
        phi0 = phi0.minus_part()
    else:
        assert sign_at_infinity == 0
        phi0 = phi0.plus_part() + phi0.minus_part()
    phi0 = 1 / gcd([val.moment(0) for val in phi0.values()]) * phi0
    Phi = phi0.lift(p,M = prec - 1,algorithm = 'stevens',eigensymbol = True)
    Phi._liftee = phi0
    return Phi
Exemple #2
0
def BigArithGroup(p,quat_data,level,base = None, grouptype = None,seed = None,use_sage_db = False,outfile = None, magma = None, timeout = 0, logfile = None, use_shapiro = True, character = None, nscartan = None, matrix_group = False):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(logfile = logfile)
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if seed is not None:
            magma.eval('SetSeed(%s)'%seed)
        magma.attach_spec(page_path)
    magma.eval('Page_initialized := true')
    a, b = None, None
    if logfile is not None:
        magma.eval('SetVerbose("Kleinian",2)')
    try:
        discriminant = ZZ(quat_data)
        if base is not None:
            assert base == QQ
        else:
            base = QQ
        fname = 'arithgroup%s_%s_%s_%s.sobj'%(seed,p,discriminant,level) # Fix this name
    except TypeError:
        a,b = quat_data
        if base is None:
            base = a.parent()
        discriminant = QuaternionAlgebra(base,a,b).discriminant()
        fname = 'arithgroup%s_%s_%s_%s.sobj'%(seed,p,discriminant,level) # Fix this name
    if base != QQ:
        use_sage_db = False # This is not implemented yet

    if grouptype is None:
        if base == QQ:
            grouptype = 'PSL2'
        else:
            grouptype = 'PGL2'

    if use_sage_db:
        try:
            newobj = db(fname)
        except IOError:
            verbose('Group not found in database. Computing from scratch.')
            newobj = BigArithGroup_class(base,p,discriminant,level,seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group)
            newobj.save_to_db()
    else:
        if a is not None:
            newobj = BigArithGroup_class(base,p,discriminant,abtuple = (a,b),level = level,seed = seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group)
        else:
            newobj = BigArithGroup_class(base,p,discriminant,level = level,seed = seed,outfile = outfile,grouptype = grouptype,magma = magma,timeout = timeout, use_shapiro = use_shapiro, character = character, nscartan = nscartan, matrix_group = matrix_group)
    return newobj
def get_overconvergent_class_quaternionic(P,phiE,G,prec,sign_at_infinity,sign_ap, use_ps_dists = False,use_sage_db = False,parallelize = False,progress_bar = False,method = None,Ename = 'unknown'):
    try:
        p = ZZ(P)
        Pnorm = p
        F = QQ
    except TypeError:
        p = ZZ(P.norm().factor()[0][0])
        Pnorm = ZZ(P.norm())
        F = P.number_field()

    if method is None:
        method = 'naive'
    else:
        if method != 'naive' and method != 'bigmatrix':
            raise ValueError('method should be either "naive" or "bigmatrix"')
    if Pnorm != p:
        raise NotImplementedError('For now I can only work over totally split')

    base_ring = Zp(p,prec)

    sgninfty = 'plus' if sign_at_infinity == 1 else 'minus'
    dist_type = 'ps' if use_ps_dists == True else 'fm'
    fname = 'moments_%s_%s_%s_%s_%s.sobj'%(p,Ename,sgninfty,prec,dist_type)
    if use_sage_db:
        try:
            Phivals = db(fname)
            CohOC = ArithCoh(G,overconvergent = 1,base = base_ring,use_ps_dists = use_ps_dists)
            CohOC._coeff_module = Phivals[0].parent()
            VOC = CohOC.coefficient_module()
            Phi = CohOC([VOC(o) for o in Phivals])
            return Phi
        except IOError: pass
    verbose('Computing moments...')
    CohOC = ArithCoh(G,overconvergent = 1,base = base_ring,use_ps_dists = use_ps_dists)
    Phi0 = CohOC(phiE)
    verbose('Now lifting...')
    Phi = CohOC.improve(Phi0, prec = prec,sign = sign_ap, parallelize = parallelize,progress_bar = progress_bar,method = method)
    if use_sage_db:
        raise NotImplementedError
        # db_save(Phi._val,fname)
    verbose('Done.')
    Phi.set_liftee(phiE)
    Phi._sign_ap = sign_ap
    return Phi
Exemple #4
0
def BigArithGroup(p,
                  quat_data,
                  level,
                  base=None,
                  grouptype=None,
                  seed=None,
                  use_sage_db=False,
                  magma=None,
                  logfile=None,
                  **kwargs):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(logfile=logfile)
    if seed is not None:
        magma.eval('SetSeed(%s)' % seed)
    if not is_page_initialized(magma):
        attach_kleinian_code(magma)
    a, b = None, None
    if logfile is not None:
        magma.eval('SetVerbose("Kleinian",2)')
    try:
        discriminant = ZZ(quat_data)
        if base is not None:
            assert base == QQ
        else:
            base = QQ
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    except TypeError:
        a, b = quat_data
        if base is None:
            base = a.parent()
        discriminant = QuaternionAlgebra(base, a, b).discriminant()
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    if base != QQ:
        use_sage_db = False  # This is not implemented yet

    if grouptype is None:
        if base == QQ:
            grouptype = 'PSL2'
        else:
            grouptype = 'PSL2'  # DEBUG, was PGL2

    if use_sage_db:
        try:
            newobj = db(fname)
        except IOError:
            verbose('Group not found in database. Computing from scratch.')
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level,
                                         seed,
                                         grouptype=grouptype,
                                         magma=magma,
                                         **kwargs)
            newobj.save_to_db()
    else:
        if a is not None:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         abtuple=(a, b),
                                         level=level,
                                         seed=seed,
                                         grouptype=grouptype,
                                         magma=magma,
                                         **kwargs)
        else:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level=level,
                                         seed=seed,
                                         grouptype=grouptype,
                                         magma=magma,
                                         **kwargs)
    return newobj
Exemple #5
0
def Lpvalue(f,
            g,
            h,
            p,
            prec,
            N=None,
            modformsring=False,
            weightbound=6,
            eps=None,
            orthogonal_form=None,
            magma_args=None,
            force_computation=False,
            algorithm='twostage'):
    if magma_args is None:
        magma_args = {}
    if algorithm not in ['twostage', 'threestage']:
        raise ValueError(
            'Algorithm should be one of "twostage" (default) or "threestage"')
    from sage.interfaces.magma import Magma
    magma = Magma(**magma_args)
    ll, mm = g.weight(), h.weight()
    t = 0  # Assume t = 0 here
    kk = ll + mm - 2 * (1 + t)  # Is this correct?
    p = ZZ(p)
    if N is None:
        N = LCM([ZZ(f.level()), ZZ(g.level()), ZZ(h.level())])
        N = N.prime_to_m_part(p)

    print("Tame level N = %s, prime p = %s" % (N, p))
    prec = ZZ(prec)

    print("Step 1: Compute the Up matrix")
    computation_name = '%s_%s_%s_%s_%s_%s' % (
        p, N, kk, prec, 'triv' if eps is None else 'char', algorithm)
    tmp_filename = '/tmp/magma_mtx_%s.tmp' % computation_name
    import os.path
    from sage.misc.persist import db, db_save
    try:
        if force_computation:
            raise IOError
        V = db('Lpvalue_Apow_ordbasis_eimat_%s' % computation_name)
        ord_basis, eimat, zetapm, elldash, mdash = V[:5]
        Apow_data = V[5:]
    except IOError:
        if force_computation or not os.path.exists(tmp_filename):
            if eps is not None:
                eps_magma = sage_character_to_magma(eps, magma=magma)
                Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(
                    p, eps_magma, kk, prec, nvals=5)
            else:
                Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(
                    p, N, kk, prec, nvals=5)
            print(" ..Converting to Sage...")
            Amodulus = Am[1, 1].Parent().Modulus().sage()
            Arows = Am.NumberOfRows().sage()
            Acols = Am.NumberOfColumns().sage()
            Emodulus = eimatm[1, 1].Parent().Modulus().sage()
            Erows = eimatm.NumberOfRows().sage()
            Ecols = eimatm.NumberOfColumns().sage()
            magma.eval('F := Open("%s", "w");' % tmp_filename)
            magma.eval('fprintf F, "Matrix(Zmod(%s),%s, %s, "' %
                       (Amodulus, Arows, Acols))
            magma.eval('fprintf F, "%%o", ElementToSequence(%s)' % Am.name())
            magma.eval('fprintf F, ") \\n"')
            magma.eval('fprintf F, "Matrix(Zmod(%s),%s, %s, "' %
                       (Emodulus, Erows, Ecols))
            magma.eval('fprintf F, "%%o", ElementToSequence(%s)' %
                       eimatm.name())
            magma.eval('fprintf F, ") \\n"')
            magma.eval('fprintf F, "%%o\\n", %s' % zetapm.name())
            magma.eval('fprintf F, "%%o\\n", %s' % elldash.name())
            magma.eval('fprintf F, "%%o\\n", %s' % mdash.name())
            magma.eval('delete F;')
            magma.quit()

        # Read A and eimat from file
        from sage.structure.sage_object import load
        from sage.misc.sage_eval import sage_eval
        with open(tmp_filename, 'r') as fmagma:
            A = sage_eval(fmagma.readline(), preparse=False)
            eimat = sage_eval(fmagma.readline(), preparse=False)
            zetapm = sage_eval(fmagma.readline())
            elldash = sage_eval(fmagma.readline())
            mdash = sage_eval(fmagma.readline())

        print("Step 3b: Apply Up^(r-1) to H")
        if algorithm == 'twostage':
            V0 = list(find_Apow_and_ord(A, eimat, p, prec))
        else:
            V0 = list(find_Apow_and_ord_three_stage(A, eimat, p, prec))
        ord_basis = V0[0]
        Apow_data = V0[1:]
        V = [ord_basis]
        V.extend([eimat, zetapm, elldash, mdash])
        V.extend(Apow_data)
        db_save(V, 'Lpvalue_Apow_ordbasis_eimat_%s' % computation_name)
        from posix import remove
        remove(tmp_filename)

    print("Step 2: p-depletion, Coleman primitive, and multiply")
    H = depletion_coleman_multiply(g, h, p, p * elldash, t=0)

    print("Step 3a: Compute Up(H)")
    UpH = vector([H(p * n) for n in range(elldash)])

    if len(Apow_data) == 1:
        Hord = compute_ordinary_projection_two_stage(UpH, Apow_data, eimat,
                                                     elldash)
    else:
        Hord = compute_ordinary_projection_three_stage(UpH,
                                                       [ord_basis] + Apow_data,
                                                       eimat, elldash)
    Hord = Hord.change_ring(Apow_data[0].parent().base_ring())

    print("Step 4: Project onto f-component")
    R = Qp(p, prec)
    if orthogonal_form is None:
        ell, piHord = project_onto_eigenspace(f, ord_basis,
                                              Hord.change_ring(R), kk, N * p,
                                              eps)
        n = 1
        while f[n] == 0:
            n += 1
        Lpa = R(piHord[n]) / R(f[n])
    else:
        ell, piHord = project_onto_eigenspace(f,
                                              ord_basis,
                                              Hord.change_ring(R),
                                              kk,
                                              N * p,
                                              eps,
                                              derivative_order=2)
        gplus, gminus = f, orthogonal_form
        l1 = 2
        while N * p * ell % l1 == 0 or gplus[l1] == 0:
            l1 = next_prime(l1)
        proj_mat = matrix([[gplus[l1], gplus[p]], [gminus[l1], gminus[p]]])
        Lpalist = (matrix([piHord[l1], piHord[p]]) * proj_mat**-1).list()
        Lpa = Lpalist[0]
        if Lpa.valuation() > prec / 2:  # this is quite arbitrary!
            Lpa = Lpalist[1]
        n = 1
        while f[n] == 0:
            n += 1
        Lpa = Lpa / f[n]
    return Lpa, ell
Exemple #6
0
def Lpvalue(f,g,h,p,prec,N = None,modformsring = False, weightbound = False, eps = None, orthogonal_form = None, data_idx=None, magma_args = None,force_computation=False, algorithm='threestage', derivative_order=1, lauders_advice = False, use_magma = True, magma = None, num_coeffs_qexpansion = 20000, max_primes=5, outfile = None):
    if magma_args is None:
        magma_args = {}
    if algorithm not in ['twostage','threestage']:
        raise ValueError('Algorithm should be one of "twostage" (default) or "threestage"')

    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(**magma_args)
    if hasattr(g,'j_invariant'):
        elliptic_curve = g
        g = g.modular_form()
    else:
        elliptic_curve = None
    data = None
    if h is None:
        if hasattr(f, 'modulus'):
            # Assume we need to create f and h from Dirichlet character
            kronecker_character = f
            f, _, h = define_qexpansions_from_dirichlet_character(p, prec, kronecker_character, num_coeffs_qexpansion, magma)
        else:
            kronecker_character = None
            # Assume that f contains a list of lines of text to initialize both f and h
            data = f
            f, h = get_magma_qexpansions(data, data_idx, max(prec,200), Qp(p,prec), magma=magma)
            eps = f.character_full()


    ll,mm = g.weight(),h.weight()
    t = 0 # Assume t = 0 here
    kk = ll + mm - 2 * (1 + t) # Is this correct?
    p = ZZ(p)
    if N is None:
        N = lcm([ZZ(f.level()),ZZ(g.level()),ZZ(h.level())])
        nu = N.valuation(p)
        N = N.prime_to_m_part(p)
    else:
        N = ZZ(N)
        nu = N.valuation(p)
    if outfile is None:
        outfile = "output_iterated_integral_%s_%s_%s_%s.txt"%(p,g.level(), h.level(), prec)
    print("Writing output to file %s"%outfile)
    fwrite("######### STARTING COMPUTATION OF Lp ###########", outfile)

    if elliptic_curve is not None:
        fwrite("E = EllipticCurve(%s)"%list(elliptic_curve.ainvs()), outfile)
        fwrite("  cond(E) = %s"%elliptic_curve.conductor(), outfile)
    if kronecker_character is not None:
        fwrite("kronecker_character = %s"%kronecker_character, outfile)
        fwrite("  conductor = %s"%kronecker_character.conductor(), outfile)
    if data is not None:
        fwrite("Data for weight-1 forms:", outfile)
        for line in data:
            fwrite(line, outfile)
    fwrite("Tame level N = %s, prime p = %s, nu = %s"%(N,p,nu), outfile)
    fwrite("precision = %s"%prec, outfile)
    fwrite("------ parameters --------------------", outfile)
    fwrite("modformsring = %s"%modformsring, outfile)
    fwrite("weightbound = %s"%weightbound, outfile)
    fwrite("eps = %s"%eps, outfile)
    fwrite("orthogonal_form = %s"%orthogonal_form, outfile)
    fwrite("magma_args = %s"%magma_args, outfile)
    fwrite("force_computation = %s"%force_computation, outfile)
    fwrite("algorithm = %s"%algorithm, outfile)
    fwrite("derivative_order = %s"%derivative_order, outfile)
    fwrite("lauders_advice = %s"%lauders_advice, outfile)
    fwrite("use_magma = %s"%use_magma, outfile)
    fwrite("num_coeffs_qexpansion = %s"%num_coeffs_qexpansion, outfile)
    fwrite("##########################################", outfile)
    prec = ZZ(prec)

    fwrite("Step 1: Compute the Up matrix", outfile)
    if algorithm == "twostage":
        computation_name = '%s_%s_%s_%s_%s_%s_%s'%(p,N,nu,kk,prec,'triv' if eps is None else 'char',algorithm)
    else:
        computation_name = '%s_%s_%s_%s_%s_%s'%(p,N,nu,kk,prec,'triv' if eps is None else 'char')
    if use_magma:
        tmp_filename = '/tmp/magma_mtx_%s.tmp'%computation_name
        import os.path
        from sage.misc.persist import db, db_save
        try:
            if force_computation:
                raise IOError
            V = db('Lpvalue_Apow_ordbasis_eimat_%s'%computation_name)
            ord_basis, eimat, zetapm, elldash, mdash = V[:5]
            Apow_data = V[5:]
        except IOError:
            if force_computation or not os.path.exists(tmp_filename):
                if eps is not None:
                    eps_magma = sage_character_to_magma(eps,N,magma=magma)
                    magma.load("overconvergent_alan.m")
                    # Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(p, eps_magma, kk, prec,WeightBound=weightbound,nvals=5)
                    Am, zetapm, eimatm, elldash, mdash = magma.HigherLevelUpGj(p, kk, prec, weightbound, eps_magma,'"B"',nvals=5)
                else:
                    # Am, zetapm, eimatm, elldash, mdash = magma.UpOperatorData(p, N, kk, prec,WeightBound=weightbound,nvals=5)
                    magma.load("overconvergent_alan.m")
                    Am, zetapm, eimatm, elldash, mdash = magma.HigherLevelUpGj(p, kk, prec, weightbound, N,'"B"',nvals=5)
                fwrite(" ..Converting to Sage...", outfile)
                Amodulus = Am[1,1].Parent().Modulus().sage()
                Aprec = Amodulus.valuation(p)
                Arows = Am.NumberOfRows().sage()
                Acols = Am.NumberOfColumns().sage()
                Emodulus = eimatm[1,1].Parent().Modulus().sage()
                Eprec = Emodulus.valuation(p)
                Erows = eimatm.NumberOfRows().sage()
                Ecols = eimatm.NumberOfColumns().sage()
                magma.load("get_qexpansions.m")
                magma.eval('F := Open("%s", "w");'%tmp_filename)
                magma.eval('fprintf F, "%s, %s, %s, %s \\n"'%(p,Aprec,Arows,Acols)) # parameters
                magma.eval('save_matrix(%s, F)'%(Am.name()))
                # for i in range(1,Arows+1):
                #     magma.eval('fprintf F, "%%o\\n", %s[%s]'%(Am.name(),i))
                magma.eval('fprintf F, "%s, %s, %s, %s \\n"'%(p,Eprec,Erows,Ecols)) # parameters
                magma.eval('save_matrix(%s, F)'%(eimatm.name()))
                # for i in range(1,Erows+1):
                #     magma.eval('fprintf F, "%%o\\n", %s[%s]'%(eimatm.name(),i))
                magma.eval('fprintf F, "%s\\n"'%zetapm)
                magma.eval('fprintf F, "%s\\n"'%elldash)
                magma.eval('fprintf F, "%s\\n"'%mdash)
                magma.eval('delete F;')
                magma.quit()

            # Read A and eimat from file
            from sage.structure.sage_object import load
            from sage.misc.sage_eval import sage_eval
            with open(tmp_filename,'r') as fmagma:
                A = read_matrix_from_file(fmagma)
                eimat = read_matrix_from_file(fmagma)
                zetapm= sage_eval(fmagma.readline())
                elldash = sage_eval(fmagma.readline())
                mdash = sage_eval(fmagma.readline())

            fwrite("Step 3b: Apply Up^(r-1) to H", outfile)
            if algorithm == 'twostage':
                V0  = list(find_Apow_and_ord_two_stage(A, eimat, p, prec))
            else:
                V0 = list(find_Apow_and_ord_three_stage(A,eimat,p,prec))
            ord_basis = V0[0]
            Apow_data = V0[1:]
            V = [ord_basis]
            V.extend([eimat, zetapm, elldash, mdash])
            V.extend(Apow_data)
            db_save(V,'Lpvalue_Apow_ordbasis_eimat_%s'%computation_name)
            from posix import remove
            remove(tmp_filename)

    else:
        A, eimat, elldash, mdash = UpOperator(p,N,kk,prec, modformsring = False, weightbound = 6)

    fwrite("Step 2: p-depletion, Coleman primitive, and multiply", outfile)
    fwrite(".. Need %s coefficients of the q-expansion..."%(p**(nu+1) * elldash), outfile)
    if data is not None:
        f, h = get_magma_qexpansions(data, data_idx, (p**(nu+1) * elldash) + 200, Qp(p,prec), magma=magma)

    H = depletion_coleman_multiply(g, h, p, p**(nu+1) * elldash, t=0)

    fwrite("Step 3a: Compute ordinary projection", outfile)

    if len(Apow_data) == 1:
        Hord = compute_ordinary_projection_two_stage(H, Apow_data, eimat, elldash,p)
    else:
        Hord = compute_ordinary_projection_three_stage(H, [ord_basis] + Apow_data, eimat, elldash,p,nu)
    fwrite('Changing Hord to ring %s'%g[1].parent(), outfile)
    Hord = Hord.change_ring(h[1].parent())
    print [Hord[i] for i in range(30)]
    fwrite("Step 4: Project onto f-component", outfile)
    while True:
        try:
            ell, piHord, epstwist = project_onto_eigenspace(f, ord_basis, Hord, kk, N * p, p = p, derivative_order=derivative_order, max_primes=max_primes)
            break
        except RuntimeError:
            derivative_order += 1
            verbose("Increasing experimental derivative order to %s"%derivative_order)
        except ValueError:
            verbose("Experimental derivative order (%s) seems too high"%derivative_order)
            fwrite("Experimental derivative_order = %s"%derivative_order, outfile)
            fwrite("Seems too high...", outfile)
            fwrite("######################################", outfile)
            assert 0
    n = 1
    while f[n] == 0:
        n = next_prime(n)
    if lauders_advice == True or orthogonal_form is None:
        Lpa =  piHord[n] / (f[n] * epstwist(n))
        fwrite("Experimental derivative_order = %s"%derivative_order, outfile)
        fwrite("Checking Lauder's coincidence... (following should be a bunch of 'large' valuations)", outfile)
        fwrite(str([(i,(Lpa * f[i] * epstwist(i) - piHord[i]).valuation(p)) for i in prime_range(50)]), outfile)
        fwrite("Done", outfile)
    else:
        gplus, gminus = f, orthogonal_form
        l1 = 2
        while N*p*ell % l1 == 0 or gplus[l1] == 0:
            l1 = next_prime(l1)
        proj_mat = matrix([[gplus[l1],gplus[p]],[gminus[l1],gminus[p]]])
        Lpalist =  (matrix([piHord[l1],piHord[p]]) * proj_mat**-1).list()
        Lpa = Lpalist[0]
        if Lpa.valuation() > prec / 2: # this is quite arbitrary!
            Lpa = Lpalist[1]
        Lpa = Lpa / f[n]
    fwrite("ell = %s"%ell, outfile)
    fwrite("######### FINISHED COMPUTATION ###########", outfile)
    fwrite("Lp = %s"%Lpa, outfile)
    fwrite("##########################################", outfile)
    return Lpa, ell
Exemple #7
0
def BigArithGroup(p,
                  quat_data,
                  level,
                  base=None,
                  grouptype=None,
                  seed=None,
                  use_sage_db=False,
                  outfile=None,
                  magma=None,
                  timeout=0,
                  logfile=None,
                  use_shapiro=True,
                  character=None,
                  nscartan=None,
                  matrix_group=False):
    if magma is None:
        from sage.interfaces.magma import Magma
        magma = Magma(logfile=logfile)
        page_path = os.path.dirname(__file__) + '/KleinianGroups-1.0/klngpspec'
        if seed is not None:
            magma.eval('SetSeed(%s)' % seed)
        magma.attach_spec(page_path)
    magma.eval('Page_initialized := true')
    a, b = None, None
    if logfile is not None:
        magma.eval('SetVerbose("Kleinian",2)')
    try:
        discriminant = ZZ(quat_data)
        if base is not None:
            assert base == QQ
        else:
            base = QQ
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    except TypeError:
        a, b = quat_data
        if base is None:
            base = a.parent()
        discriminant = QuaternionAlgebra(base, a, b).discriminant()
        fname = 'arithgroup%s_%s_%s_%s.sobj' % (seed, p, discriminant, level
                                                )  # Fix this name
    if base != QQ:
        use_sage_db = False  # This is not implemented yet

    if grouptype is None:
        if base == QQ:
            grouptype = 'PSL2'
        else:
            grouptype = 'PGL2'

    if use_sage_db:
        try:
            newobj = db(fname)
        except IOError:
            verbose('Group not found in database. Computing from scratch.')
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level,
                                         seed,
                                         outfile=outfile,
                                         grouptype=grouptype,
                                         magma=magma,
                                         timeout=timeout,
                                         use_shapiro=use_shapiro,
                                         character=character,
                                         nscartan=nscartan,
                                         matrix_group=matrix_group)
            newobj.save_to_db()
    else:
        if a is not None:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         abtuple=(a, b),
                                         level=level,
                                         seed=seed,
                                         outfile=outfile,
                                         grouptype=grouptype,
                                         magma=magma,
                                         timeout=timeout,
                                         use_shapiro=use_shapiro,
                                         character=character,
                                         nscartan=nscartan,
                                         matrix_group=matrix_group)
        else:
            newobj = BigArithGroup_class(base,
                                         p,
                                         discriminant,
                                         level=level,
                                         seed=seed,
                                         outfile=outfile,
                                         grouptype=grouptype,
                                         magma=magma,
                                         timeout=timeout,
                                         use_shapiro=use_shapiro,
                                         character=character,
                                         nscartan=nscartan,
                                         matrix_group=matrix_group)
    return newobj