def __init__(self, parent, x, check): r""" Create an element of the parent group algebra. Not intended to be called by the user; see GroupAlgebra.__call__ for examples and doctests.""" AlgebraElement.__init__(self, parent) if not hasattr(x, 'parent'): x = IntegerRing( )(x) # occasionally coercion framework tries to pass a Python int if isinstance(x, FormalSum): if check: for c, d in x._data: if d.parent() != self.parent().group(): raise TypeError("%s is not an element of group %s" % (d, self.parent().group())) self._fs = x else: self._fs = x elif self.base_ring().has_coerce_map_from(x.parent()): self._fs = self.parent()._formal_sum_module([ (x, self.parent().group()(1)) ]) elif self.parent().group().has_coerce_map_from(x.parent()): self._fs = self.parent()._formal_sum_module([ (1, self.parent().group()(x)) ]) else: raise TypeError( "Don't know how to create an element of %s from %s" % (self.parent(), x))
def __init__(self, group, base_ring=IntegerRing()): r""" See :class:`GroupAlgebra` for full documentation. EXAMPLES:: sage: GroupAlgebra(GL(3, GF(7))) Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring """ from sage.groups.group import Group from sage.groups.old import Group as OldGroup if not base_ring.is_commutative(): raise NotImplementedError("Base ring must be commutative") if not isinstance(group, (Group, OldGroup)): raise TypeError('"%s" is not a group' % group) self._group = group CombinatorialFreeModule.__init__(self, base_ring, group, prefix='', bracket=False, category=HopfAlgebrasWithBasis(base_ring)) if not base_ring.has_coerce_map_from(group) : ## some matrix groups assume that coercion is only valid to ## other matrix groups. This is a workaround ## call _element_constructor_ to coerce group elements #try : self._populate_coercion_lists_(coerce_list=[base_ring, group]) #except TypeError : # self._populate_coercion_lists_( coerce_list = [base_ring] ) else : self._populate_coercion_lists_(coerce_list=[base_ring])
def __init__(self, group, base_ring = IntegerRing()): r""" Create the given group algebra. INPUT: -- (Group) group: a generic group. -- (Ring) base_ring: a commutative ring. OUTPUT: -- a GroupAlgebra instance. EXAMPLES:: sage: from sage.algebras.group_algebra import GroupAlgebra doctest:1: DeprecationWarning:... sage: GroupAlgebra(GL(3, GF(7))) Group algebra of group "General Linear Group of degree 3 over Finite Field of size 7" over base ring Integer Ring sage: GroupAlgebra(1) Traceback (most recent call last): ... TypeError: "1" is not a group sage: GroupAlgebra(SU(2, GF(4, 'a')), IntegerModRing(12)).category() Category of group algebras over Ring of integers modulo 12 """ if not base_ring.is_commutative(): raise NotImplementedError("Base ring must be commutative") if not is_Group(group): raise TypeError('"%s" is not a group' % group) ParentWithGens.__init__(self, base_ring, category = GroupAlgebras(base_ring)) self._formal_sum_module = FormalSums(base_ring) self._group = group
def __init__(self, F, Nbound = 50,Tbound = 5, prec = 500): self._F = F self._solved = False self._disc = self._F.discriminant() self._w = self._F.maximal_order().ring_generators()[0] self._eps = self._F.units()[0] self._Phi = self._F.real_embeddings(prec=prec) a = F.gen() self.Pointxy = namedtuple('Pointxy', 'x y') if self._disc % 2 ==0 : self._changebasismatrix = 1 else: self._changebasismatrix = Matrix(IntegerRing(),2,2,[1,-1,0,2]) # We assume here that Phi orders the embeddings to that # Phi[1] is the largest self._Rw = self._Phi[1](self._w) self._Rwconj = self._Phi[0](self._w) self._used_regions = [] self._Nboundmin = 2 self._Nboundmax = Nbound self._Nboundinc = 1 self._Nbound = Nbound self._epsto = [self._F(1)] self._Dmax = self.embed(self._w) self._Tbound = Tbound self._ranget = sorted(range(-self._Tbound,self._Tbound+2),key=abs) self._M = ~Matrix(RealField(), 2, 2, [1,self._Rw,1,self._Rwconj]) self.initialize_fundom() self._master_regs = Regions(self) self._maxdepth = 0
def __init__(self,F,Nbound=_sage_const_50 ,Tbound=_sage_const_5 ): self._F=F self._solved=False self._disc=self._F.discriminant() self._w=self._F.maximal_order().ring_generators()[_sage_const_0 ] self._eps=self._F.units()[_sage_const_0 ] self._Phi=self._F.real_embeddings(prec=_sage_const_500 ) a=F.gen() self.Pointxy=namedtuple('Pointxy','x y') if(self._disc%_sage_const_2 ==_sage_const_0 ): self._changebasismatrix=_sage_const_1 else: self._changebasismatrix=Matrix(IntegerRing(),_sage_const_2 ,_sage_const_2 ,[_sage_const_1 ,-_sage_const_1 ,_sage_const_0 ,_sage_const_2 ]) # We assume here that Phi orders the embeddings to that # Phi[1] is the largest self._Rw=self._Phi[_sage_const_1 ](self._w) self._Rwconj=self._Phi[_sage_const_0 ](self._w) self._used_regions=[] self._Nboundmin=_sage_const_2 self._Nboundmax=Nbound self._Nboundinc=_sage_const_1 self._Nbound=Nbound self._epsto=[self._F(_sage_const_1 )] self._Dmax=self.embed(self._w) self._Tbound=Tbound self._ranget=sorted(range(-self._Tbound,self._Tbound+_sage_const_2 ),key=abs) self._M=Matrix(RealField(),_sage_const_2 ,_sage_const_2 ,[_sage_const_1 ,self._Rw,_sage_const_1 ,self._Rwconj]).inverse() self.initialize_fundom() self._master_regs=Regions(self) self._maxdepth=_sage_const_0
def evaluate_number(self,x,all_vector=True): y = self.fundom_rep(x) d = x - y P = self.embed(y) vv = [[reg[1][0]+d,reg[1][1]] for reg in filter(lambda reg: reg[2].contains_point(P),self._used_regions)] if all_vector: return vv else: return vv[IntegerRing().random_element(len(vv))]
def __init__(self, parent, x, check): r""" Create an element of the parent group algebra. Not intended to be called by the user; see GroupAlgebra.__call__ for examples and doctests.""" AlgebraElement.__init__(self, parent) if not hasattr(x, 'parent'): x = IntegerRing()(x) # occasionally coercion framework tries to pass a Python int if isinstance(x, FormalSum): if check: for c,d in x._data: if d.parent() != self.parent().group(): raise TypeError("%s is not an element of group %s" % (d, self.parent().group())) self._fs = x else: self._fs = x elif self.base_ring().has_coerce_map_from(x.parent()): self._fs = self.parent()._formal_sum_module([ (x, self.parent().group()(1)) ]) elif self.parent().group().has_coerce_map_from(x.parent()): self._fs = self.parent()._formal_sum_module([ (1, self.parent().group()(x)) ]) else: raise TypeError("Don't know how to create an element of %s from %s" % (self.parent(), x))
def get_regions(self,B): regions=self._regions if(B>self._N): F=self._F eps=self._eps newelts=dict([(IntegerRing()(n),[I.gens_reduced()[_sage_const_0 ] for I in v if I.is_principal()]) for n,v in self._F.ideals_of_bdd_norm(B-_sage_const_1 ).iteritems() if n>=self._N]) self._N=B for nn in range(len(self._epsto),B): self._epsto.append(self._epsto[nn-_sage_const_1 ]*eps) for nn,v in newelts.iteritems(): assert not regions.has_key(nn) regions[nn]=[] for q in v: invden=_sage_const_1 /q invden_red=self.fundom_rep(invden) q0=invden_red-invden m_invden_red=self.fundom_rep(-invden) m_q0=m_invden_red+invden a,b=self._parent._change_basis(invden_red) am,bm=self._parent._change_basis(m_invden_red) regions[nn].extend([[invden_red,[q0,q],Region(self.embed(invden_red),RealField()(_sage_const_1 /nn)),[a,b],nn],[m_invden_red,[m_q0,-q],Region(self.embed(m_invden_red),RealField()(_sage_const_1 /nn)),[am,bm],nn]]) for jj in range(_sage_const_1 ,nn): x=self._epsto[jj]*invden x_red=self.fundom_rep(x) x_red_minus=self.fundom_rep(-x_red) regs=regions[nn] if(x_red==regs[_sage_const_0 ][_sage_const_0 ] or x_red_minus==regs[_sage_const_0 ][_sage_const_0 ]): continue q0_minus=x_red_minus+x q0=x_red-x q1=_sage_const_1 /x a,b=self._parent._change_basis(x_red) am,bm=self._parent._change_basis(x_red_minus) regions[nn].extend([[x_red,[q0,q1],Region(self.embed(x_red),RealField()(_sage_const_1 /nn)),[a,b],nn],[x_red_minus,[q0_minus,-q1],Region(self.embed(x_red_minus),RealField()(_sage_const_1 /nn)),[am,bm],nn]]) else: # We have all the required regions pass return [reg for nn,lst in regions.iteritems() if nn<B for reg in lst]
def hilbert_class_polynomial(D, algorithm=None): r""" Return the Hilbert class polynomial for discriminant `D`. INPUT: - ``D`` (int) -- a negative integer congruent to 0 or 1 modulo 4. - ``algorithm`` (string, default None). OUTPUT: (integer polynomial) The Hilbert class polynomial for the discriminant `D`. ALGORITHM: - If ``algorithm`` = "arb" (default): Use Arb's implementation which uses complex interval arithmetic. - If ``algorithm`` = "sage": Use complex approximations to the roots. - If ``algorithm`` = "magma": Call the appropriate Magma function (if available). AUTHORS: - Sage implementation originally by Eduardo Ocampo Alvarez and AndreyTimofeev - Sage implementation corrected by John Cremona (using corrected precision bounds from Andreas Enge) - Magma implementation by David Kohel EXAMPLES:: sage: hilbert_class_polynomial(-4) x - 1728 sage: hilbert_class_polynomial(-7) x + 3375 sage: hilbert_class_polynomial(-23) x^3 + 3491750*x^2 - 5151296875*x + 12771880859375 sage: hilbert_class_polynomial(-37*4) x^2 - 39660183801072000*x - 7898242515936467904000000 sage: hilbert_class_polynomial(-37*4, algorithm="magma") # optional - magma x^2 - 39660183801072000*x - 7898242515936467904000000 sage: hilbert_class_polynomial(-163) x + 262537412640768000 sage: hilbert_class_polynomial(-163, algorithm="sage") x + 262537412640768000 sage: hilbert_class_polynomial(-163, algorithm="magma") # optional - magma x + 262537412640768000 TESTS:: sage: all([hilbert_class_polynomial(d, algorithm="arb") == \ ....: hilbert_class_polynomial(d, algorithm="sage") \ ....: for d in range(-1,-100,-1) if d%4 in [0,1]]) True """ if algorithm is None: algorithm = "arb" D = Integer(D) if D >= 0: raise ValueError("D (=%s) must be negative" % D) if not (D % 4 in [0, 1]): raise ValueError("D (=%s) must be a discriminant" % D) if algorithm == "arb": import sage.libs.arb.arith return sage.libs.arb.arith.hilbert_class_polynomial(D) if algorithm == "magma": magma.eval("R<x> := PolynomialRing(IntegerRing())") f = str(magma.eval("HilbertClassPolynomial(%s)" % D)) return IntegerRing()['x'](f) if algorithm != "sage": raise ValueError("%s is not a valid algorithm" % algorithm) from sage.quadratic_forms.binary_qf import BinaryQF_reduced_representatives from sage.rings.all import RR, ComplexField from sage.functions.all import elliptic_j # get all primitive reduced quadratic forms, (necessary to exclude # imprimitive forms when D is not a fundamental discriminant): rqf = BinaryQF_reduced_representatives(D, primitive_only=True) # compute needed precision # # NB: [https://arxiv.org/abs/0802.0979v1], quoting Enge (2006), is # incorrect. Enge writes (2009-04-20 email to John Cremona) "The # source is my paper on class polynomials # [https://hal.inria.fr/inria-00001040] It was pointed out to me by # the referee after ANTS that the constant given there was # wrong. The final version contains a corrected constant on p.7 # which is consistent with your example. It says: # "The logarithm of the absolute value of the coefficient in front # of X^j is bounded above by # # log (2*k_2) * h + pi * sqrt(|D|) * sum (1/A_i) # # independently of j", where k_2 \approx 10.163. h = len(rqf) # class number c1 = 3.05682737291380 # log(2*10.63) c2 = sum([1 / RR(qf[0]) for qf in rqf], RR(0)) prec = c2 * RR(3.142) * RR(D).abs().sqrt() + h * c1 # bound on log prec = prec * 1.45 # bound on log_2 (1/log(2) = 1.44..) prec = 10 + prec.ceil() # allow for rounding error # set appropriate precision for further computing Dsqrt = D.sqrt(prec=prec) R = ComplexField(prec)['t'] t = R.gen() pol = R(1) for qf in rqf: a, b, c = list(qf) tau = (b + Dsqrt) / (a << 1) pol *= (t - elliptic_j(tau)) coeffs = [cof.real().round() for cof in pol.coefficients(sparse=False)] return IntegerRing()['x'](coeffs)
def GroupAlgebra(G, R=IntegerRing()): """ Return the group algebra of `G` over `R`. INPUT: - `G` -- a group - `R` -- (default: `\ZZ`) a ring EXAMPLES: The *group algebra* `A=RG` is the space of formal linear combinations of elements of `G` with coefficients in `R`:: sage: G = DihedralGroup(3) sage: R = QQ sage: A = GroupAlgebra(G, R); A Algebra of Dihedral group of order 6 as a permutation group over Rational Field sage: a = A.an_element(); a () + 4*(1,2,3) + 2*(1,3) This space is endowed with an algebra structure, obtained by extending by bilinearity the multiplication of `G` to a multiplication on `RG`:: sage: A in Algebras True sage: a * a 5*() + 8*(2,3) + 8*(1,2) + 8*(1,2,3) + 16*(1,3,2) + 4*(1,3) :func:`GroupAlgebra` is just a short hand for a more general construction that covers, e.g., monoid algebras, additive group algebras and so on:: sage: G.algebra(QQ) Algebra of Dihedral group of order 6 as a permutation group over Rational Field sage: GroupAlgebra(G,QQ) is G.algebra(QQ) True sage: M = Monoids().example(); M An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') sage: M.algebra(QQ) Algebra of An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd') over Rational Field See the documentation of :mod:`sage.categories.algebra_functor` for details. TESTS:: sage: GroupAlgebra(1) Traceback (most recent call last): ... ValueError: 1 is not a magma or additive magma sage: GroupAlgebra(GL(3, GF(7))) Algebra of General Linear Group of degree 3 over Finite Field of size 7 over Integer Ring sage: GroupAlgebra(GL(3, GF(7)), QQ) Algebra of General Linear Group of degree 3 over Finite Field of size 7 over Rational Field """ if not (G in Magmas() or G in AdditiveMagmas()): raise ValueError("%s is not a magma or additive magma" % G) if not R in Rings(): raise ValueError("%s is not a ring" % R) return G.algebra(R)
from sage.rings.power_series_ring import PowerSeriesRing from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.arith.all import divisors, prime_divisors, is_square, euler_phi, gcd from sage.rings.all import Integer, IntegerRing, RationalField from sage.groups.old import AbelianGroup from sage.structure.element import MultiplicativeGroupElement from sage.structure.formal_sum import FormalSum from sage.rings.finite_rings.integer_mod import Mod from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.matrix.constructor import matrix from sage.modules.free_module import FreeModule from sage.misc.misc import union import weakref ZZ = IntegerRing() QQ = RationalField() _cache = {} def EtaGroup(level): r""" Create the group of eta products of the given level. EXAMPLES:: sage: EtaGroup(12) Group of eta products on X_0(12) sage: EtaGroup(1/2) Traceback (most recent call last):