def function_field_equation(R, F): r""" Return the equation defining a function field. INPUT: - ``R`` -- an integral domain - ``F`` -- a function field, defined as a simple finite extension of a rational function field over the fraction field `K` of `R` OUTPUT: a polynomial `G` over `R` in two variables such that `F = K(x, y | G(x,y)=0)`. """ G = F.polynomial() # G should be an univariat polynomial over a rational function field F0 F0 = G.parent().base_ring() A0 = F0._ring() # A0 is a polynomial ring over K, the fraction field of R K = A0.base_ring() assert R.fraction_field() == K, "K must be the fraction field of R" coeffs = [G[i] for i in range(G.degree() + 1)] a = lcm([c.denominator() for c in coeffs if not c.is_zero()]) coeffs = [(a * c).numerator() for c in coeffs] # now coeffs is a list of univariat polynomials over a field common_denominator = R.one() for c in coeffs: common_denominator = lcm([ c[i].denominator() for i in range(c.degree() + 1) if not c[i].is_zero() ] + [common_denominator]) B = PolynomialRing(R, 2, ['x', 'y']) x = B.gens()[0] y = B.gens()[1] coeffs = [(common_denominator * c)(x) for c in coeffs] return sum([coeffs[i] * y**i for i in range(len(coeffs))])
def get_C_integer_type1(K, q, bad_aux_prime_dict, C_K, bound_so_far): running_primes = gcd(q, bound_so_far) if str(q) in bad_aux_prime_dict: running_primes = lcm(running_primes, gcd(bad_aux_prime_dict[str(q)], bound_so_far)) norms_clexp = {(frak_q.absolute_norm(), C_K(frak_q).multiplicative_order()) for frak_q in K.primes_above(q)} for nm_q, frak_q_class_group_order in norms_clexp: exponent = 12 * frak_q_class_group_order N_cusp = ZZ(nm_q)**exponent - 1 N_cusp = gcd(N_cusp, bound_so_far) running_primes = lcm(running_primes, N_cusp) weil_polys = get_weil_polys(GF(nm_q)) for wp in weil_polys: N = get_N(wp, nm_q, exponent) assert N != 0 N = gcd(N, bound_so_far) running_primes = lcm(running_primes, N) if running_primes == bound_so_far: break return gcd(running_primes, bound_so_far)
def divisor_data(P): R = PolynomialRing(QQ,['x','z']); x = R('x');z = R('z') xP,yP = P[0],P[1] xden,yden = lcm([r[1] for r in xP]), lcm([r[1] for r in yP]) xD = sum([ZZ(xden)*ZZ(xP[i][0])/ZZ(xP[i][1])*x**i*z**(len(xP)-i-1) for i in range(len(xP))]) if str(xD.factor())[:4] == "(-1)": xD = -xD yD = sum([ZZ(yden)*ZZ(yP[i][0])/ZZ(yP[i][1])*x**i*z**(len(yP)-i-1) for i in range(len(yP))]) return [make_bigint(elt, 10) for elt in [str(xD.factor()).replace("**","^").replace("*",""), str(yden)+"y" if yden > 1 else "y", str(yD).replace("**","^").replace("*","")]], xD, yD, yden
def get_not_type_one_two_primes(K, aux_prime_count=3, loop_curves=False): """Not type 1-2 primes are the finitely many primes outside of which the isogeny character is necessarily of Momose Type 1 or 2 (or 3, which is not relevant for us).""" if K.is_totally_real(): aux_primes = K.primes_of_degree_one_list(aux_prime_count) else: it = K.primes_of_degree_one_iter() aux_primes = [] while len(aux_primes) < aux_prime_count: aux_prime_candidate = next(it) if not aux_prime_candidate.is_principal(): aux_primes.append(aux_prime_candidate) tracking_dict = {} epsilons = EPSILONS_NOT_TYPE_1_2 C_K = K.class_group() for q in aux_primes: q_class_group_order = C_K(q).multiplicative_order() # these will be dicts with keys the epsilons, values sets of primes AB_primes_dict = get_AB_primes(q, epsilons, q_class_group_order) C_primes_dict = get_C_primes(K, q, epsilons, q_class_group_order, loop_curves) unified_dict = {} q_rat = Integer(q.norm()) assert q_rat.is_prime() for eps in epsilons: unified_dict[eps] = lcm([q_rat, AB_primes_dict[eps], C_primes_dict[eps]]) tracking_dict[q] = unified_dict tracking_dict_inv_collapsed = {} for eps in epsilons: q_dict = {} for q in aux_primes: q_dict[q] = tracking_dict[q][eps] q_dict_collapsed = gcd(list(q_dict.values())) tracking_dict_inv_collapsed[eps] = q_dict_collapsed final_split_dict = {} for eps_type in set(epsilons.values()): eps_type_tracking_dict_inv = { eps: ZZ(tracking_dict_inv_collapsed[eps]) for eps in epsilons if epsilons[eps] == eps_type } eps_type_output = lcm(list(eps_type_tracking_dict_inv.values())) eps_type_output = eps_type_output.prime_divisors() eps_type_output = filter_ABC_primes(K, eps_type_output, eps_type) final_split_dict[eps_type] = set(eps_type_output) output = set.union(*(val for val in final_split_dict.values())) output = list(output) output.sort() return output
def get_C_primes( K, frak_q, epsilons, q_class_group_order, loop_curves=False, ordinary=False ): # Initialise output dict to empty sets output_dict_C = {} for eps in epsilons: output_dict_C[eps] = 1 residue_field = frak_q.residue_field(names="z") alphas = (frak_q ** q_class_group_order).gens_reduced() assert len(alphas) == 1, "q^q_class_group_order not principal, which is very bad" alpha = alphas[0] if loop_curves: frob_polys_to_loop = get_weil_polys(residue_field, ordinary=ordinary) else: res_field_card = residue_field.cardinality() frob_polys_to_loop = R.weil_polynomials(2, res_field_card) if ordinary: q, _ = res_field_card.perfect_power() frob_polys_to_loop = [f for f in frob_polys_to_loop if f[1] % q != 0] for frob_poly in frob_polys_to_loop: if frob_poly.is_irreducible(): frob_poly_root_field = frob_poly.root_field("a") _, K_into_KL, L_into_KL, _ = K.composite_fields( frob_poly_root_field, "c", both_maps=True )[0] else: frob_poly_root_field = IntegerRing() roots_of_frob = frob_poly.roots(frob_poly_root_field) betas = [r for r, e in roots_of_frob] for beta in betas: if beta in K: for eps in epsilons: N = ( group_ring_exp(alpha, eps) - beta ** (12 * q_class_group_order) ).absolute_norm() N = ZZ(N) output_dict_C[eps] = lcm(output_dict_C[eps], N) else: for eps in epsilons: N = ( K_into_KL(group_ring_exp(alpha, eps)) - L_into_KL(beta ** (12 * q_class_group_order)) ).absolute_norm() N = ZZ(N) output_dict_C[eps] = lcm(output_dict_C[eps], N) return output_dict_C
def function_field_element(f, R): r""" Return the numerator and denominator of a function field element. INPUT: - ``f`` -- an element of a function field `F`, which is a finite extension of a rational function field `F_0` over a field `K` - ``R`` -- an order of `K` OUTPUT: a pair `g, h` of polynomials over `R` in two variables `x, y` such that f = g/h (if we map `x` to the generator of `F_0` and `y` to the generator of `F/F_0`. """ F = f.parent() if hasattr(F, "polynomial"): # F0 = F.base_field() # A0 = F0._ring f = f.element() n = f.degree() # now f is an univariant polynomial over F0 h = lcm([f[i].denominator() for i in range(n + 1)]) g = h * f a = lcm([ common_denominator_of_polynomial(g[i].numerator(), ZZ) for i in range(n + 1) if not g[i].is_zero() ]) b = common_denominator_of_polynomial(h, R) c = lcm(a, b) g = c * g h = c * h B = PolynomialRing(R, 2, ['x', 'y']) x = B.gens()[0] y = B.gens()[1] g = sum([g[i].numerator()(x) * y**i for i in range(g.degree() + 1)]) h = h(x) return g, h else: # f seems to constant in y g = f.numerator() h = f.denominator() a = common_denominator_of_polynomial(g, R) b = common_denominator_of_polynomial(h, R) c = lcm(a, b) g = c * g h = c * h B = PolynomialRing(R, 2, ['x', 'y']) x = B.gens()[0] return g(x), h(x)
def circle_drops(A, B): # Drops going around the unit circle for those A and B. # See http://user.math.uzh.ch/dehaye/thesis_students/Nicolas_Wider-Integrality_of_factorial_ratios.pdf # for longer description (not original, better references exist) marks = lcm(lcm(A), lcm(B)) tmp = [0 for i in range(marks)] for a in A: for i in range(a): if gcd(i, a) == 1: tmp[i * marks / a] -= 1 for b in B: for i in range(b): if gcd(i, b) == 1: tmp[i * marks / b] += 1 return [sum(tmp[:j]) for j in range(marks)]
def _action(self, A): [a, b, c, d] = A if not c % self._level == 0: raise ValueError("Need A in {0}! Got: {1}".format(self.group, A)) fak = 1 if c < 0: a = -a b = -b c = -c d = -d fak = -self._fak #fak = fak*(-1)**(self._exp_num-self._exp_den) res = 1 exp = 0 for i in range(len(self._exponents)): z = CyclotomicField(lcm(12, self._exponents[i].denominator())).gen() arg, v = eta_conjugated(a, b, c, d, self._arguments[i]) #arg2,v2 = eta_conjugated(a,b,c,d,self._arg_den) #res=self._z**(arg1*self._exp_num-arg2*self._exp_den) # exp += arg*self._exponents[i] if v != 1: res = res * v**self._exponents[i] #if v2<>1: #res=res/v2**self._exp_den res = res * z**(arg * self._exponents[i].numerator()) # res = res*self._z**exp if fak != 1: res = res * fak**exp return res
def construct_M(d, M_start=None, M_stop=None, positive_char=True): """ Gets an integer M such that R_du is rank d for all u in (Z/MZ)^*. If positive_char=False then R_du only has rank d in characteristic 0 Otherwise it has rank d in all characteristics > 2. """ if not M_start: M_start = 3 if not M_stop: # based on trial and error, should be big enough # if not we just raise an error M_stop = 20 * d for M in range(M_start, M_stop, 2): columns = [(a, int((ZZ(1) / a) % M)) for a in range(M) if gcd(a, M) == 1] M_lcm = 1 for u in range(M): if gcd(u, M) != 1: continue r_du = R_du(d, u, M, columns, a_inv=True) if r_du.rank() < d: break assert r_du.nrows() == d elt_divs = r_du.elementary_divisors() if positive_char and elt_divs[-1].prime_to_m_part(2) > 1: break M_lcm = lcm(M_lcm, elt_divs[-1]) else: return (M, M_lcm) raise ValueError( "M_stop was to small, no valid value of M < M_stop could be found")
def __get_lcm(self, input): r''' Auxiliary method for computing the lcm of a sequence. Private method for computing a common multiple of a sequence given in ``input``. This method relies on the Sage implementation of ``lcm`` and, if this fails tries to compute a least common multiple using the GCD of the sequence: .. MATH:: lcm(a_1,\ldots,a_n) = \frac{a_1 \cdots a_n}{gcd(a_1,\ldots,a_n)}. In case the computation of the gcd fails again, we just return the product of all the elements of the input. ''' try: return lcm(input) except AttributeError: ## No lcm for this class, implementing a general lcm try: ## Relying on gcd p = self.__parent res = p(1) for el in input: res = p((res * el) / gcd(res, el)) return res except AttributeError: ## Returning the product of everything return prod(input)
def _action(self,A): [a,b,c,d]=A if not c % self._level == 0 : raise ValueError,"Need A in {0}! Got: {1}".format(self.group,A) fak=1 if c<0: a=-a; b=-b; c=-c; d=-d; fak=-self._fak #fak = fak*(-1)**(self._exp_num-self._exp_den) res = 1 exp = 0 for i in range(len(self._exponents)): z = CyclotomicField(lcm(12,self._exponents[i].denominator())).gen() arg,v = eta_conjugated(a,b,c,d,self._arguments[i]) #arg2,v2 = eta_conjugated(a,b,c,d,self._arg_den) #res=self._z**(arg1*self._exp_num-arg2*self._exp_den) # exp += arg*self._exponents[i] if v<>1: res=res*v**self._exponents[i] #if v2<>1: #res=res/v2**self._exp_den res = res*z**(arg*self._exponents[i].numerator()) # res = res*self._z**exp if fak<>1: res=res*fak**exp return res
def global_height(x, prec=53): r""" Return the (correct) global height of a homogeneous coordinate. EXAMPLES:: sage: from rational_points import global_height sage: global_height([1/1,2/3,5/8]) 24 sage: F.<u> = NumberField(x^3-5) sage: P = ProjectiveSpace(F, 2) sage: global_height(P(u,u^2/5,1)) 2.92401773821287 """ k = x[0].parent() # first get rid of the denominators denom = lcm([xi.denominator() for xi in x]) x = [xi * denom for xi in x] if is_RationalField(k): return max(abs(xi) for xi in x) / gcd(x) else: finite = 1 / sum(k.ideal(xi) for xi in x).norm() d = k.degree() infinite = product( max(abs(xi.complex_embedding(prec, i)) for xi in x) for i in range(d)) return (finite * infinite)**(RR(1) / d)
def projective_height(projective_point, abs_val=lambda x: x.abs()): """The projective exponential height function (works only over the rationals?).""" denoms = [v.denominator() for v in projective_point] nums = [v.numerator() for v in projective_point] d = lcm(denoms) g = gcd(nums) return abs_val(d)/abs_val(g) * max([abs_val(v) for v in projective_point])
def weight_one_half_dim(FQM, use_reduction=True, proof=False, debug=0, local=True): N = Integer(FQM.level()) if not N % 4 == 0: return 0 m = Integer(N / Integer(4)) d = 0 for l in m.divisors(): if is_squarefree(m / l): if debug > 1: print "l = {0}".format(l) TM = FiniteQuadraticModule([2 * l], [-1 / Integer(4 * l)]) if local: dd = [0, 0] # eigenvalue 1, -1 multiplicity for p, n in lcm(FQM.level(), 4 * l).factor(): N = None TN = None J = FQM.jordan_decomposition() L = TM.jordan_decomposition() for j in xrange(1, n + 1): C = J.constituent(p**j)[0] D = L.constituent(p**j)[0] if debug > 1: print "C = {0}, D = {1}".format(C, D) if N == None and C.level() != 1: N = C elif C.level() != 1: N = N + C if TN == None and D.level() != 1: TN = D elif D.level() != 1: TN = TN + D dd1 = invariants_eps(N, TN, use_reduction, proof, debug) if debug > 1: print "dd1 = {}".format(dd1) if dd1 == [0, 0]: # the result is multiplicative # a single [0,0] as a local result # yields [0,0] in the end # and we're done here dd = [0, 0] break if dd == [0, 0]: # this is the first prime dd = dd1 else: # some basic arithmetic ;-) # 1 = 1*1 = (-1)(-1) # -1 = 1*(-1) = (-1)*1 ddtmp = copy(dd) ddtmp[0] = dd[0] * dd1[0] + dd[1] * dd1[1] ddtmp[1] = dd[0] * dd1[1] + dd[1] * dd1[0] dd = ddtmp if debug > 1: print "dd = {0}".format(dd) d += dd[0] else: d += invariants_eps(FQM, TM, use_reduction, proof, debug)[0] return d
def circle_drops(A,B): # Drops going around the unit circle for those A and B. # See http://user.math.uzh.ch/dehaye/thesis_students/Nicolas_Wider-Integrality_of_factorial_ratios.pdf # for longer description (not original, better references exist) marks = lcm(lcm(A),lcm(B)) tmp = [0 for i in range(marks)] for a in A: # print tmp for i in range(a): if gcd(i, a) == 1: tmp[i*marks/a] -= 1 for b in B: # print tmp for i in range(b): if gcd(i, b) == 1: tmp[i*marks/b] += 1 # print tmp return [sum(tmp[:j]) for j in range(marks)]
def __init__(self, A, B, r, s, k=None, number=0, ch=None, dual=False, version=1, **kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) EXAMPLE: """ self._level = lcm(A, B) G = Gamma0(self._level) if k == None: k = (QQ(r) - QQ(s)) / QQ(2) self._weight = QQ(k) if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight - QQ(1) / QQ(2)): self._half_integral_weight = 1 else: self._half_integral_weight = 0 MultiplierSystem.__init__(self, G, dimension=1, character=ch, dual=dual) number = number % 12 if not is_even(number): raise ValueError("Need to have v_eta^(2(k+r)) with r even!") self._arg_num = A self._arg_den = B self._exp_num = r self._exp_den = s self._pow = QQ((self._weight + number)) ## k+r self._k_den = self._pow.denominator() self._k_num = self._pow.numerator() self._K = CyclotomicField(12 * self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def get_PIL_integers(aux_primes, frob_polys_dict, Kgal, epsilons, embeddings, C_K): Lambda = principal_ideal_lattice(aux_primes, C_K) Lambda_basis = Lambda.basis() logger.debug("Lambda basis = {}".format(Lambda_basis)) good_basis_elements = [v for v in Lambda_basis if len(v.nonzero_positions()) > 1] relevant_aux_prime_positions = { k for v in good_basis_elements for k in v.nonzero_positions() } relevant_beta_mats = get_relevant_beta_mats( aux_primes, relevant_aux_prime_positions, frob_polys_dict ) alphas_dict = {} collapsed_beta_mats = {} for v in good_basis_elements: the_nonzero_positions = v.nonzero_positions() alphas = prod( [aux_primes[i] ** v[i] for i in the_nonzero_positions] ).gens_reduced() assert len(alphas) == 1, "uh oh" alphas_dict[v] = alphas[0] list_list_mats = [ relevant_beta_mats[aux_primes[i]] for i in the_nonzero_positions ] beta_mat_tuples = list(product(*list_list_mats)) # import pdb; pdb.set_trace() collapsed_beta_mats[v] = [ collapse_tuple(a_beta_tuple) for a_beta_tuple in beta_mat_tuples ] logger.debug("Made the alphas and beta_mat_tuples") output_dict = {} how_many_eps = len(epsilons) i = 1 for eps in epsilons: running_gcd = 0 for v in good_basis_elements: running_lcm = 1 for a_beta_mat in collapsed_beta_mats[v]: alpha_to_eps_mat = eps_exp(alphas_dict[v], eps, embeddings).matrix() pil_mat = alpha_to_eps_mat.tensor_product(a_beta_mat.parent()(1)) - ( alpha_to_eps_mat.parent()(1) ).tensor_product(a_beta_mat) pil_int = pil_mat.det() running_lcm = lcm(pil_int, running_lcm) running_gcd = gcd(running_lcm, running_gcd) output_dict[eps] = running_gcd logger.debug( "Successfully computed PIL int for {} epsilons. {} to go".format( i, how_many_eps - i ) ) i += 1 return output_dict
def weight_one_half_dim(FQM, use_reduction = True, proof = False, debug = 0, local=True): N = Integer(FQM.level()) if not N % 4 == 0: return 0 m = Integer(N/Integer(4)) d = 0 for l in m.divisors(): if is_squarefree(m/l): if debug > 1: print "l = {0}".format(l) TM = FiniteQuadraticModule([2*l],[-1/Integer(4*l)]) if local: dd = [0,0] # eigenvalue 1, -1 multiplicity for p,n in lcm(FQM.level(),4*l).factor(): N = None TN = None J = FQM.jordan_decomposition() L = TM.jordan_decomposition() for j in xrange(1,n+1): C = J.constituent(p**j)[0] D = L.constituent(p**j)[0] if debug > 1: print "C = {0}, D = {1}".format(C,D) if N == None and C.level() != 1: N = C elif C.level() != 1: N = N + C if TN == None and D.level() != 1: TN = D elif D.level() != 1: TN = TN + D dd1 = invariants_eps(N, TN, use_reduction, proof, debug) if debug > 1: print "dd1 = {}".format(dd1) if dd1 == [0,0]: # the result is multiplicative # a single [0,0] as a local result # yields [0,0] in the end # and we're done here dd = [0,0] break if dd == [0,0]: # this is the first prime dd = dd1 else: # some basic arithmetic ;-) # 1 = 1*1 = (-1)(-1) # -1 = 1*(-1) = (-1)*1 ddtmp = copy(dd) ddtmp[0] = dd[0]*dd1[0] + dd[1]*dd1[1] ddtmp[1] = dd[0]*dd1[1] + dd[1]*dd1[0] dd = ddtmp if debug > 1: print "dd = {0}".format(dd) d += dd[0] else: d += invariants_eps(FQM, TM, use_reduction, proof, debug)[0] return d
def type_three_not_momose(K, embeddings, strong_type_3_epsilons): """Compute a superset of TypeThreeNotMomosePrimes""" if len(strong_type_3_epsilons) == 0: return [], [] C_K = K.class_group() h_K = C_K.order() # Since the data in strong_type_3_epsilons also contains the # IQF L, we need to extract only the epsilons for the actual # computation. On the other hand, we also want to report the Ls # higher up the stack, so we get those as well actual_type_3_epsilons = set(strong_type_3_epsilons.keys()) type_3_fields = set(strong_type_3_epsilons.values()) if h_K == 1: return [], type_3_fields aux_gen_list = auxgens(K) bound_dict = {eps: 0 for eps in actual_type_3_epsilons} for gen_list in aux_gen_list: eps_lcm_dict = get_eps_lcm_dict( C_K, actual_type_3_epsilons, embeddings, gen_list ) for eps in actual_type_3_epsilons: bound_dict[eps] = gcd(bound_dict[eps], eps_lcm_dict[eps]) for eps in actual_type_3_epsilons: bound_dict[eps] = lcm( bound_dict[eps], strong_type_3_epsilons[eps].discriminant() ) Kgal = embeddings[0].codomain() epsilons_for_ice = {eps: "quadratic-non-constant" for eps in actual_type_3_epsilons} output = character_enumeration_filter( K, C_K, Kgal, bound_dict, epsilons_for_ice, 1000, embeddings, auto_stop_strategy=True, ) return output, type_3_fields
def get_AB_primes(q, epsilons, q_class_group_order): output_dict_AB = {} alphas = (q ** q_class_group_order).gens_reduced() assert len(alphas) == 1, "q^q_class_group_order not principal, which is very bad" alpha = alphas[0] rat_q = ZZ(q.norm()) assert rat_q.is_prime(), "somehow the degree 1 prime is not prime" for eps in epsilons: alpha_to_eps = group_ring_exp(alpha, eps) A = (alpha_to_eps - 1).norm() B = (alpha_to_eps - (rat_q ** (12 * q_class_group_order))).norm() output_dict_AB[eps] = lcm(A, B) return output_dict_AB
def roots_finite_field_fn(cycle_type, defining_polynomial): d = lcm(cycle_type) def roots_finite_field(p): Fq = FiniteField(p ** d, "a") Fq_X = PolynomialRing(Fq, "x") pol = Fq_X(defining_polynomial) # print "Got cycle_type", cycle_type # print "I compute the polynomial to be ", pol # print "I am looking for solution over ", Fq_X roots = pol.roots(multiplicities=False) assert len(roots) == len(defining_polynomial) - 1 return roots return roots_finite_field
def roots_finite_field_fn(cycle_type, defining_polynomial): d = lcm(cycle_type) def roots_finite_field(p): Fq = FiniteField(p**d, "a") Fq_X = PolynomialRing(Fq, "x") pol = Fq_X(defining_polynomial) # print "Got cycle_type", cycle_type # print "I compute the polynomial to be ", pol # print "I am looking for solution over ", Fq_X roots = pol.roots(multiplicities=False) assert len(roots) == len(defining_polynomial) - 1 return roots return roots_finite_field
def get_the_lcm(C_K, gen_list): K = C_K.number_field() epsilons = {(6, 6): "type-2"} running_lcm = 1 for q in gen_list: q_class_group_order = C_K(q).multiplicative_order() AB_lcm = get_AB_primes(q, epsilons, q_class_group_order)[(6, 6)] C_o = get_C_primes(K, q, epsilons, q_class_group_order, ordinary=True)[(6, 6)] rat_q = ZZ(q.norm()) assert ( rat_q.is_prime() ), "Somehow there is a split prime ideal whose norm is not prime!" running_lcm = lcm([running_lcm, AB_lcm, C_o, rat_q]) return running_lcm
def __get_lcm(self, input): try: return lcm(input) except AttributeError: ## No lcm for this class, implementing a general lcm try: ## Relying on gcd p = self.__conversion.poly_ring() res = p(1) for el in input: res = p((res * el) / gcd(res, el)) return res except AttributeError: ## Returning the product of everything return prod(input)
def common_denominator_of_polynomial(g, R): r""" Return the lcm of the denominators of the coefficients of this polynomial. INPUT: - ``g`` -- an univariat polynomial over a field `K` - ``R`` -- an order of `K` OUTPUT: the lcm of the denominators of the coefficients of `g` with respect to `R`. It is never zero. """ return lcm([ denominator_wrt_order(g[i], R) for i in range(g.degree() + 1) if not g[i].is_zero() ])
def get_the_lcm(C_K, embeddings, d, gen_list): type_2_eps = (6, ) * d epsilons = {type_2_eps: "type-2"} running_lcm = 1 for frak_q in gen_list: nm_q = ZZ(frak_q.absolute_norm()) q, a = nm_q.perfect_power() q_class_group_order = C_K(frak_q).multiplicative_order() ordinary_frob_polys = get_ordinary_weil_polys_from_values(q, a) ABCo_lcm = ABC_integers(embeddings, frak_q, epsilons, q_class_group_order, ordinary_frob_polys)[type_2_eps] running_lcm = lcm([running_lcm, ABCo_lcm, ZZ(nm_q)]) return running_lcm
def __init__(self, args=[1], exponents=[1], ch=None, dual=False, version=1, **kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) EXAMPLE: """ assert len(args) == len(exponents) self._level = lcm(args) G = Gamma0(self._level) k = sum([QQ(x) * QQ(1) / QQ(2) for x in exponents]) self._weight = QQ(k) if floor(self._weight - QQ(1) / QQ(2)) == ceil(self._weight - QQ(1) / QQ(2)): self._half_integral_weight = 1 else: self._half_integral_weight = 0 MultiplierSystem.__init__(self, G, dimension=1, character=ch, dual=dual) self._arguments = args self._exponents = exponents self._pow = QQ((self._weight)) ## k+r self._k_den = self._weight.denominator() self._k_num = self._weight.numerator() self._K = CyclotomicField(12 * self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2 * self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def _compute_simple_derivative_solution(self, bound=5): order = self.order() i = 0 ring = self.noetherian_ring() solution = None while ((solution is None) and (i < bound)): A, b = self._get_system_derivative(order + i, True) try: solution = self._solve_linear_system(A, b, ring) den_lcm = lcm([el.denominator() for el in solution]) solution = [(-el.numerator() * den_lcm) // el.denominator() for el in solution] except ValueError: # No solution to the system i += 1 return self.__class__(self.base(), solution + [den_lcm], self.derivate())
def order_gen(self): if self.field_poly_root_of_unity == 4: return r'\(i = \sqrt{-1}\)' elif self.hecke_ring_power_basis and self.field_poly_is_cyclotomic: return r'a primitive root of unity \(\zeta_{%s}\)' % self.field_poly_root_of_unity elif self.dim == 2: c, b, a = map(ZZ, self.field_poly) D = b**2 - 4*a*c d = D.squarefree_part() s = (D//d).isqrt() if self.hecke_ring_power_basis: k, l = ZZ(0), ZZ(1) else: k, l = map(ZZ, self.hecke_ring_numerators[1]) k = k / self.hecke_ring_denominators[1] l = l / self.hecke_ring_denominators[1] beta = vector((k - (b*l)/(2*a), ((s*l)/(2*a)).abs())) den = lcm(beta[0].denom(), beta[1].denom()) beta *= den if d == -1: Sqrt = 'i' else: Sqrt = r'\sqrt{%s}' % d if beta[1] != 1: Sqrt = r'%s%s' % (beta[1], Sqrt) if beta[0] == 0: Num = Sqrt else: Num = r'%s + %s' % (beta[0], Sqrt) if den == 1: Frac = Num else: Frac = r'\frac{1}{%s}(%s)' % (den, Num) return r'\(\beta = %s\)' % Frac elif self.hecke_ring_power_basis: return r'a root \(\beta\) of the polynomial %s' % (self.defining_polynomial()) else: if self.dim <= 5: betas = ",".join(r"\beta_%s" % (i) for i in range(1, self.dim)) else: betas = r"\beta_1,\ldots,\beta_{%s}" % (self.dim - 1) return r'a basis \(1,%s\) for the coefficient ring described below' % (betas)
def exponent(self): """ Return the exponent of this finite abelian group. OUTPUT: Integer EXAMPLES:: sage: from sage_modabvar import J0 sage: t = J0(33).hecke_operator(7) sage: G = t.kernel()[0]; G Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3 sage: G.exponent() 4 """ try: return self.__exponent except AttributeError: e = lcm(self.invariants()) self.__exponent = e return e
def _get_element_nullspace(self, M): from ajpastor.misc.bareiss import BareissAlgorithm ## We take the domain where our elements will lie parent = M.parent().base().base() ## Computing the kernell of the matrix try: lcms = [lcm([el.denominator() for el in row]) for row in M] N = Matrix(parent, [[el*lcms[i] for el in M[i]] for i in range(M.nrows())]) ba = BareissAlgorithm(parent, N, lambda p : False) ker = ba.syzygy().transpose() except Exception as e: print(e) ker = M.right_kernel_matrix() #ker = M.right_kernel_matrix() ## If the nullspace has hight dimension, we try to reduce the final vector computing zeros at the end aux = [row for row in ker] i = 1 while(len(aux) > 1): new = [] current = None for j in range(len(aux)): if(aux[j][-(i)] == 0): new += [aux[j]] elif(current is None): current = j else: new += [aux[current]*aux[j][-(i)] - aux[j]*aux[current][-(i)]] current = j aux = [el/gcd(el) for el in new] i = i+1 ## When exiting the loop, aux has just one vector sol = aux[0] ## Our solution has denominators. We clean them all p = prod([el.denominator() for el in sol]) return vector(parent, [el*p for el in sol])
def __init__(self,A,B,r,s,k=None,number=0,ch=None,dual=False,version=1,**kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) EXAMPLE: """ self._level=lcm(A,B) G = Gamma0(self._level) if k==None: k = (QQ(r)-QQ(s))/QQ(2) self._weight=QQ(k) if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)): self._half_integral_weight=1 else: self._half_integral_weight=0 MultiplierSystem.__init__(self,G,dimension=1,character=ch,dual=dual) number = number % 12 if not is_even(number): raise ValueError,"Need to have v_eta^(2(k+r)) with r even!" self._arg_num = A self._arg_den = B self._exp_num = r self._exp_den = s self._pow=QQ((self._weight+number)) ## k+r self._k_den=self._pow.denominator() self._k_num=self._pow.numerator() self._K = CyclotomicField(12*self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def num_denom_for_rational_function_field(f, R): r""" Return the numerator and denominator of a function field element. INPUT: - ``f`` -- an element of a rational function field over a field `K` - ``R`` -- an order in K OUTPUT: a pair `g, h` of univariate polynomials over `R` such that `f = g/h`. """ # F = f.parent() # A = F._ring It seems I don't need these lines B = PolynomialRing(R, 'x') g = f.numerator() a = common_denominator_of_polynomial(g, R) h = f.denominator() b = common_denominator_of_polynomial(g, R) c = lcm(a, b) return B(c * g), B(c * h)
def get_eps_lcm_dict(C_K, epsilons, embeddings, gen_list): ABCstar_lcm = {eps: 1 for eps in epsilons} for frak_q in gen_list: q_class_group_order = C_K(frak_q).multiplicative_order() nm_frak_q = frak_q.absolute_norm() frob_polys = get_weil_polys(GF(nm_frak_q)) ABCstar_lcm_one_q = ABC_integers( embeddings, frak_q, epsilons, q_class_group_order, frob_polys, ensure_C_nonzero=True, ) for eps in epsilons: ABCstar_lcm[eps] = lcm(ABCstar_lcm[eps], ABCstar_lcm_one_q[eps]) return ABCstar_lcm
def rank_fieldextension(frob_polynomial, shift=0): """ Return rank, degree of field extension, and the factorization of characteristic polynomial, into twisted cyclotomic factors, of the Frobenius action on Tate classes factorized Input:: - frob_polynomial, Frobenius polynomial for H^2 - shift, an integer, 0 by default, accounting for missing cycles, for example when frob_polynomial doesn't include the polarization """ p = frob_polynomial.list()[-1].prime_factors()[0] rank = shift k = 1 cyc_factorization = [] for fac, exp in frob_polynomial.factor(): ki = fac(fac.variables()[0] / p).is_cyclotomic(certificate=True) if ki: k = lcm(k, ki) cyc_factorization.append((fac, exp)) rank += fac.degree() * exp return rank, k, Factorization(cyc_factorization)
def order_gen(self): if self.field_poly_root_of_unity == 4: return r'\(i = \sqrt{-1}\)' elif self.hecke_ring_power_basis and self.field_poly_root_of_unity != 0: return r'a primitive root of unity \(\zeta_{%s}\)' % self.field_poly_root_of_unity elif self.dim == 2: c, b, a = map(ZZ, self.field_poly) D = b**2 - 4*a*c d = D.squarefree_part() s = (D//d).isqrt() k, l = map(ZZ, self.hecke_ring_numerators[1]) k = k / self.hecke_ring_denominators[1] l = l / self.hecke_ring_denominators[1] beta = vector((k - (b*l)/(2*a), ((s*l)/(2*a)).abs())) den = lcm(beta[0].denom(), beta[1].denom()) beta *= den if d == -1: Sqrt = 'i' else: Sqrt = r'\sqrt{%s}' % d if beta[1] != 1: Sqrt = r'%s%s' % (beta[1], Sqrt) if beta[0] == 0: Num = Sqrt else: Num = r'%s + %s' % (beta[0], Sqrt) if den == 1: Frac = Num else: Frac = r'\frac{1}{%s}(%s)' % (den, Num) return r'\(\beta = %s\)' % Frac elif self.hecke_ring_power_basis: return r'a root \(\beta\) of the polynomial %s' % (self.defining_polynomial()) else: if self.dim <= 5: betas = ",".join(r"\beta_%s" % (i) for i in range(1, self.dim)) else: betas = r"\beta_1,\ldots,\beta_{%s}" % (self.dim - 1) return r'a basis \(1,%s\) for the coefficient ring described below' % (betas)
def singular_locus(self): r""" Return the singular locus of the affine model of the curve. OUTPUT: a list of discrete valuations on the base field `k(x)` which represent the `x`-coordinates of the points where the affine model of the curve given by the defining equation of the function field may be singular. """ F = self.function_field() F0 = F.base_field() if F is F0: # the curve is the projective line return [] f = F.polynomial() # this is the defining equation, as a polynomial over F0 = k(x) # the coefficients may not be integral; we have to multiply f by # the lcm of the denominators of the coefficients c = lcm([f[i].denominator() for i in range(f.degree()+1)]) f = c*f f = f.map_coefficients(lambda c:c.numerator(), F0._ring) y = f.parent().gen() x = f.base_ring().gen() # now f is a polynomial in y over the polynomial ring in x if f.derivative(y) == 0: # F/F0 is inseparable g = f.derivative(x) D = f.resultant(g) else: Dy = f.discriminant().numerator() fx = f.derivative(x) if not fx.is_zero(): Dx = f.resultant(fx) D = Dx.gcd(Dy) else: D = Dy return [F0.valuation(g.monic()) for g, m in D.factor()]
def __init__(self,args=[1],exponents=[1],ch=None,dual=False,version=1,**kwargs): r""" Initialize the Eta multiplier system: $\nu_{\eta}^{2(k+r)}$. INPUT: - G -- Group - ch -- character - dual -- if we have the dual (in this case conjugate) - weight -- Weight (recall that eta has weight 1/2 and eta**2k has weight k. If weight<>k we adjust the power accordingly. - number -- we consider eta^power (here power should be an integer so as not to change the weight...) EXAMPLE: """ assert len(args) == len(exponents) self._level=lcm(args) G = Gamma0(self._level) k = sum([QQ(x)*QQ(1)/QQ(2) for x in exponents]) self._weight=QQ(k) if floor(self._weight-QQ(1)/QQ(2))==ceil(self._weight-QQ(1)/QQ(2)): self._half_integral_weight=1 else: self._half_integral_weight=0 MultiplierSystem.__init__(self,G,dimension=1,character=ch,dual=dual) self._arguments = args self._exponents =exponents self._pow=QQ((self._weight)) ## k+r self._k_den = self._weight.denominator() self._k_num = self._weight.numerator() self._K = CyclotomicField(12*self._k_den) self._z = self._K.gen()**self._k_num self._i = CyclotomicField(4).gen() self._fak = CyclotomicField(2*self._k_den).gen()**-self._k_num self._version = version self.is_consistent(k) # test consistency
def modn_exponent(n): """ given a nonzero integer n, returns the group exponent of (Z/nZ)* """ return lcm([(p - 1) * p**(e - 1) for (p, e) in factor(n)]) // (1 if n % 8 else 2)
def rho(self,M,silent=0,numeric=0,prec=-1): r""" The Weil representation acting on SL(2,Z). INPUT:: -``M`` -- element of SL2Z - ''numeric'' -- set to 1 to return a Matrix_complex_dense with prec=prec instead of exact - ''prec'' -- precision EXAMPLES:: sage: WR=WeilRepDiscriminantForm(1,dual=False) sage: S,T=SL2Z.gens() sage: WR.rho(S) [ [-zeta8^3 -zeta8^3] [-zeta8^3 zeta8^3], sqrt(1/2) ] sage: WR.rho(T) [ [ 1 0] [ 0 -zeta8^2], 1 ] sage: A=SL2Z([-1,1,-4,3]); WR.rho(A) [ [zeta8^2 0] [ 0 1], 1 ] sage: A=SL2Z([41,77,33,62]); WR.rho(A) [ [-zeta8^3 zeta8^3] [ zeta8 zeta8], sqrt(1/2) ] """ N=self._N; D=2*N; D2=2*D if numeric==0: K=CyclotomicField (lcm(4*self._N,8)) z=K(CyclotomicField(4*self._N).gen()) rho=matrix(K,D) else: CF = MPComplexField(prec) RF = CF.base() MS = MatrixSpace(CF,int(D),int(D)) rho = Matrix_complex_dense(MS) #arg = RF(2)*RF.pi()/RF(4*self._N) z = CF(0,RF(2)*RF.pi()/RF(4*self._N)).exp() [a,b,c,d]=M fak=1; sig=1 if c<0: # need to use the reflection # r(-A)=r(Z)r(A)sigma(Z,A) where sigma(Z,A)=-1 if c>0 sig=-1 if numeric==0: fz=CyclotomicField(4).gen() # = i else: fz=CF(0,1) # the factor is rho(Z) sigma(Z,-A) #if(c < 0 or (c==0 and d>0)): # fak=-fz #else: #sig=1 #fz=1 fak=fz a=-a; b=-b; c=-c; d=-d; A=SL2Z([a,b,c,d]) if numeric==0: chi=self.xi(A) else: chi=CF(self.xi(A).complex_embedding(prec)) if(silent>0): print "fz=",fz print "chi=",chi elif c==0: # then we use the simple formula if d<0: sig=-1 if numeric==0: fz=CyclotomicField(4).gen() else: fz=CF(0,1) fak=fz a=-a; b=-b; c=-c; d=-d; else: fak=1 for alpha in range(D): arg=(b*alpha*alpha ) % D2 if(sig==-1): malpha = (D - alpha) % D rho[malpha,alpha]=fak*z**arg else: #print "D2=",D2 #print "b=",b #print "arg=",arg rho[alpha,alpha]=z**arg return [rho,1] else: if numeric==0: chi=self.xi(M) else: chi=CF(self.xi(M).complex_embedding(prec)) Nc=gcd(Integer(D),Integer(c)) #chi=chi*sqrt(CF(Nc)/CF(D)) if( valuation(Integer(c),2)==valuation(Integer(D),2)): xc=Integer(N) else: xc=0 if(silent>0): print "c=",c print "xc=",xc print "chi=",chi for alpha in range(D): al=QQ(alpha)/QQ(D) for beta in range(D): be=QQ(beta)/QQ(D) c_div=False if(xc==0): alpha_minus_dbeta=(alpha-d*beta) % D else: alpha_minus_dbeta=(alpha-d*beta-xc) % D if(silent > 0): # and alpha==7 and beta == 7): print "alpha,beta=",alpha,',',beta print "c,d=",c,',',d print "alpha-d*beta=",alpha_minus_dbeta invers=0 for r in range(D): if((r*c - alpha_minus_dbeta) % D ==0): c_div=True invers=r break if c_div and silent > 0: print "invers=",invers print " inverse(alpha-d*beta) mod c=",invers elif(silent>0): print " no inverse!" if(c_div): y=invers if xc==0: argu=a*c*y**2+b*d*beta**2+2*b*c*y*beta else: argu=a*c*y**2+2*xc*(a*y+b*beta)+b*d*beta**2+2*b*c*y*beta argu = argu % D2 tmp1=z**argu # exp(2*pi*I*argu) if silent>0:# and alpha==7 and beta==7): print "a,b,c,d=",a,b,c,d print "xc=",xc print "argu=",argu print "exp(...)=",tmp1 print "chi=",chi print "sig=",sig if sig==-1: minus_alpha = (D - alpha) % D rho[minus_alpha,beta]=tmp1*chi else: rho[alpha,beta]=tmp1*chi #print "fak=",fak if numeric==0: return [fak*rho,sqrt(QQ(Nc)/QQ(D))] else: return [CF(fak)*rho,RF(sqrt(QQ(Nc)/QQ(D)))]
#ar = ArtinRepresentation('2.2e3_3e2.6t5.1c1') baselabel=label.split('c') a = rep.find_one({'Baselabel': baselabel[0]}) ar=ArtinRepresentation(label) outfile=open(label, 'w') cf=a['CharacterField'] cfz = ZZ(cf) nf = ar.nf() nfcc = nf.conjugacy_classes() nfcc = [int(z.order()) for z in nfcc] nfcc = lcm(nfcc) if not cfz.divides(nfcc): print "Failure "+str(cfz)+" divides "+str(nfcc)+" from "+label sys.exit() R,x = QQ['x'].objgen() pol1 = R.cyclotomic_polynomial(nfcc) K,z=NumberField(R.cyclotomic_polynomial(nfcc),'z').objgen() RR,y = K['y'].objgen() zsmall = z**(nfcc/cfz) allpols = [sum(y**k * sum(pp[k][j] * zsmall**j for j in range(len(pp[k]))) for k in range(len(pp))) for pp in ar.local_factors_table()] allroots = [myroots(pp, nfcc, z) for pp in allpols] outfile.write(str(nfcc)+"\n") outfile.write(str(allroots)+"\n") j=0 p=1
def modn_exponent(n): """ given a nonzero integer n, returns the group exponent of (Z/nZ)* """ return lcm( [ (p-1)*p**(e-1) for (p,e) in factor(n) ] ) // (1 if n%8 else 2)