Example #1
0
    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))
Example #2
0
    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])
Example #3
0
    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
Example #5
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))]
Example #7
0
    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))
Example #8
0
    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]
Example #9
0
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)
Example #10
0
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)
Example #11
0
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):