def _to_bivariate_polynomial(self, f): """ Convert ``f`` from a univariate polynomial over the rational function field into a bivariate polynomial and a denominator. INPUT: - ``f`` -- a univariate polynomial over self. OUTPUT: - bivariate polynomial, denominator EXAMPLES:: sage: R.<t> = FunctionField(GF(7)) sage: S.<X> = R[] sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) sage: R._to_bivariate_polynomial(f) (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3) """ v = f.list() from sage.rings.arith import LCM denom = LCM([a.denominator() for a in v]) S = denom.parent() x, t = S.base_ring()['%s,%s' % (f.parent().variable_name(), self.variable_name())].gens() phi = S.hom([t]) return sum([ phi((denom * v[i]).numerator()) * x**i for i in range(len(v)) ]), denom
def _to_bivariate_polynomial(self, f): """ Convert ``f`` from a univariate polynomial over the rational function field into a bivariate polynomial and a denominator. INPUT: - ``f`` -- a univariate polynomial over self. OUTPUT: - bivariate polynomial, denominator EXAMPLES:: sage: R.<t> = FunctionField(GF(7)) sage: S.<X> = R[] sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3) sage: R._to_bivariate_polynomial(f) (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3) """ v = f.list() from sage.rings.arith import LCM denom = LCM([a.denominator() for a in v]) S = denom.parent() x,t = S.base_ring()['%s,%s'%(f.parent().variable_name(),self.variable_name())].gens() phi = S.hom([t]) return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom
def symmetrizer(self): """ Return the symmetrizer of ``self``. EXAMPLES:: sage: cm = CartanMatrix([[2,-5],[-2,2]]) sage: cm.symmetrizer() Finite family {0: 2, 1: 5} TESTS: Check that the symmetrizer computed from the Cartan matrix agrees with the values given by the Cartan type:: sage: ct = CartanType(['B',4,1]) sage: ct.symmetrizer() Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1} sage: ct.cartan_matrix().symmetrizer() Finite family {0: 2, 1: 2, 2: 2, 3: 2, 4: 1} """ sym = self.is_symmetrizable(True) if not sym: raise ValueError("the Cartan matrix is not symmetrizable") iset = self.index_set() # The result from is_symmetrizable needs to be scaled # to integer coefficients from sage.rings.arith import LCM from sage.rings.all import QQ scalar = LCM(map(lambda x: QQ(x).denominator(), sym)) return Family( {iset[i]: ZZ(val*scalar) for i, val in enumerate(sym)} )
def unit_group_exponent(self): """ EXAMPLES:: sage: R = IntegerModRing(17) sage: R.unit_group_exponent() 16 sage: R = IntegerModRing(18) sage: R.unit_group_exponent() 6 """ if self.__unit_group_exponent != None: return self.__unit_group_exponent a = [] for p, r in self.factored_order(): if p != 2: a.append((p - 1) * (p**(r - 1))) # phi(p**r) else: # p=2 if r == 2: a.append(2) elif r > 2: a.append(2**(r - 2)) #endif #endfor self.__unit_group_exponent = int(LCM(a)) return self.__unit_group_exponent
def __init__(self, ray_class_group, base_ring): names = tuple(["chi%i" % i for i in range(ray_class_group.ngens())]) if base_ring is None: from sage.rings.number_field.number_field import CyclotomicField from sage.rings.arith import LCM base_ring = CyclotomicField(LCM(ray_class_group.gens_orders())) DualAbelianGroup_class.__init__(self, ray_class_group, names, base_ring) """ ray_class_group accessible as self.group() """
def __init__(self, ray_class_group, base_ring): names = tuple(["chi%i" % i for i in range(ray_class_group.ngens())]) if base_ring is None: from sage.rings.number_field.number_field import CyclotomicField # FIXME: following is deprecated starting from sage 7.1 # replace by from sage.arith.all import LCM from sage.rings.arith import LCM base_ring = CyclotomicField(LCM(ray_class_group.gens_orders())) DualAbelianGroup_class.__init__(self, ray_class_group, names, base_ring) """ ray_class_group accessible as self.group() """
def __init__(self, G, names="X", bse_ring=None): """ If G has invariants invs = [n1,...,nk] then the default base_ring is CyclotoomicField(N), where N = LCM(n1,...,nk). """ if bse_ring == None: base_ring = CyclotomicField(LCM(G.invariants())) else: base_ring = bse_ring self.__group = G self._assign_names(names) self._base_ring = base_ring
def padic_height(self, prec=20): r""" Returns the canonical `p`-adic height function on the original curve. INPUT: - ``prec`` - the `p`-adic precision, default is 20. OUTPUT: - A function that can be evaluated on rational points of `E`. EXAMPLES:: sage: e = EllipticCurve('130a1') sage: eq = e.tate_curve(5) sage: h = eq.padic_height(prec=10) sage: P=e.gens()[0] sage: h(P) 2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + O(5^8) Check that it is a quadratic function:: sage: h(3*P)-3^2*h(P) O(5^8) """ if not self.is_split(): raise NotImplementedError, "The curve must have split multiplicative reduction" p = self._p # we will have to do it properly with David Harvey's _multiply_point(E, R, Q) n = LCM(self._E.tamagawa_numbers()) * (p - 1) # this function is a closure, I don't see how to doctest it (PZ) def _height(P, check=True): if check: assert P.curve( ) == self._E, "the point P must lie on the curve from which the height function was created" Q = n * P cQ = denominator(Q[0]) uQ = self.lift(Q, prec=prec) si = self.__padic_sigma_square(uQ, prec=prec) nn = self._q.valuation() qEu = self._q / p**nn return -(log(si * self._Csquare() / cQ) + log(uQ)**2 / log(qEu)) / n**2 return _height
def order(self): r""" Finds the order of the given S-ideal class. EXAMPLES:: sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: J = K.ideal(7,a) sage: G = K.ideal(3,a+1) sage: CS(I).order() 1 sage: CS(J).order() 1 sage: CS(G).order() 2 """ return LCM([e.additive_order() for e in self.list()])
def unit_group_exponent(self): """ EXAMPLES:: sage: R = IntegerModRing(17) sage: R.unit_group_exponent() 16 sage: R = IntegerModRing(18) sage: R.unit_group_exponent() 6 """ a = [] for p, r in self.factored_order(): if p != 2: a.append((p - 1) * (p**(r - 1))) # phi(p**r) elif r == 2: # p=2 from this point on a.append(2) elif r > 2: a.append(2**(r - 2)) return int(LCM(a))
def spol(f, g): """ Computes the S-polynomial of f and g. INPUT: - ``f,g`` - polynomials OUTPUT: - The S-polynomial of f and g. EXAMPLES:: sage: R.<x,y,z> = PolynomialRing(QQ,3) sage: from sage.rings.polynomial.toy_buchberger import spol sage: spol(x^2 - z - 1, z^2 - y - 1) x^2*y - z^3 + x^2 - z^2 """ fg_lcm = LCM(LM(f), LM(g)) return fg_lcm // LT(f) * f - fg_lcm // LT(g) * g
def select(P): """ The normal selection strategy INPUT: - ``P`` - a list of critical pairs OUTPUT: an element of P EXAMPLES:: sage: from sage.rings.polynomial.toy_buchberger import select sage: R.<x,y,z> = PolynomialRing(QQ,3, order='lex') sage: ps = [x^3 - z -1, z^3 - y - 1, x^5 - y - 2] sage: pairs = [[ps[i],ps[j]] for i in range(3) for j in range(i+1,3)] sage: select(pairs) [x^3 - z - 1, -y + z^3 - 1] """ return min(P, key=lambda fi_fj: LCM(LM(fi_fj[0]), LM(fi_fj[1])).total_degree())
def order(self): """ Return the order of this element. OUTPUT: An integer or ``infinity``. EXAMPLES:: sage: F = AbelianGroup(3,[7,8,9]) sage: Fd = F.dual_group() sage: A,B,C = Fd.gens() sage: (B*C).order() 72 sage: F = AbelianGroup(3,[7,8,9]); F Multiplicative Abelian group isomorphic to C7 x C8 x C9 sage: F.gens()[2].order() 9 sage: a,b,c = F.gens() sage: (b*c).order() 72 sage: G = AbelianGroup(3,[7,8,9]) sage: type((G.0 * G.1).order())==Integer True """ M = self.parent() order = M.gens_orders() L = self.exponents() N = LCM([ order[i] / GCD(order[i], L[i]) for i in range(len(order)) if L[i] != 0 ]) if N == 0: return infinity else: return ZZ(N)
def order(self): """ Returns the (finite) order of this element or Infinity if this element does not have finite order. EXAMPLES:: sage: F = AbelianGroup(3,[7,8,9]); F Multiplicative Abelian Group isomorphic to C7 x C8 x C9 sage: F.gens()[2].order() 9 sage: a,b,c = F.gens() sage: (b*c).order() 72 sage: G = AbelianGroup(3,[7,8,9]) sage: type((G.0 * G.1).order())==Integer True """ M = self.parent() if self == M(1): return Integer(1) invs = M.invariants() if self in M.gens(): o = invs[list(M.gens()).index(self)] if o == 0: return infinity return o L = list(self.list()) N = LCM([ invs[i] // GCD(invs[i], L[i]) for i in range(len(invs)) if L[i] != 0 ]) if N == 0: return infinity else: return Integer(N)
def update(G, B, h): """ Update ``G`` using the list of critical pairs ``B`` and the polynomial ``h`` as presented in [BW93]_, page 230. For this, Buchberger's first and second criterion are tested. This function implements the Gebauer-Moeller Installation. INPUT: - ``G`` - an intermediate Groebner basis - ``B`` - a list of critical pairs - ``h`` - a polynomial OUTPUT: a tuple of an intermediate Groebner basis and a list of critical pairs EXAMPLES:: sage: from sage.rings.polynomial.toy_buchberger import update sage: R.<x,y,z> = PolynomialRing(QQ,3) sage: set_verbose(0) sage: update(set(),set(),x*y*z) ({x*y*z}, set()) sage: G,B = update(set(),set(),x*y*z-1) sage: G,B = update(G,B,x*y^2-1) sage: G,B ({x*y*z - 1, x*y^2 - 1}, {(x*y^2 - 1, x*y*z - 1)}) """ R = h.parent() C = set([(h, g) for g in G]) D = set() while C != set(): (h, g) = C.pop() lcm_divides = lambda rhs: R.monomial_divides(LCM(LM(h), LM(rhs[1])), LCM(LM(h), LM(g))) if R.monomial_pairwise_prime(LM(h),LM(g)) or \ (\ not any( lcm_divides(f) for f in C ) \ and not any( lcm_divides(f) for f in D ) \ ): D.add((h, g)) E = set() while D != set(): (h, g) = D.pop() if not R.monomial_pairwise_prime(LM(h), LM(g)): E.add((h, g)) B_new = set() while B != set(): g1, g2 = B.pop() if not R.monomial_divides( LM(h), LCM(LM(g1),LM(g2)) ) or \ R.monomial_lcm(LM(g1),LM( h)) == LCM(LM(g1),LM(g2)) or \ R.monomial_lcm(LM( h),LM(g2)) == LCM(LM(g1),LM(g2)) : B_new.add((g1, g2)) B_new = B_new.union(E) G_new = set() while G != set(): g = G.pop() if not R.monomial_divides(LM(h), LM(g)): G_new.add(g) G_new.add(h) return G_new, B_new
def level(self): r""" Determines the level of the quadratic form over a PID, which is a generator for the smallest ideal `N` of `R` such that N * (the matrix of 2*Q)^(-1) is in R with diagonal in 2*R. Over `\ZZ` this returns a non-negative number. (Caveat: This always returns the unit ideal when working over a field!) EXAMPLES:: sage: Q = QuadraticForm(ZZ, 2, range(1,4)) sage: Q.level() 8 sage: Q1 = QuadraticForm(QQ, 2, range(1,4)) sage: Q1.level() # random UserWarning: Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!? 1 sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7]) sage: Q.level() 420 """ ## Try to return the cached level try: return self.__level except AttributeError: ## Check that the base ring is a PID if not is_PrincipalIdealDomain(self.base_ring()): raise TypeError("Oops! The level (as a number) is only defined over a Principal Ideal Domain. Try using level_ideal().") ## Warn the user if the form is defined over a field! if self.base_ring().is_field(): warn("Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?") #raise RuntimeError, "Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?" ## Check invertibility and find the inverse try: mat_inv = self.matrix()**(-1) except ZeroDivisionError: raise TypeError("Oops! The quadratic form is degenerate (i.e. det = 0). =(") ## Compute the level inv_denoms = [] for i in range(self.dim()): for j in range(i, self.dim()): if (i == j): inv_denoms += [denominator(mat_inv[i,j] / 2)] else: inv_denoms += [denominator(mat_inv[i,j])] lvl = LCM(inv_denoms) lvl = ideal(self.base_ring()(lvl)).gen() ############################################################## ## To do this properly, the level should be the inverse of the ## fractional ideal (over R) generated by the entries whose ## denominators we take above. =) ############################################################## ## Normalize the result over ZZ if self.base_ring() == IntegerRing(): lvl = abs(lvl) ## Cache and return the level self.__level = lvl return lvl
def BCHCode(n,delta,F,b=0): r""" A 'Bose-Chaudhuri-Hockenghem code' (or BCH code for short) is the largest possible cyclic code of length n over field F=GF(q), whose generator polynomial has zeros (which contain the set) `Z = \{a^{b},a^{b+1}, ..., a^{b+delta-2}\}`, where a is a primitive `n^{th}` root of unity in the splitting field `GF(q^m)`, b is an integer `0\leq b\leq n-delta+1` and m is the multiplicative order of q modulo n. (The integers `b,...,b+delta-2` typically lie in the range `1,...,n-1`.) The integer `delta \geq 1` is called the "designed distance". The length n of the code and the size q of the base field must be relatively prime. The generator polynomial is equal to the least common multiple of the minimal polynomials of the elements of the set `Z` above. Special cases are b=1 (resulting codes are called 'narrow-sense' BCH codes), and `n=q^m-1` (known as 'primitive' BCH codes). It may happen that several values of delta give rise to the same BCH code. The largest one is called the Bose distance of the code. The true minimum distance, d, of the code is greater than or equal to the Bose distance, so `d\geq delta`. EXAMPLES:: sage: FF.<a> = GF(3^2,"a") sage: x = PolynomialRing(FF,"x").gen() sage: L = [b.minpoly() for b in [a,a^2,a^3]]; g = LCM(L) sage: f = x^(8)-1 sage: g.divides(f) True sage: C = codes.CyclicCode(8,g); C Linear code of length 8, dimension 4 over Finite Field of size 3 sage: C.minimum_distance() 4 sage: C = codes.BCHCode(8,3,GF(3),1); C Linear code of length 8, dimension 4 over Finite Field of size 3 sage: C.minimum_distance() 4 sage: C = codes.BCHCode(8,3,GF(3)); C Linear code of length 8, dimension 5 over Finite Field of size 3 sage: C.minimum_distance() 3 sage: C = codes.BCHCode(26, 5, GF(5), b=1); C Linear code of length 26, dimension 10 over Finite Field of size 5 """ from sage.misc.misc import srange q = F.order() R = IntegerModRing(n) m = R(q).multiplicative_order() FF = GF(q**m,"z") z = FF.gen() e = z.multiplicative_order()/n a = z**e # order n P = PolynomialRing(F,"x") x = P.gen() cosets = Set([]) for i in srange(b,b+delta-1): cosets = cosets.union(Set(cyclotomic_cosets(q, n, i))) L0 = [a**j for j in cosets] L1 = [P(ai.minpoly()) for ai in L0] g = P(LCM(L1)) #print cosets, "\n", g, "\n", (x**n-1).factor(), "\n", L1, "\n", g.divides(x**n-1) if not(g.divides(x**n-1)): raise ValueError, "BCH codes does not exist with the given input." return CyclicCodeFromGeneratingPolynomial(n,g)