def number_of_classes(self, invertible=False, q=None):
        """
        Return the number of similarity classes of matrices of type ``self``.

        IMPUT:

        - ``invertible`` -- Boolean; return number of invertible classes if set
          to ``True``

        - ``q`` -- An integer or an indeterminate

        EXAMPLES::

            sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
            sage: tau.number_of_classes()
            1/2*q^2 - 1/2*q
        """
        if q is None:
            q = ZZ["q"].gen()
        if self.size() == 0:
            return q.parent().one()
        list_of_degrees = [PT.degree() for PT in self]
        maximum_degree = max(list_of_degrees)
        numerator = prod(
            [
                prod([primitives(d + 1, invertible=invertible, q=q) - i for i in range(list_of_degrees.count(d + 1))])
                for d in range(maximum_degree)
            ]
        )
        tau_list = list(self)
        D = dict((i, tau_list.count(i)) for i in tau_list)
        denominator = reduce(mul, [factorial(D[primary_type]) for primary_type in D.keys()])
        return numerator / denominator
def Pall_mass_density_at_odd_prime(self, p):
    """
    Returns the local representation density of a form (for
    representing itself) defined over `ZZ`, at some prime `p>2`.

    REFERENCES:
        Pall's article "The Weight of a Genus of Positive n-ary Quadratic Forms"
        appearing in Proc. Symp. Pure Math. VIII (1965), pp95--105.

    INPUT:
        `p` -- a prime number > 2.

    OUTPUT:
        a rational number.

    EXAMPLES::

        sage: Q = QuadraticForm(ZZ, 3, [1,0,0,1,0,1])
        sage: Q.Pall_mass_density_at_odd_prime(3)
        [(0, Quadratic form in 3 variables over Integer Ring with coefficients:
        [ 1 0 0 ]
        [ * 1 0 ]
        [ * * 1 ])] [(0, 3, 8)] [8/9] 8/9
        8/9
    """
    ## Check that p is a positive prime -- unnecessary since it's done implicitly in the next step. =)
    if p<=2:
        raise TypeError, "Oops!  We need p to be a prime > 2."

    ## Step 1: Obtain a p-adic (diagonal) local normal form, and
    ## compute the invariants for each Jordan block.
    jordan_list = self.jordan_blocks_by_scale_and_unimodular(p)
    modified_jordan_list = [(a, Q.dim(), Q.det())  for (a,Q) in jordan_list]     ## List of pairs (scale, det)
    #print jordan_list
    #print modified_jordan_list

    ## Step 2: Compute the list of local masses for each Jordan block
    jordan_mass_list = []
    for (s,n,d) in modified_jordan_list:
        generic_factor = prod([1 - p**(-2*j)  for j in range(1, floor((n-1)/2)+1)])
        #print "generic factor: ", generic_factor
        if (n % 2 == 0):
            m = n/2
            generic_factor *= (1 + legendre_symbol(((-1)**m) * d, p) * p**(-m))
        #print "jordan_mass: ", generic_factor
        jordan_mass_list = jordan_mass_list + [generic_factor]

    ## Step 3: Compute the local mass $\al_p$ at p.
        MJL = modified_jordan_list
    s = len(modified_jordan_list)
    M = [sum([MJL[j][1]  for j in range(i, s)])  for i in range(s-1)]    ## Note: It's s-1 since we don't need the last M.
    #print "M = ", M
    nu = sum([M[i] * MJL[i][0] * MJL[i][1]  for i in range(s-1)]) - ZZ(sum([J[0] * J[1] * (J[1]-1)  for J in MJL]))/ZZ(2)
    p_mass = prod(jordan_mass_list)
    p_mass *= 2**(s-1) * p**nu

    print jordan_list, MJL, jordan_mass_list, p_mass

    ## Return the result
    return p_mass
Beispiel #3
0
def q_catalan_number(n,p=None):
    """
    Returns the `q`-Catalan number of index `n`.

    If `p` is unspecified, then it defaults to using the generator `q` for
    a univariate polynomial ring over the integers.

    There are several `q`-Catalan numbers. This procedure
    returns the one which can be written using the `q`-binomial coefficients.

    EXAMPLES::

        sage: from sage.combinat.q_analogues import q_catalan_number
        sage: q_catalan_number(4)
        q^12 + q^10 + q^9 + 2*q^8 + q^7 + 2*q^6 + q^5 + 2*q^4 + q^3 + q^2 + 1
        sage: p = ZZ['p'].0
        sage: q_catalan_number(4,p)
        p^12 + p^10 + p^9 + 2*p^8 + p^7 + 2*p^6 + p^5 + 2*p^4 + p^3 + p^2 + 1

    The `q`-Catalan number of index `n` is only defined for `n` a
    nonnegative integer (:trac:`11411`)::

        sage: q_catalan_number(-2)
        Traceback (most recent call last):
        ...
        ValueError: Argument (-2) must be a nonnegative integer.
    """
    if n in ZZ and n >= 0:
        return prod(q_int(j, p) for j in range(n+2, 2*n+1)) / prod(q_int(j, p) for j in range(2,n+1))
    else:
        raise ValueError("Argument (%s) must be a nonnegative integer." %n)
Beispiel #4
0
def q_binomial(n,k,p=None):
    """
    Returns the ``q``-binomial coefficient.

    If ``p`` is unspecified, then it defaults to using the generator ``q`` for
    a univariate polynomial ring over the integers.

    EXAMPLES::

        sage: import sage.combinat.q_analogues as q_analogues
        sage: q_analogues.q_binomial(4,2)
        q^4 + q^3 + 2*q^2 + q + 1
        sage: p = ZZ['p'].0
        sage: q_analogues.q_binomial(4,2,p)
        p^4 + p^3 + 2*p^2 + p + 1

    The ``q``-analogue of ``binomial(n,k)`` is currently only defined for
    ``n`` a nonnegative integer, it is zero for negative k  (trac #11411)::

        sage: q_analogues.q_binomial(5, -1)
        0
    """
    if not (n in ZZ and k in ZZ):
        raise ValueError, "Argument (%s, %s) must be integers."%(n, k)
    if n < 0:
        raise NotImplementedError
    if 0 <= k and k <= n:
        k=min(k, n-k)
        return (prod(q_int(j, p) for j in range(n-k+1, n+1)) /
                prod(q_int(j, p) for j in range(1, k+1)))
    else:
        return 0
Beispiel #5
0
def DuadicCodeOddPair(F,S1,S2):
    """
    Constructs the "odd pair" of duadic codes associated to the
    "splitting" S1, S2 of n.

    .. warning::

       Maybe the splitting should be associated to a sum of
       q-cyclotomic cosets mod n, where q is a *prime*.

    EXAMPLES::

        sage: from sage.coding.code_constructions import is_a_splitting
        sage: n = 11; q = 3
        sage: C = cyclotomic_cosets(q,n); C
        [[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]
        sage: S1 = C[1]
        sage: S2 = C[2]
        sage: is_a_splitting(S1,S2,11)
        (True, 2)
        sage: DuadicCodeOddPair(GF(q),S1,S2)
        (Linear code of length 11, dimension 6 over Finite Field of size 3,
         Linear code of length 11, dimension 6 over Finite Field of size 3)

    This is consistent with Theorem 6.1.3 in [HP]_.
    """
    n = max(S1+S2)+1
    if not(is_a_splitting(S1,S2,n)):
        raise TypeError, "%s, %s must be a splitting of %s."%(S1,S2,n)
    q = F.order()
    k = Mod(q,n).multiplicative_order()
    FF = GF(q**k,"z")
    z = FF.gen()
    zeta = z**((q**k-1)/n)
    P1 = PolynomialRing(FF,"x")
    x = P1.gen()
    g1 = prod([x-zeta**i for i in S1+[0]])
    g2 = prod([x-zeta**i for i in S2+[0]])
    j = sum([x**i/n for i in range(n)])
    P2 = PolynomialRing(F,"x")
    x = P2.gen()
    coeffs1 = [lift2smallest_field(c)[0] for c in (g1+j).coeffs()]
    coeffs2 = [lift2smallest_field(c)[0] for c in (g2+j).coeffs()]
    gg1 = P2(coeffs1)
    gg2 = P2(coeffs2)
    C1 = CyclicCodeFromGeneratingPolynomial(n,gg1)
    C2 = CyclicCodeFromGeneratingPolynomial(n,gg2)
    return C1,C2
Beispiel #6
0
 def _gap_init_(self):
     r"""
     Return string that defines corresponding abelian group in GAP.
     
     EXAMPLES::
     
         sage: G = AbelianGroup([2,3,9])
         sage: G._gap_init_()
         'AbelianGroup([2, 3, 9])'
         sage: gap(G)
         Group( [ f1, f2, f3 ] )
     
     Only works for finite groups.
     
     ::
     
         sage: G = AbelianGroup(3,[0,3,4],names="abc"); G
         Multiplicative Abelian Group isomorphic to Z x C3 x C4
         sage: G._gap_init_()
         Traceback (most recent call last):
         ...
         TypeError: abelian groups in GAP are finite, but self is infinite
     """
     # TODO: Use the package polycyclic has AbelianPcpGroup, which can handle
     # the infinite case but it is a GAP package not GPL'd.
     # Use this when the group is infinite...
     if (False and prod(self.invariants())==0):   # if False for now...
         return 'AbelianPcpGroup(%s)'%self.invariants()
     if not self.is_finite():
         raise TypeError, "abelian groups in GAP are finite, but self is infinite"
     return 'AbelianGroup(%s)'%self.invariants()
Beispiel #7
0
def Ht(mu, q=None, t=None, pi=None):
    """
    Returns the symmetric Macdonald polynomial using the Haiman,
    Haglund, and Loehr formula.

    Note that if both `q` and `t` are specified, then they must have the
    same parent.

    REFERENCE:

    - J. Haglund, M. Haiman, N. Loehr.
      *A combinatorial formula for non-symmetric Macdonald polynomials*.
      :arXiv:`math/0601693v3`.

    EXAMPLES::

        sage: from sage.combinat.sf.ns_macdonald import Ht
        sage: HHt = SymmetricFunctions(QQ['q','t'].fraction_field()).macdonald().Ht()
        sage: Ht([0,0,1])
        x0 + x1 + x2
        sage: HHt([1]).expand(3)
        x0 + x1 + x2
        sage: Ht([0,0,2])
        x0^2 + (q + 1)*x0*x1 + x1^2 + (q + 1)*x0*x2 + (q + 1)*x1*x2 + x2^2
        sage: HHt([2]).expand(3)
        x0^2 + (q + 1)*x0*x1 + x1^2 + (q + 1)*x0*x2 + (q + 1)*x1*x2 + x2^2
    """
    P, q, t, n, R, x = _check_muqt(mu, q, t, pi)
    res = 0
    for a in n:
        weight = a.weight()
        res += q**a.maj()*t**a.inv()*prod( x[i]**weight[i] for i in range(len(weight)) )
    return res
Beispiel #8
0
    def exp(self, exponents):
        r"""
        Return unit with given exponents with respect to group generators.

        INPUT:

        - ``u`` -- Any object from which an element of the unit
          group's number field `K` may be constructed; an error is
          raised if an element of `K` cannot be constructed from u, or
          if the element constructed is not a unit.

        OUTPUT: a list of integers giving the exponents of ``u`` with
        respect to the unit group's basis.
        
        EXAMPLES::

            sage: x = polygen(QQ)
            sage: K.<z> = CyclotomicField(13)
            sage: UK = UnitGroup(K)
            sage: [UK.log(u) for u in UK.gens()]
            [(1, 0, 0, 0, 0, 0),
             (0, 1, 0, 0, 0, 0),
             (0, 0, 1, 0, 0, 0),
             (0, 0, 0, 1, 0, 0),
             (0, 0, 0, 0, 1, 0),
             (0, 0, 0, 0, 0, 1)]
            sage: vec = [65,6,7,8,9,10]
            sage: unit = UK.exp(vec)
            sage: UK.log(unit)
            (13, 6, 7, 8, 9, 10)
            sage: UK.exp(UK.log(u)) == u.value()
            True
        """
        return prod([u**e for u,e in zip(self.gens_values(),exponents)], self.number_field().one_element())
Beispiel #9
0
def q_factorial(n, p=None):
    """
    Returns the `q`-analogue of the factorial `n!`

    If `p` is unspecified, then it defaults to using the generator `q` for
    a univariate polynomial ring over the integers.

    EXAMPLES::

        sage: from sage.combinat.q_analogues import q_factorial
        sage: q_factorial(3)
        q^3 + 2*q^2 + 2*q + 1
        sage: p = ZZ['p'].0
        sage: q_factorial(3, p)
        p^3 + 2*p^2 + 2*p + 1

    The `q`-analogue of `n!` is only defined for `n` a nonnegative
    integer (:trac:`11411`)::

        sage: q_factorial(-2)
        Traceback (most recent call last):
        ...
        ValueError: Argument (-2) must be a nonnegative integer.
    """
    if n in ZZ and n >= 0:
        return prod([q_int(i, p) for i in range(1, n+1)])
    else:
        raise ValueError("Argument (%s) must be a nonnegative integer." %n)
Beispiel #10
0
    def cardinality(self):
        """
        Returns the number of Lyndon words with the evaluation e.

        EXAMPLES::

            sage: LyndonWords([]).cardinality()
            0
            sage: LyndonWords([2,2]).cardinality()
            1
            sage: LyndonWords([2,3,2]).cardinality()
            30

        Check to make sure that the count matches up with the number of
        Lyndon words generated.

        ::

            sage: comps = [[],[2,2],[3,2,7],[4,2]]+Compositions(4).list()
            sage: lws = [ LyndonWords(comp) for comp in comps]
            sage: all( [ lw.cardinality() == len(lw.list()) for lw in lws] )
            True
        """
        evaluation = self.e
        le = __builtin__.list(evaluation)
        if len(evaluation) == 0:
            return 0

        n = sum(evaluation)

        return sum([moebius(j)*factorial(n/j) / prod([factorial(ni/j) for ni in evaluation]) for j in divisors(gcd(le))])/n
 def __pow__(self, n):
     """
     requires that len(invs) = n
     """
     if not isinstance(n, (int, long, Integer)):
         raise TypeError, "Argument n (= %s) must be an integer."%n
     n = int(n)
     M = self.parent()
     N = M.ngens()
     invs = M.invariants()
     if n < 0:  
         L =[n*self.list()[i]%M.gen(i).order() for i in range(M.ngens())]
         return prod([M.gen(i)**L[i] for i in range(M.ngens())])
         #m = LCM(invs) ## Not very efficient version
         #pw = (n)%m
         #x = self**pw
         #return x
     elif n == 0:
         return M(1)
     elif n == 1:
         return self
     elif n == 2:
         return self * self
     k = n//2
     return self**k * self**(n-k)
Beispiel #12
0
    def nu3(self):
        r"""
        Return the number of elliptic points of order 3 for this congruence
        subgroup `\Gamma_0(N)`. The number of these is given by a standard formula:
        0 if `N` is divisible by 9 or any prime congruent to -1 mod 3, and
        otherwise `2^d` where d is the number of primes other than 3 dividing `N`.

        EXAMPLE::

            sage: Gamma0(2).nu3()
            0
            sage: Gamma0(3).nu3()
            1
            sage: Gamma0(9).nu3()
            0
            sage: Gamma0(7).nu3()
            2
            sage: Gamma0(21).nu3()
            2
            sage: Gamma0(1729).nu3()
            8
        """
        n = self.level()
        if (n % 9 == 0):
            return ZZ(0)
        return prod([ 1 + kronecker_symbol(-3, p) for p, _ in n.factor()])
    def cardinality(self):
        r"""
        Return the cardinality of ``self``.

        The number of ordered set partitions of a set of length `k` with
        composition shape `\mu` is equal to

        .. MATH::

            \frac{k!}{\prod_{\mu_i \neq 0} \mu_i!}.

        EXAMPLES::

            sage: OrderedSetPartitions(5,[2,3]).cardinality()
            10
            sage: OrderedSetPartitions(0, []).cardinality()
            1
            sage: OrderedSetPartitions(0, [0]).cardinality()
            1
            sage: OrderedSetPartitions(0, [0,0]).cardinality()
            1
            sage: OrderedSetPartitions(5, [2,0,3]).cardinality()
            10
        """
        return factorial(len(self._set))/prod([factorial(i) for i in self.c])
Beispiel #14
0
def psi(N):
    """
    The index `[\Gamma : \Gamma_0(N)]`, where `\Gamma = GL(2, R)` for `R` the
    corresponding ring of integers, and `\Gamma_0(N)` standard congruence
    subgroup.

    EXAMPLES::

        sage: from sage.modular.modsym.p1list_nf import psi
        sage: k.<a> = NumberField(x^2 + 23)
        sage: N = k.ideal(3, a - 1)
        sage: psi(N)
        4

    ::

        sage: k.<a> = NumberField(x^2 + 23)
        sage: N = k.ideal(5)
        sage: psi(N)
        26
    """
    if not N.is_integral():
        raise ValueError("psi only defined for integral ideals")

    from sage.misc.misc import prod
    return prod([(np+1)*np**(e-1) \
                     for np,e in [(p.absolute_norm(),e) \
                                  for p,e in N.factor()]])
Beispiel #15
0
    def cardinality(self):
        """
        Returns the number of integer necklaces with the evaluation e.
        
        EXAMPLES::
        
            sage: Necklaces([]).cardinality()
            0
            sage: Necklaces([2,2]).cardinality()
            2
            sage: Necklaces([2,3,2]).cardinality()
            30
        
        Check to make sure that the count matches up with the number of
        Lyndon words generated.
        
        ::
        
            sage: comps = [[],[2,2],[3,2,7],[4,2]]+Compositions(4).list()
            sage: ns = [ Necklaces(comp) for comp in comps]
            sage: all( [ n.cardinality() == len(n.list()) for n in ns] )
            True
        """
        evaluation = self.e
        le = list(evaluation)
        if len(le) == 0:
            return 0

        n = sum(le)

        return sum([euler_phi(j)*factorial(n/j) / prod([factorial(ni/j) for ni in evaluation]) for j in divisors(gcd(le))])/n
Beispiel #16
0
 def _kohnen_phi(self, a, t) :
     ## We use a modified power of a, namely for each prime factor p of a
     ## we use p**floor(v_p(a)/2). This is compensated for in the routine
     ## of \rho
     a_modif = 1
     for (p,e) in a.factor() :
         a_modif = a_modif * p**(e // 2)
     
     res = 0
     for dsq in filter(lambda d: d.is_square(), a.divisors()) :
         d = isqrt(dsq)
         
         for g_diag in itertools.ifilter( lambda diag: prod(diag) == d,
                               itertools.product(*[d.divisors() for _ in xrange(t.nrows())]) ) :
             for subents in itertools.product(*[xrange(r) for (j,r) in enumerate(g_diag) for _ in xrange(j)]) :
                 columns = [subents[(j * (j - 1)) // 2:(j * (j + 1)) // 2] for j in xrange(t.nrows())]
                 g = diagonal_matrix(list(g_diag))
                 for j in xrange(t.nrows()) :
                     for i in xrange(j) :
                         g[i,j] = columns[j][i]
                      
                 ginv = g.inverse()   
                 tg = ginv.transpose() * t * ginv
                 try :
                     tg= matrix(ZZ, tg)
                 except :
                     continue
                 if any(tg[i,i] % 2 == 1 for i in xrange(tg.nrows())) :
                     continue
                 
                 tg.set_immutable()
                     
                 res = res + self._kohnen_rho(tg, a // dsq)
     
     return a_modif * res
    def statistic(self, func, q=None):
        """
        Return

        .. MATH::

            prod_{(d, \lambda)\in \tau} n_\lambda(q^d)

        where `n_\lambda(q)` is the value returned by ``func`` on the input
        `\lambda`.

        INPUT:

        - ``func`` -- a function that takes a partition to a polynomial in ``q``

        - ``q`` -- an integer or an indeterminate

        EXAMPLES::

            sage: tau = SimilarityClassType([[1, [1]], [1, [2, 1]], [2, [1, 1]]])
            sage: from sage.combinat.similarity_class_type import fq
            sage: tau.statistic(lambda la: prod([fq(m) for m in la.to_exp()]))
            (q^9 - 3*q^8 + 2*q^7 + 2*q^6 - 4*q^5 + 4*q^4 - 2*q^3 - 2*q^2 + 3*q - 1)/q^9
            sage: q = ZZ['q'].gen()
            sage: tau.statistic(lambda la: q**la.size(), q = q)
            q^8
        """
        if q is None:
            q = FractionField(ZZ["q"]).gen()
        return prod([PT.statistic(func, q=q) for PT in self])
Beispiel #18
0
def _monomial_exponent_to_lower_factorial(me, x):
    r"""
    Converts a tuple of exponents to the monomial obtained by replacing
    each me[i] with `x_i*(x_i - 1)*\cdots*(x_i - a_i + 1)`
    
    EXAMPLES::
    
        sage: from sage.combinat.misc import _monomial_exponent_to_lower_factorial
        sage: R.<x,y,z> = QQ[]
        sage: a = R.gens()
        sage: _monomial_exponent_to_lower_factorial(([1,0,0]),a)
        x
        sage: _monomial_exponent_to_lower_factorial(([2,0,0]),a)
        x^2 - x
        sage: _monomial_exponent_to_lower_factorial(([0,2,0]),a)
        y^2 - y
        sage: _monomial_exponent_to_lower_factorial(([1,1,0]),a)
        x*y
        sage: _monomial_exponent_to_lower_factorial(([1,1,2]),a)
        x*y*z^2 - x*y*z
        sage: _monomial_exponent_to_lower_factorial(([2,2,2]),a)
        x^2*y^2*z^2 - x^2*y^2*z - x^2*y*z^2 - x*y^2*z^2 + x^2*y*z + x*y^2*z + x*y*z^2 - x*y*z
    """
    terms = []
    for i in range(len(me)):
        for j in range(me[i]):
            terms.append(x[i] - j)
    return prod(terms)
def centralizer_group_cardinality(la, q=None):
    r"""
    Return the cardinality of the centralizer group in `GL_n(\mathbf{F}_q)`
    of a nilpotent matrix whose Jordan blocks are given by ``la``.

    INPUT:

    - ``lambda`` -- a partition

    - ``q`` -- an integer or an indeterminate

    OUTPUT:

    A polynomial function of ``q``.

    EXAMPLES::

        sage: from sage.combinat.similarity_class_type import centralizer_group_cardinality
        sage: q = ZZ['q'].gen()
        sage: centralizer_group_cardinality(Partition([2, 1]))
        q^5 - 2*q^4 + q^3
    """
    if q is None:
        q = ZZ["q"].gen()
    return q ** centralizer_algebra_dim(la) * prod([fq(m, q=q) for m in la.to_exp()])
Beispiel #20
0
    def __getitem__(self, support):
        r"""
        INPUT:

         - ``support`` - a proper subset of the index_set, as a list or set.

        Returns the cyclicaly decreasing element associated with ``support``.

        EXAMPLES::
:
            sage: W = WeylGroup(["A", 5, 1])
            sage: W.pieri_factors()[[0,1,2,3,5]].reduced_word()
            [3, 2, 1, 0, 5]
            sage: W.pieri_factors()[[0,1,3,4,5]].reduced_word()
            [1, 0, 5, 4, 3]
            sage: W.pieri_factors()[[0,1,2,3,4]].reduced_word()
            [4, 3, 2, 1, 0]

        """
        index_set = sorted(self.W.index_set())
        support   = sorted(support)
        assert set(support).issubset(set(index_set))
        assert support != index_set
        if len(support) == 0:
            return self.W.one()
        s = self.W.simple_reflections()
        i = 0
        while i < len(support) and support[i] == index_set[i]:
            i += 1
        # This finds the first hole: either ley[i] is maximal or support[i] < support[i+1]+1
        return prod((s[j] for j in list(reversed(support[0:i])) + list(reversed(support[i:]))), self.W.one())
Beispiel #21
0
    def _Chow_group_free(self):
        r"""
        Return the relations coming from the free part of the Chow group

        OUTPUT:

        A tuple containing the elements of $Hom(A_{d-1,\text{free}},
        F^\times)$, including the identity.

        EXAMPLES::

            sage: fan = NormalFan(ReflexivePolytope(2, 0))
            sage: X = ToricVariety(fan, base_field=GF(7))
            sage: X.Chow_group().degree(1)
            C3 x Z
            sage: enum = X.point_set()._naive_enumerator()
            sage: enum._Chow_group_free()
            ((1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6))
        """
        units = self.units()
        result = []
        rays = self.fan().rays() + self.fan().virtual_rays()
        ker = rays.matrix().integer_kernel().matrix()
        for phases in CartesianProduct(*([units] * ker.nrows())):
            phases = tuple(prod(mu**exponent for mu, exponent in zip(phases, column))
                           for column in ker.columns())
            result.append(phases)
        return tuple(sorted(result))
 def __call__( self, g ):
     """
     Some python code for wrapping GAP's Images function but only for
     permutation groups. Returns an error if g is not in G.
     
     EXAMPLES::
     
         sage: H = AbelianGroup(3, [2,3,4], names="abc")
         sage: a,b,c = H.gens()
         sage: G = AbelianGroup(2, [2,3], names="xy")
         sage: x,y = G.gens()
         sage: phi = AbelianGroupMorphism(G,H,[x,y],[a,b])
         sage: phi(y*x)
         a*b
         sage: phi(y^2)
         b^2
     """
     G = g.parent()
     w = g.word_problem(self.domaingens)
     n = len(w)
     #print w,g.word_problem(self.domaingens)
     # g.word_problem is faster in general than word_problem(g)
     gens = self.codomaingens
     h = prod([gens[(self.domaingens).index(w[i][0])]**(w[i][1]) for i in range(n)])
     return h
Beispiel #23
0
def units_mod_ideal(I):
    """
    Returns integral elements of the number field representing the images of
    the global units modulo the ideal ``I``.

    INPUT:

    - ``I`` -- number field ideal.

    OUTPUT:

    A list of integral elements of the number field representing the images of
    the global units modulo the ideal ``I``. Elements of the list might be
    equivalent to each other mod ``I``.

    EXAMPLES::

        sage: from sage.modular.cusps_nf import units_mod_ideal
        sage: k.<a> = NumberField(x^2 + 1)
        sage: I = k.ideal(a + 1)
        sage: units_mod_ideal(I)
        [1]
        sage: I = k.ideal(3)
        sage: units_mod_ideal(I)
        [1, a, -1, -a]

    ::

        sage: from sage.modular.cusps_nf import units_mod_ideal
        sage: k.<a> = NumberField(x^3 + 11)
        sage: k.unit_group()
        Unit group with structure C2 x Z of Number Field in a with defining polynomial x^3 + 11
        sage: I = k.ideal(5, a + 1)
        sage: units_mod_ideal(I)
        [1,
        2*a^2 + 4*a - 1,
        ...]

    ::

        sage: from sage.modular.cusps_nf import units_mod_ideal
        sage: k.<a> = NumberField(x^4 - x^3 -21*x^2 + 17*x + 133)
        sage: k.unit_group()
        Unit group with structure C6 x Z of Number Field in a with defining polynomial x^4 - x^3 - 21*x^2 + 17*x + 133
        sage: I = k.ideal(3)
        sage: U = units_mod_ideal(I)
        sage: all([U[j].is_unit() and not (U[j] in I) for j in range(len(U))])
        True
    """
    k = I.number_field()
    Uk = k.unit_group()
    Istar = I.idealstar(2)
    ulist = Uk.gens_values()
    elist = [Istar(I.ideallog(u)).order() for u in ulist]

    from sage.misc.mrange import xmrange
    from sage.misc.misc import prod

    return [prod([u**e for u,e in zip(ulist,ei)],k(1)) for ei in xmrange(elist)]
Beispiel #24
0
    def cardinality(self):
        """
        EXAMPLES::

            sage: [ ContreTableaux(n).cardinality() for n in range(0, 11)]
            [1, 1, 2, 7, 42, 429, 7436, 218348, 10850216, 911835460, 129534272700]
        """
        return prod( [ factorial(3*k+1)/factorial(self.n+k) for k in range(self.n)] )
        def weyl_dimension(self, highest_weight):
            """
            EXAMPLES::

                sage: RootSystem(['A',3]).ambient_lattice().weyl_dimension([2,1,0,0])
                20

                sage: type(RootSystem(['A',3]).ambient_lattice().weyl_dimension([2,1,0,0]))
                <type 'sage.rings.integer.Integer'>
            """
            highest_weight = self(highest_weight)
            assert(highest_weight.is_dominant())
            rho = self.rho()
            n = prod([(rho+highest_weight).dot_product(x) for x in self.positive_roots()])
            d = prod([ rho.dot_product(x) for x in self.positive_roots()])
            from sage.rings.integer import Integer
            return Integer(n/d)
Beispiel #26
0
def DuadicCodeEvenPair(F,S1,S2):
    r"""
    Constructs the "even pair" of duadic codes associated to the
    "splitting" (see the docstring for ``is_a_splitting``
    for the definition) S1, S2 of n.

    .. warning::

       Maybe the splitting should be associated to a sum of
       q-cyclotomic cosets mod n, where q is a *prime*.

    EXAMPLES::

        sage: from sage.coding.code_constructions import is_a_splitting
        sage: n = 11; q = 3
        sage: C = cyclotomic_cosets(q,n); C
        [[0], [1, 3, 4, 5, 9], [2, 6, 7, 8, 10]]
        sage: S1 = C[1]
        sage: S2 = C[2]
        sage: is_a_splitting(S1,S2,11)
        (True, 2)
        sage: DuadicCodeEvenPair(GF(q),S1,S2)
        (Linear code of length 11, dimension 5 over Finite Field of size 3,
         Linear code of length 11, dimension 5 over Finite Field of size 3)
    """
    n = max(S1+S2)+1
    if not(is_a_splitting(S1,S2,n)):
        raise TypeError, "%s, %s must be a splitting of %s."%(S1,S2,n)
    q = F.order()
    k = Mod(q,n).multiplicative_order()
    FF = GF(q**k,"z")
    z = FF.gen()
    zeta = z**((q**k-1)/n)
    P1 = PolynomialRing(FF,"x")
    x = P1.gen()
    g1 = prod([x-zeta**i for i in S1+[0]])
    g2 = prod([x-zeta**i for i in S2+[0]])
    P2 = PolynomialRing(F,"x")
    x = P2.gen()
    gg1 = P2([lift2smallest_field(c)[0] for c in g1.coeffs()])
    gg2 = P2([lift2smallest_field(c)[0] for c in g2.coeffs()])
    C1 = CyclicCodeFromGeneratingPolynomial(n,gg1)
    C2 = CyclicCodeFromGeneratingPolynomial(n,gg2)
    return C1,C2
Beispiel #27
0
def q_multinomial(seq, q=None, binomial_algorithm="auto"):
    r"""
    Return the `q`-multinomial coefficient.

    This is also known as the Gaussian multinomial coefficient, and is
    defined by

    .. MATH::

        \binom{n}{k_1, k_2, \ldots, k_m}_q = \frac{[n]_q!}
        {[k_1]_q! [k_2]_q! \cdots [k_m]_q!}

    where `n = k_1 + k_2 + \cdots + k_m`.

    If `q` is unspecified, then the variable is the generator `q` for
    a univariate polynomial ring over the integers.

    INPUT:

    - ``seq`` -- an iterable of the values `k_1` to `k_m` defined above

    - ``q`` -- (default: ``None``) the variable `q`; if ``None``, then use a
      default variable in `\ZZ[q]`

    - ``binomial_algorithm`` -- (default: ``'auto'``) the algorithm to use
      in :meth:`~sage.combinat.q_analogues.q_binomial`; see possible values
      there

    ALGORITHM:

    We use the equivalent formula

    .. MATH::

        \binom{k_1 + \cdots + k_m}{k_1, \ldots, k_m}_q
        = \prod_{i=1}^m \binom{\sum_{j=1}^i k_j}{k_i}_q.

    EXAMPLES::

        sage: from sage.combinat.q_analogues import q_multinomial
        sage: q_multinomial([1,2,1])
        q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 2*q + 1
        sage: q_multinomial([1,2,1], q=1) == multinomial([1,2,1])
        True
        sage: q_multinomial((3,2)) == q_binomial(5,3)
        True
        sage: q_multinomial([])
        1
    """
    binomials = []
    partial_sum = 0
    for elem in seq:
        partial_sum += elem
        binomials.append(q_binomial(partial_sum, elem, q=q, algorithm=binomial_algorithm))
    return prod(binomials)
Beispiel #28
0
def c1(part, t):
    """
    EXAMPLES::
    
        sage: from sage.combinat.sf.jack import c1
        sage: t = QQ['t'].gen()
        sage: [c1(p,t) for p in Partitions(3)]
        [2*t^2 + 3*t + 1, t + 2, 6]
    """
    return prod([1+t*part.arm_lengths(flat=True)[i]+part.leg_lengths(flat=True)[i] for i in range(sum(part))],
                t.parent()(1)) # FIXME: use .one()
Beispiel #29
0
def c2(part, t):
    """
    EXAMPLES::
    
        sage: from sage.combinat.sf.jack import c2
        sage: t = QQ['t'].gen()
        sage: [c2(p,t) for p in Partitions(3)]
        [6*t^3, 2*t^3 + t^2, t^3 + 3*t^2 + 2*t]
    """
    return prod([t+t*part.arm_lengths(flat=True)[i]+part.leg_lengths(flat=True)[i] for i in range(sum(part))],
                t.parent()(1)) # FIXME: use .one()
Beispiel #30
0
def egros_from_j(j,S=[]):
    r"""
    Given a rational j and a list of primes S, returns a list of
    elliptic curves over Q with j-invariant j and good reduction
    outside S, by checking all relevant quadratic twists.

    INPUT:

        -  j - a rational number.

        -  S - list of primes (default: empty list).

    .. note::

        Primality of elements of S is not checked, and the output
        is undefined if S is not a list or contains non-primes.

    OUTPUT:

        A sorted list of all elliptic curves defined over `Q` with
        `j`-invariant equal to `j` and with good reduction at
        all primes outside the list ``S``.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j
        sage: [e.label() for e in egros_from_j(0,[3])]
        ['27a1', '27a3', '243a1', '243a2', '243b1', '243b2']
        sage: [e.label() for e in egros_from_j(1728,[2])]
        ['32a1', '32a2', '64a1', '64a4', '256b1', '256b2', '256c1', '256c2']
        sage: elist=egros_from_j(-4096/11,[11])
        sage: [e.label() for e in elist]
        ['11a3', '121d1']

    """
    if j == 1728:
        return egros_from_j_1728(S)

    if j == 0:
        return egros_from_j_0(S)

    # Now j != 0, 1728

    E = EllipticCurve_from_j(j)
    Elist=[]

    for ei in xmrange([2]*(1+len(S))):
        u = prod([p**e for p,e in zip(reversed([-1]+S),ei)],QQ(1))
        Eu = E.quadratic_twist(u).minimal_model()
        if Eu.has_good_reduction_outside_S(S):
            Elist += [Eu]

    Elist.sort(cmp=curve_cmp)
    return Elist
 def cardinality(self):
     """
     EXAMPLES::
     
         sage: OrderedSetPartitions(5,[2,3]).cardinality()
         10
         sage: OrderedSetPartitions(0, []).cardinality()
         1
         sage: OrderedSetPartitions(0, [0]).cardinality()
         1
         sage: OrderedSetPartitions(0, [0,0]).cardinality()
         1
         sage: OrderedSetPartitions(5, [2,0,3]).cardinality()
         10
     """
     return factorial(len(self.s))/prod([factorial(i) for i in self.c])
Beispiel #32
0
    def index(self):
        r"""
        Return the index of self in the full modular group. This is given by the formula

        .. math::

            N^2 \prod_{\substack{p \mid N \\ \text{$p$ prime}}} \left( 1 - \frac{1}{p^2}\right).

        EXAMPLE::

            sage: Gamma1(180).index()
            20736
            sage: [Gamma1(n).projective_index() for n in [1..16]]
            [1, 3, 4, 6, 12, 12, 24, 24, 36, 36, 60, 48, 84, 72, 96, 96]
        """
        return prod([p**(2*e) - p**(2*e-2) for (p,e) in self.level().factor()])
Beispiel #33
0
    def centralizer_group_card(self, q=None):
        """
        Return the cardinality of the group of matrices in `GL_n(\mathbf{F}_q)`
        which commute with a matrix of type ``self``.

        INPUT:

        - ``q`` -- an integer or an indeterminate

        EXAMPLES::

            sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
            sage: tau.centralizer_group_card()
            q^2 - 2*q + 1
        """
        return prod([PT.centralizer_group_card(q=q) for PT in self])
Beispiel #34
0
    def index(self):
        r"""
        Return the index of self in the full modular group. This is given by

        .. math::

          \prod_{\substack{p \mid N \\ \text{$p$ prime}}}\left(p^{3e}-p^{3e-2}\right).

        EXAMPLE::
            sage: [Gamma(n).index() for n in [1..19]]
            [1, 6, 24, 48, 120, 144, 336, 384, 648, 720, 1320, 1152, 2184, 2016, 2880, 3072, 4896, 3888, 6840]
            sage: Gamma(32041).index()
            32893086819240
        """
        return prod(
            [p**(3 * e - 2) * (p * p - 1) for (p, e) in self.level().factor()])
    def __call__(self, g):
        """
        Evaluate ``self`` on a group element ``g``.

        OUTPUT:

        An element in
        :meth:`~sage.groups.abelian_gps.dual_abelian_group.DualAbelianGroup_class.base_ring`.

        EXAMPLES::

            sage: F = AbelianGroup(5, [2,3,5,7,8], names="abcde")
            sage: a,b,c,d,e = F.gens()
            sage: Fd = F.dual_group(names="ABCDE")
            sage: A,B,C,D,E = Fd.gens()
            sage: A*B^2*D^7
            A*B^2
            sage: A(a)
            -1
            sage: B(b)
            zeta840^140 - 1
            sage: CC(B(b))    # abs tol 1e-8
            -0.499999999999995 + 0.866025403784447*I
            sage: A(a*b)
            -1
        """
        F = self.parent().base_ring()
        expsX = self.exponents()
        expsg = g.exponents()
        order = self.parent().gens_orders()
        N = LCM(order)
        if is_ComplexField(F):
            from sage.symbolic.constants import pi
            I = F.gen()
            PI = F(pi)
            ans = prod([
                exp(2 * PI * I * expsX[i] * expsg[i] / order[i])
                for i in range(len(expsX))
            ])
            return ans
        ans = F(1)  ## assumes F is the cyclotomic field
        zeta = F.gen()
        for i in range(len(expsX)):
            order_noti = N / order[i]
            ans = ans * zeta**(expsX[i] * expsg[i] * order_noti)
        return ans
Beispiel #36
0
def egros_from_j_0(S=[]):
    r"""
    Given a list of primes S, returns a list of elliptic curves over Q
    with j-invariant 0 and good reduction outside S, by checking all
    relevant sextic twists.

    INPUT:

        -  S - list of primes (default: empty list).

    .. note::

        Primality of elements of S is not checked, and the output
        is undefined if S is not a list or contains non-primes.

    OUTPUT:

        A sorted list of all elliptic curves defined over `Q` with
        `j`-invariant equal to `0` and with good reduction at
        all primes outside the list ``S``.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j_0
        sage: egros_from_j_0([])
        []
        sage: egros_from_j_0([2])
        []
        sage: [e.label() for e in egros_from_j_0([3])]
        ['27a1', '27a3', '243a1', '243a2', '243b1', '243b2']
        sage: len(egros_from_j_0([2,3,5]))
        432
    """
    Elist = []
    if not 3 in S:
        return Elist
    no2 = not 2 in S
    for ei in xmrange([2] + [6] * len(S)):
        u = prod([p**e for p, e in zip([-1] + S, ei)], QQ(1))
        if no2:
            u *= 16  ## make sure 12|val(D,2)
        Eu = EllipticCurve([0, 0, 0, 0, u]).minimal_model()
        if Eu.has_good_reduction_outside_S(S):
            Elist += [Eu]
    Elist.sort(cmp=curve_cmp)
    return Elist
Beispiel #37
0
    def exp(self, exponents):
        r"""
        Return unit with given exponents with respect to group generators.

        INPUT:

        - ``u`` -- Any object from which an element of the unit
          group's number field `K` may be constructed; an error is
          raised if an element of `K` cannot be constructed from u, or
          if the element constructed is not a unit.

        OUTPUT: a list of integers giving the exponents of ``u`` with
        respect to the unit group's basis.

        EXAMPLES::

            sage: x = polygen(QQ)
            sage: K.<z> = CyclotomicField(13)
            sage: UK = UnitGroup(K)
            sage: [UK.log(u) for u in UK.gens()]
            [(1, 0, 0, 0, 0, 0),
             (0, 1, 0, 0, 0, 0),
             (0, 0, 1, 0, 0, 0),
             (0, 0, 0, 1, 0, 0),
             (0, 0, 0, 0, 1, 0),
             (0, 0, 0, 0, 0, 1)]
            sage: vec = [65,6,7,8,9,10]
            sage: unit = UK.exp(vec)
            sage: UK.log(unit)
            (13, 6, 7, 8, 9, 10)
            sage: UK.exp(UK.log(u)) == u.value()
            True

        An S-unit example::

           sage: SUK = UnitGroup(K,S=2)
           sage: v = (3,1,4,1,5,9,2)
           sage: u = SUK.exp(v); u
           -997204*z^11 - 2419728*z^10 - 413812*z^9 - 413812*z^8 - 2419728*z^7 - 997204*z^6 - 2129888*z^4 - 1616524*z^3 + 149364*z^2 - 1616524*z - 2129888
           sage: SUK.log(u)
           (3, 1, 4, 1, 5, 9, 2)
           sage: SUK.log(u) == v
           True
        """
        return prod([u**e for u, e in zip(self.gens_values(), exponents)],
                    self.number_field().one_element())
Beispiel #38
0
 def omega_qt(self):
     """
 Returns the image of self under the `\omega_{qt}`
 automorphism.
 
 EXAMPLES::
 
     sage: H = MacdonaldPolynomialsH(QQ)
     sage: H([1,1]).omega_qt()
     ((2*q^2-2*q*t-2*q+2*t)/(t^3-t^2-t+1))*McdH[1, 1] + ((q-1)/(t-1))*McdH[2]
 """
     P = self.parent()
     p = sfa.SFAPower(self.parent().base_ring())
     p_self = p(self)
     f = lambda part: (-1)**(part.size() - part.length()) * prod(
         [(1 - P.q**i) / (1 - P.t**i) for i in part]) * p(part)
     return P(p._apply_module_morphism(p_self, f))
    def cardinality(self):
        r"""
        Return the cardinality of ``self``.

        The number of `n \times n` alternating sign matrices is equal to

        .. MATH::

            \prod_{k=0}^{n-1} \frac{(3k+1)!}{(n+k)!} = \frac{1! 4! 7! 10!
            \cdots (3n-2)!}{n! (n+1)! (n+2)! (n+3)! \cdots (2n-1)!}

        EXAMPLES::

            sage: [AlternatingSignMatrices(n).cardinality() for n in range(0, 11)]
            [1, 1, 2, 7, 42, 429, 7436, 218348, 10850216, 911835460, 129534272700]
        """
        return Integer(prod( [ factorial(3*k+1)/factorial(self._n+k)
                       for k in range(self._n)] ))
    def __pow__(self, n):
        """
        EXAMPLES::

            sage: L = LazyPowerSeriesRing(QQ)
            sage: f = L([1,1,0])  # 1+x
            sage: g = f^3
            sage: g.coefficients(4)
            [1, 3, 3, 1]

        ::

            sage: f^0
            1
        """
        if not isinstance(n, (int, Integer)) or n < 0:
            raise ValueError("n must be a nonnegative integer")
        return prod([self] * n, self.parent().identity_element())
def E(mu, q=None, t=None, pi=None):
    """
    Returns the non-symmetric Macdonald polynomial in type A
    corresponding to a shape ``mu``, with basement permuted according to
    ``pi``.

    Note that if both `q` and `t` are specified, then they must have
    the same parent.

    REFERENCE:

    - J. Haglund, M. Haiman, N. Loehr.
      *A combinatorial formula for non-symmetric Macdonald polynomials*.
      :arXiv:`math/0601693v3`.

    EXAMPLES::

        sage: from sage.combinat.sf.ns_macdonald import E
        sage: E([0,0,0])
        1
        sage: E([1,0,0])
        x0
        sage: E([0,1,0])
        ((-t + 1)/(-q*t^2 + 1))*x0 + x1
        sage: E([0,0,1])
        ((-t + 1)/(-q*t + 1))*x0 + ((-t + 1)/(-q*t + 1))*x1 + x2
        sage: E([1,1,0])
        x0*x1
        sage: E([1,0,1])
        ((-t + 1)/(-q*t^2 + 1))*x0*x1 + x0*x2
        sage: E([0,1,1])
        ((-t + 1)/(-q*t + 1))*x0*x1 + ((-t + 1)/(-q*t + 1))*x0*x2 + x1*x2
        sage: E([2,0,0])
        x0^2 + ((-q*t + q)/(-q*t + 1))*x0*x1 + ((-q*t + q)/(-q*t + 1))*x0*x2
        sage: E([0,2,0])
        ((-t + 1)/(-q^2*t^2 + 1))*x0^2 + ((-q^2*t^3 + q^2*t^2 - q*t^2 + 2*q*t - q + t - 1)/(-q^3*t^3 + q^2*t^2 + q*t - 1))*x0*x1 + x1^2 + ((q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1))*x0*x2 + ((-q*t + q)/(-q*t + 1))*x1*x2
    """
    P, q, t, n, R, x = _check_muqt(mu, q, t, pi)
    res = 0
    for a in n:
        weight = a.weight()
        res += q**a.maj() * t**a.coinv() * a.coeff(q, t) * prod(
            x[i]**weight[i] for i in range(len(weight)))
    return res
Beispiel #42
0
    def Tokuyama_formula(self, name='t'):
        r"""
        Return the Tokuyama formula of ``self``.

        Following the exposition of [BBF]_, Tokuyama's formula asserts

        .. MATH::

            \sum_{G} (t+1)^{s(G)} t^{l(G)}
            z_1^{d_{n+1}} z_2^{d_{n}-d_{n+1}} \cdots z_{n+1}^{d_1-d_2}
            = s_{\lambda} (z_1, \ldots, z_{n+1}) \prod_{i<j} (z_j+tz_i),

        where the sum is over all strict Gelfand-Tsetlin patterns with fixed
        top row `\lambda+\rho`, with `\lambda` a partition with at most
        `n+1` parts and `\rho = (n,n-1,\dots,1,0)`, and `s_{\lambda}` is a Schur
        function.

        INPUT:

        - ``name`` -- (Default: ``'t'``) An alternative name for the
          variable `t`.

        EXAMPLES::

            sage: GT = GelfandTsetlinPatterns(top_row=[2,1,0],strict=True)
            sage: GT.Tokuyama_formula()
            t^3*x1^2*x2 + t^2*x1*x2^2 + t^2*x1^2*x3 + t^2*x1*x2*x3 + t*x1*x2*x3 + t*x2^2*x3 + t*x1*x3^2 + x2*x3^2
            sage: GT = GelfandTsetlinPatterns(top_row=[3,2,1],strict=True)
            sage: GT.Tokuyama_formula()
            t^3*x1^3*x2^2*x3 + t^2*x1^2*x2^3*x3 + t^2*x1^3*x2*x3^2 + t^2*x1^2*x2^2*x3^2 + t*x1^2*x2^2*x3^2 + t*x1*x2^3*x3^2 + t*x1^2*x2*x3^3 + x1*x2^2*x3^3
            sage: GT = GelfandTsetlinPatterns(top_row=[1,1,1],strict=True)
            sage: GT.Tokuyama_formula()
            0
        """
        n = self._n
        variables = [name] + ["x%d" % i for i in range(1, n + 1)]
        R = PolynomialRing(ZZ, names=variables)
        t = R.gen(0)
        x = R.gens()[1:]
        GT = GelfandTsetlinPatterns(top_row=self._row, strict=True)
        return sum((t + 1)**(gt.number_of_special_entries()) *
                   t**(gt.number_of_boxes()) * prod(x[i]**gt.weight()[i]
                                                    for i in range(n))
                   for gt in GT)
Beispiel #43
0
    def value(self):
        """
        Return the value of the group element.

        OUTPUT:

        The value according to the values for generators, see
        :meth:`~AbelianGroupWithValues.gens_values`.

        EXAMPLES::

            sage: G = AbelianGroupWithValues([5], 1)
            sage: G.0.value()
            5
        """
        if self._value is None:
            values = self.parent().gens_values()
            self._value = prod(v**e for v, e in zip(values, self.exponents()))
        return self._value
    def _kohnen_phi(self, a, t):
        ## We use a modified power of a, namely for each prime factor p of a
        ## we use p**floor(v_p(a)/2). This is compensated for in the routine
        ## of \rho
        a_modif = 1
        for (p, e) in a.factor():
            a_modif = a_modif * p**(e // 2)

        res = 0
        for dsq in filter(lambda d: d.is_square(), a.divisors()):
            d = isqrt(dsq)

            for g_diag in itertools.ifilter(
                    lambda diag: prod(diag) == d,
                    itertools.product(
                        *[d.divisors() for _ in xrange(t.nrows())])):
                for subents in itertools.product(*[
                        xrange(r) for (j, r) in enumerate(g_diag)
                        for _ in xrange(j)
                ]):
                    columns = [
                        subents[(j * (j - 1)) // 2:(j * (j + 1)) // 2]
                        for j in xrange(t.nrows())
                    ]
                    g = diagonal_matrix(list(g_diag))
                    for j in xrange(t.nrows()):
                        for i in xrange(j):
                            g[i, j] = columns[j][i]

                    ginv = g.inverse()
                    tg = ginv.transpose() * t * ginv
                    try:
                        tg = matrix(ZZ, tg)
                    except:
                        continue
                    if any(tg[i, i] % 2 == 1 for i in xrange(tg.nrows())):
                        continue

                    tg.set_immutable()

                    res = res + self._kohnen_rho(tg, a // dsq)

        return a_modif * res
    def cardinality(self):
        r"""
        Cardinality of ``self``.

        The number of monotone triangles with `n` rows is equal to

        .. MATH::

            \prod_{k=0}^{n-1} \frac{(3k+1)!}{(n+k)!} = \frac{1! 4! 7! 10!
            \cdots (3n-2)!}{n! (n+1)! (n+2)! (n+3)! \cdots (2n-1)!}

        EXAMPLES::

            sage: M = MonotoneTriangles(4)
            sage: M.cardinality()
            42
        """
        return Integer(prod( [ factorial(3*k+1)/factorial(self._n+k)
                       for k in range(self._n)] ))
def E_integral(mu, q=None, t=None, pi=None):
    """
    Returns the integral form for the non-symmetric Macdonald
    polynomial in type A corresponding to a shape mu.

    Note that if both q and t are specified, then they must have the
    same parent.

    REFERENCE:

    - J. Haglund, M. Haiman, N. Loehr.
      *A combinatorial formula for non-symmetric Macdonald polynomials*.
      :arXiv:`math/0601693v3`.

    EXAMPLES::

        sage: from sage.combinat.sf.ns_macdonald import E_integral
        sage: E_integral([0,0,0])
        1
        sage: E_integral([1,0,0])
        (-t + 1)*x0
        sage: E_integral([0,1,0])
        (-q*t^2 + 1)*x0 + (-t + 1)*x1
        sage: E_integral([0,0,1])
        (-q*t + 1)*x0 + (-q*t + 1)*x1 + (-t + 1)*x2
        sage: E_integral([1,1,0])
        (t^2 - 2*t + 1)*x0*x1
        sage: E_integral([1,0,1])
        (q*t^3 - q*t^2 - t + 1)*x0*x1 + (t^2 - 2*t + 1)*x0*x2
        sage: E_integral([0,1,1])
        (q^2*t^3 + q*t^4 - q*t^3 - q*t^2 - q*t - t^2 + t + 1)*x0*x1 + (q*t^2 - q*t - t + 1)*x0*x2 + (t^2 - 2*t + 1)*x1*x2
        sage: E_integral([2,0,0])
        (t^2 - 2*t + 1)*x0^2 + (q^2*t^2 - q^2*t - q*t + q)*x0*x1 + (q^2*t^2 - q^2*t - q*t + q)*x0*x2
        sage: E_integral([0,2,0])
        (q^2*t^3 - q^2*t^2 - t + 1)*x0^2 + (q^4*t^3 - q^3*t^2 - q^2*t + q*t^2 - q*t + q - t + 1)*x0*x1 + (t^2 - 2*t + 1)*x1^2 + (q^4*t^3 - q^3*t^2 - q^2*t + q)*x0*x2 + (q^2*t^2 - q^2*t - q*t + q)*x1*x2
    """
    P, q, t, n, R, x = _check_muqt(mu, q, t, pi)
    res = 0
    for a in n:
        weight = a.weight()
        res += q**a.maj() * t**a.coinv() * a.coeff_integral(q, t) * prod(
            x[i]**weight[i] for i in range(len(weight)))
    return res
Beispiel #47
0
    def ncusps(self):
        r"""
        Return the number of cusps of this subgroup `\Gamma(N)`.

        EXAMPLES::

            sage: [Gamma(n).ncusps() for n in [1..19]]
            [1, 3, 4, 6, 12, 12, 24, 24, 36, 36, 60, 48, 84, 72, 96, 96, 144, 108, 180]
            sage: Gamma(30030).ncusps()
            278691840
            sage: Gamma(2^30).ncusps()
            432345564227567616
        """
        n = self.level()
        if n==1:
            return ZZ(1)
        if n==2:
            return ZZ(3)
        return prod([p**(2*e) - p**(2*e-2) for (p,e) in n.factor()])//2
def clifford_conductor(self):
    """
    This is the product of all primes where the Clifford invariant is -1

    Note: For ternary forms, this is the discriminant of the
    quaternion algebra associated to the quadratic space
    (i.e. the even Clifford algebra)

    EXAMPLES::

        sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5])
        sage: Q.clifford_invariant(2)
        1
        sage: Q.clifford_invariant(37)
        -1
        sage: Q.clifford_conductor()
        37

    ::

        sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).clifford_conductor()
        2
        sage: QuadraticForm(ZZ, 3, [2, -2, 0, 2, 0, 5]).clifford_conductor()
        30

    For hyperbolic spaces, the clifford conductor is 1::

        sage: H = QuadraticForm(ZZ, 2, [0, 1, 0])
        sage: H.clifford_conductor()
        1
        sage: (H + H).clifford_conductor()
        1
        sage: (H + H + H).clifford_conductor()
        1
        sage: (H + H + H + H).clifford_conductor()
        1

    """
    D = self.disc()
    return prod(
        filter(lambda p: self.clifford_invariant(p) == -1,
               map(lambda x: x[0], factor(2 * self.level()))))
Beispiel #49
0
    def order(self):
        """
        Return the order (number of elements) of this finite subgroup.

        EXAMPLES::

            sage: J = J0(42)
            sage: C = J.cuspidal_subgroup()
            sage: C.order()
            2304
        """
        try:
            return self.__order
        except AttributeError:
            if self.__abvar.dimension() == 0:
                self.__order = ZZ(1)
                return self.__order
            o = prod(self.invariants())
            self.__order = o
            return o
    def __call__(self, g):
        """
        Computes the value of a character self on a group element
        g (g must be an element of self.group())

        EXAMPLES:
            sage: F = AbelianGroup(5, [2,3,5,7,8], names="abcde")
            sage: a,b,c,d,e = F.gens()
            sage: Fd = DualAbelianGroup(F, names="ABCDE")
            sage: A,B,C,D,E = Fd.gens()
            sage: A*B^2*D^7
            A*B^2
            sage: A(a)    ## random last few digits
            -1.0000000000000000 + 0.00000000000000013834419720915037*I
            sage: B(b)    ## random last few digits
            -0.49999999999999983 + 0.86602540378443871*I
            sage: A(a*b)    ## random last few digits
            -1.0000000000000000 + 0.00000000000000013834419720915037*I
        """
        F = self.parent().base_ring()
        expsX = list(self.list())
        expsg = list(g.list())
        invs = self.parent().invariants()
        N = LCM(invs)
        if is_ComplexField(F):
            from sage.symbolic.constants import pi
            I = F.gen()
            PI = F(pi)
            ans = prod([
                exp(2 * PI * I * expsX[i] * expsg[i] / invs[i])
                for i in range(len(expsX))
            ])
            return ans
        ans = F(1)  ## assumes F is the cyclotomic field
        zeta = F.gen()
        #print F,zeta
        for i in range(len(expsX)):
            inv_noti = N / invs[i]
            ans = ans * zeta**(expsX[i] * expsg[i] * inv_noti)
        return ans
Beispiel #51
0
def order_of_general_linear_group(n, q=None):
    """
    Return the cardinality of the group of `n \times n` invertible matrices
    with entries in a field of order ``q``.

    INPUT:

    - ``n`` -- a non-negative integer

    - ``q`` -- an integer or an indeterminate

    EXAMPLES::

        sage: from sage.combinat.similarity_class_type import order_of_general_linear_group
        sage: order_of_general_linear_group(0)
        1
        sage: order_of_general_linear_group(2)
        q^4 - q^3 - q^2 + q
    """
    if q is None:
        q = ZZ['q'].gen()
    return prod([q**n - q**i for i in range(n)])
Beispiel #52
0
 def _to_s(self, part):
     """
     Returns a function which gives the coefficient of a partition in
     the Schur expansion of self(part).
     
     EXAMPLES::
     
         sage: S = MacdonaldPolynomialsS(QQ)
         sage: S2 = S._to_s(Partition([2]))
         sage: S2(Partition([2]))
         -t + 1
         sage: S2(Partition([1,1]))
         t^2 - t
     """
     #Covert to the power sum
     p = sfa.SFAPower(QQqt)
     s = sfa.SFASchur(QQqt)
     p_x = p(s(part))
     t = self.t
     f = lambda m, c: (m, c * prod([(1 - t**k) for k in m]))
     res = s(p_x.map_item(f))
     f = lambda part2: res.coefficient(part2)
     return f
def hasse_conductor(self):
    """
    This is the product of all primes where the Hasse invariant equals -1

    EXAMPLES::

        sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5])
        sage: Q.hasse_invariant(2)
        -1
        sage: Q.hasse_invariant(37)
        -1
        sage: Q.hasse_conductor()
        74

    ::

        sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).hasse_conductor()
        1
        sage: QuadraticForm(ZZ, 3, [2, -2, 0, 2, 0, 5]).hasse_conductor()
        10
    """
    D = self.disc()
    return prod([x[0] for x in factor(2 * self.level()) if self.hasse_invariant(x[0]) == -1])
Beispiel #54
0
def change_support(perm, support, change_perm=None):
    """
    Changes the support of a permutation defined on [1, ..., n] to
    support.

    EXAMPLES::

        sage: from sage.combinat.species.misc import change_support
        sage: p = PermutationGroupElement((1,2,3)); p
        (1,2,3)
        sage: change_support(p, [3,4,5])
        (3,4,5)
    """
    if change_perm is None:
        change_perm = prod([
            PermutationGroupElement((i + 1, support[i]))
            for i in range(len(support)) if i + 1 != support[i]
        ], PermutationGroupElement([], SymmetricGroup(support)))

    if isinstance(perm, PermutationGroup_generic):
        return PermutationGroup(
            [change_support(g, support, change_perm) for g in perm.gens()])

    return change_perm * perm * ~change_perm
Beispiel #55
0
 def order(self):
     """
     Return the order of this group.
     
     EXAMPLES::
     
         sage: G = AbelianGroup(2,[2,3])
         sage: G.order()
         6
         sage: G = AbelianGroup(3,[2,3,0])
         sage: G.order()
         +Infinity
     """
     try:
         return self.__len
     except AttributeError:
         from sage.rings.all import infinity, Integer
         if len(self.invariants()) < self.ngens():
             self.__len = infinity
         else:
             self.__len = Integer(prod(self.invariants()))
             if self.__len == 0:
                 self.__len = infinity
     return self.__len
Beispiel #56
0
    def nu2(self):
        r""" 
        Return the number of elliptic points of order 2 for this congruence
        subgroup `\Gamma_0(N)`. The number of these is given by a standard formula:
        0 if `N` is divisible by 4 or any prime congruent to -1 mod 4, and
        otherwise `2^d` where d is the number of odd primes dividing `N`.

        EXAMPLE::

            sage: Gamma0(2).nu2()
            1
            sage: Gamma0(4).nu2()
            0
            sage: Gamma0(21).nu2()
            0
            sage: Gamma0(1105).nu2()
            8
            sage: [Gamma0(n).nu2() for n in [1..19]]
            [1, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0]
        """
        n = self.level()
        if n%4 == 0:
            return ZZ(0)
        return prod([ 1 + kronecker_symbol(-4, p) for p, _ in n.factor()])
def Kitaoka_mass_at_2(self):
    """
    Returns the local mass of the quadratic form when `p=2`, according
    to Theorem 5.6.3 on pp108--9 of Kitaoka's Book "The Arithmetic of
    Quadratic Forms".

    INPUT:
        none

    OUTPUT:
        a rational number > 0

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1])
        sage: Q.Kitaoka_mass_at_2()   ## WARNING:  WE NEED TO CHECK THIS CAREFULLY!
        1/2

    """
    ## Make a 0-dim'l quadratic form (for initialization purposes)
    Null_Form = copy.deepcopy(self)
    Null_Form.__init__(ZZ, 0)

    ## Step 0: Compute Jordan blocks and bounds of the scales to keep track of
    Jordan_Blocks = self.jordan_blocks_by_scale_and_unimodular(2)
    scale_list = [B[0] for B in Jordan_Blocks]
    s_min = min(scale_list)
    s_max = max(scale_list)

    ## Step 1: Compute dictionaries of the diagonal block and 2x2 block for each scale
    diag_dict = dict(
        (i, Null_Form)
        for i in range(s_min - 2, s_max + 4))  ## Initialize with the zero form
    dim2_dict = dict(
        (i, Null_Form)
        for i in range(s_min, s_max + 4))  ## Initialize with the zero form
    for (s, L) in Jordan_Blocks:
        i = 0
        while (i < L.dim() - 1) and (L[i, i + 1]
                                     == 0):  ## Find where the 2x2 blocks start
            i = i + 1
        if i < (L.dim() - 1):
            diag_dict[s] = L.extract_variables(range(i))  ## Diagonal Form
            dim2_dict[s + 1] = L.extract_variables(range(
                i, L.dim()))  ## Non-diagonal Form
        else:
            diag_dict[s] = L

    #print "diag_dict = ", diag_dict
    #print "dim2_dict = ", dim2_dict
    #print "Jordan_Blocks = ", Jordan_Blocks

    ##################  START EDITING HERE  ##################

    ## Compute q := sum of the q_j
    q = 0
    for j in range(s_min, s_max + 1):
        if diag_dict[j].dim(
        ) > 0:  ## Check that N_j is odd (i.e. rep'ns an odd #)
            if diag_dict[j + 1].dim() == 0:
                q += Jordan_Blocks[j][1].dim(
                )  ## When N_{j+1} is "even", add n_j
            else:
                q += Jordan_Blocks[j][1].dim(
                ) + 1  ## When N_{j+1} is "odd", add n_j + 1

    ## Compute P = product of the P_j
    P = QQ(1)
    for j in range(s_min, s_max + 1):
        tmp_m = dim2_dict[j].dim() / 2
        P *= prod([QQ(1) - QQ(4**(-k)) for j in range(1, tmp_m + 1)])

    ## Compute the product E := prod_j (1 / E_j)
    E = QQ(1)
    for j in range(s_min - 1, s_max + 2):
        if (diag_dict[j-1].dim() == 0) and (diag_dict[j+1].dim() == 0) and \
           ((diag_dict[j].dim() != 2) or (((diag_dict[j][0,0] - diag_dict[j][1,1]) % 4) != 0)):

            ## Deal with the complicated case:
            tmp_m = dim2_dict[j].dim() / 2
            if dim2_dict[j].is_hyperbolic(2):
                E *= 2 / (1 + 2**(-tmp_m))
            else:
                E *= 2 / (1 - 2**(-tmp_m))

        else:
            E *= 2

    ## DIAGNOSTIC
    #print "\nFinal Summary:"
    #print "nu =", nu
    #print "q = ", q
    #print "P = ", P
    #print "E = ", E

    ## Compute the exponent w
    w = QQ(0)
    for j in range(s_min, s_max + 1):
        n_j = Jordan_Blocks[j][1].dim()
        for k in range(j + 1, s_max + 1):
            n_k = Jordan_Blocks[k][1].dim()
            w += j * n_j * (n_k + QQ(n_j + 1) / 2)

    ## Step 5: Compute the local mass for the prime 2.
    mass_at_2 = (QQ(2)**(w - q)) * P * E
    return mass_at_2
def mass__by_Siegel_densities(self,
                              odd_algorithm="Pall",
                              even_algorithm="Watson"):
    """
    Gives the mass of transformations (det 1 and -1).

    WARNING: THIS IS BROKEN RIGHT NOW... =(

    Optional Arguments:

    - When p > 2  --  odd_algorithm = "Pall" (only one choice for now)
    - When p = 2  --  even_algorithm = "Kitaoka" or "Watson"

    REFERENCES:

    - Nipp's Book "Tables of Quaternary Quadratic Forms".
    - Papers of Pall (only for p>2) and Watson (for `p=2` -- tricky!).
    - Siegel, Milnor-Hussemoller, Conway-Sloane Paper IV, Kitoaka (all of which
      have problems...)

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1])
        sage: Q.mass__by_Siegel_densities()
        1/384
        sage: Q.mass__by_Siegel_densities() - (2^Q.dim() * factorial(Q.dim()))^(-1)
        0

    ::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1])
        sage: Q.mass__by_Siegel_densities()
        1/48
        sage: Q.mass__by_Siegel_densities() - (2^Q.dim() * factorial(Q.dim()))^(-1)
        0

    """
    ## Setup
    n = self.dim()
    s = floor((n - 1) / 2)
    if n % 2 != 0:
        char_d = squarefree_part(2 *
                                 self.det())  ## Accounts for the det as a QF
    else:
        char_d = squarefree_part(self.det())

    ## Form the generic zeta product
    generic_prod = ZZ(2) * (pi)**(-ZZ(n) * (n + 1) / 4)
    ##########################################
    generic_prod *= (self.det())**(
        ZZ(n + 1) / 2)  ## ***** This uses the Hessian Determinant ********
    ##########################################
    #print "gp1 = ", generic_prod
    generic_prod *= prod([gamma__exact(ZZ(j) / 2) for j in range(1, n + 1)])
    #print "\n---", [(ZZ(j)/2, gamma__exact(ZZ(j)/2))  for j in range(1,n+1)]
    #print "\n---", prod([gamma__exact(ZZ(j)/2)  for j in range(1,n+1)])
    #print "gp2 = ", generic_prod
    generic_prod *= prod([zeta__exact(ZZ(j)) for j in range(2, 2 * s + 1, 2)])
    #print "\n---", [zeta__exact(ZZ(j))  for j in range(2, 2*s+1, 2)]
    #print "\n---", prod([zeta__exact(ZZ(j))  for j in range(2, 2*s+1, 2)])
    #print "gp3 = ", generic_prod
    if (n % 2 == 0):
        generic_prod *= ZZ(1) * quadratic_L_function__exact(
            n / 2, (-1)**(n / 2) * char_d)
        #print " NEW = ", ZZ(1) * quadratic_L_function__exact(n/2, (-1)**(n/2) * char_d)
        #print
    #print "gp4 = ", generic_prod

    #print "generic_prod =", generic_prod

    ## Determine the adjustment factors
    adj_prod = 1
    for p in prime_divisors(2 * self.det()):
        ## Cancel out the generic factors
        p_adjustment = prod([1 - ZZ(p)**(-j) for j in range(2, 2 * s + 1, 2)])
        if (n % 2 == 0):
            p_adjustment *= ZZ(1) * (1 - kronecker(
                (-1)**(n / 2) * char_d, p) * ZZ(p)**(-n / 2))
            #print " EXTRA = ", ZZ(1) * (1 - kronecker((-1)**(n/2) * char_d, p) * ZZ(p)**(-n/2))
        #print "Factor to cancel the generic one:", p_adjustment

        ## Insert the new mass factors
        if p == 2:
            if even_algorithm == "Kitaoka":
                p_adjustment = p_adjustment / self.Kitaoka_mass_at_2()
            elif even_algorithm == "Watson":
                p_adjustment = p_adjustment / self.Watson_mass_at_2()
            else:
                raise TypeError(
                    "There is a problem -- your even_algorithm argument is invalid.  Try again. =("
                )
        else:
            if odd_algorithm == "Pall":
                p_adjustment = p_adjustment / self.Pall_mass_density_at_odd_prime(
                    p)
            else:
                raise TypeError(
                    "There is a problem -- your optional arguments are invalid.  Try again. =("
                )

        #print "p_adjustment for p =", p, "is", p_adjustment

        ## Put them together (cumulatively)
        adj_prod *= p_adjustment

    #print "Cumulative adj_prod =", adj_prod

    ## Extra adjustment for the case of a 2-dimensional form.
    #if (n == 2):
    #    generic_prod *= 2

    ## Return the mass
    mass = generic_prod * adj_prod
    return mass
Beispiel #59
0
def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=False):
    r"""
    Utility function. Given a nonempty list of pairs ``(k,f)``, where `k` is an
    integer and `f` is a power series, and a weight l, return all weight l
    forms obtained by multiplying together the given forms.

    INPUT:

    - ``forms`` -- list of pairs `(k, f)` with k an integer and f a power
      series (all over the same base ring)
    - ``weight`` -- an integer
    - ``prec`` -- an integer (less than or equal to the precision of all the
      forms in ``forms``) -- precision to use in power series computations.
    - ``stop_dim`` -- an integer: stop as soon as we have enough forms to span
      a submodule of this rank (a saturated one if the base ring is `\ZZ`).
      Ignored if ``use_random`` is False.
    - ``use_random`` -- which algorithm to use. If True, tries random products
      of the generators of the appropriate weight until a large enough
      submodule is found (determined by ``stop_dim``). If False, just tries
      everything.

    Note that if the given forms do generate the whole space, then
    ``use_random=True`` will often be quicker (particularly if the weight is
    large); but if the forms don't generate, the randomized algorithm is no
    help and will actually be substantially slower, because it needs to do
    repeated echelon form calls to check if vectors are in a submodule, while
    the non-randomized algorithm just echelonizes one enormous matrix at the
    end.

    EXAMPLES::

        sage: import sage.modular.modform.find_generators as f
        sage: forms = [(4, 240*eisenstein_series_qexp(4,5)), (6,504*eisenstein_series_qexp(6,5))]
        sage: f._span_of_forms_in_weight(forms, 12, prec=5)
        Vector space of degree 5 and dimension 2 over Rational Field
        Basis matrix:
        [        1         0    196560  16773120 398034000]
        [        0         1       -24       252     -1472]
        sage: f._span_of_forms_in_weight(forms, 24, prec=5)
        Vector space of degree 5 and dimension 3 over Rational Field
        Basis matrix:
        [          1           0           0    52416000 39007332000]
        [          0           1           0      195660    12080128]
        [          0           0           1         -48        1080]
        sage: ModularForms(1, 24).q_echelon_basis(prec=5)
        [
        1 + 52416000*q^3 + 39007332000*q^4 + O(q^5),
        q + 195660*q^3 + 12080128*q^4 + O(q^5),
        q^2 - 48*q^3 + 1080*q^4 + O(q^5)
        ]

    Test the alternative randomized algorithm::

        sage: f._span_of_forms_in_weight(forms, 24, prec=5, use_random=True, stop_dim=3)
        Vector space of degree 5 and dimension 3 over Rational Field
        Basis matrix:
        [          1           0           0    52416000 39007332000]
        [          0           1           0      195660    12080128]
        [          0           0           1         -48        1080]
    """
    t = verbose('multiplying forms up to weight %s'%weight)
    # Algorithm: run through the monomials of the appropriate weight, and build
    # up the vector space they span.

    n = len(forms)
    R = forms[0][1].base_ring()
    V = R ** prec
    W = V.zero_submodule()
    shortforms = [f[1].truncate_powerseries(prec) for f in forms]

    # List of weights
    from sage.combinat.integer_vector_weighted import WeightedIntegerVectors
    wts = list(WeightedIntegerVectors(weight, [f[0] for f in forms]))
    t = verbose("calculated weight list", t)
    N = len(wts)

    if use_random:
        if stop_dim is None:
            raise ValueError("stop_dim must be provided if use_random is True")
        shuffle(wts)

        for c in xrange(N):
            w = V(prod(shortforms[i]**wts[c][i] for i in xrange(n)).padded_list(prec))
            if w in W: continue
            W = V.span(list(W.gens()) + [w])
            if stop_dim and W.rank() == stop_dim:
                if R != ZZ or W.index_in_saturation() == 1:
                    verbose("Succeeded after %s of %s" % (c, N), t)
                    return W
        verbose("Nothing worked", t)
        return W
    else:
        G = [V(prod(forms[i][1]**c[i] for i in xrange(n)).padded_list(prec)) for c in wts]
        t = verbose('found %s candidates' % N, t)
        W = V.span(G)
        verbose('span has dimension %s' % W.rank(), t)
        return W
        def partial_fraction_decomposition(self):
            """
            Decomposes fraction field element into a whole part and a list of
            fraction field elements over prime power denominators.
            
            The sum will be equal to the original fraction.
            
            AUTHORS:
            
            - Robert Bradshaw (2007-05-31)
            
            EXAMPLES::
            
                sage: S.<t> = QQ[]
                sage: q = 1/(t+1) + 2/(t+2) + 3/(t-3); q
                (6*t^2 + 4*t - 6)/(t^3 - 7*t - 6)
                sage: whole, parts = q.partial_fraction_decomposition(); parts
                [3/(t - 3), 1/(t + 1), 2/(t + 2)]
                sage: sum(parts) == q
                True
                sage: q = 1/(t^3+1) + 2/(t^2+2) + 3/(t-3)^5
                sage: whole, parts = q.partial_fraction_decomposition(); parts
                [1/3/(t + 1), 3/(t^5 - 15*t^4 + 90*t^3 - 270*t^2 + 405*t - 243), (-1/3*t + 2/3)/(t^2 - t + 1), 2/(t^2 + 2)]
                sage: sum(parts) == q
                True
            
            We do the best we can over inexact fields::
            
                sage: R.<x> = RealField(20)[]
                sage: q = 1/(x^2 + x + 2)^2 + 1/(x-1); q
                (x^4 + 2.0000*x^3 + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000)
                sage: whole, parts = q.partial_fraction_decomposition(); parts
                [1.0000/(x - 1.0000), 1.0000/(x^4 + 2.0000*x^3 + 5.0000*x^2 + 4.0000*x + 4.0000)]
                sage: sum(parts)
                (x^4 + 2.0000*x^3 + 5.0000*x^2 + 5.0000*x + 3.0000)/(x^5 + x^4 + 3.0000*x^3 - x^2 - 4.0000)
   
            TESTS:

            We test partial fraction for irreducible denominators::
            
                sage: R.<x> = ZZ[]
                sage: q = x^2/(x-1)
                sage: q.partial_fraction_decomposition()
                (x + 1, [1/(x - 1)])
                sage: q = x^10/(x-1)^5
                sage: whole, parts = q.partial_fraction_decomposition()
                sage: whole + sum(parts) == q
                True

            And also over finite fields (see trac #6052, #9945)::
            
                sage: R.<x> = GF(2)[]
                sage: q = (x+1)/(x^3+x+1)
                sage: q.partial_fraction_decomposition()
                (0, [(x + 1)/(x^3 + x + 1)])

                sage: R.<x> = GF(11)[]
                sage: q = x + 1 + 1/(x+1) + x^2/(x^3 + 2*x + 9)
                sage: q.partial_fraction_decomposition()
                (x + 1, [1/(x + 1), x^2/(x^3 + 2*x + 9)])
            
            And even the rationals::
            
                sage: (26/15).partial_fraction_decomposition()
                (1, [1/3, 2/5])
            """
            from sage.misc.misc import prod
            denom = self.denominator()
            whole, numer = self.numerator().quo_rem(denom)
            factors = denom.factor()
            if factors.unit() != 1:
                numer *= ~factors.unit()
            if len(factors) == 1:
                return whole, [numer/r**e for r,e in factors]
            if not self.parent().is_exact():
                # factors not grouped in this case
                all = {}
                for r in factors: all[r[0]] = 0
                for r in factors: all[r[0]] += r[1]
                factors = all.items()
                factors.sort() # for doctest consistency
            factors = [r**e for r,e in factors]
            parts = []
            for d in factors:
                # note that the product below is non-empty, since the case
                # of only one factor has been dealt with above
                n = numer * prod([r for r in factors if r != d]).inverse_mod(d) % d # we know the inverse exists as the two are relatively prime
                parts.append(n/d)
            return whole, parts