Ticket #3397: 3397-2008-07-18.patch

File 3397-2008-07-18.patch, 204.1 KB (added by jhpalmieri, 11 years ago)
  • sage/algebras/all.py

    # HG changeset patch
    # User J. H. Palmieri <palmieri@math.washington.edu>
    # Date 1216395124 25200
    # Node ID c7742f1ad322bf0c7a25730fbe402957b5f87951
    # Parent  96e35b9306b1c3ba8c066e4877187ca1c18066a8
    Steenrod algebra
    
    diff -r 96e35b9306b1 -r c7742f1ad322 sage/algebras/all.py
    a b from quaternion_algebra import (Quaterni 
    3131     hilbert_symbol, fundamental_discriminant)
    3232from quaternion_order import QuaternionOrderWithBasis, QuaternionDefiningOrder
    3333from quaternion_order_ideal import QuaternionOrderLeftIdeal, QuaternionOrderRightIdeal, QuaternionOrderTwoSidedIdeal
     34from steenrod_algebra import SteenrodAlgebra
     35from steenrod_algebra_element import Sq
     36from steenrod_algebra_bases import steenrod_algebra_basis
    3437
    3538   
    3639def is_R_algebra(Q, R):
    3740    # TODO: do something nontrivial when morphisms are defined.
    3841    return True
    39 
    40 
    41 
    42 
  • new file sage/algebras/steenrod_algebra.py

    diff -r 96e35b9306b1 -r c7742f1ad322 sage/algebras/steenrod_algebra.py
    - +  
     1r"""
     2Defining the mod p Steenrod algebra.
     3
     4AUTHORS:
     5    - John H. Palmieri (2008-07-17: version 0.8)
     6
     7This package defines the mod $p$ Steenrod algebra, some of its
     8properties, and ways to define elements of it.  In this package,
     9elements in the Steenrod algebra are represented, by default, using
     10the Milnor basis.
     11
     12EXAMPLES:
     13Some properties of the Steenrod algebra are available:
     14    sage: A = SteenrodAlgebra(2)
     15    sage: A.ngens()  # number of generators
     16    +Infinity
     17    sage: A.gen(5)   # 5th generator
     18    Sq(32)
     19    sage: A.order()
     20    +Infinity
     21    sage: A.is_finite()
     22    False
     23    sage: A.is_commutative()
     24    False
     25    sage: A.is_noetherian()
     26    False
     27    sage: A.is_integral_domain()
     28    False
     29    sage: A.is_field()
     30    False
     31    sage: A.is_division_algebra()
     32    False
     33    sage: A.category()
     34    Category of algebras over Finite Field of size 2
     35
     36There are methods for constructing elements of the Steenrod algebra:
     37    sage: A2 = SteenrodAlgebra(2); A2
     38    mod 2 Steenrod algebra
     39    sage: A2.Sq(1,2,6)
     40    Sq(1,2,6)
     41    sage: A2.Q(3,4)  # product of Milnor primitives Q_3 and Q_4
     42    Sq(0,0,0,1,1)
     43    sage: A2.pst(2,3)  # Margolis pst element
     44    Sq(0,0,4)
     45    sage: A5 = SteenrodAlgebra(5); A5
     46    mod 5 Steenrod algebra
     47    sage: A5.P(1,2,6)
     48    P(1,2,6)
     49    sage: A5.Q(3,4)
     50    Q_3 Q_4
     51    sage: A5.Q(3,4) * A5.P(1,2,6)
     52    Q_3 Q_4 P(1,2,6)
     53    sage: A5.pst(2,3)
     54    P(0,0,25)
     55   
     56You can test whether elements are contained in the Steenrod algebra:
     57    sage: w = Sq(2) * Sq(4)
     58    sage: w in SteenrodAlgebra(2)
     59    True
     60    sage: w in SteenrodAlgebra(17)
     61    False
     62   
     63Different bases for the Steenrod algebra:
     64   
     65There are two standard vector space bases for the mod $p$ Steenrod
     66algebra: the Milnor basis and the Serre-Cartan basis.  When $p=2$,
     67there are also several other, less well-known, bases.  The following
     68bases have been implemented in this package.
     69
     70  * 'milnor': Milnor basis.  When $p=2$, the Milnor basis consists of
     71     symbols of the form $\text{Sq}(m_1, m_2, ..., m_t)$, where each
     72     $m_i$ is a non-negative integer and if $t>1$, then the last entry
     73     $m_t > 0$.  When $p$ is odd, the Milnor basis consists of
     74     symbols of the form $Q_{e_1} Q_{e_2} ... \mathcal{P}(m_1, m_2,
     75     ..., m_t)$, where $0 \leq e_1 < e_2 < ...$, each $m_i$ is a
     76     non-negative integer, and if $t>1$, then the last entry $m_t >
     77     0$.
     78
     79  * 'serre-cartan' or 'adem' or 'admissible': Serre-Cartan basis.  The
     80    Serre-Cartan basis consists of 'admissible monomials' in the
     81    Steenrod operations.  Thus at the prime 2, it consists of
     82    monomials $\text{Sq}^{m_1} \text{Sq}^{m_2} ... \text{Sq}^{m_t}$
     83    with $m_i \geq 2m_{i+1}$ for each $i$.  At odd primes, it consists
     84    of monomials $\beta^{\epsilon_0} \mathcal{P}^{s_1}
     85    \beta^{\epsilon_1} \mathcal{P}^{s_2} ...  \mathcal{P}^{s_k}
     86    \beta^{\epsilon_k}$ with each $\epsilon_i$ either 0 or 1, $s_i
     87    \geq p s_{i+1} + \epsilon_i$, and $s_k \geq 1$.
     88
     89When $p=2$, the element $\text{Sq}^a$ equals the Milnor element
     90$\text{Sq}(a)$; when $p$ is odd, $\mathcal{P}^a = \mathcal{P}(a)$ and
     91$\beta = Q_0$.  Hence for any Serre-Cartan basis element, one can
     92represent it in the Milnor basis by computing an appropriate product
     93using Milnor multiplication.
     94
     95The rest of these bases are only defined when $p=2$.
     96
     97  * 'wood_y': Wood's Y basis.  For pairs of non-negative integers
     98    $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Y$
     99    basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     100    $(m_i,k_i) > (m_{i+1},k_{i+1})$, in left lex order.
     101
     102  * 'wood_z': Wood's Z basis.  For pairs of non-negative integers
     103    $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Z$
     104    basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     105    $(m_i+k_i,m_i) > (m_{i+1}+k_{i+1},m_{i+1})$, in left lex order.
     106
     107  * 'wall': Wall's basis.  For any pair of integers $(m,k)$ with $m
     108    \geq k \geq 0$, let $Q^m_k = \text{Sq}^{2^k} \text{Sq}^{2^{k+1}}
     109    ... \text{Sq}^{2^m}$.  The elements of Wall's basis are monomials
     110    $Q^{m_0}_{k_0} ... Q^{m_t}_{k_t}$ with $(m_i, k_i) > (m_{i+1},
     111    k_{i+1})$, ordered left lexicographically.
     112
     113    The standard way of printing elements of the Wall basis is to
     114    write elements in terms of the $Q^m_k$.  If one sets the basis to
     115    'wall_long' instead of 'wall', then each $Q^m_k$ is expanded as a
     116    product of factors of the form $\text{Sq}^{2^i}$.
     117
     118  * 'arnon_a': Arnon's A basis.  For any pair of integers $(m,k)$ with
     119    $m \geq k \geq 0$, let $X^m_k = \text{Sq}^{2^m}
     120    \text{Sq}^{2^{m-1}} ... \text{Sq}^{2^k}$.  The elements of Arnon's
     121    A basis are monomials $X^{m_0}_{k_0} ... X^{m_t}_{k_t}$ with
     122    $(m_i, k_i) < (m_{i+1}, k_{i+1})$, ordered left lexicographically.
     123
     124    The standard way of printing elements of Arnon's A basis is to
     125    write elements in terms of the $X^m_k$.  If one sets the basis to
     126    'arnon_a_long' instead of 'arnon_a', then each $X^m_k$ is expanded
     127    as a product of factors of the form $\text{Sq}^{2^i}$.
     128
     129  * 'arnon_c': Arnon's C basis.  The elements of Arnon's C basis are
     130    monomials of the form $\text{Sq}^{t_1} ... \text{Sq}^{t_m}$ where
     131    for each $i$, we have $t_i \leq 2t_{i+1}$ and $2^i | t_{m-i}$.
     132
     133  * 'pst', 'pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz': various
     134    P^s_t-bases.  For integers $s \geq 0$ and $t > 0$, the element
     135    $P^s_t$ is the Milnor basis element $\text{Sq}(0, ..., 0, 2^s, 0,
     136    ...)$, with the nonzero entry in position $t$.  To obtain a
     137    $P^s_t$-basis, for each set $\{P^{s_1}_{t_1}, ...,
     138    P^{s_k}_{t_k}\}$ of (distinct) $P^s_t$'s, one chooses an ordering
     139    and forms the resulting monomial.  The set of all such monomials
     140    then forms a basis, and so one gets a basis by choosing an
     141    ordering on each monomial.
     142
     143    The strings 'rlex', 'llex', etc., correspond to the following
     144    orderings.  These are all 'global' -- they give a global ordering
     145    on the $P^s_t$'s, not different orderings depending on the
     146    monomial.  They order the $P^s_t$'s using the pair of integers
     147    $(s,t)$ as follows:
     148
     149      * 'rlex': right lexicographic ordering
     150
     151      * 'llex': left lexicographic ordering
     152
     153      * 'deg': ordered by degree, which is the same as left
     154        lexicographic ordering on the pair $(s+t,t)$
     155
     156      * 'revz': left lexicographic ordering on the pair $(s+t,s)$,
     157        which is the reverse of the ordering used (on elements in the
     158        same degrees as the $P^s_t$'s) in Wood's Z basis: 'revz'
     159        stands for 'reversed Z'.  This is the default: 'pst' is the
     160        same as 'pst_revz'.
     161
     162  * 'comm', 'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz': various
     163    commutator bases.  Let $c_{i,1} = \text{Sq}^{2^i}$, let $c_{i,2} =
     164    [c_{i,1}, c_{i+1,1}]$, and inductively define $c_{i,k} =
     165    [c_{i,k-1}, c_{i+k-1,1}]$.  Thus $c_{i,k}$ is a $k$-fold iterated
     166    commutator of the elements $\text{Sq}^{2^i}$, ...,
     167    $\text{Sq}^{2^{i+k-1}}$.  Note that $\dim c_{i,k} = \dim P^i_k$.
     168
     169    To obtain a commutator basis, for each set $\{c_{s_1,t_1}, ...,
     170    c_{s_k,t_k}\}$ of (distinct) $c_{s,t}$'s, one chooses an ordering
     171    and forms the resulting monomial.  The set of all such monomials
     172    then forms a basis, and so one gets a basis by choosing an
     173    ordering on each monomial.  The strings 'rlex', etc., have the
     174    same meaning as for the orderings on $P^s_t$-bases.  As with the
     175    $P^s_t$-bases, 'comm_revz' is the default: 'comm' means
     176    'comm_revz'.
     177
     178    The commutator bases have alternative representations, obtained by
     179    appending 'long' to their names: instead of, say, $c_{2,2}$, the
     180    representation is $s_{48}$, indicating the commutator of
     181    $\text{Sq}^4$ and $\text{Sq}^8$, and $c_{0,3}$, which is equal to
     182    $[[\text{Sq}^1, \text{Sq}^2], \text{Sq}^4]$, is written as
     183    $s_{124}$.
     184
     185When defining a Steenrod algebra, you can specify a basis.  Then
     186elements of that Steenrod algebra are printed in that basis
     187    sage: adem = SteenrodAlgebra(2, 'adem')
     188    sage: x = adem.Sq(2,1)  # Sq(-) always means a Milnor basis element
     189    sage: x
     190    Sq^{4} Sq^{1} + Sq^{5}
     191    sage: y = Sq(0,1)    # unadorned Sq defines elements w.r.t. Milnor basis
     192    sage: y
     193    Sq(0,1)
     194    sage: adem(y)
     195    Sq^{2} Sq^{1} + Sq^{3}
     196    sage: adem5 = SteenrodAlgebra(5, 'serre-cartan')
     197    sage: adem5.P(0,2)
     198    P^{10} P^{2} + 4 P^{11} P^{1} + 4 P^{12}
     199
     200You can get a list of basis elements in a given dimension:
     201    sage: A3 = SteenrodAlgebra(3, 'milnor')
     202    sage: A3.basis(13)
     203    (Q_1 P(2), Q_0 P(3))
     204
     205As noted above, several of the bases ('arnon_a', 'wall', 'comm') have
     206alternate, longer, representations.  These provide ways of expressing
     207elements of the Steenrod algebra in terms of the $\text{Sq}^{2^n}$.
     208    sage: A_long = SteenrodAlgebra(2, 'arnon_a_long')
     209    sage: A_long(Sq(6))
     210    Sq^{1} Sq^{2} Sq^{1} Sq^{2} + Sq^{2} Sq^{4}
     211    sage: SteenrodAlgebra(2, 'wall_long')(Sq(6))
     212    Sq^{2} Sq^{1} Sq^{2} Sq^{1} + Sq^{2} Sq^{4}
     213    sage: SteenrodAlgebra(2, 'comm_deg_long')(Sq(6))
     214    s_{1} s_{2} s_{12} + s_{2} s_{4}
     215
     216**************
     217
     218Internal documentation:
     219If you want to implement a new basis for the Steenrod algebra:
     220
     221    In this file ('steenrod_algebra.py'):
     222
     223        add functionality to 'get_basis_name': this should accept as
     224        input various synonyms for the basis, and its output should be
     225        an element of '_steenrod_basis_unique_names' (see the next
     226        file).
     227
     228    In the file 'steenrod_algebra_element.py':
     229
     230        add name of basis to '_steenrod_basis_unique_names'
     231
     232        add functionality to 'string_rep', which probably involves
     233        adding a 'BASIS_mono_to_string' function
     234
     235        add functionality to the _basis_dictionary method
     236
     237    In the file 'steenrod_algebra_bases.py':
     238
     239        add appropriate lines to 'steenrod_algebra_basis'
     240
     241        add a function to compute the basis in a given dimension (to be
     242        called by 'steenrod_algebra_basis')
     243
     244   
     245REFERENCES:
     246    [Mil] J. W. Milnor, "The Steenrod algebra and its dual," Ann. of Math.
     247          (2) 67 (1958), 150--171.
     248    [Mon] K. G. Monks, "Change of basis, monomial relations, and $P^s_t$
     249          bases for the Steenrod algebra," J. Pure Appl. Algebra 125 (1998),
     250          no. 1-3, 235--260.
     251    [Woo] R. M. W. Wood, "Problems in the Steenrod algebra," Bull. London
     252          Math. Soc. 30 (1998), no. 5, 449--517.
     253"""
     254
     255#*****************************************************************************
     256#       Copyright (C) 2008 William Stein <wstein@gmail.com>
     257#       Copyright (C) 2008 John H. Palmieri <palmieri@math.washington.edu>
     258#  Distributed under the terms of the GNU General Public License (GPL)
     259#*****************************************************************************
     260
     261from sage.rings.ring import Algebra
     262from sage.algebras.algebra_element import AlgebraElement
     263from sage.structure.parent_gens import ParentWithGens
     264from sage.structure.element import RingElement
     265from sage.rings.all import GF
     266from sage.misc.functional import parent
     267from sage.rings.integer import Integer
     268
     269class SteenrodAlgebra_generic(Algebra):
     270    r"""
     271    The mod $p$ Steenrod algebra.
     272
     273    Users should not call this, but use the function 'SteenrodAlgebra'
     274    instead.  See that function for extensive documentation.
     275
     276    EXAMPLES:
     277        sage: sage.algebras.steenrod_algebra.SteenrodAlgebra_generic()
     278        mod 2 Steenrod algebra
     279        sage: sage.algebras.steenrod_algebra.SteenrodAlgebra_generic(5)
     280        mod 5 Steenrod algebra
     281        sage: sage.algebras.steenrod_algebra.SteenrodAlgebra_generic(5, 'adem')
     282        mod 5 Steenrod algebra
     283    """
     284
     285    def __init__(self, p=2, basis='milnor'):
     286        """
     287        INPUT:
     288            p (optional, default = 2) -- positive prime integer
     289            basis (optional, default = 'milnor') -- string
     290       
     291        OUTPUT:
     292            mod p Steenrod algebra with basis
     293
     294        EXAMPLES:
     295            sage: SteenrodAlgebra()   # 2 is the default prime
     296            mod 2 Steenrod algebra
     297            sage: SteenrodAlgebra(5)
     298            mod 5 Steenrod algebra
     299            sage: SteenrodAlgebra(2, 'milnor').Sq(0,1)
     300            Sq(0,1)
     301            sage: SteenrodAlgebra(2, 'adem').Sq(0,1)
     302            Sq^{2} Sq^{1} + Sq^{3}
     303        """
     304        from sage.rings.arith import is_prime
     305        if is_prime(p):
     306            self.prime = p
     307            ParentWithGens.__init__(self, GF(p))
     308            self._basis_name = basis
     309        else:
     310            raise ValueError, "%s is not prime." % p
     311
     312
     313    def _repr_(self):
     314        """
     315        Printed representation of the Steenrod algebra.
     316
     317        EXAMPLES:
     318            sage: SteenrodAlgebra(3)
     319            mod 3 Steenrod algebra
     320            sage: B = SteenrodAlgebra(2003)
     321            sage: B
     322            mod 2003 Steenrod algebra
     323            sage: B._repr_()
     324            'mod 2003 Steenrod algebra'
     325        """
     326        return "mod %d Steenrod algebra" % self.prime
     327   
     328
     329    def _latex_(self):
     330        """
     331        LaTeX representation of the Steenrod algebra.
     332       
     333        EXAMPLES:
     334            sage: C = SteenrodAlgebra(3)
     335            sage: C
     336            mod 3 Steenrod algebra
     337            sage: C._latex_()
     338            '\\mathcal{A}_{3}'
     339        """
     340        return "\\mathcal{A}_{%s}" % self.prime
     341   
     342
     343    def ngens(self):
     344        """
     345        Number of generators of the Steenrod algebra.
     346
     347        This returns infinity, since the Steenrod algebra is infinitely
     348        generated.
     349
     350        EXAMPLES:
     351            sage: A = SteenrodAlgebra(3)
     352            sage: A.ngens()
     353            +Infinity
     354        """
     355        from sage.rings.infinity import Infinity
     356        return Infinity
     357
     358
     359    def gen(self, i=0):
     360        """
     361        The ith generator of the Steenrod algebra.
     362
     363        INPUT:
     364            i -- non-negative integer
     365
     366        OUTPUT: The ith generator of the Steenrod algebra: Sq(2**i) at
     367            the prime 2; when p is odd, the 0th generator is beta =
     368            Q(0), and for i>0, the ith generator is P(p**(i-1)).
     369
     370        EXAMPLES:
     371            sage: A = SteenrodAlgebra(2)
     372            sage: A.gen(4)
     373            Sq(16)
     374            sage: B = SteenrodAlgebra(5)
     375            sage: B.gen(0)
     376            Q_0
     377            sage: B.gen(2)
     378            P(5)
     379        """
     380        if not isinstance(i, (Integer, int)) and i >= 0:
     381            raise ValueError, "%s is not a non-negative integer" % i
     382        if self.prime == 2:
     383            return self.Sq(self.prime**i)
     384        else:
     385            if i == 0:
     386                return self.Q(0)
     387            else:
     388                return self.P(self.prime**(i-1))
     389
     390    def __cmp__(self,right):
     391        """
     392        Two Steenrod algebras are equal <=> their associated primes are equal.
     393
     394        EXAMPLES:
     395            sage: A = SteenrodAlgebra(2)
     396            sage: B = SteenrodAlgebra(2, 'adem')
     397            sage: cmp(A, B)
     398            0
     399            sage: A.__cmp__(B)
     400            0
     401            sage: A is B
     402            False
     403            sage: C = SteenrodAlgebra(17)
     404            sage: cmp(A,C)
     405            -1
     406        """
     407        if type(self) == type(right) and self.prime == right.prime:
     408            return 0
     409        else:
     410            return -1
     411
     412
     413    def __call__(self, x):
     414        """
     415        Try to turn x into an element of self.
     416
     417        INPUT:
     418            x -- a SteenrodAlgebra element or an element of F_p
     419
     420        OUTPUT:
     421            x as a member of self
     422
     423        EXAMPLES:
     424            sage: x = Sq(2,1)
     425            sage: x
     426            Sq(2,1)
     427            sage: B = SteenrodAlgebra(2, 'adem')
     428            sage: B(x)
     429            Sq^{4} Sq^{1} + Sq^{5}
     430        """
     431        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     432        if isinstance(x, SteenrodAlgebraElement) and x.parent() == self:
     433            dict = x._raw
     434            a = SteenrodAlgebraElement(dict['milnor'],
     435                                       p=x._prime,
     436                                       basis=self._basis_name)
     437            a._raw = dict
     438            return a
     439        else:
     440            return SteenrodAlgebraElement(x, p=self.prime,
     441                                          basis=self._basis_name)
     442
     443
     444    def _coerce_impl(self, x):
     445        """
     446        Return the coercion of x into this Steenrod algebra.
     447
     448        INPUT:
     449            x -- a SteenrodAlgebraElement or an element of F_p
     450
     451        OUTPUT:
     452            coercion of x into the Steenrod algebra
     453       
     454        EXAMPLES:
     455            sage: A = SteenrodAlgebra(); A
     456            mod 2 Steenrod algebra
     457            sage: A(1)     # convert 1 to an element of A
     458            Sq(0)
     459            sage: A(Sq(3))
     460            Sq(3)
     461       
     462        The algebras that coerce into the mod p Steenrod algebra are:
     463       
     464           * the mod p Steenrod algebra
     465           * its base field GF(p)
     466        """
     467        return self._coerce_try(x, [self.base_ring()])
     468       
     469
     470    def __contains__(self, x):
     471        """
     472        Instances of the class SteenrodAlgebraElement with the same
     473        prime are contained in the Steenrod algebra.
     474
     475        EXAMPLES:
     476            sage: A = SteenrodAlgebra()
     477            sage: x = Sq(2) * Sq(1); x
     478            Sq(0,1) + Sq(3)
     479            sage: x in A
     480            True
     481            sage: x in SteenrodAlgebra(5)
     482            False
     483        """
     484        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     485        return (isinstance(x, SteenrodAlgebraElement) and x.parent() == self) \
     486            or (GF(self.prime).__contains__(x))
     487
     488
     489    def is_commutative(self):
     490        """
     491        The Steenrod algebra is not commutative.
     492       
     493        EXAMPLES:
     494            sage: A = SteenrodAlgebra(3)
     495            sage: A.is_commutative()
     496            False
     497        """
     498        return False
     499
     500
     501    def is_finite(self):
     502        """
     503        The Steenrod algebra is not finite.
     504       
     505        EXAMPLES:
     506            sage: A = SteenrodAlgebra(3)
     507            sage: A.is_finite()
     508            False
     509        """
     510        return False
     511
     512
     513    def order(self):
     514        """
     515        The Steenrod algebra has infinite order.
     516       
     517        EXAMPLES:
     518            sage: A = SteenrodAlgebra(3)
     519            sage: A.order()
     520            +Infinity
     521        """
     522        from sage.rings.infinity import Infinity
     523        return Infinity
     524
     525
     526    def is_division_algebra(self):
     527        """
     528        The Steenrod algebra is not a division algebra.
     529       
     530        EXAMPLES:
     531            sage: A = SteenrodAlgebra(3)
     532            sage: A.is_division_algebra()
     533            False
     534        """
     535        return False
     536   
     537
     538    def is_field(self):
     539        """
     540        The Steenrod algebra is not a field.
     541       
     542        EXAMPLES:
     543            sage: A = SteenrodAlgebra(3)
     544            sage: A.is_field()
     545            False
     546        """
     547        return False
     548   
     549
     550    def is_integral_domain(self):
     551        """
     552        The Steenrod algebra is not an integral domain.
     553       
     554        EXAMPLES:
     555            sage: A = SteenrodAlgebra(3)
     556            sage: A.is_integral_domain()
     557            False
     558        """
     559        return False
     560   
     561
     562    def is_noetherian(self):
     563        """
     564        The Steenrod algebra is not noetherian.
     565       
     566        EXAMPLES:
     567            sage: A = SteenrodAlgebra(3)
     568            sage: A.is_noetherian()
     569            False
     570        """
     571        return False
     572       
     573
     574    def category(self):
     575        """
     576        The Steenrod algebra is an algebra over $F_p$.
     577       
     578        EXAMPLES:
     579            sage: A = SteenrodAlgebra(3)
     580            sage: A.category()
     581            Category of algebras over Finite Field of size 3
     582        """
     583        from sage.categories.category_types import Algebras
     584        return Algebras(GF(self.prime))
     585
     586
     587    def basis(self, n):
     588        """
     589        Basis for self in dimension n
     590
     591        EXAMPLES:
     592            sage: A3 = SteenrodAlgebra(3)
     593            sage: A3.basis(13)
     594            (Q_1 P(2), Q_0 P(3))
     595            sage: SteenrodAlgebra(2, 'adem').basis(12)
     596            (Sq^{12},
     597            Sq^{11} Sq^{1},
     598            Sq^{9} Sq^{2} Sq^{1},
     599            Sq^{8} Sq^{3} Sq^{1},
     600            Sq^{10} Sq^{2},
     601            Sq^{9} Sq^{3},
     602            Sq^{8} Sq^{4})
     603        """
     604        from steenrod_algebra_bases import steenrod_algebra_basis
     605        return steenrod_algebra_basis(n, basis=self._basis_name, p=self.prime)
     606
     607
     608    def P(self, *nums):
     609        r"""
     610        The element $\mathcal{P}(n_1, n_2, ...)$
     611
     612        INPUT:
     613            nums -- tuple of non-negative integers
     614           
     615        OUTPUT:
     616            element of the Steenrod algebra given by the single basis
     617            element P(n_1, n_2, ...)
     618
     619        Note that at the prime 2, this is the same element as Sq(n_1, n_2, ...)
     620
     621        EXAMPLES:
     622            sage: A = SteenrodAlgebra(2)
     623            sage: A.P(5)
     624            Sq(5)
     625            sage: B = SteenrodAlgebra(3)
     626            sage: B.P(5,1,1)
     627            P(5,1,1)
     628        """
     629        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     630        if self.prime == 2:
     631            dict = {nums: 1}
     632        else:
     633            dict = {((), nums): 1}
     634        return SteenrodAlgebraElement(dict, p=self.prime,
     635                                      basis=self._basis_name)
     636
     637
     638    def Q_exp(self, *nums):
     639        r"""
     640        The element $Q_0^{e_0} Q_1^{e_1} ...$, given by specifying the exponents.
     641       
     642        INPUT:
     643            nums -- tuple of 0s and 1s, say (e_0, e_1, ...)
     644
     645        OUTPUT:
     646            The element Q_0^{e_0} Q_1^{e_1} ...
     647       
     648        Note that at the prime 2, $Q_n$ is the element
     649        $\text{Sq}(0,0,...,1)$, where the 1 is in the $n+1$st
     650        position.
     651       
     652        Compare this to the method 'Q', which defines a similar
     653        element, but by specifying the tuple of subscripts of terms
     654        with exponent 1.
     655
     656        EXAMPLES:
     657            sage: A2 = SteenrodAlgebra(2)
     658            sage: A5 = SteenrodAlgebra(5)
     659            sage: A2.Q_exp(0,0,1,1,0)
     660            Sq(0,0,1,1)
     661            sage: A5.Q_exp(0,0,1,1,0)
     662            Q_2 Q_3
     663            sage: A5.Q(2,3)
     664            Q_2 Q_3
     665            sage: A5.Q_exp(0,0,1,1,0) == A5.Q(2,3)
     666            True
     667        """
     668        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     669        if not set(nums).issubset(set((0,1))):
     670            raise ValueError, "The tuple %s should consist " % (nums,) + \
     671                "only of 0's and 1's"
     672        else:
     673            if self.prime == 2:
     674                answer = self.Sq(0)
     675                index = 0
     676                for n in nums:
     677                    if n == 1:
     678                        answer = answer * self.pst(0,index+1)
     679                    index += 1
     680                return answer
     681            else:
     682                mono = ()
     683                index = 0
     684                for e in nums:
     685                    if e == 1:
     686                        mono = mono + (index,)
     687                    index += 1
     688                dict = {((mono), ()): 1}
     689                return SteenrodAlgebraElement(dict, p=self.prime,
     690                                              basis=self._basis_name)
     691
     692           
     693    def Q(self, *nums):
     694        r"""
     695        The element $Q_n0 Q_n1 ...$, given by specifying the subscripts.
     696       
     697        INPUT:
     698            nums -- tuple of non-negative integers, say (n_0, n_1, ...)
     699
     700        OUTPUT:
     701            The element Q_n0 Q_n1 ...
     702
     703        Note that at the prime 2, $Q_n$ is the element
     704        $\text{Sq}(0,0,...,1)$, where the 1 is in the $n+1$st
     705        position.
     706       
     707        Compare this to the method 'Q_exp', which defines a similar element,
     708        but by specifying the tuple of exponents.
     709
     710        EXAMPLES:
     711            sage: A2 = SteenrodAlgebra(2)
     712            sage: A5 = SteenrodAlgebra(5)
     713            sage: A2.Q(2,3)
     714            Sq(0,0,1,1)
     715            sage: A5.Q(1,4)
     716            Q_1 Q_4
     717            sage: A5.Q(1,4) == A5.Q_exp(0,1,0,0,1)
     718            True
     719        """
     720        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     721        if len(nums) != len(set(nums)):
     722            return self(0)
     723        else:
     724            if self.prime == 2:
     725                if len(nums) == 0:
     726                    return Sq(0)
     727                else:
     728                    list = (1+max(nums)) * [0]
     729                    for i in nums:
     730                        list[i] = 1
     731                    return SteenrodAlgebraElement({tuple(list): 1}, p=2,
     732                                                  basis=self._basis_name)
     733            else:
     734                return SteenrodAlgebraElement({(nums, ()): 1}, p=self.prime,
     735                                              basis=self._basis_name)
     736
     737
     738    def pst(self,s,t):
     739        r"""
     740        The Margolis element $P^s_t$.
     741       
     742        INPUT:
     743            s -- non-negative integer
     744            t -- positive integer
     745            p -- positive prime number
     746       
     747        OUTPUT:
     748            The Margolis element P^s_t of the mod p Steenrod algebra: the
     749            element equal to P(0,0,...,0,p^s), where the p^s is in
     750            position t.
     751
     752        EXAMPLES:
     753            sage: A2 = SteenrodAlgebra(2)
     754            sage: A2.pst(3,5)
     755            Sq(0,0,0,0,8)
     756            sage: A2.pst(1,2) == Sq(4)*Sq(2) + Sq(2)*Sq(4)
     757            True
     758            sage: SteenrodAlgebra(5).pst(3,5)
     759            P(0,0,0,0,125)
     760        """
     761        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     762        if not isinstance(s, (Integer, int)) and s >= 0:
     763            raise ValueError, "%s is not a non-negative integer" % s
     764        if not isinstance(t, (Integer, int)) and t > 0:
     765            raise ValueError, "%s is not a positive integer" % t
     766        nums = (0,)*(t-1) + (self.prime**s,)
     767        if self.prime == 2:
     768            return SteenrodAlgebraElement({nums: 1}, p=2, basis=self._basis_name)
     769        else:
     770            return SteenrodAlgebraElement({((), nums): 1}, p=self.prime,
     771                                          basis=self._basis_name)
     772
     773
     774class SteenrodAlgebra_mod_two(SteenrodAlgebra_generic):
     775    """
     776    The mod 2 Steenrod algebra.
     777
     778    Users should not call this, but use the function 'SteenrodAlgebra'
     779    instead.  See that function for extensive documentation.  (This
     780    differs from SteenrodAlgebra_generic only in that it has a method
     781    'Sq' for defining elements.)
     782    """
     783    def Sq(self, *nums):
     784        r"""
     785        Milnor element $\text{Sq}(a,b,c,...)$.
     786
     787        INPUT:
     788            nums -- tuple of non-negative integers
     789       
     790        OUTPUT:
     791            element of the Steenrod algebra given by the single basis
     792            element Sq(a, b, c, ...)
     793   
     794        EXAMPLES:
     795            sage: A = SteenrodAlgebra(2)
     796            sage: A.Sq(5)
     797            Sq(5)
     798            sage: A.Sq(5,0,2)
     799            Sq(5,0,2)
     800
     801        Entries must be non-negative integers; otherwise, an error results.
     802        """
     803        from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     804        if self.prime == 2:
     805            dict = {nums: 1}
     806            return SteenrodAlgebraElement(dict, p=2, basis=self._basis_name)
     807        else:
     808            raise ValueError, "Sq is only defined at the prime 2"
     809
     810
     811def SteenrodAlgebra(p=2, basis='milnor'):
     812    r"""
     813    The mod $p$ Steenrod algebra
     814
     815    INPUT:
     816        p (optional, default = 2) -- positive prime integer
     817        basis (optional, default = 'milnor') -- string
     818
     819    OUTPUT:
     820        mod p Steenrod algebra with basis
     821
     822    This returns the mod $p$ Steenrod algebra, elements of which are
     823    printed using basis.
     824
     825    EXAMPLES:
     826    Some properties of the Steenrod algebra are available:
     827        sage: A = SteenrodAlgebra(2)
     828        sage: A.ngens()  # number of generators
     829        +Infinity
     830        sage: A.gen(5)   # 5th generator
     831        Sq(32)
     832        sage: A.order()
     833        +Infinity
     834        sage: A.is_finite()
     835        False
     836        sage: A.is_commutative()
     837        False
     838        sage: A.is_noetherian()
     839        False
     840        sage: A.is_integral_domain()
     841        False
     842        sage: A.is_field()
     843        False
     844        sage: A.is_division_algebra()
     845        False
     846        sage: A.category()
     847        Category of algebras over Finite Field of size 2
     848
     849    There are methods for constructing elements of the Steenrod algebra:
     850        sage: A2 = SteenrodAlgebra(2); A2
     851        mod 2 Steenrod algebra
     852        sage: A2.Sq(1,2,6)
     853        Sq(1,2,6)
     854        sage: A2.Q(3,4)  # product of Milnor primitives Q_3 and Q_4
     855        Sq(0,0,0,1,1)
     856        sage: A2.pst(2,3)  # Margolis pst element
     857        Sq(0,0,4)
     858        sage: A5 = SteenrodAlgebra(5); A5
     859        mod 5 Steenrod algebra
     860        sage: A5.P(1,2,6)
     861        P(1,2,6)
     862        sage: A5.Q(3,4)
     863        Q_3 Q_4
     864        sage: A5.Q(3,4) * A5.P(1,2,6)
     865        Q_3 Q_4 P(1,2,6)
     866        sage: A5.pst(2,3)
     867        P(0,0,25)
     868
     869    You can test whether elements are contained in the Steenrod algebra:
     870        sage: w = Sq(2) * Sq(4)
     871        sage: w in SteenrodAlgebra(2)
     872        True
     873        sage: w in SteenrodAlgebra(17)
     874        False
     875
     876    Different bases for the Steenrod algebra:
     877
     878    There are two standard vector space bases for the mod $p$ Steenrod
     879    algebra: the Milnor basis and the Serre-Cartan basis.  When $p=2$,
     880    there are also several other, less well-known, bases.  The following
     881    bases have been implemented in this package.
     882
     883      * 'milnor': Milnor basis.  When $p=2$, the Milnor basis consists
     884        of symbols of the form $\text{Sq}(m_1, m_2, ..., m_t)$, where each
     885        $m_i$ is a non-negative integer and if $t>1$, then the last
     886        entry $m_t > 0$.  When $p$ is odd, the Milnor basis consists
     887        of symbols of the form $Q_{e_1} Q_{e_2} ... \mathcal{P}(m_1,
     888        m_2, ..., m_t)$, where $0 \leq e_1 < e_2 < ...$, each $m_i$ is
     889        a non-negative integer, and if $t>1$, then the last entry $m_t
     890        > 0$.
     891
     892      * 'serre-cartan' or 'adem' or 'admissible': Serre-Cartan basis.
     893        The Serre-Cartan basis consists of 'admissible monomials' in
     894        the Steenrod operations.  Thus at the prime 2, it consists of
     895        monomials $\text{Sq}^{m_1} \text{Sq}^{m_2} ... \text{Sq}^{m_t}$ with $m_i \geq
     896        2m_{i+1}$ for each $i$.  At odd primes, it consists of
     897        monomials $\beta^{\epsilon_0} \mathcal{P}^{s_1}
     898        \beta^{\epsilon_1} \mathcal{P}^{s_2} ...  \mathcal{P}^{s_k}
     899        \beta^{\epsilon_k}$ with each $\epsilon_i$ either 0 or 1, $s_i
     900        \geq p s_{i+1} + \epsilon_i$, and $s_k \geq 1$.
     901
     902        When $p=2$, the element $\text{Sq}^a$ equals the Milnor element
     903        $\text{Sq}(a)$; when $p$ is odd, $\mathcal{P}^a = \mathcal{P}(a)$ and
     904        $\beta = Q_0$.  Hence for any Serre-Cartan basis element, one
     905        can represent it in the Milnor basis by computing an
     906        appropriate product using Milnor multiplication.
     907
     908    The rest of these bases are only defined when $p=2$.
     909
     910      * 'wood_y': Wood's Y basis.  For pairs of non-negative integers
     911        $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Y$
     912        basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     913        $(m_i,k_i) > (m_{i+1},k_{i+1})$, in left lex order.
     914
     915      * 'wood_z': Wood's Z basis.  For pairs of non-negative integers
     916        $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Z$
     917        basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     918        $(m_i+k_i,m_i) > (m_{i+1}+k_{i+1},m_{i+1})$, in left lex
     919        order.
     920
     921      * 'wall': Wall's basis.  For any pair of integers $(m,k)$ with
     922        $m \geq k \geq 0$, let $Q^m_k = \text{Sq}^{2^k} \text{Sq}^{2^{k+1}}
     923        ... \text{Sq}^{2^m}$.  The elements of Wall's basis are monomials
     924        $Q^{m_0}_{k_0} ... Q^{m_t}_{k_t}$ with $(m_i, k_i) > (m_{i+1},
     925        k_{i+1})$, ordered left lexicographically.
     926
     927        The standard way of printing elements of the Wall basis is to
     928        write elements in terms of the $Q^m_k$.  If one sets the basis
     929        to 'wall_long' instead of 'wall', then each $Q^m_k$ is
     930        expanded as a product of factors of the form $\text{Sq}^{2^i}$.
     931
     932      * 'arnon_a': Arnon's A basis.  For any pair of integers $(m,k)$
     933        with $m \geq k \geq 0$, let $X^m_k = \text{Sq}^{2^m} \text{Sq}^{2^{m-1}}
     934        ... \text{Sq}^{2^k}$.  The elements of Arnon's A basis are monomials
     935        $X^{m_0}_{k_0} ... X^{m_t}_{k_t}$ with $(m_i, k_i) < (m_{i+1},
     936        k_{i+1})$, ordered left lexicographically.
     937
     938        The standard way of printing elements of Arnon's A basis is to
     939        write elements in terms of the $X^m_k$.  If one sets the basis
     940        to 'arnon_a_long' instead of 'arnon_a', then each $X^m_k$ is
     941        expanded as a product of factors of the form $\text{Sq}^{2^i}$.
     942
     943      * 'arnon_c': Arnon's C basis.  The elements of Arnon's C basis
     944        are monomials of the form $\text{Sq}^{t_1} ... \text{Sq}^{t_m}$ where for
     945        each $i$, we have $t_i \leq 2t_{i+1}$ and $2^i | t_{m-i}$.
     946
     947      * 'pst', 'pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz': various
     948        P^s_t-bases.  For integers $s \geq 0$ and $t > 0$, the element
     949        $P^s_t$ is the Milnor basis element $\text{Sq}(0, ..., 0, 2^s, 0,
     950        ...)$, with the nonzero entry in position $t$.  To obtain a
     951        $P^s_t$-basis, for each set $\{P^{s_1}_{t_1}, ...,
     952        P^{s_k}_{t_k}\}$ of (distinct) $P^s_t$'s, one chooses an
     953        ordering and forms the resulting monomial.  The set of all
     954        such monomials then forms a basis, and so one gets a basis by
     955        choosing an ordering on each monomial.
     956
     957        The strings 'rlex', 'llex', etc., correspond to the following
     958        orderings.  These are all 'global' -- they give a global
     959        ordering on the $P^s_t$'s, not different orderings depending
     960        on the monomial.  They order the $P^s_t$'s using the pair of
     961        integers $(s,t)$ as follows:
     962
     963          * 'rlex': right lexicographic ordering
     964
     965          * 'llex': left lexicographic ordering
     966
     967          * 'deg': ordered by degree, which is the same as left
     968            lexicographic ordering on the pair $(s+t,t)$
     969
     970          * 'revz': left lexicographic ordering on the pair $(s+t,s)$,
     971            which is the reverse of the ordering used (on elements in
     972            the same degrees as the $P^s_t$'s) in Wood's Z basis:
     973            'revz' stands for 'reversed Z'.  This is the default:
     974            'pst' is the same as 'pst_revz'.
     975
     976      * 'comm', 'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz':
     977        various commutator bases.  Let $c_{i,1} = \text{Sq}^{2^i}$, let
     978        $c_{i,2} = [c_{i,1}, c_{i+1,1}]$, and inductively define
     979        $c_{i,k} = [c_{i,k-1}, c_{i+k-1,1}]$.  Thus $c_{i,k}$ is a
     980        $k$-fold iterated commutator of the elements $\text{Sq}^{2^i}$, ...,
     981        $\text{Sq}^{2^{i+k-1}}$.  Note that $\dim c_{i,k} = \dim P^i_k$.
     982
     983        To obtain a commutator basis, for each set $\{c_{s_1,t_1},
     984        ..., c_{s_k,t_k}\}$ of (distinct) $c_{s,t}$'s, one chooses an
     985        ordering and forms the resulting monomial.  The set of all
     986        such monomials then forms a basis, and so one gets a basis by
     987        choosing an ordering on each monomial.  The strings 'rlex',
     988        etc., have the same meaning as for the orderings on
     989        $P^s_t$-bases.  As with the $P^s_t$-bases, 'comm_revz' is the
     990        default: 'comm' means 'comm_revz'.
     991
     992        The commutator bases have alternative representations,
     993        obtained by appending 'long' to their names: instead of, say,
     994        $c_{2,2}$, the representation is $s_{48}$, indicating the
     995        commutator of $\text{Sq}^4$ and $\text{Sq}^8$, and $c_{0,3}$, which is equal
     996        to $[[\text{Sq}^1, \text{Sq}^2], \text{Sq}^4]$, is written as $s_{124}$.
     997
     998    When defining a Steenrod algebra, you can specify a basis.  Then
     999    elements of that Steenrod algebra are printed in that basis
     1000        sage: adem = SteenrodAlgebra(2, 'adem')
     1001        sage: x = adem.Sq(2,1)  # Sq(-) always means a Milnor basis element
     1002        sage: x
     1003        Sq^{4} Sq^{1} + Sq^{5}
     1004        sage: y = Sq(0,1)    # unadorned Sq defines elements w.r.t. Milnor basis
     1005        sage: y
     1006        Sq(0,1)
     1007        sage: adem(y)
     1008        Sq^{2} Sq^{1} + Sq^{3}
     1009        sage: adem5 = SteenrodAlgebra(5, 'serre-cartan')
     1010        sage: adem5.P(0,2)
     1011        P^{10} P^{2} + 4 P^{11} P^{1} + 4 P^{12}
     1012
     1013    You can get a list of basis elements in a given dimension:
     1014        sage: A3 = SteenrodAlgebra(3, 'milnor')
     1015        sage: A3.basis(13)
     1016        (Q_1 P(2), Q_0 P(3))
     1017
     1018    As noted above, several of the bases ('arnon_a', 'wall', 'comm')
     1019    have alternate, longer, representations.  These provide ways of
     1020    expressing elements of the Steenrod algebra in terms of the
     1021    $\text{Sq}^{2^n}$.
     1022        sage: A_long = SteenrodAlgebra(2, 'arnon_a_long')
     1023        sage: A_long(Sq(6))
     1024        Sq^{1} Sq^{2} Sq^{1} Sq^{2} + Sq^{2} Sq^{4}
     1025        sage: SteenrodAlgebra(2, 'wall_long')(Sq(6))
     1026        Sq^{2} Sq^{1} Sq^{2} Sq^{1} + Sq^{2} Sq^{4}
     1027        sage: SteenrodAlgebra(2, 'comm_deg_long')(Sq(6))
     1028        s_{1} s_{2} s_{12} + s_{2} s_{4}
     1029    """
     1030    basis_name = get_basis_name(basis, p)
     1031    if p == 2:
     1032        return SteenrodAlgebra_mod_two(2, basis_name)
     1033    else:
     1034        return SteenrodAlgebra_generic(p, basis_name)
     1035
     1036"""
     1037These are the recognized basis names.  For the Milnor and Serre-Cartan
     1038bases, give a list of synonyms:
     1039"""
     1040
     1041_steenrod_milnor_basis_names = ['milnor']
     1042_steenrod_serre_cartan_basis_names = ['serre_cartan', 'serre-cartan', 'sc',
     1043                                         'adem', 'admissible']
     1044
     1045"""
     1046For the other bases, use pattern-matching rather than a list of
     1047synonyms:
     1048  * Search for 'wood' and 'y' or 'wood' and 'z' to get the Wood bases.
     1049  * Search for 'arnon' and 'c' for the Arnon C basis.
     1050  * Search for 'arnon' (and no 'c') for the Arnon A basis.  Also see if
     1051    'long' is present, for the long form of the basis.
     1052  * Search for 'wall' for the Wall basis. Also see if 'long' is present.
     1053  * Search for 'pst' for P^s_t bases, then search for the order type:
     1054    'rlex', 'llex', 'deg', 'revz'.
     1055  * For commutator types, search for 'comm', an order type, and also
     1056    check to see if 'long' is present.
     1057"""
     1058
     1059def get_basis_name(basis, p):
     1060    """
     1061    Return canonical basis named by string basis at the prime p.
     1062   
     1063    INPUT:
     1064        basis -- string
     1065        p -- positive prime number
     1066
     1067    OUTPUT:
     1068        basis_name -- string
     1069
     1070    EXAMPLES:
     1071        sage: sage.algebras.steenrod_algebra.get_basis_name('adem', 2)
     1072        'serre-cartan'
     1073        sage: sage.algebras.steenrod_algebra.get_basis_name('milnor', 2)
     1074        'milnor'
     1075        sage: sage.algebras.steenrod_algebra.get_basis_name('MiLNoR', 5)
     1076        'milnor'
     1077        sage: sage.algebras.steenrod_algebra.get_basis_name('pst-llex', 2)
     1078        'pst_llex'
     1079    """
     1080    basis = basis.lower()
     1081    if basis in _steenrod_milnor_basis_names:
     1082        result = 'milnor'
     1083    elif basis in _steenrod_serre_cartan_basis_names:
     1084        result = 'serre-cartan'
     1085    elif p == 2 and basis.find('pst') >= 0:
     1086        if basis.find('rlex') >= 0:
     1087            result = 'pst_rlex'
     1088        elif basis.find('llex') >= 0:
     1089            result = 'pst_llex'
     1090        elif basis.find('deg') >= 0:
     1091            result = 'pst_deg'
     1092        elif basis.find('revz') >= 0:
     1093            result = 'pst_revz'
     1094        else:
     1095            result = 'pst_revz'
     1096    elif p == 2 and basis.find('comm') >= 0:
     1097        if basis.find('rlex') >= 0:
     1098            result = 'comm_rlex'
     1099        elif basis.find('llex') >= 0:
     1100            result = 'comm_llex'
     1101        elif basis.find('deg') >= 0:
     1102            result = 'comm_deg'
     1103        elif basis.find('revz') >= 0:
     1104            result = 'comm_revz'
     1105        else:
     1106            result = 'comm_revz'
     1107        if basis.find('long') >= 0:
     1108            result = result + '_long'
     1109    elif p == 2 and basis.find('wood') >= 0:
     1110        if basis.find('y') >= 0:
     1111            result = 'woody'
     1112        else:
     1113            result = 'woodz'
     1114    elif p == 2 and basis.find('arnon') >= 0:
     1115        if basis.find('c') >= 0:
     1116            result = 'arnonc'
     1117        else:
     1118            result = 'arnona'
     1119            if basis.find('long') >= 0:
     1120                result = result + '_long'
     1121    elif p == 2 and basis.find('wall') >= 0:
     1122        result = 'wall'
     1123        if basis.find('long') >= 0:
     1124            result = result + '_long'
     1125    else:
     1126        raise ValueError, "%s is not a recognized basis at the prime %s." % (basis, p)
     1127    return result
  • new file sage/algebras/steenrod_algebra_bases.py

    diff -r 96e35b9306b1 -r c7742f1ad322 sage/algebras/steenrod_algebra_bases.py
    - +  
     1r"""
     2Vector space bases for the mod p Steenrod algebra.
     3
     4AUTHORS:
     5    - John H. Palmieri (2008-07-17: version 0.8)
     6
     7This package defines functions for computing various bases of the
     8Steenrod algebra, and for converting between the Milnor basis and any
     9other basis.
     10
     11A number of different bases have been implemented, at least at the
     12prime 2.  The first two are the most familiar and most standard ones,
     13and all of the others are defined in terms of one of these.  See the
     14papers by Monks [M] and Wood [W] for more information about most of
     15these.  For commutator bases, see the preprint by Palmieri and Zhang
     16[PZ].
     17
     18  * 'milnor': Milnor basis.  When $p=2$, the Milnor basis consists of
     19    symbols of the form $\text{Sq}(m_1, m_2, ..., m_t)$, where each
     20    $m_i$ is a non-negative integer and if $t>1$, then the last entry
     21    $m_t \neq 0$.  When $p$ is odd, the Milnor basis consists of
     22    symbols of the form $Q_{e_1} Q_{e_2} ... \mathcal{P}(m_1, m_2,
     23    ..., m_t)$, where $0 \leq e_1 < e_2 < ...$, each $m_i$ is a
     24    non-negative integer, and if $t>1$, then the last entry $m_t \neq
     25    0$.
     26
     27  * 'serre-cartan' or 'adem' or 'admissible': Serre-Cartan basis.  The
     28    Serre-Cartan basis consists of 'admissible monomials' in the
     29    Steenrod operations.  Thus at the prime 2, it consists of
     30    monomials $\text{Sq}^{m_1} \text{Sq}^{m_2} ... \text{Sq}^{m_t}$
     31    with $m_i \geq 2m_{i+1}$ for each $i$.  At odd primes, it consists
     32    of monomials $\beta^{\epsilon_0} \mathcal{P}^{s_1}
     33    \beta^{\epsilon_1} \mathcal{P}^{s_2} ...  \mathcal{P}^{s_k}
     34    \beta^{\epsilon_k}$ with each $\epsilon_i$ either 0 or 1, $s_i
     35    \geq p s_{i+1} + \epsilon_i$, and $s_k \geq 1$.
     36
     37    When $p=2$, the element $\text{Sq}^a$ equals the Milnor element
     38    $\text{Sq}(a)$; when $p$ is odd, $\mathcal{P}^a = \mathcal{P}(a)$
     39    and $\beta = Q_0$.  Hence one can represent any Serre-Cartan basis
     40    element in the Milnor basis by computing an appropriate product
     41    using Milnor multiplication.
     42
     43The other bases implemented are as follows; these are only
     44defined when $p=2$:
     45
     46  * 'wood_y': Wood's Y basis.  For pairs of non-negative integers
     47    $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Y$
     48    basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     49    $(m_i,k_i) > (m_{i+1},k_{i+1})$, in left lex order.
     50
     51  * 'wood_z': Wood's Z basis.  For pairs of non-negative integers
     52    $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Z$
     53    basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     54    $(m_i+k_i,m_i) > (m_{i+1}+k_{i+1},m_{i+1})$, in left lex order.
     55
     56  * 'wall': Wall's basis.  For any pair of integers $(m,k)$ with $m
     57    \geq k \geq 0$, let $Q^m_k = \text{Sq}^{2^k} \text{Sq}^{2^{k+1}}
     58    ... \text{Sq}^{2^m}$.  The elements of Wall's basis are monomials
     59    $Q^{m_0}_{k_0} ... Q^{m_t}_{k_t}$ with $(m_i, k_i) > (m_{i+1},
     60    k_{i+1})$, ordered left lexicographically.
     61
     62    The standard way of printing elements of the Wall basis is to
     63    write elements in terms of the $Q^m_k$.  If one sets the basis to
     64    'wall_long' instead of 'wall', then each $Q^m_k$ is expanded as a
     65    product of factors of the form $\text{Sq}^{2^i}$.
     66
     67  * 'arnon_a': Arnon's A basis. For any pair of integers $(m,k)$ with
     68    $m \geq k \geq 0$, let $X^m_k = \text{Sq}^{2^m}
     69    \text{Sq}^{2^{m-1}} ... \text{Sq}^{2^k}$.  The elements of Arnon's
     70    A basis are monomials $X^{m_0}_{k_0} ... X^{m_t}_{k_t}$ with
     71    $(m_i, k_i) < (m_{i+1}, k_{i+1})$, ordered left lexicographically.
     72
     73    The standard way of printing elements of Arnon's A basis is to
     74    write elements in terms of the $X^m_k$.  If one sets the basis to
     75    'arnon_a_long' instead of 'arnon_a', then each $X^m_k$ is expanded
     76    as a product of factors of the form $\text{Sq}^{2^i}$.
     77
     78  * 'arnon_c': Arnon's C basis. The elements of Arnon's C basis are
     79    monomials of the form $\text{Sq}^{t_1} ... \text{Sq}^{t_m}$ where
     80    for each $i$, we have $t_i \leq 2t_{i+1}$ and $2^i | t_{m-i}$.
     81
     82  * 'pst' or 'pst_ORDER': Various $P^s_t$-bases. For integers $s \geq
     83    0$ and $t > 0$, the element $P^s_t$ is the Milnor basis element
     84    $\text{Sq}(0, ..., 0, 2^s, 0, ...)$, with the nonzero entry in
     85    position $t$.  To obtain a $P^s_t$-basis, for each set
     86    $\{P^{s_1}_{t_1}, ..., P^{s_k}_{t_k}\}$ of (distinct) $P^s_t$'s,
     87    one chooses an ordering and forms the resulting monomial.  The set
     88    of all such monomials then forms a basis, and so one gets a basis
     89    by choosing an ordering on each monomial.
     90
     91    The string ORDER corresponds to the following orderings.  These
     92    are all 'global' -- they give a global ordering on the $P^s_t$'s,
     93    not different orderings depending on the monomial.  They order the
     94    $P^s_t$'s using the pair of integers $(s,t)$ as follows:
     95
     96      * 'rlex': right lexicographic ordering
     97
     98      * 'llex': left lexicographic ordering
     99
     100      * 'deg': ordered by degree, which is the same as left
     101        lexicographic ordering on the pair $(s+t,t)$
     102
     103      * 'revz': left lexicographic ordering on the pair $(s+t,s)$,
     104        which is the reverse of the ordering used (on elements in the
     105        same degrees as the $P^s_t$'s) in Wood's Z basis: 'revz'
     106        stands for 'reversed Z'.  This is the default: if ORDER is
     107        omitted, this ordering is used.
     108
     109  * 'comm' or 'comm_ORDER': Various commutator bases.  Let $c_{i,1} =
     110    \text{Sq}^{2^i}$, let $c_{i,2} = [c_{i,1}, c_{i+1,1}]$, and
     111    inductively define $c_{i,k} = [c_{i,k-1}, c_{i+k-1,1}]$.  Thus
     112    $c_{i,k}$ is a $k$-fold iterated commutator of the elements
     113    $\text{Sq}^{2^i}$, ..., $\text{Sq}^{2^{i+k-1}}$.  Note that $\dim
     114    c_{i,k} = \dim P^i_k$.
     115
     116    To obtain a commutator basis, for each set $\{c_{s_1,t_1}, ...,
     117    c_{s_k,t_k}\}$ of (distinct) $c_{s,t}$'s, one chooses an ordering
     118    and forms the resulting monomial.  The set of all such monomials
     119    then forms a basis, and so one gets a basis by choosing an
     120    ordering on each monomial.  The string ORDER has the same meaning
     121    as for the orderings on $P^s_t$-bases.
     122
     123    The commutator bases have alternative representations, obtained by
     124    appending 'long' to their names: instead of, say, $c_{2,2}$, the
     125    representation is $s_{48}$, indicating the commutator of
     126    $\text{Sq}^4$ and $\text{Sq}^8$, and $c_{0,3}$, which is equal to
     127    $[[\text{Sq}^1, \text{Sq}^2], \text{Sq}^4]$, is written as
     128    $s_{124}$.
     129
     130EXAMPLES:
     131    sage: steenrod_algebra_basis(7,'milnor')
     132    (Sq(0,0,1), Sq(1,2), Sq(4,1), Sq(7))
     133    sage: steenrod_algebra_basis(5)   # milnor basis is the default
     134    (Sq(2,1), Sq(5))
     135
     136The third (optional) argument to 'steenrod_algebra_basis' is the prime p:
     137    sage: steenrod_algebra_basis(9, 'milnor', p=3)
     138    (Q_1 P(1), Q_0 P(2))
     139    sage: steenrod_algebra_basis(9, 'milnor', 3)
     140    (Q_1 P(1), Q_0 P(2))
     141    sage: steenrod_algebra_basis(17, 'milnor', 3)
     142    (Q_2, Q_1 P(3), Q_0 P(0,1), Q_0 P(4))
     143
     144Other bases:
     145    sage: steenrod_algebra_basis(7,'admissible')
     146    (Sq^{7}, Sq^{6} Sq^{1}, Sq^{4} Sq^{2} Sq^{1}, Sq^{5} Sq^{2})
     147    sage: [x.basis('milnor') for x in steenrod_algebra_basis(7,'admissible')]
     148    [Sq(7),
     149    Sq(4,1) + Sq(7),
     150    Sq(0,0,1) + Sq(1,2) + Sq(4,1) + Sq(7),
     151    Sq(1,2) + Sq(7)]
     152    sage: Aw = SteenrodAlgebra(2, basis = 'wall_long')
     153    sage: [Aw(x) for x in steenrod_algebra_basis(7,'admissible')]
     154    [Sq^{1} Sq^{2} Sq^{4},
     155    Sq^{2} Sq^{4} Sq^{1},
     156    Sq^{4} Sq^{2} Sq^{1},
     157    Sq^{4} Sq^{1} Sq^{2}]
     158    sage: steenrod_algebra_basis(13,'admissible',p=3)
     159    (beta P^{3}, P^{3} beta)
     160    sage: steenrod_algebra_basis(5,'wall')
     161    (Q^{2}_{2} Q^{0}_{0}, Q^{1}_{1} Q^{1}_{0})
     162    sage: steenrod_algebra_basis(5,'wall_long')
     163    (Sq^{4} Sq^{1}, Sq^{2} Sq^{1} Sq^{2})
     164    sage: steenrod_algebra_basis(5,'pst-rlex')
     165    (P^{0}_{1} P^{2}_{1}, P^{1}_{1} P^{0}_{2})
     166
     167This file also contains a function 'milnor_convert' which converts
     168elements from the (default) Milnor basis representation to a
     169representation in another basis.  The output is a dictionary which
     170gives the new representation; its form depends on the chosen basis.
     171For example, in the basis of admissible sequences (a.k.a. the
     172Serre-Cartan basis), each basis element is of the form $\text{Sq}^a
     173\text{Sq}^b ...$, and so is represented by a tuple $(a,b,...)$ of
     174integers.  Thus the dictionary has such tuples as keys, with the
     175coefficient of the basis element as the associated value:
     176    sage: from sage.algebras.steenrod_algebra_bases import milnor_convert
     177    sage: milnor_convert(Sq(2)*Sq(4) + Sq(2)*Sq(5), 'admissible')
     178    {(5, 1): 1, (6, 1): 1, (6,): 1}
     179    sage: milnor_convert(Sq(2)*Sq(4) + Sq(2)*Sq(5), 'pst')
     180    {((1, 1), (2, 1)): 1, ((0, 1), (1, 1), (2, 1)): 1, ((0, 2), (2, 1)): 1}
     181
     182Users shouldn't need to call 'milnor_convert'; they should use the
     183'basis' method to view a single element in another basis, or define a
     184Steenrod algebra with a different default basis and work in that
     185algebra:
     186    sage: x = Sq(2)*Sq(4) + Sq(2)*Sq(5)
     187    sage: x
     188    Sq(3,1) + Sq(4,1) + Sq(6) + Sq(7)
     189    sage: x.basis('milnor')  # 'milnor' is the default basis
     190    Sq(3,1) + Sq(4,1) + Sq(6) + Sq(7)
     191    sage: x.basis('adem')
     192    Sq^{5} Sq^{1} + Sq^{6} + Sq^{6} Sq^{1}
     193    sage: x.basis('pst')
     194    P^{0}_{1} P^{1}_{1} P^{2}_{1} + P^{0}_{2} P^{2}_{1} + P^{1}_{1} P^{2}_{1}
     195    sage: A = SteenrodAlgebra(2, basis='pst')
     196    sage: A(Sq(2) * Sq(4) + Sq(2) * Sq(5))
     197    P^{0}_{1} P^{1}_{1} P^{2}_{1} + P^{0}_{2} P^{2}_{1} + P^{1}_{1} P^{2}_{1}
     198
     199REFERENCES:
     200    [M]  K. G. Monks, "Change of basis, monomial relations, and $P^s_t$
     201         bases for the Steenrod algebra," J. Pure Appl. Algebra 125 (1998),
     202         no. 1-3, 235--260.
     203    [PZ] J. H. Palmieri and J. J. Zhang, "Commutators in the Steenrod
     204         algebra," preprint (2008)
     205    [W]  R. M. W. Wood, "Problems in the Steenrod algebra," Bull. London
     206         Math. Soc. 30 (1998), no. 5, 449--517.
     207"""
     208
     209#*****************************************************************************
     210#       Copyright (C) 2008 William Stein <wstein@gmail.com>
     211#       Copyright (C) 2008 John H. Palmieri <palmieri@math.washington.edu>
     212#  Distributed under the terms of the GNU General Public License (GPL)
     213#*****************************************************************************
     214
     215from sage.rings.integer import Integer
     216from sage.rings.all import GF
     217
     218from steenrod_algebra import SteenrodAlgebra, \
     219    _steenrod_serre_cartan_basis_names, _steenrod_milnor_basis_names, get_basis_name
     220from steenrod_algebra_element import SteenrodAlgebraElement, \
     221    Sq, pst
     222
     223
     224class memoize:
     225    """
     226    Taken from the web page
     227    <http://avinashv.net/2008/04/python-decorators-syntactic-sugar/>
     228    """
     229    def __init__(self, function):
     230        self.function = function
     231        self.memoized = {}
     232
     233    def __call__(self, *args):
     234        try:
     235            return self.memoized[args]
     236        except KeyError:
     237            self.memoized[args] = self.function(*args)
     238            return self.memoized[args]
     239
     240@memoize
     241def convert_to_milnor_matrix(n, basis, p=2):
     242    r"""
     243    Change-of-basis matrix, 'basis' to Milnor, in dimension $n$, at the prime $p$.
     244
     245    INPUT:
     246        n -- non-negative integer, the dimension
     247        basis -- string, the basis from which to convert
     248        p (optional, default 2) -- positive prime number
     249
     250    OUTPUT:
     251        matrix -- change-of-basis matrix, a square matrix over GF(p)
     252
     253    (This is not really intended for casual users, so no error
     254    checking is made on the integer $n$, the basis name, or the prime.)
     255
     256    EXAMPLES:
     257        sage: from sage.algebras.steenrod_algebra_bases import convert_to_milnor_matrix
     258        sage: convert_to_milnor_matrix(5, 'adem')
     259        [0 1]
     260        [1 1]
     261        sage: convert_to_milnor_matrix(45, 'milnor')
     262        111 x 111 dense matrix over Finite Field of size 2
     263        sage: convert_to_milnor_matrix(12,'wall')
     264        [1 0 0 1 0 0 0]
     265        [1 1 0 0 0 1 0]
     266        [0 1 0 1 0 0 0]
     267        [0 0 0 1 0 0 0]
     268        [1 1 0 0 1 0 0]
     269        [0 0 1 1 1 0 1]
     270        [0 0 0 0 1 0 1]
     271
     272    The function takes an optional argument, the prime p over which to work:
     273        sage: convert_to_milnor_matrix(17,'adem',3)
     274        [0 0 1 1]
     275        [0 0 0 1]
     276        [1 1 1 1]
     277        [0 1 0 1]
     278        sage: convert_to_milnor_matrix(48,'adem',5)
     279        [0 1]
     280        [1 1]
     281    """
     282    from sage.matrix.constructor import matrix
     283    milnor_base = steenrod_algebra_basis(n,'milnor',p)
     284    rows = []
     285    for poly in steenrod_algebra_basis(n,basis,p):
     286        for v in milnor_base:
     287            if v in poly: rows = rows + [1]
     288            else: rows = rows + [0]
     289    d = len(milnor_base)
     290    return matrix(GF(p),d,d,rows)
     291
     292
     293def convert_from_milnor_matrix(n, basis, p=2):
     294    r"""
     295    Change-of-basis matrix, Milnor to 'basis', in dimension $n$.
     296
     297    INPUT:
     298        n -- non-negative integer, the dimension
     299        basis -- string, the basis to which to convert
     300        p (optional, default 2) -- positive prime number
     301
     302    OUTPUT:
     303        matrix -- change-of-basis matrix, a square matrix over GF(p)
     304
     305    (This is not really intended for casual users, so no error
     306    checking is made on the integer $n$, the basis name, or the prime.)
     307
     308    EXAMPLES:
     309        sage: from sage.algebras.steenrod_algebra_bases import convert_from_milnor_matrix, convert_to_milnor_matrix
     310        sage: convert_from_milnor_matrix(12,'wall')
     311        [1 0 0 1 0 0 0]
     312        [0 0 1 1 0 0 0]
     313        [0 0 0 1 0 1 1]
     314        [0 0 0 1 0 0 0]
     315        [1 0 1 0 1 0 0]
     316        [1 1 1 0 0 0 0]
     317        [1 0 1 0 1 0 1]
     318        sage: convert_from_milnor_matrix(38,'serre_cartan')
     319        72 x 72 dense matrix over Finite Field of size 2
     320        sage: x = convert_to_milnor_matrix(20,'wood_y')
     321        sage: y = convert_from_milnor_matrix(20,'wood_y')
     322        sage: x*y
     323        [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     324        [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     325        [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     326        [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
     327        [0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
     328        [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
     329        [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
     330        [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
     331        [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
     332        [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
     333        [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
     334        [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
     335        [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
     336        [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0]
     337        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0]
     338        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0]
     339        [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
     340
     341    The function takes an optional argument, the prime p over which to work:
     342        sage: convert_from_milnor_matrix(17,'adem',3)
     343        [2 1 1 2]
     344        [0 2 0 1]
     345        [1 2 0 0]
     346        [0 1 0 0]
     347    """
     348    mat = convert_to_milnor_matrix(n,basis,p)
     349    if mat.nrows() != 0:
     350        return convert_to_milnor_matrix(n,basis,p).inverse()
     351    else:
     352        return mat
     353
     354
     355def make_elt_homogeneous(poly):
     356    """
     357    Break element of the Steenrod algebra into a list of homogeneous pieces.
     358
     359    INPUT:
     360        poly -- an element of the Steenrod algebra
     361
     362    OUTPUT:
     363        list of homogeneous elements of the Steenrod algebra whose sum is poly
     364
     365    EXAMPLES:
     366        sage: from sage.algebras.steenrod_algebra_bases import make_elt_homogeneous
     367        sage: make_elt_homogeneous(Sq(2)*Sq(4) + Sq(2)*Sq(5))
     368        [Sq(3,1) + Sq(6), Sq(4,1) + Sq(7)]
     369    """
     370    degrees = set([m.degree() for m in poly])   # set of degrees in poly
     371    result = []
     372    for d in degrees:
     373        result_d = 0
     374        for m in poly:
     375            if m.degree() == d:
     376                result_d = result_d + m
     377        result.append(result_d)
     378    return result
     379
     380
     381def milnor_convert(poly, basis):
     382    """
     383    Convert an element of the Steenrod algebra in the Milnor basis
     384    to its representation in the chosen basis.
     385
     386    INPUT:
     387        poly -- element of the Steenrod algebra
     388        basis -- basis to which to convert
     389
     390    OUTPUT:
     391        dict -- dictionary of terms of the form (mono: coeff), where
     392        mono is a monomial in 'basis'.  The form of mono depends on
     393        the chosen basis.
     394   
     395    EXAMPLES:
     396        sage: from sage.algebras.steenrod_algebra_bases import milnor_convert
     397        sage: milnor_convert(Sq(2)*Sq(4) + Sq(2)*Sq(5), 'adem')
     398        {(5, 1): 1, (6, 1): 1, (6,): 1}
     399        sage: A3 = SteenrodAlgebra(3)
     400        sage: a = A3.Q(1) * A3.P(2,2); a
     401        Q_1 P(2,2)
     402        sage: milnor_convert(a, 'adem')
     403        {(0, 9, 1, 2, 0): 1, (1, 9, 0, 2, 0): 2}
     404        sage: milnor_convert(2 * a, 'adem')
     405        {(0, 9, 1, 2, 0): 2, (1, 9, 0, 2, 0): 1}
     406        sage: (Sq(2)*Sq(4) + Sq(2)*Sq(5)).basis('adem')
     407        Sq^{5} Sq^{1} + Sq^{6} + Sq^{6} Sq^{1}
     408        sage: a.basis('adem')
     409        P^{9} beta P^{2} + 2 beta P^{9} P^{2}
     410        sage: milnor_convert(Sq(2)*Sq(4) + Sq(2)*Sq(5), 'pst')
     411        {((1, 1), (2, 1)): 1, ((0, 1), (1, 1), (2, 1)): 1, ((0, 2), (2, 1)): 1}
     412        sage: (Sq(2)*Sq(4) + Sq(2)*Sq(5)).basis('pst')
     413        P^{0}_{1} P^{1}_{1} P^{2}_{1} + P^{0}_{2} P^{2}_{1} + P^{1}_{1}
     414        P^{2}_{1}
     415    """
     416    from sage.matrix.constructor import matrix
     417    p = poly._prime
     418    basis_name = get_basis_name(basis, p)
     419    if basis_name.find('long') >= 0:
     420        basis_name = basis_name.rsplit('_', 1)[0]
     421    if basis_name == 'milnor': return poly._raw['milnor']
     422    dict = {}
     423    for x in make_elt_homogeneous(poly):
     424        dim = x.degree()
     425        vec = []
     426        for mono in steenrod_algebra_basis(dim,'milnor',p):
     427            if mono._raw['milnor'].keys()[0] in x._raw['milnor'].keys():
     428                for entry in mono._raw['milnor']:
     429                    coeff =  x._raw['milnor'][entry]
     430                vec = vec + [coeff]
     431            else:
     432                vec = vec + [0]
     433        new_vec = (matrix(GF(p),1,len(vec),vec)
     434                   * convert_from_milnor_matrix(dim, basis_name, p)).row(0)
     435        for (mono,coeff) in zip(steenrod_algebra_basis(dim, basis_name, p), new_vec):
     436            if coeff != 0:
     437                old_dict = mono._raw[basis_name]
     438                for entry in old_dict:
     439                    dict[entry] = coeff
     440    return dict
     441
     442
     443_steenrod_bases = {}
     444
     445def steenrod_algebra_basis(n, basis='milnor', p=2):
     446    r"""
     447    Basis for the Steenrod algebra in degree $n$.
     448
     449    INPUT:
     450        n -- non-negative integer
     451        basis (optional) -- string, which basis to use.  If omitted,
     452            use the current basis
     453        p (optional, default = 2) -- positive prime number
     454
     455    OUTPUT:
     456        tuple of basis elements for the Steenrod algebra in dimension n
     457
     458    The choices for the string basis are as follows:
     459   
     460    'milnor': Milnor basis.  At the prime 2, the Milnor basis consists
     461    of symbols of the form $\text{Sq}(m_1, m_2, ..., m_t)$, where each
     462    $m_i$ is a non-negative integer and if $t>1$, then $m_t \neq 0$.
     463    At odd primes, it consists of symbols of the form $Q_{e_1} Q_{e_2}
     464    ... P(m_1, m_2, ..., m_t)$, where $0 \leq e_1 < e_2 < ...$, each
     465    $m_i$ is a non-negative integer, and if $t>1$, then $m_t \neq 0$.
     466
     467    'serre-cartan' or 'adem' or 'admissible': Serre-Cartan basis.
     468    The Serre-Cartan basis consists of 'admissible monomials in the
     469    Steenrod squares'.  Thus at the prime 2, it consists of monomials
     470    $\text{Sq}^{m_1} \text{Sq}^{m_2} ... \text{Sq}^{m_t}$ with $m_i
     471    \geq 2m_{i+1}$ for each $i$.  At odd primes, it consists of
     472    monomials $\beta^{\epsilon_0} \mathcal{P}^{s_1} \beta^{\epsilon_1}
     473    \mathcal{P}^{s_2} ...  \mathcal{P}^{s_k} \beta^{\epsilon_k}$ with
     474    each $\epsilon_i$ either 0 or 1, $s_i \geq p s_{i+1} +
     475    \epsilon_i$, and $s_k \geq 1$.
     476
     477    The rest of the bases are only defined when $p=2$.
     478
     479    'wood_y': Wood's Y basis.  For pairs of non-negative integers
     480    $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Y$
     481    basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     482    $(m_i,k_i) > (m_{i+1},k_{i+1})$, in left lex order.
     483
     484    'wood_z': Wood's Z basis.  For pairs of non-negative integers
     485    $(m,k)$, let $w(m,k) = \text{Sq}^{2^m (2^{k+1}-1)}$.  Wood's $Z$
     486    basis consists of monomials $w(m_0,k_0) ... w(m_t, k_t)$ with
     487    $(m_i+k_i,m_i) > (m_{i+1}+k_{i+1},m_{i+1})$, in left lex order.
     488
     489    'wall': Wall's basis.  For any pair of integers $(m,k)$ with $m
     490    \geq k \geq 0$, let $Q^m_k = \text{Sq}^{2^k} \text{Sq}^{2^{k+1}}
     491    ... \text{Sq}^{2^m}$.  The elements of Wall's basis are
     492    monomials $Q^{m_0}_{k_0} ... Q^{m_t}_{k_t}$ with $(m_i, k_i) >
     493    (m_{i+1}, k_{i+1})$, ordered left lexicographically.
     494
     495    The standard way of printing elements of the Wall basis is to write
     496    elements in terms of the $Q^m_k$.  If one sets the basis to
     497    'wall_long' instead of 'wall', then each $Q^m_k$ is expanded as a
     498    product of factors of the form $\text{Sq}^{2^i}$.
     499
     500    'arnon_a': Arnon's A basis. For any pair of integers $(m,k)$ with
     501    $m \geq k \geq 0$, let $X^m_k = \text{Sq}^{2^m}
     502    \text{Sq}^{2^{m-1}} ... \text{Sq}^{2^k}$.  The elements of
     503    Arnon's A basis are monomials $X^{m_0}_{k_0} ... X^{m_t}_{k_t}$
     504    with $(m_i, k_i) < (m_{i+1}, k_{i+1})$, ordered left
     505    lexicographically.
     506
     507    The standard way of printing elements of Arnon's A basis is to
     508    write elements in terms of the $X^m_k$.  If one sets the basis to
     509    'arnon_a_long' instead of 'arnon_a', then each $X^m_k$ is expanded
     510    as a product of factors of the form $\text{Sq}^{2^i}$.
     511
     512    'arnon_c': Arnon's C basis. The elements of Arnon's C basis are
     513    monomials of the form $\text{Sq}^{t_1} ... \text{Sq}^{t_m}$
     514    where for each $i$, we have $t_i \leq 2t_{i+1}$ and $2^i |
     515    t_{m-i}$.
     516
     517    'pst' or 'pst_ORDER': Various $P^s_t$-bases. To obtain a
     518    $P^s_t$-basis, for each set $\{P^{s_1}_{t_1}, ...,
     519    P^{s_k}_{t_k}\}$ of (distinct) $P^s_t$'s, one chooses an ordering
     520    and forms the resulting monomial.  The set of all such monomials
     521    then forms a basis, and so one gets a basis by choosing an
     522    ordering on each monomial.
     523   
     524    The string ORDER corresponds to the following orderings.  These
     525    are all 'global' -- they give a global ordering on the $P^s_t$'s,
     526    not different orderings depending on the monomial.  They order the
     527    $P^s_t$'s using the pair of integers $(s,t)$ as follows:
     528
     529        'rlex': right lexicographic ordering
     530        'llex': left lexicographic ordering
     531        'deg': ordered by degree, which is the same as left lexicographic
     532            ordering on the pair $(s+t,t)$
     533        'revz': left lexicographic ordering on the pair $(s+t,s)$, which is
     534            the reverse of the ordering used (on elements in the same
     535            degrees as the $P^s_t$'s) in Wood's Z basis: 'revz' stands
     536            for 'reversed Z'.  This is the default: if ORDER is omitted,
     537            this ordering is used.
     538
     539    'comm' or 'comm_ORDER': Various commutator bases.  Let $c_{i,1} =
     540    \text{Sq}^{2^i}$, let $c_{i,2} = [c_{i,1}, c_{i+1,1}]$, and
     541    inductively define $c_{i,k} = [c_{i,k-1}, c_{i+k-1,1}]$.  Thus
     542    $c_{i,k}$ is a $k$-fold iterated commutator of the elements
     543    $\text{Sq}^{2^i}$, ..., $\text{Sq}^{2^{i+k-1}}$, and $\dim
     544    c_{i,k} = \dim P^i_k$.
     545       
     546    To obtain a commutator basis, for each set $\{c_{s_1,t_1}, ...,
     547    c_{s_k,t_k}\}$ of (distinct) $c_{s,t}$'s, one chooses an ordering
     548    and forms the resulting monomial.  The set of all such monomials
     549    then forms a basis, and so one gets a basis by choosing an
     550    ordering on each monomial.  The string ORDER has the same meaning
     551    as for the orderings on $P^s_t$-bases.
     552
     553    The commutator bases have alternative representations, obtained by
     554    appending 'long' to their names: instead of, say, $c_{2,2}$, the
     555    representation is $s_{48}$, indicating the commutator of
     556    $\text{Sq}^4$ and $\text{Sq}^8$, and $c_{0,3}$, which is equal to
     557    $[[\text{Sq}^1, \text{Sq}^2], \text{Sq}^4]$, is written as
     558    $s_{124}$.
     559
     560    EXAMPLES:
     561        sage: steenrod_algebra_basis(7,'milnor')
     562        (Sq(0,0,1), Sq(1,2), Sq(4,1), Sq(7))
     563        sage: steenrod_algebra_basis(5)   # milnor basis is the default
     564        (Sq(2,1), Sq(5))
     565
     566    The third (optional) argument to 'steenrod_algebra_basis' is the prime p:
     567        sage: steenrod_algebra_basis(9, 'milnor', p=3)
     568        (Q_1 P(1), Q_0 P(2))
     569        sage: steenrod_algebra_basis(9, 'milnor', 3)
     570        (Q_1 P(1), Q_0 P(2))
     571        sage: steenrod_algebra_basis(17, 'milnor', 3)
     572        (Q_2, Q_1 P(3), Q_0 P(0,1), Q_0 P(4))
     573
     574    Other bases:
     575        sage: steenrod_algebra_basis(7,'admissible')
     576        (Sq^{7}, Sq^{6} Sq^{1}, Sq^{4} Sq^{2} Sq^{1}, Sq^{5} Sq^{2})
     577        sage: [x.basis('milnor') for x in steenrod_algebra_basis(7,'admissible')]
     578        [Sq(7),
     579        Sq(4,1) + Sq(7),
     580        Sq(0,0,1) + Sq(1,2) + Sq(4,1) + Sq(7),
     581        Sq(1,2) + Sq(7)]
     582        sage: steenrod_algebra_basis(13,'admissible',p=3)
     583        (beta P^{3}, P^{3} beta)
     584        sage: steenrod_algebra_basis(5,'wall')
     585        (Q^{2}_{2} Q^{0}_{0}, Q^{1}_{1} Q^{1}_{0})
     586        sage: steenrod_algebra_basis(5,'wall_long')
     587        (Sq^{4} Sq^{1}, Sq^{2} Sq^{1} Sq^{2})
     588        sage: steenrod_algebra_basis(5,'pst-rlex')
     589        (P^{0}_{1} P^{2}_{1}, P^{1}_{1} P^{0}_{2})
     590    """
     591    if not (isinstance(n, (Integer, int)) and n >= 0):
     592        raise ValueError, "%s is not a non-negative integer." % n
     593    basis_name = get_basis_name(basis, p)
     594    if basis_name.find('long') >= 0:
     595        long = True
     596        basis_name = basis_name.rsplit('_', 1)[0]
     597    else:
     598        long = False
     599
     600    ## Milnor basis
     601    if basis_name == 'milnor':
     602        return milnor_basis(n,p)
     603    ## Serre-Cartan basis
     604    elif basis_name == 'serre-cartan':
     605        return serre_cartan_basis(n,p)
     606    ## Atomic bases
     607    elif p == 2 and (basis_name == 'woody' or basis_name == 'woodz'
     608                     or basis_name == 'wall' or basis_name == 'arnona'
     609                     or basis_name.find('pst') >= 0
     610                     or basis_name.find('comm') >= 0):
     611        return atomic_basis(n, basis_name, long=long)
     612    ## Arnon 'C' basis
     613    elif p == 2 and basis == 'arnonc':
     614        return arnonC_basis(n)
     615
     616
     617def restricted_partitions(n, list, no_repeats=False):
     618    """
     619    List of 'restricted' partitions of n: partitions with parts taken from list.
     620
     621    INPUT:
     622        n -- non-negative integer
     623        list -- list of positive integers
     624        no_repeats (optional, default = False) -- if True, only return
     625            partitions with no repeated parts
     626
     627    This seems to be faster than RestrictedPartitions, although I
     628    don't know why.  Maybe because all I want is the list of
     629    partitions (with each partitions represented as a list), not the
     630    extra stuff provided by RestrictedPartitions.
     631
     632    EXAMPLES:
     633        sage: from sage.algebras.steenrod_algebra_bases import restricted_partitions
     634        sage: restricted_partitions(10, [7,5,1])
     635        [[7, 1, 1, 1], [5, 5], [5, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
     636        sage: restricted_partitions(10, [6,5,4,3,2,1], no_repeats=True)
     637        [[6, 4], [6, 3, 1], [5, 4, 1], [5, 3, 2], [4, 3, 2, 1]]
     638        sage: restricted_partitions(10, [6,4,2])
     639        [[6, 4], [6, 2, 2], [4, 4, 2], [4, 2, 2, 2], [2, 2, 2, 2, 2]]
     640        sage: restricted_partitions(10, [6,4,2], no_repeats=True)
     641        [[6, 4]]
     642
     643    'list' may have repeated elements.  If 'no_repeats' is False, this
     644    has no effect.  If 'no_repeats' is True, and if the repeated
     645    elements appear consecutively in 'list', then each element may be
     646    used only as many times as it appears in 'list':
     647        sage: restricted_partitions(10, [6,4,2,2], no_repeats=True)
     648        [[6, 4], [6, 2, 2]]
     649        sage: restricted_partitions(10, [6,4,2,2,2], no_repeats=True)
     650        [[6, 4], [6, 2, 2], [4, 2, 2, 2]]
     651
     652    (If the repeated elements don't appear consecutively, the results
     653    are likely meaningless, containing several partitions more than
     654    once, for example.)
     655
     656    In the following examples, 'no_repeats' is False:
     657        sage: restricted_partitions(10, [6,4,2])
     658        [[6, 4], [6, 2, 2], [4, 4, 2], [4, 2, 2, 2], [2, 2, 2, 2, 2]]
     659        sage: restricted_partitions(10, [6,4,2,2,2])
     660        [[6, 4], [6, 2, 2], [4, 4, 2], [4, 2, 2, 2], [2, 2, 2, 2, 2]]
     661        sage: restricted_partitions(10, [6,4,4,4,2,2,2,2,2,2])
     662        [[6, 4], [6, 2, 2], [4, 4, 2], [4, 2, 2, 2], [2, 2, 2, 2, 2]]
     663    """
     664    if n < 0:
     665        return []
     666    elif n == 0:
     667        return [[]]
     668    else:
     669        results = []
     670        if no_repeats:
     671            index = 1
     672        else:
     673            index = 0
     674        old_i = 0
     675        for i in list:
     676            if old_i != i:
     677                for sigma in restricted_partitions(n-i, list[index:], no_repeats):
     678                    results.append([i] + sigma)
     679            index += 1
     680            old_i = i
     681        return results
     682
     683
     684def list_to_hist(list):
     685    """
     686    Given list of positive integers [a,b,c,...], return corresponding 'histogram'.
     687
     688    That is, in the output [n1, n2, ...], n1 is the number of 1's in
     689    the original list, n2 is the number of 2's, etc.
     690
     691    INPUT:
     692        list -- list of positive integers
     693    OUTPUT:
     694        list -- list of non-negative integers
     695
     696    EXAMPLES:
     697        sage: from sage.algebras.steenrod_algebra_bases import list_to_hist
     698        sage: list_to_hist([1,2,3,4,2,1,2])
     699        [2, 3, 1, 1]
     700        sage: list_to_hist([2,2,2,2])
     701        [0, 4]
     702    """
     703    if len(list) == 0:
     704        return list
     705    else:
     706        answer = [0] * max(list)
     707        for i in list:
     708            answer[i-1] += 1
     709        return answer
     710
     711
     712"""
     713Functions for defining bases. They work like this:
     714
     715First, check to see if the basis has been computed already: look for
     716  the cached result in _steenrod_bases.  If so, filter the result
     717  based on the optional argument bound.
     718
     719Second, if there is no cached result, build directly or recursively,
     720  whichever is more convenient.  The details are documented for each
     721  basis.  As each basis element is constructed, so is its dictionary
     722  for the current basis.  For example, in 'serre_cartan_basis', each
     723  new element is obtained by taking an element in a lower-dimensional
     724  basis and multiplying, on the right, by Sq(last).  Call this element
     725  'new'.  Then set new._raw['serre-cartan'] to be the dictionary of
     726  Serre-Cartan monomials describing this element.  This makes
     727  conversion of the element to the chosen basis instantaneous; this is
     728  useful on its own, and crucial for computing change-of-basis
     729  matrices for general conversion.
     730
     731Finally, if there is no cached result, cache the result.
     732"""
     733
     734def milnor_basis(n, p=2):
     735    r"""
     736    Milnor basis in dimension $n$.
     737
     738    INPUT:
     739        n -- non-negative integer
     740        p (optional, default 2) -- positive prime number
     741
     742    OUTPUT:
     743        tuple of mod p Milnor basis elements in dimension n
     744
     745    At the prime 2, the Milnor basis consists of symbols of the form
     746    $\text{Sq}(m_1, m_2, ..., m_t)$, where each $m_i$ is a
     747    non-negative integer and if $t>1$, then $m_t \neq 0$.
     748    At odd primes, it consists of symbols of the form
     749    $Q_{e_1} Q_{e_2} ... P(m_1, m_2, ..., m_t)$, where
     750    $0 \leq e_1 < e_2 < ...$, each $m_i$ is a non-negative integer,
     751    and if $t>1$, then $m_t \neq 0$.
     752
     753    EXAMPLES:
     754        sage: from sage.algebras.steenrod_algebra_bases import milnor_basis
     755        sage: milnor_basis(7)
     756        (Sq(0,0,1), Sq(1,2), Sq(4,1), Sq(7))
     757        sage: milnor_basis(7, 2)
     758        (Sq(0,0,1), Sq(1,2), Sq(4,1), Sq(7))
     759        sage: milnor_basis(9, 3)
     760        (Q_1 P(1), Q_0 P(2))
     761        sage: milnor_basis(17, 3)
     762        (Q_2, Q_1 P(3), Q_0 P(0,1), Q_0 P(4))
     763        sage: milnor_basis(48, p=5)
     764        (P(0,1), P(6))
     765        sage: len(milnor_basis(100,3))
     766        13
     767        sage: len(milnor_basis(200,7))
     768        0
     769        sage: len(milnor_basis(240,7))
     770        3
     771    """
     772    def xi_degrees(n,p=2):
     773        r"""
     774        When p=2: decreasing list of the degrees of the $\xi_i$'s with
     775        degree at most n.
     776       
     777        At odd primes: decreasing list of these degrees, each divided
     778        by 2(p-1).
     779        """
     780        result = []
     781        deg = 1
     782        while deg <= n:
     783            result.insert(0,deg)
     784            deg = p*deg + 1
     785        return result
     786
     787    if n == 0:
     788        if p == 2:
     789            return (Sq(0),)
     790        else:
     791            return (SteenrodAlgebra(p).P(0),)
     792    else:
     793        result = []
     794        if _steenrod_bases.has_key(('milnor',n,p)):
     795            result = _steenrod_bases[('milnor',n,p)]
     796        else:
     797            if p == 2:
     798                # build basis from partitions of n, with parts taken
     799                # from the list xi_degrees(n)
     800                for sigma in restricted_partitions(n,xi_degrees(n)):
     801                    sigma_exp = list_to_hist(sigma)
     802                    deg = 1
     803                    i = 0
     804                    exponents = []
     805                    while deg <= len(sigma_exp):
     806                        exponents.insert(i,sigma_exp[deg-1])
     807                        deg = 2*deg + 1
     808                        i = i + 1
     809                    result.append(SteenrodAlgebraElement({tuple(exponents): 1}))
     810                    _steenrod_bases[('milnor',n,p)] = tuple(result)
     811            else:  # p odd
     812                # first find the P part of each basis element.
     813                # in this part of the code (the P part), all dimensions are
     814                # divided by 2(p-1).
     815                for dim in range(n/(2*(p-1)) + 1):
     816                    if dim == 0:
     817                        P_result = [[0]]
     818                    else:
     819                        P_result = []
     820                    for sigma in restricted_partitions(dim, xi_degrees(dim,p)):
     821                        sigma_exp = list_to_hist(sigma)
     822                        deg = 1
     823                        i = 0
     824                        p_mono = []
     825                        while deg <= len(sigma_exp):
     826                            p_mono.insert(i, sigma_exp[deg-1])
     827                            deg = p*deg + 1
     828                            i = i + 1
     829                        if len(p_mono) > 0:
     830                            P_result.append(p_mono)
     831                    # now find the Q part of the basis element.
     832                    # dimensions here are back to normal.
     833                    for p_mono in P_result:
     834                        deg = n - 2*dim*(p-1)
     835                        q_degrees = [1+2*(p-1)*d for d in
     836                                     xi_degrees((deg - 1)/(2*(p-1)), p)] + [1]
     837                        q_degrees_decrease = q_degrees
     838                        q_degrees.reverse()
     839                        if deg % (2*(p-1)) <= len(q_degrees):
     840                            # if this inequality fails, no way to have a partition
     841                            # with distinct parts.
     842                            for sigma in restricted_partitions(deg,
     843                                                               q_degrees_decrease,
     844                                                               no_repeats = True):
     845                                index = 0
     846                                q_mono = []
     847                                for q in q_degrees:
     848                                    if q in sigma:
     849                                        q_mono.append(index)
     850                                    index += 1
     851                                result.append(SteenrodAlgebraElement(
     852                                        {(tuple(q_mono), tuple(p_mono)): 1}, p))
     853                _steenrod_bases[('milnor',n,p)] = tuple(result)
     854        return tuple(result)
     855
     856
     857def serre_cartan_basis(n, p=2, bound=1):
     858    r"""
     859    Serre-Cartan basis in dimension $n$.
     860
     861    INPUT:
     862        n -- non-negative integer
     863        bound (optional) -- positive integer
     864        prime (optional, default 2) -- positive prime number
     865
     866    OUTPUT:
     867        tuple of mod p Serre-Cartan basis elements in dimension n
     868
     869    The Serre-Cartan basis consists of 'admissible monomials in the
     870    Steenrod squares'.  Thus at the prime 2, it consists of monomials
     871    $\text{Sq}^{m_1} \text{Sq}^{m_2} ... \text{Sq}^{m_t}$ with $m_i
     872    \geq 2m_{i+1}$ for each $i$.  At odd primes, it consists of
     873    monomials $\beta^{\epsilon_0} \mathcal{P}^{s_1} \beta^{\epsilon_1}
     874    \mathcal{P}^{s_2} ...  \mathcal{P}^{s_k} \beta^{\epsilon_k}$ with
     875    each $\epsilon_i$ either 0 or 1, $s_i \geq p s_{i+1} +
     876    \epsilon_i$, and $s_k \geq 1$.
     877
     878    EXAMPLES:
     879        sage: from sage.algebras.steenrod_algebra_bases import serre_cartan_basis
     880        sage: serre_cartan_basis(7)
     881        (Sq^{7}, Sq^{6} Sq^{1}, Sq^{4} Sq^{2} Sq^{1}, Sq^{5} Sq^{2})
     882        sage: serre_cartan_basis(13,3)
     883        (beta P^{3}, P^{3} beta)
     884        sage: serre_cartan_basis(50,5)
     885        (beta P^{5} P^{1} beta, beta P^{6} beta)
     886
     887    If optional argument bound is present, include only those
     888    monomials whose last term is at least bound (when p=2), or those
     889    for which s_k - epsilon_k >= bound (when p is odd).
     890        sage: serre_cartan_basis(7, bound=2)
     891        (Sq^{7}, Sq^{5} Sq^{2})
     892        sage: serre_cartan_basis(13, 3, bound=3)
     893        (beta P^{3},)
     894    """
     895    if not (isinstance(bound, (Integer, int)) and bound >= 1):
     896        raise ValueError, "%s is not a positive integer." % bound
     897    A = SteenrodAlgebra(p, 'serre-cartan')
     898    if n == 0:
     899        if p == 2:
     900            return (Sq(0),)
     901        else:
     902            return (A.P(0),)
     903    else:
     904        if _steenrod_bases.has_key(('serre-cartan',n,p)):
     905            result = []
     906            lookup = _steenrod_bases[('serre-cartan',n,p)]
     907            for vec in lookup:
     908                for mono in vec._basis_dictionary('serre-cartan'):
     909                    if (bound == 1) or \
     910                            (p == 2 and mono[-1] >= bound) or \
     911                            (p > 2 and (len(mono)<2 or mono[-2] - mono[-1] >= bound)):
     912                        result.append(vec)
     913        else:
     914            if p == 2:
     915                # Build basis recursively.  last = last term.
     916                # last is >= bound, and we will append (last,) to the end of
     917                # elements from serre_cartan_basis (n - last, bound=2 * last).
     918                # This means that 2 last <= n - last, or 3 last <= n.
     919                result = [A(Sq(n))]
     920                for last in range(bound, 1+n/3):
     921                    for vec in serre_cartan_basis(n - last, bound = 2*last):
     922                        new = vec * Sq(last)
     923                        for m in vec._basis_dictionary('serre-cartan'):
     924                            sc_mono = m
     925                        new._raw['serre-cartan'] = {sc_mono + (last,): 1}
     926                        result.append(A(new))
     927                if bound == 1: _steenrod_bases[('serre-cartan',n,p)] = tuple(result)
     928            else: # p odd
     929                if n % (2 * (p-1)) == 0 and n/(2 * (p-1)) >= bound:
     930                    a = A.P(int(n/(2 * (p-1))))
     931                    a._raw['serre-cartan'] = {(0,int(n/(2 * (p-1))),0): 1}
     932                    result = [a]
     933                elif n == 1:
     934                    a = A.Q(0)
     935                    a._raw['serre-cartan'] = {(1,): 1}
     936                    result = [a]
     937                else:
     938                    result = []
     939                # 2 cases: append P^{last}, or append P^{last} beta
     940                # case 1: append P^{last}
     941                for last in range(bound, 1+n/(2*(p - 1))):
     942                    if n - 2*(p-1)*last > 0:
     943                        for vec in serre_cartan_basis(n - 2*(p-1)*last,
     944                                                      p, p*last):
     945                            new = vec * A.P(last,)
     946                            for m in vec._basis_dictionary('serre-cartan'):
     947                                sc_mono = m
     948                            new._raw['serre-cartan'] = {sc_mono + (last,0): 1}
     949                            result.append(A(new))
     950                # case 2: append P^{last} beta
     951                if bound == 1:
     952                    bound = 0
     953                for last in range(bound+1, 1+n/(2*(p - 1))):
     954                    basis = serre_cartan_basis(n - 2*(p-1)*last - 1,
     955                                               p, p*last)
     956                    for vec in basis:
     957                        if vec == 1:
     958                            vec._raw['serre-cartan'] = {(0,): 1}
     959                        new = vec * A.P(last,) * A.Q(0)
     960                        for m in vec._basis_dictionary('serre-cartan'):
     961                            sc_mono = m
     962                        new._raw['serre-cartan'] = {sc_mono + (last,1): 1}
     963                        result.append(A(new))
     964                if bound <= 1: _steenrod_bases[('serre-cartan',n,p)] = tuple(result)
     965        return tuple(result)
     966
     967
     968def atomic_basis(n, basis, long=False):
     969    r"""
     970    Basis for dimension $n$ made of elements in 'atomic' degrees:
     971    degrees of the form $2^i (2^j - 1)$.
     972
     973    This includes Wood's Y and Z bases, Wall's basis, Arnon's A basis,
     974    the $P^s_t$-bases, and the commutator bases.  (All of these bases
     975    are constructed similarly, hence their constructions have been
     976    consolidated into a single function.)
     977
     978    INPUT:
     979        n -- non-negative integer
     980        basis -- string, the name of the basis
     981
     982    OUTPUT:
     983        tuple of basis elements in dimension n
     984
     985    Wood's $Y$ and $Z$ bases are defined as follows.  For pairs of
     986    non-negative integers $(m,k)$, let $w(m,k) = \text{Sq}^{2^m
     987    (2^{k+1}-1)}$.  The $Y$ basis consists of monomials $w(m_0,k_0)
     988    ... w(m_t, k_t)$ with $(m_i,k_i) > (m_{i+1},k_{i+1})$, in left
     989    lex order.  The $Z$ basis consists of monomials $w(m_0,k_0) ...
     990    w(m_t, k_t)$ with $(m_i+k_i,m_i) > (m_{i+1}+k_{i+1},m_{i+1})$,
     991    also in left lex order.
     992
     993    EXAMPLES:
     994        sage: from sage.algebras.steenrod_algebra_bases import atomic_basis
     995        sage: atomic_basis(6,'woody')
     996        (Sq^{2} Sq^{3} Sq^{1}, Sq^{4} Sq^{2}, Sq^{6})
     997        sage: atomic_basis(8,'woodz')
     998        (Sq^{4} Sq^{3} Sq^{1}, Sq^{7} Sq^{1}, Sq^{6} Sq^{2}, Sq^{8})
     999        sage: atomic_basis(6,'woodz') == atomic_basis(6, 'woody')
     1000        True
     1001        sage: atomic_basis(9,'woodz') == atomic_basis(9, 'woody')
     1002        False
     1003
     1004    Wall's basis: for any pair of integers $(m,k)$ with $m \geq k \geq
     1005    0$, let $Q^m_k = \text{Sq}^{2^k} \text{Sq}^{2^{k+1}} ...
     1006    \text{Sq}^{2^m}$.  The elements of Wall's basis are monomials
     1007    $Q^{m_0}_{k_0} ... Q^{m_t}_{k_t}$ with $(m_i, k_i) > (m_{i+1},
     1008    k_{i+1})$, ordered left lexicographically.
     1009
     1010    (Note that $Q^m_k$ is the reverse of the element $X^m_k$ used in
     1011    defining Arnon's A basis.)
     1012        sage: atomic_basis(6,'wall')
     1013        (Q^{1}_{1} Q^{1}_{0} Q^{0}_{0}, Q^{2}_{2} Q^{1}_{1}, Q^{2}_{1})
     1014
     1015    Elements of the Wall basis have an alternate, 'long'
     1016    representation as monomials in the $\text{Sq}^{2^n}$s:   
     1017        sage: atomic_basis(6, 'wall', long=True)
     1018        (Sq^{2} Sq^{1} Sq^{2} Sq^{1}, Sq^{4} Sq^{2}, Sq^{2} Sq^{4})
     1019
     1020    Arnon's A basis: for any pair of integers $(m,k)$ with $m \geq k
     1021    \geq 0$, let $X^m_k = \text{Sq}^{2^m} \text{Sq}^{2^{m-1}} ...
     1022    \text{Sq}^{2^k}$.  The elements of Arnon's A basis are monomials
     1023    $X^{m_0}_{k_0} ... X^{m_t}_{k_t}$ with $(m_i, k_i) < (m_{i+1},
     1024    k_{i+1})$, ordered left lexicographically.
     1025
     1026    (Note that $X^m_k$ is the reverse of the element $Q^m_k$ used in
     1027    defining Wall's basis.)
     1028        sage: atomic_basis(7,'arnona')
     1029        (X^{0}_{0} X^{1}_{1} X^{2}_{2},
     1030        X^{0}_{0} X^{2}_{1},
     1031        X^{1}_{0} X^{2}_{2},
     1032        X^{2}_{0})
     1033
     1034    These also have a 'long' representation:
     1035        sage: atomic_basis(7,'arnona',long=True)
     1036        (Sq^{1} Sq^{2} Sq^{4},
     1037        Sq^{1} Sq^{4} Sq^{2},
     1038        Sq^{2} Sq^{1} Sq^{4},
     1039        Sq^{4} Sq^{2} Sq^{1})
     1040
     1041    To obtain a $P^s_t$-basis, for each set $\{P^{s_1}_{t_1}, ...,
     1042    P^{s_k}_{t_k}\}$ of (distinct) $P^s_t$'s, one chooses an ordering
     1043    and forms the resulting monomial.  The set of all such monomials
     1044    then forms a basis, and so one gets a basis by choosing an ordering
     1045    on each monomial.
     1046   
     1047    The name of the basis has the form 'pst_ORDER', where ORDER is a
     1048    string corresponding to one of the following orderings.  These are
     1049    all 'global' -- they give a global ordering on the $P^s_t$'s, not
     1050    different orderings depending on the monomial.  They order the
     1051    $P^s_t$'s using the pair of integers $(s,t)$ as follows:
     1052
     1053        'rlex': right lexicographic ordering
     1054        'llex': left lexicographic ordering
     1055        'deg': ordered by degree, which is the same as left lexicographic
     1056            ordering on the pair $(s+t,t)$
     1057        'revz': left lexicographic ordering on the pair $(s+t,s)$, which is
     1058            the reverse of the ordering used (on elements in the same
     1059            degrees as the $P^s_t$'s) in Wood's Z basis: 'revz' stands
     1060            for 'reversed Z'.
     1061
     1062    Here are some examples:
     1063        sage: atomic_basis(7,'pst_rlex')
     1064        (P^{0}_{1} P^{1}_{1} P^{2}_{1},
     1065        P^{0}_{1} P^{1}_{2},
     1066        P^{2}_{1} P^{0}_{2},
     1067        P^{0}_{3})
     1068        sage: atomic_basis(7,'pst_llex')
     1069        (P^{0}_{1} P^{1}_{1} P^{2}_{1},
     1070        P^{0}_{1} P^{1}_{2},
     1071        P^{0}_{2} P^{2}_{1},
     1072        P^{0}_{3})
     1073        sage: atomic_basis(7,'pst_deg')
     1074        (P^{0}_{1} P^{1}_{1} P^{2}_{1},
     1075        P^{0}_{1} P^{1}_{2},
     1076        P^{0}_{2} P^{2}_{1},
     1077        P^{0}_{3})
     1078        sage: atomic_basis(7,'pst_revz')
     1079        (P^{0}_{1} P^{1}_{1} P^{2}_{1},
     1080        P^{0}_{1} P^{1}_{2},
     1081        P^{0}_{2} P^{2}_{1},
     1082        P^{0}_{3})
     1083
     1084    Commutator bases: let $c_{i,1} = \text{Sq}^{2^i}$, let $c_{i,2} =
     1085    [c_{i,1}, c_{i+1,1}]$, and inductively define $c_{i,k} =
     1086    [c_{i,k-1}, c_{i+k-1,1}]$.  Thus $c_{i,k}$ is a $k$-fold iterated
     1087    commutator of the elements $\text{Sq}^{2^i}$, ...,
     1088    $\text{Sq}^{2^{i+k-1}}$, and $\dim c_{i,k} = \dim P^i_k$.
     1089       
     1090    To obtain a commutator basis, for each set $\{c_{s_1,t_1}, ...,
     1091    c_{s_k,t_k}\}$ of (distinct) $c_{s,t}$'s, one chooses an ordering
     1092    and forms the resulting monomial.  The set of all such monomials
     1093    then forms a basis, and so one gets a basis by choosing an ordering
     1094    on each monomial.
     1095   
     1096    The name of the basis has the form 'comm_ORDER', where ORDER is a
     1097    string corresponding to an ordering, just as with the pst bases.
     1098        sage: atomic_basis(7,'comm_rlex')
     1099        (c_{0,1} c_{1,1} c_{2,1}, c_{0,1} c_{1,2}, c_{2,1} c_{0,2}, c_{0,3})
     1100        sage: atomic_basis(7,'comm_llex')
     1101        (c_{0,1} c_{1,1} c_{2,1}, c_{0,1} c_{1,2}, c_{0,2} c_{2,1}, c_{0,3})
     1102        sage: atomic_basis(7,'comm_deg')
     1103        (c_{0,1} c_{1,1} c_{2,1}, c_{0,1} c_{1,2}, c_{0,2} c_{2,1}, c_{0,3})
     1104        sage: atomic_basis(7,'comm_revz')
     1105        (c_{0,1} c_{1,1} c_{2,1}, c_{0,1} c_{1,2}, c_{0,2} c_{2,1}, c_{0,3})
     1106
     1107    Elements of commutator bases have long representations; instead
     1108    of, say, $c_{2,2}$, the representation is $s_{48}$, indicating the
     1109    commutator of $\text{Sq}^4$ and $\text{Sq}^8$, and $c_{0,3}$,
     1110    which is equal to $[[\text{Sq}^1, \text{Sq}^2], \text{Sq}^4]$, is
     1111    written as $s_{124}$:
     1112        sage: atomic_basis(7,'comm_revz', long=True)
     1113        (s_{1} s_{2} s_{4}, s_{1} s_{24}, s_{12} s_{4}, s_{124})
     1114    """
     1115    def degree_dictionary(n, basis):
     1116        """
     1117        Dictionary of atomic degrees for basis up to degree n.
     1118
     1119        The keys for the dictionary are the atomic degrees -- the
     1120        numbers of the form 2^i (2^j - 1) -- which are less than or
     1121        equal to n.  The value associated to such a degree depends on
     1122        basis; it has the form ((s,t), x), where (s,t) is a pair of
     1123        integers which indexes the corresponding element, and x is the
     1124        element in the Milnor basis.
     1125        """
     1126        dict = {}
     1127        if basis.find('wood') >= 0:
     1128            k=0
     1129            m=0
     1130            deg = 2**m * (2**(k+1) - 1)
     1131            while deg <= n:
     1132                dict[deg] = ((m,k), Sq(deg))
     1133                if m>0:
     1134                    m = m - 1
     1135                    k = k + 1
     1136                else:
     1137                    m = k + 1
     1138                    k = 0
     1139                deg = 2**m * (2**(k+1) - 1)
     1140        elif basis.find('wall') >= 0 or basis.find('arnon') >= 0:
     1141            k=0
     1142            m=0
     1143            deg = 2**k * (2**(m-k+1) - 1)
     1144            while deg <= n:
     1145                dict[deg] = ((m,k), Q(m,k,basis))
     1146                if k == 0:
     1147                    m = m + 1
     1148                    k = m
     1149                else:
     1150                    k = k - 1
     1151                deg = 2**k * (2**(m-k+1) - 1)
     1152        elif basis.find('pst') >= 0 or basis.find('comm') >= 0:
     1153            s=0
     1154            t=1
     1155            deg = 2**s * (2**t - 1)
     1156            while deg <= n:
     1157                if basis.find('pst') >= 0:
     1158                    dict[deg] = ((s,t), pst(s,t))
     1159                else:  # comm
     1160                    dict[deg] = ((s,t), commutator(s,t))
     1161                if s == 0:
     1162                    s = t
     1163                    t = 1
     1164                else:
     1165                    s = s - 1
     1166                    t = t + 1
     1167                deg = 2**s * (2**t - 1)
     1168        return dict
     1169   
     1170    def sorting_pair(s,t,basis):   # pair used for sorting the basis
     1171        if basis.find('wood') >= 0 and basis.find('z') >= 0:
     1172            # return (s+t,s)
     1173            return (-s-t,-s)
     1174        elif basis.find('wood') >= 0 or basis.find('wall') >= 0 or \
     1175                basis.find('arnon') >= 0:
     1176            #return (s,t)
     1177            return (-s,-t)
     1178        elif basis.find('rlex') >= 0:
     1179            return (t,s)
     1180        elif basis.find('llex') >= 0:
     1181            return (s,t)
     1182        elif basis.find('deg') >= 0:
     1183            return (s+t,t)
     1184        elif basis.find('revz') >= 0:
     1185            return (s+t,s)
     1186
     1187    from sage.misc.misc import prod
     1188    if long:
     1189        basis_long_name = basis + "_long"
     1190    else:
     1191        basis_long_name = basis
     1192    A = SteenrodAlgebra(2, basis_long_name)
     1193    if n == 0:
     1194        return (A.Sq(0),)
     1195    else:
     1196        result = []
     1197        if _steenrod_bases.has_key((basis,n)):
     1198            if basis == basis_long_name:
     1199                result = _steenrod_bases[(basis,n)]
     1200            else:
     1201                result = tuple([A(a) for a in _steenrod_bases[(basis,n)]])
     1202        else:
     1203            degrees_etc = degree_dictionary(n, basis)
     1204            degrees = degrees_etc.keys()
     1205            for sigma in restricted_partitions(n, degrees, no_repeats=True):
     1206                big_list = [degrees_etc[part] for part in sigma]
     1207                big_list.sort(key=lambda x: x[0],
     1208                              cmp = lambda x, y: cmp(sorting_pair(x[0], x[1], basis),
     1209                                                     sorting_pair(y[0], y[1], basis)))
     1210                # reverse = True)
     1211                # arnon: sort like wall, then reverse end result
     1212                if basis.find('arnon') >= 0:
     1213                    big_list.reverse()
     1214                list_of_pairs = [d[0] for d in big_list]
     1215                mono_list = [d[1] for d in big_list]
     1216                new = prod(mono_list)
     1217                new._raw[basis] = {tuple(list_of_pairs): 1}
     1218                result.append(A(new))
     1219            _steenrod_bases[(basis,n)] = tuple(result)
     1220        return tuple(result)
     1221
     1222
     1223def Q(m,k,basis):
     1224    r"""
     1225    Compute Q^m_k (Wall basis) and X^m_k (Arnon's A basis).
     1226
     1227    INPUT:
     1228        m,k -- non-negative integers with m >= k
     1229        basis -- 'wall' or 'arnona'
     1230       
     1231    OUTPUT:
     1232        if basis is 'wall', Q^m_k = Sq(2^k) Sq(2^(k+1)) ... Sq(2^m)
     1233        if basis is 'arnona', the reverse of this:
     1234            X^m_k = Sq(2^m) ... Sq(2^(k+1)) Sq(2^k)
     1235
     1236    EXAMPLES:
     1237        sage: from sage.algebras.steenrod_algebra_bases import Q
     1238        sage: Q(2,2,'wall')
     1239        Sq(4)
     1240        sage: Q(2,2,'arnona')
     1241        Sq(4)
     1242        sage: Q(3,2,'wall')
     1243        Sq(6,2) + Sq(12)
     1244        sage: Q(3,2,'arnona')
     1245        Sq(0,4) + Sq(3,3) + Sq(6,2) + Sq(12)
     1246    """
     1247    exponent = 2**k
     1248    result = Sq(exponent)
     1249    for i in range(m-k):
     1250        exponent = exponent * 2
     1251        if basis == 'wall':
     1252            result = result * Sq(exponent)
     1253        elif basis == 'arnona':
     1254            result = Sq(exponent) * result
     1255    return result
     1256
     1257
     1258def arnonC_basis(n,bound=1):
     1259    r"""
     1260    Arnon's C basis in dimension $n$.
     1261
     1262    INPUT:
     1263        n -- non-negative integer
     1264        bound (optional) -- positive integer
     1265
     1266    OUTPUT:
     1267        tuple of basis elements in dimension n
     1268
     1269    The elements of Arnon's C basis are monomials of the form
     1270    $\text{Sq}^{t_1} ... \text{Sq}^{t_m}$ where for each $i$, we
     1271    have $t_i \leq 2t_{i+1}$ and $2^i | t_{m-i}$.
     1272
     1273    EXAMPLES:
     1274        sage: from sage.algebras.steenrod_algebra_bases import arnonC_basis
     1275        sage: arnonC_basis(7)
     1276        (Sq^{7}, Sq^{2} Sq^{5}, Sq^{4} Sq^{3}, Sq^{4} Sq^{2} Sq^{1})
     1277
     1278    If optional argument bound is present, include only those monomials whose
     1279    first term is at least as large as bound:
     1280        sage: arnonC_basis(7,3)
     1281        (Sq^{7}, Sq^{4} Sq^{3}, Sq^{4} Sq^{2} Sq^{1})
     1282    """
     1283    if not (isinstance(bound, (Integer, int)) and bound >= 1):
     1284        raise ValueError, "%s is not a positive integer." % bound
     1285    A = SteenrodAlgebra(2, 'arnonc')   
     1286    if n == 0:
     1287        return (A.Sq(0),)
     1288    else:
     1289        if _steenrod_bases.has_key(('arnonc',n)):
     1290            result = []
     1291            lookup = _steenrod_bases[('arnonc',n)]
     1292            for vec in lookup:
     1293                for mono in vec._basis_dictionary('arnonc'):
     1294                    if mono[0] >= bound:
     1295                        result.append(vec)
     1296        else:
     1297            # Build basis recursively.  first = first term.
     1298            # first is >= bound, and we will prepend (first,) to the
     1299            # elements from arnonC_basis (n - first, first / 2).
     1300            # first also must be divisible by 2**(len(old-basis-elt))
     1301            # This means that 3 first <= 2 n.
     1302            result = [A(Sq(n))]
     1303            for first in range(bound,1+2*n/3):
     1304                for vec in arnonC_basis(n - first, max(first/2,1)):
     1305                    if len(vec._basis_dictionary('arnonc')) > 1: print "Error in Arnon's C basis!"
     1306                    for m in vec._basis_dictionary('arnonc'):
     1307                        arnonc_mono = m
     1308                    if first % 2**len(arnonc_mono) == 0:
     1309                        new = Sq(first) * vec
     1310                        new._raw['arnonc'] = {(first,) + arnonc_mono: 1}
     1311                        result.append(A(new))
     1312            if bound == 1: _steenrod_bases[('arnonc',n)] = tuple(result)
     1313        return tuple(result)
     1314
     1315
     1316@memoize
     1317def commutator(s,t):
     1318    r"""
     1319    $t$th iterated commutator of consecutive $\text{Sq}^2^i$'s.
     1320
     1321    INPUT:
     1322        s, t: integers
     1323       
     1324    OUTPUT:
     1325        If t=1, return Sq(2^s).  Otherwise, return the commutator
     1326        [commutator(s,t-1), Sq(2^{s+t-1})].
     1327
     1328    EXAMPLES:
     1329        sage: from sage.algebras.steenrod_algebra_bases import commutator
     1330        sage: commutator(1,2)
     1331        Sq(0,2)
     1332        sage: commutator(0,4)
     1333        Sq(0,0,0,1)
     1334        sage: commutator(2,2)
     1335        Sq(0,4) + Sq(3,3)
     1336
     1337    NOTES:
     1338        commutator(0,n) is equal to $\text{Sq}(0,...,0,1)$, with the
     1339        1 in the $n$th spot.  commutator(i,n) always has
     1340        $\text{Sq}(0,...,0,2^i)$, with $2^i$ in the $n$th spot, as a
     1341        summand, but there may be other terms, as the example of
     1342        commutator(2,2) illustrates.
     1343
     1344        That is, commutator(s,t) is equal to $P^s_t$, possibly plus
     1345        other Milnor basis elements.
     1346    """
     1347    if t == 1:
     1348        return Sq(2**s)
     1349    else:
     1350        x = commutator(s,t-1)
     1351        y = Sq(2**(s+t-1))
     1352        return x*y + y*x
     1353
     1354   
     1355#############################################################################
     1356def steenrod_basis_error_check(dim,p):
     1357    """
     1358    This performs crude error checking.
     1359
     1360    INPUT:
     1361        dim -- non-negative integer
     1362        p -- positive prime number
     1363
     1364    OUTPUT:
     1365        None
     1366
     1367    This checks to see if the different bases have the same length,
     1368    and if the change-of-basis matrices are invertible.  If something
     1369    goes wrong, an error message is printed.
     1370   
     1371    This function checks at the prime p as the dimension goes up from
     1372    0, in which case the basis functions use the saved basis
     1373    computations in lower dimensions in the computations.  It also
     1374    checks as the dimension goes down from the top, in which case it
     1375    doesn't have access to the saved computations.  (The saved
     1376    computations are deleted first: the cache _steenrod_bases is set
     1377    to {} before doing the computations.)
     1378
     1379    EXAMPLES:
     1380        sage: sage.algebras.steenrod_algebra_bases.steenrod_basis_error_check(12,2)
     1381        p=2, in decreasing order of dimension, starting in dimension 12.
     1382        down to dimension  10
     1383        down to dimension  5
     1384        p=2, now in increasing order of dimension, up to dimension 12
     1385        up to dimension  0
     1386        up to dimension  5
     1387        up to dimension  10
     1388        done checking
     1389        sage: sage.algebras.steenrod_algebra_bases.steenrod_basis_error_check(30,3)
     1390        p=3, in decreasing order of dimension, starting in dimension 30.
     1391        down to dimension  30
     1392        down to dimension  25
     1393        down to dimension  20
     1394        down to dimension  15
     1395        down to dimension  10
     1396        down to dimension  5
     1397        p=3, now in increasing order of dimension, up to dimension 30
     1398        up to dimension  0
     1399        up to dimension  5
     1400        up to dimension  10
     1401        up to dimension  15
     1402        up to dimension  20
     1403        up to dimension  25
     1404        done checking
     1405    """
     1406    global _steenrod_bases
     1407   
     1408    _steenrod_bases = {}
     1409
     1410    if p == 2:
     1411        bases = ('adem','woody', 'woodz', 'wall', 'arnona', 'arnonc',
     1412                 'pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz',
     1413                 'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz')
     1414    else:
     1415        bases = ('adem', 'milnor')
     1416
     1417    print "p=%s, in decreasing order of dimension, starting in dimension %s." % (p, dim)
     1418    for i in range(dim,0,-1):
     1419        if i % 5 == 0: print "down to dimension ", i
     1420        for B in bases:
     1421            if len(steenrod_algebra_basis(i,'milnor')) != len(steenrod_algebra_basis(i,B)):
     1422                print "problem with milnor/" + B + " in dimension ", i
     1423            mat = convert_to_milnor_matrix(i,B,p)
     1424            if mat.nrows() != 0 and not mat.is_invertible():
     1425                print "%s invertibility problem in dim %s at the prime %s" % (B, i, p)
     1426
     1427    _steenrod_bases = {}
     1428
     1429    print "p=%s, now in increasing order of dimension, up to dimension %s" % (p, dim)
     1430    for i in range(dim):
     1431        if i % 5 == 0: print "up to dimension ", i
     1432        for B in bases:
     1433            if len(steenrod_algebra_basis(i,'milnor')) != len(steenrod_algebra_basis(i,B)):
     1434                print "problem with milnor/" + B + " in dimension ", i
     1435            mat = convert_to_milnor_matrix(i,B,p)
     1436            if mat.nrows() != 0 and not mat.is_invertible():
     1437                print "%s invertibility problem in dim %s at the prime %s" % (B, i, p)
     1438
     1439    print "done checking"
  • new file sage/algebras/steenrod_algebra_element.py

    diff -r 96e35b9306b1 -r c7742f1ad322 sage/algebras/steenrod_algebra_element.py
    - +  
     1r"""
     2Computations with elements of the mod p Steenrod algebra.
     3
     4AUTHORS:
     5    - John H. Palmieri (2008-07-17: version 0.8)
     6
     7This package provides for basic algebra with elements in the mod $p$
     8Steenrod algebra.  In this package, elements in the Steenrod algebra
     9are represented, by default, using the Milnor basis.
     10
     11EXAMPLES:
     12Basic arithmetic, $p=2$.  To construct an element of the mod 2
     13Steenrod algebra, use the function 'Sq':
     14    sage: a = Sq(1,2)
     15    sage: b = Sq(4,1)
     16    sage: z = a + b
     17    sage: z
     18    Sq(1,2) + Sq(4,1)
     19    sage: Sq(4) * Sq(1,2)
     20    Sq(1,1,1) + Sq(2,3) + Sq(5,2)
     21    sage: z**2          # non-negative exponents work as they should
     22    Sq(1,2,1) + Sq(4,1,1)
     23    sage: z**0
     24    Sq(0)
     25
     26Basic arithmetic, $p>2$.  To construct an element of the mod $p$
     27Steenrod algebra when $p$ is odd, you should first define a Steenrod
     28algebra, using the 'SteenrodAlgebra' command:
     29    sage: SteenrodAlgebra()   # 2 is the default prime
     30    mod 2 Steenrod algebra
     31    sage: A3 = SteenrodAlgebra(3)
     32    sage: A3
     33    mod 3 Steenrod algebra
     34
     35Having done this, the newly created algebra 'A3' has methods 'Q' and
     36'P' which construct elements of A3:   
     37    sage: c = A3.Q(1,3,6); c
     38    Q_1 Q_3 Q_6
     39    sage: d = A3.P(2,0,1); d
     40    P(2,0,1)
     41    sage: c * d
     42    Q_1 Q_3 Q_6 P(2,0,1)
     43    sage: e = A3.P(3)
     44    sage: d * e
     45    P(5,0,1)
     46    sage: e * d
     47    P(1,1,1) + P(5,0,1)
     48    sage: c * c
     49    0
     50    sage: e ** 3
     51    2 P(1,2)
     52
     53Note that one can construct an element like 'c' above in one step,
     54without first constructing the algebra:
     55    sage: c = SteenrodAlgebra(3).Q(1,3,6)
     56    sage: c
     57    Q_1 Q_3 Q_6
     58
     59And of course, you can do similar constructions with the mod 2
     60Steenrod algebra:
     61    sage: A = SteenrodAlgebra(2); A
     62    mod 2 Steenrod algebra
     63    sage: A.Sq(2,3,5)
     64    Sq(2,3,5)
     65    sage: A.P(2,3,5)   # when p=2, P = Sq
     66    Sq(2,3,5)
     67    sage: A.Q(1,4)     # when p=2, this gives a product of Milnor primitives
     68    Sq(0,1,0,0,1)
     69   
     70Regardless of the prime, each element has an 'excess', and if the
     71element is homogeneous, a 'degree'.  The excess of
     72$\text{Sq}(i_1,i_2,i_3,...)$ is $i_1 + i_2 + i_3 + ...$; when $p$
     73is odd, the excess of $Q_{0}^{\epsilon_0} Q_{1}^{\epsilon_1}
     74... \mathcal{P}(r_1, r_2, ...)$ is $\sum epsilon_i + 2 \sum r_i$.  The
     75excess of a linear combination of Milnor basis elements is the minimum
     76of the excesses of those basis elements.
     77
     78The degree of $\text{Sq}(i_1,i_2,i_3,...) is $i_1 + 3 i_2 + 7 i_3 +
     79... + (2^n-1) i_n + ...$, and when $p$ is odd, the degree of
     80$Q_{0}^{\epsilon_0} Q_{1}^{\epsilon_1} ... \mathcal{P}(r_1, r_2, ...)$
     81is $\sum \epsilon_i (2p^i - 1) + \sum r_j (2p^j - 2)$.  The degree of
     82a linear combination of such terms is only defined if the terms all
     83have the same degree.
     84
     85Here are some simple examples:
     86    sage: z = Sq(1,2) + Sq(4,1)
     87    sage: z.degree()
     88    7
     89    sage: (Sq(0,0,1) + Sq(5,3)).degree()
     90    Element is not homogeneous.
     91    sage: Sq(7,2,1).excess()
     92    10
     93    sage: z.excess()
     94    3
     95    sage: B = SteenrodAlgebra(3)
     96    sage: x = B.Q(1,4)
     97    sage: y = B.P(1,2,3)
     98    sage: x.degree()
     99    166
     100    sage: x.excess()
     101    2
     102    sage: y.excess()
     103    12
     104           
     105Elements have a 'weight' in the May filtration, which (when $p=2$) is
     106related to the 'height' function defined by Wall:
     107    sage: Sq(2,1,5).may_weight()
     108    9
     109    sage: Sq(2,1,5).wall_height()
     110    [2, 3, 2, 1, 1]
     111    sage: b = Sq(4)*Sq(8) + Sq(8)*Sq(4)
     112    sage: b.may_weight()
     113    2
     114    sage: b.wall_height()
     115    [0, 0, 1, 1]
     116
     117Odd primary May weights:   
     118    sage: A5 = SteenrodAlgebra(5)
     119    sage: a = A5.Q(1,2,4)
     120    sage: b = A5.P(1,2,1)
     121    sage: a.may_weight()
     122    10
     123    sage: b.may_weight()
     124    8
     125    sage: (a * b).may_weight()
     126    18
     127    sage: A5.P(0,0,1).may_weight()
     128    3
     129
     130Since the Steenrod algebra is a Hopf algebra, every element has an
     131antipode.
     132    sage: d = Sq(0,0,1); d
     133    Sq(0,0,1)
     134    sage: d.antipode()
     135    Sq(0,0,1)
     136    sage: Sq(4).antipode()
     137    Sq(1,1) + Sq(4)
     138    sage: (Sq(4) * Sq(2)).antipode()
     139    Sq(6)
     140    sage: SteenrodAlgebra(7).P(3,1).antipode()
     141    3 P(3,1) + 4 P(11)
     142
     143Applying the antipode twice returns the original element:
     144    sage: y = Sq(8)*Sq(4)
     145    sage: y == (y.antipode()).antipode()
     146    True
     147
     148You can treat elements of the Steenrod algebra like lists of Milnor
     149basis elements:
     150    sage: y = Sq(4) * Sq(1,2); y
     151    Sq(1,1,1) + Sq(2,3) + Sq(5,2)
     152    sage: for m in y: m
     153    Sq(1,1,1)
     154    Sq(2,3)
     155    Sq(5,2)
     156    sage: [(m.degree(),m.excess()) for m in y]
     157    [(11, 3), (11, 5), (11, 7)]
     158
     159Once you've define a Steenrod algebra, the method pst(s,t) is another
     160way to define elements of it: pst(s,t) is the Margolis element
     161$P^{s}_{t}$, the basis element $\mathcal{P}(0,...,0,p^s)$ with $p^s$
     162in position $t$:
     163    sage: A2 = SteenrodAlgebra(2)
     164    sage: Q2 = A2.pst(0,3)
     165    sage: Q2
     166    Sq(0,0,1)
     167    sage: Q2*Q2
     168    0
     169    sage: A2.pst(1,2) == Sq(2)*Sq(4) + Sq(4)*Sq(2)
     170    True
     171    sage: A5 = SteenrodAlgebra(5)
     172    sage: A5.pst(2,2)
     173    P(0,25)
     174
     175There are a number of different bases available in which to represent
     176elements of the Steenrod algebra.  When $p>2$, the choices are the
     177Milnor basis ('milnor') or the Serre-Cartan basis ('serre-cartan' or
     178'adem' or 'admissible').  When $p=2$, the choices are those, along
     179with Wood's Y basis ('wood_y'), Wood's Z basis ('wood_z'), Wall's
     180basis ('wall' or 'wall_long'), Arnon's A basis ('arnon_a' or
     181'arnon_a_long'), Arnon's C basis ('arnon_c'), various $P^s_t$ bases
     182('pst_ORDER' for various values of ORDER), and various commutator
     183bases ('comm_ORDER' or 'comm_ORDER_long' for various values of ORDER).
     184
     185See documentation for the function 'SteenrodAlgebra' for descriptions
     186of these bases.
     187
     188To access representations of elements with respect to these different
     189bases, you can either use the 'basis' method for an element, or define
     190a Steenrod algebra with respect to a particular basis and then use that:
     191    sage: c = Sq(2) * Sq(1); c
     192    Sq(0,1) + Sq(3)
     193    sage: c.basis('serre-cartan')
     194    Sq^{2} Sq^{1}
     195    sage: c.basis('milnor')
     196    Sq(0,1) + Sq(3)
     197    sage: adem = SteenrodAlgebra(2, 'serre-cartan')
     198    sage: x = Sq(7,3,1)   # top class in the subalagebra A(2)
     199    sage: adem(x)
     200    Sq^{17} Sq^{5} Sq^{1}
     201    sage: SteenrodAlgebra(2, 'pst')(x)
     202    P^{0}_{1} P^{0}_{2} P^{1}_{1} P^{0}_{3} P^{1}_{2} P^{2}_{1}
     203
     204Multiplication works within bases:
     205    sage: adem = SteenrodAlgebra(2, 'adem')
     206    sage: x = adem.Sq(5)
     207    sage: y = adem.Sq(1)
     208    sage: x * y
     209    Sq^{5} Sq^{1}
     210
     211Multiplying elements defined with respect to two different bases may
     212have unpredictable results (as far as the basis in which the result is
     213printed):
     214    sage: milnor = SteenrodAlgebra(2, 'milnor')
     215    sage: xm = milnor.Sq(5)
     216    sage: ym = milnor.Sq(1)
     217    sage: xm * ym
     218    Sq(3,1)
     219    sage: xm * y
     220    Sq^{5} Sq^{1}
     221    sage: x * ym
     222    Sq^{5} Sq^{1}
     223
     224Several of these bases ('arnon_a', 'wall', 'comm') have alternate,
     225longer, representations.  These provide ways of expressing elements of
     226the Steenrod algebra in terms of the $\text{Sq}^{2^n}$.
     227    sage: Sq(6).basis('arnon_a_long')
     228    Sq^{1} Sq^{2} Sq^{1} Sq^{2} + Sq^{2} Sq^{4}
     229    sage: Sq(6).basis('wall_long')
     230    Sq^{2} Sq^{1} Sq^{2} Sq^{1} + Sq^{2} Sq^{4}
     231    sage: SteenrodAlgebra(2,'comm_deg_long')(Sq(6))
     232    s_{1} s_{2} s_{12} + s_{2} s_{4}
     233
     234**************
     235
     236Internal documentation for SteenrodAlgebraElement (for people who want
     237to delve into or extend the code):
     238
     239Attributes for a SteenrodAlgebraElement self:
     240
     241  self._base_field: GF(p), where p is the associated prime
     242
     243  self._prime: p
     244 
     245  self._basis: basis in which to print this element
     246 
     247  self._raw: dictionary.  keys are basis names, taken from
     248    '_steenrod_basis_unique_names', and the associated values are
     249    dictionaries themselves; if the dictionary is nonempty, it gives
     250    the representation for that element in the given basis.  If it is
     251    empty, that means that the representation in that basis hasn't
     252    been computed yet.  The representation of an element with respect
     253    to a basis (other than the Milnor basis, which is how elements are
     254    stored internally) isn't computed until requested, either by
     255    calling the method _basis_dictionary('basis_name'), or more
     256    typically, by calling the method basis('basis_name') or by
     257    defining a Steenrod algebra at that basis and applying its call
     258    method to the element.
     259   
     260    The dictionaries are defined as follows.  In the Milnor basis at
     261    the prime 2, for example, since monomials are of the form
     262    Sq(a,b,c,...), then monomials are stored as tuples of integers
     263    (a,b,c,...).  Thus if y = Sq(5,3) + Sq(0,0,2), then
     264    y._raw['milnor'] is {{(0, 0, 2): 1, (5, 3): 1}.  (The 1's
     265    following the colons are the coefficients of the monomials
     266    associated to the tuples.)  Each basis has its own representation
     267    as a dictionary; Arnon's C basis represents basis elements as
     268    tuples of integers, just like the Milnor basis and the
     269    Serre-Cartan basis, while the other bases represent basis elements
     270    as tuples of pairs of integers.  From the descriptions of the
     271    bases given in the file 'steenrod_algebra_bases.py', it should be
     272    clear how to associate a tuple of pairs of integers to a basis
     273    element.  See also the function 'string_rep'.
     274
     275    When the element is initially defined by calling Sq() or
     276    SteenrodAlgebraElement(), typically only the 'milnor' dictionary
     277    is non-empty, while if the element is defined by the function
     278    'steenrod_algebra_basis', its dictionary for the given basis is
     279    also initialized correctly.  For example:
     280        sage: B = steenrod_algebra_basis(6,'adem'); B
     281        (Sq^{6}, Sq^{5} Sq^{1}, Sq^{4} Sq^{2})
     282        sage: x = B[1]; x
     283        Sq^{5} Sq^{1}
     284        sage: x._raw
     285        {'milnor': {(3, 1): 1}, 'serre-cartan': {(5, 1): 1}}
     286       
     287    Note that the keys 'milnor' and 'serre-cartan' (a synonym for
     288    'adem') have nonempty associated values.
     289   
     290    When any element is converted to another basis (by changing the
     291    basis and then printing the element), its dictionary for that
     292    basis gets stored, as well:
     293        sage: x.basis('arnona')
     294        X^{0}_{0} X^{1}_{0} X^{1}_{1}
     295        sage: x._raw
     296        {'arnona': {((0, 0), (1, 0), (1, 1)): 1},
     297        'milnor': {(3, 1): 1},
     298        'serre-cartan': {(5, 1): 1}}
     299
     300Methods for a SteenrodAlgebraElement self:
     301
     302Most of these are self-explanatory.
     303
     304    _mul_: multiply two elements.  This is done using Milnor
     305    multiplication, the code for which is in a separate file,
     306    'steenrod_milnor_multiplication'.  In a long computation, it seems
     307    that a lot of time is spent here, so one way to speed things up
     308    would be to optimize the Milnor multiplication routine.
     309
     310    _basis_dictionary: compute the dictionary of the element with
     311    respect to the given basis.  This is basically done by doing a
     312    basis conversion from the Milnor basis to the given basis.  There
     313    are two parts to this function; first, some elements (e.g.,
     314    Sq(2^n)) may be easy to convert directly.  This is done one basis
     315    at a time, and so takes up most of the lines of code.  If the
     316    element is not recognizable as being easy to convert, then the
     317    function 'milnor_convert' from the file 'steenrod_algebra_bases'
     318    is called.  This does linear algebra: computes the Milnor basis
     319    and the new basis in the appropriate dimension, computes the
     320    change-of-basis matrix, etc.
     321
     322    basis: display the element in the given basis.
     323
     324    milnor: display the element in the Milnor basis.
     325
     326    serre_cartan: display the element in the Serre-Cartan basis.
     327
     328    adem: display the element in the Serre-Cartan basis.
     329
     330    _repr_ and _latex_ call the function string_rep, which has cases
     331    depending on the basis.
     332
     333REFERENCES:
     334    [Mil] J. W. Milnor, "The Steenrod algebra and its dual," Ann. of Math.
     335          (2) 67 (1958), 150--171.
     336    [Mon] K. G. Monks, "Change of basis, monomial relations, and $P^s_t$
     337          bases for the Steenrod algebra," J. Pure Appl. Algebra 125 (1998),
     338          no. 1-3, 235--260.
     339    [Woo] R. M. W. Wood, "Problems in the Steenrod algebra," Bull. London
     340          Math. Soc. 30 (1998), no. 5, 449--517.
     341"""
     342
     343#*****************************************************************************
     344#       Copyright (C) 2008 William Stein <wstein@gmail.com>
     345#       Copyright (C) 2008 John H. Palmieri <palmieri@math.washington.edu>
     346#  Distributed under the terms of the GNU General Public License (GPL)
     347#*****************************************************************************
     348
     349from sage.rings.ring import Algebra
     350from sage.algebras.algebra_element import AlgebraElement
     351from sage.structure.parent_gens import ParentWithGens
     352from sage.structure.element import RingElement
     353from sage.rings.all import GF
     354from sage.misc.functional import parent
     355from sage.rings.integer import Integer
     356
     357def check_and_trim(nums):
     358    """
     359    Check that list or tuple consists of non-negative integers, and
     360    strip trailing zeroes.
     361
     362    INPUT:
     363        nums -- a list or tuple
     364
     365    OUTPUT:
     366        If nums contains anything other than a non-negative integer,
     367        raise an exception.  Otherwise, return a new list or tuple, obtained
     368        from nums by omitting any zeroes from the end.
     369       
     370    EXAMPLES:
     371        sage: from sage.algebras.steenrod_algebra_element import check_and_trim
     372        sage: check_and_trim([3,4,1])
     373        [3, 4, 1]
     374        sage: a=[3,2,1,0,0]
     375        sage: check_and_trim(a)
     376        [3, 2, 1]
     377        sage: a    # check_and_trim doesn't affect its input
     378        [3, 2, 1, 0, 0]
     379        sage: check_and_trim([0]*127)
     380        []
     381        sage: check_and_trim((1,2,3,4,0,0,0))  # works on tuples, too
     382        (1, 2, 3, 4)
     383       
     384    If input contains anything other than non-negative integer, return
     385    an error.  The right-most problematic entry is identified.
     386    """
     387    index = len(nums)
     388    for i in range(index-1, -1, -1):
     389        if nums[i] == 0 and i == index - 1:
     390            index = i
     391        if not (isinstance(nums[i], (Integer, int)) and nums[i] >= 0):
     392            print type(nums[i])
     393            raise ValueError, "%s is not a non-negative integer" % nums[i]
     394    return nums[:index]
     395
     396
     397def convert_perm(m):
     398    """
     399    Convert tuple m of non-negative integers to a permutation in one-line form.
     400
     401    INPUT:
     402        m -- tuple of non-negative integers with no repetitions
     403    OUTPUT:
     404        list -- conversion of m to a permutation of the set {1,2,...,len(m)}
     405
     406    If m=(3,7,4), then one can view m as representing the permutation
     407    of the set {3,4,7} sending 3 to 3, 4 to 7, and 7 to 4.  This
     408    function converts m to the list [1,3,2], which represents
     409    essentially the same permutation, but of the set {1,2,3}.  This
     410    list can then be passed to Permutation, and its signature can be
     411    computed.
     412
     413    EXAMPLES:
     414        sage: sage.algebras.steenrod_algebra_element.convert_perm((3,7,4))
     415        [1, 3, 2]
     416        sage: sage.algebras.steenrod_algebra_element.convert_perm((5,0,6,3))
     417        [2, 4, 1, 3]
     418    """   
     419    m2 = list(m)
     420    m2.sort()
     421    return [list(m).index(x)+1 for x in m2]
     422
     423
     424def base_p_expansion(n, p):
     425    r"""
     426    Return list of digits in the base p expansion of n.
     427
     428    INPUT:
     429        n -- non-negative integer
     430        p -- positive prime number
     431
     432    OUTPUT:
     433        list of digits in the base p expansion of n
     434
     435    EXAMPLES:
     436        sage: sage.algebras.steenrod_algebra_element.base_p_expansion(10,2)
     437        [0, 1, 0, 1]
     438        sage: sage.algebras.steenrod_algebra_element.base_p_expansion(10,3)
     439        [1, 0, 1]
     440        sage: sage.algebras.steenrod_algebra_element.base_p_expansion(10,5)
     441        [0, 2]
     442        sage: sage.algebras.steenrod_algebra_element.base_p_expansion(10,7)
     443        [3, 1]
     444        sage: sage.algebras.steenrod_algebra_element.base_p_expansion(0,7)
     445        []
     446    """
     447    result = []
     448    while n > 0:
     449        remainder = n % p
     450        result.append(remainder)
     451        n = int((n - remainder)/p)
     452    return result
     453
     454
     455def integer_base_2_log(n):
     456    """
     457    Largest integer k so that 2^k <= n
     458
     459    INPUT:
     460        n -- positive integer
     461
     462    OUTPUT:
     463        k -- integer so that 2^k <= n, 2^{k+1} > n
     464
     465    EXAMPLES:
     466        sage: sage.algebras.steenrod_algebra_element.integer_base_2_log(7)
     467        2
     468        sage: sage.algebras.steenrod_algebra_element.integer_base_2_log(8)
     469        3
     470        sage: sage.algebras.steenrod_algebra_element.integer_base_2_log(9)
     471        3
     472    """
     473    answer = 0
     474    while 2**(answer+1) <= n:
     475        answer += 1
     476    return answer
     477
     478# These are for internal use only; they are the names used in the code
     479# to represent each basis.
     480_steenrod_basis_unique_names_odd =  ('serre-cartan', 'milnor')
     481_steenrod_basis_unique_names = _steenrod_basis_unique_names_odd + \
     482    ('pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz',
     483     'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz',
     484     'comm_rlex_long', 'comm_llex_long', 'comm_deg_long', 'comm_revz_long',
     485     'woody', 'woodz', 'arnona', 'arnona_long', 'arnonc', 'wall', 'wall_long')
     486
     487# This dictionary is for caching Steenrod algebras at various primes,
     488# to make sure that SteenrodAlgebraElements defined at the same prime
     489# have the same parent.
     490_steenrod_algebras = {}
     491
     492class SteenrodAlgebraElement(AlgebraElement):
     493    r"""
     494    Element of the mod p Steenrod algebra.
     495
     496    At the prime 2, use the function 'Sq' to define these, as in
     497    'w=Sq(4,3,3)' or 'z=Sq(1,2)+Sq(4,1)' or 'q=Sq(8)*Sq(4) + Sq(12)'.
     498
     499    At odd primes, use the methods 'P' and 'Q' to define these, as
     500    in 'w=SteenrodAlgebra(3).Q(1,5) * SteenrodAlgebra(3).P(4,3)'.
     501
     502    EXAMPLES:
     503        sage: w = Sq(4,3,3)
     504        sage: w
     505        Sq(4,3,3)
     506
     507    The function 'Sq', together with addition, provides an easy way to
     508    define elements when $p=2$:
     509        sage: b = Sq(3) + Sq(0,1)
     510        sage: b
     511        Sq(0,1) + Sq(3)
     512
     513    When $p$ is odd, first define a Steenrod algebra to specify the
     514    prime, and then use the methods 'P' and 'Q', together with
     515    multiplication and addition:
     516        sage: A7 = SteenrodAlgebra(7)
     517        sage: u = A7.Q(0,4); u
     518        Q_0 Q_4
     519        sage: v = A7.P(1,2,3); v
     520        P(1,2,3)
     521        sage: u * v
     522        Q_0 Q_4 P(1,2,3)
     523        sage: 10 * u * v
     524        3 Q_0 Q_4 P(1,2,3)
     525        sage: u + v
     526        P(1,2,3) + Q_0 Q_4
     527    """
     528   
     529    def __init__(self, poly, p=2, basis='milnor'):
     530        r"""
     531        INPUT:
     532            poly -- dictionary with entries of form (monomial: coefficient)
     533            Each coefficient is in GF(p), and each monomial is a tuple
     534            of non-negative integers (a, b, c, ...), corresponding to
     535            the Milnor basis element Sq(a, b, c, ...).
     536
     537            At odd primes, the monomials are pairs of tuples: they are
     538            of the form ((e0, e1, e2, ...), (r1, r2, ...)),
     539            corresponding to the element $Q_{e_0} Q_{e_1} ... \mathcal{P}(r_1, r_2, ...)$.
     540
     541            Alternatively, poly can be an integer n, in which case it
     542            is viewed as being in the field GF(p): the resulting
     543            element is n * Sq(0).
     544           
     545            p -- positive prime number (default 2)
     546
     547        EXAMPLES:
     548            sage: from sage.algebras.steenrod_algebra_element import SteenrodAlgebraElement
     549            sage: SteenrodAlgebraElement({(1,2,3): 1}, 2)
     550            Sq(1,2,3)
     551            sage: SteenrodAlgebraElement({(1,2,3): 4}, 2)
     552            0
     553            sage: SteenrodAlgebraElement({((0,3), (1,2)): 5}, 7)
     554            5 Q_0 Q_3 P(1,2)
     555            sage: SteenrodAlgebraElement({((0,3), (1,2)): 5}, p=7)
     556            5 Q_0 Q_3 P(1,2)
     557
     558        The input can also be an integer, in which case it is treated
     559        as a multiple, mod p, of the unit element P(0) (a.k.a. Sq(0)
     560        at the prime 2):
     561            sage: SteenrodAlgebraElement(3,2)
     562            Sq(0)
     563            sage: SteenrodAlgebraElement(6)   # p=2 is the default prime
     564            0
     565            sage: SteenrodAlgebraElement(6, p=5)
     566            P(0)
     567        """
     568        from sage.rings.arith import is_prime
     569        from sage.algebras.steenrod_algebra import SteenrodAlgebra
     570        if not is_prime(p):
     571            raise ValueError, "%s is not prime." % p
     572        else:
     573            # get cached Steenrod algebra at the prime p
     574            if _steenrod_algebras.has_key((p,basis)):
     575                alg = _steenrod_algebras[(p,basis)]
     576            else:
     577                _steenrod_algebras[(p,basis)] = SteenrodAlgebra(p,basis)
     578                alg = _steenrod_algebras[(p,basis)]
     579            if isinstance(poly, SteenrodAlgebraElement):
     580                if poly.parent().prime == p:
     581                    self._raw = poly._raw
     582                else:
     583                    raise ValueError, "Mismatch: %s is defined at the prime %s, \
     584not %s" % (poly, poly.parent().prime, p)
     585            # basic initializations:
     586            RingElement.__init__(self, alg)
     587            F = alg.base_ring()
     588            self._base_field = F
     589            self._prime = p
     590            self._basis = basis
     591            # now comes most of the work:
     592            if isinstance(poly, dict):
     593                new_poly = {}
     594                for mono in poly:
     595                    if p == 2:
     596                        # when p=2, mono is a tuple of integers
     597                        trimmed = check_and_trim(mono)
     598                        if new_poly.has_key(trimmed):
     599                            coeff = F(poly[mono] + new_poly[trimmed])
     600                        else:
     601                            coeff = F(poly[mono])
     602                        if not coeff.is_zero():
     603                            new_poly[trimmed] = coeff
     604                    else:
     605                        # when p is odd, mono is either an empty tuple
     606                        # or a pair of tuples
     607                        if len(mono) == 0:
     608                            if new_poly.has_key(mono):
     609                                coeff = F(poly[mono] + new_poly[mono])
     610                            else:
     611                                coeff = F(poly[mono])
     612                            if not coeff.is_zero():
     613                                new_poly[mono] = coeff
     614                        else:
     615                            # mono is a pair of tuples
     616                            mono1, mono2 = mono
     617                            multiplier = 1
     618                            # see if there are any repetitions in the Q monomial:
     619                            if len(mono1) != len(set(mono1)):
     620                                return self(0)
     621                            # if not, sort them and introduce the correct sign:
     622                            if len(mono1) > 0:
     623                                from sage.combinat.permutation import Permutation
     624                                multiplier = Permutation(
     625                                    convert_perm(mono1)).signature()
     626                                mono1 = tuple(sorted(mono1))
     627                            trimmed2 = check_and_trim(mono2)
     628                            if len(mono1) + len(trimmed2) > 0:
     629                                if new_poly.has_key((mono1,trimmed2)):
     630                                    coeff = F(multiplier * poly[mono] \
     631                                                  + new_poly[(mono1, trimmed2)])
     632                                else:
     633                                    coeff = F(multiplier * poly[mono])
     634                                if not coeff.is_zero():
     635                                    new_poly[(mono1,trimmed2)] = coeff
     636                            else:
     637                                if new_poly.has_key(()):
     638                                    coeff = F(poly[mono] + new_poly[()])
     639                                else:
     640                                    coeff = F(poly[mono])
     641                                if not coeff.is_zero():
     642                                    new_poly[()] = coeff
     643                # now define the _raw attribute: a dictionary keyed by the
     644                # basis names.  set the 'milnor' value to by new_poly
     645                self._raw = {}
     646                self._raw['milnor'] = new_poly
     647            elif isinstance(poly, (Integer, int)) or poly.parent() == F:
     648                # a scalar, i.e., a scalar multiple of Sq(0) or P(0)
     649                if F(poly) != 0:
     650                    new_poly = {(): F(poly)}
     651                else:
     652                    new_poly = {}
     653                self._raw = {}
     654                if p == 2:
     655                    basis_list = _steenrod_basis_unique_names
     656                else:
     657                    basis_list = _steenrod_basis_unique_names_odd
     658                for basis in basis_list:
     659                    self._raw[basis] = new_poly
     660            elif isinstance(poly, SteenrodAlgebraElement):
     661                self._raw = poly._raw
     662            else:
     663                raise ValueError, "%s is not of the correct form" % poly
     664   
     665
     666    def is_unit(self):
     667        """
     668        True if element has a scalar multiple of P(0) as a summand, False otherwise.
     669
     670        EXAMPLES:
     671            sage: z = Sq(4,2) + Sq(7,1) + Sq(3,0,1)
     672            sage: z.is_unit()
     673            False
     674            sage: u = 1 + Sq(3,1)
     675            sage: u == Sq(0) + Sq(3,1)
     676            True
     677            sage: u.is_unit()
     678            True
     679            sage: A5 = SteenrodAlgebra(5)
     680            sage: v = A5.P(0)
     681            sage: (v + v + v).is_unit()
     682            True
     683        """
     684        if self._raw['milnor'].has_key(()):
     685            return True
     686        else:
     687            return False
     688
     689    def is_nilpotent(self):
     690        """
     691        True if element is not a unit, False otherwise.
     692
     693        EXAMPLES:
     694            sage: z = Sq(4,2) + Sq(7,1) + Sq(3,0,1)
     695            sage: z.is_nilpotent()
     696            True
     697            sage: u = 1 + Sq(3,1)
     698            sage: u == Sq(0) + Sq(3,1)
     699            True
     700            sage: u.is_nilpotent()
     701            False
     702        """
     703        return not self.is_unit()
     704
     705
     706    def _add_(self, other):
     707        """
     708        Addition for elements of the Steenrod algebra.
     709
     710        EXAMPLES:
     711            sage: a = Sq(3,1) + Sq(6)
     712            sage: b = Sq(0,2)
     713            sage: c = Sq(6) + Sq(0,2)
     714            sage: a + b
     715            Sq(0,2) + Sq(3,1) + Sq(6)
     716            sage: b + c
     717            Sq(6)
     718            sage: A7 = SteenrodAlgebra(7)
     719            sage: x = A7.P(1,2); y = A7.Q(3,4) * A7.P(1,2)
     720            sage: x + 3 * y
     721            P(1,2) + 3 Q_3 Q_4 P(1,2)
     722            sage: x + 10 * y
     723            P(1,2) + 3 Q_3 Q_4 P(1,2)
     724        """
     725        F = self._base_field
     726        poly1 = self._raw['milnor']
     727        poly2 = other._raw['milnor']
     728        result = poly1.copy()
     729        for mono in poly2:
     730            if result.has_key(mono):
     731                coeff = F(result[mono] + poly2[mono])
     732            else:
     733                coeff = F(poly2[mono])
     734            if coeff == 0:
     735                del result[mono]
     736            else:
     737                result[mono] = coeff
     738        sum = SteenrodAlgebraElement(result, p=self._prime)
     739        return sum
     740
     741
     742    def _neg_(self):
     743        """
     744        Multiply every coefficient by the base field element -1.
     745
     746        EXAMPLES:
     747            sage: a = Sq(4,2) + Sq(5)
     748            sage: -a
     749            Sq(4,2) + Sq(5)
     750            sage: A5 = SteenrodAlgebra(5)
     751            sage: b = 2 * A5.P(2,0,1)
     752            sage: b
     753            2 P(2,0,1)
     754            sage: -b
     755            3 P(2,0,1)
     756        """
     757        p = self._prime
     758        if p == 2:
     759            return self
     760        else:
     761            F = self._base_field
     762            dict = self._raw['milnor']
     763            for mono in dict:
     764                dict[mono] = F(-dict[mono])
     765            return SteenrodAlgebraElement(dict,p)
     766
     767
     768    def _sub_(self, other):
     769        """
     770        Subtraction for elements of the Steenrod algebra.
     771
     772        EXAMPLES:
     773            sage: A7 = SteenrodAlgebra(7)
     774            sage: A7.P(2,1) - A7.Q(0,3)
     775            P(2,1) + 6 Q_0 Q_3
     776        """
     777        return self._add_(other._neg_())
     778
     779
     780    def _mul_(self, other):
     781        """
     782        Multiplication for elements of the Steenrod algebra.
     783
     784        EXAMPLES:
     785            sage: Sq(2) * Sq(1)
     786            Sq(0,1) + Sq(3)
     787            sage: Sq(0) * (Sq(6,2) + Sq(9,1))
     788            Sq(6,2) + Sq(9,1)
     789            sage: 1 * (Sq(6,2) + Sq(9,1))
     790            Sq(6,2) + Sq(9,1)
     791            sage: 4 * (Sq(6,2) + Sq(9,1))
     792            0
     793            sage: A5 = SteenrodAlgebra(5)
     794            sage: A5.P(5) * A5.P(1,2)
     795            3 P(0,3) + P(6,2)
     796            sage: A5.Q(1,2,3) * A5.Q(0,5)
     797            4 Q_0 Q_1 Q_2 Q_3 Q_5
     798            sage: A5.Q(1,2,3) * A5.Q(0,3)
     799            0
     800        """
     801        from sage.algebras.steenrod_algebra import SteenrodAlgebra
     802        p = self._prime
     803        if p == 2:
     804            from steenrod_milnor_multiplication import milnor_multiplication
     805        else:
     806            from steenrod_milnor_multiplication_odd import milnor_multiplication_odd
     807        F = self._base_field
     808        poly1 = self._raw['milnor']
     809        poly2 = other._raw['milnor']
     810        result = {}
     811        for mono1 in poly1:
     812            for mono2 in poly2:
     813                if len(mono1) == 0:    # multiplying by scalar multiple of one
     814                    if result.has_key(mono2):
     815                        result[mono2] = F(result[mono2] + poly1[mono1]
     816                                          * poly2[mono2])
     817                    else:
     818                        result[mono2] = F(poly1[mono1] * poly2[mono2])
     819                elif len(mono2) == 0:    # multiplying by scalar multiple of one
     820                    if result.has_key(mono1):
     821                        result[mono1] = F(result[mono1] + poly1[mono1]
     822                                          * poly2[mono2])
     823                    else:
     824                        result[mono1] = F(poly1[mono1] * poly2[mono2])
     825                else:
     826                    if p == 2:
     827                        new_dict = milnor_multiplication(mono1, mono2)
     828                    else:
     829                        new_dict = milnor_multiplication_odd(mono1, mono2, p=p)
     830                    for new_mono in new_dict:
     831                        if result.has_key(new_mono):
     832                            result[new_mono] = F(result[new_mono]
     833                                                 + new_dict[new_mono]
     834                                                 * poly1[mono1] * poly2[mono2])
     835                        else:
     836                            result[new_mono] = F(new_dict[new_mono]
     837                                                 * poly1[mono1] * poly2[mono2])
     838        product = SteenrodAlgebraElement(result, p=p)
     839        return SteenrodAlgebra(p, basis=self._basis)(product)
     840
     841
     842    def __cmp_not_in_use__(self,other):
     843        """
     844        Two elements are equal if their difference is zero.
     845
     846        EXAMPLES:
     847             sage: A5 = SteenrodAlgebra(5)
     848             sage: cmp(A5.P(0,1), A5.P(0,2))
     849             -1
     850             sage: cmp(A5.P(0,1), A5.pst(0,2))
     851             0
     852        """
     853        if isinstance(self, SteenrodAlgebraElement) \
     854                and isinstance(other, SteenrodAlgebraElement) \
     855                and self.parent() == other.parent():
     856            difference = self - other
     857            if len(difference._raw['milnor']) == 0:
     858                return 0
     859            else:
     860                return -1
     861        else:
     862            return -1
     863
     864    def __cmp__(self,other):
     865        """
     866        Two elements are equal if their difference is zero.
     867
     868        EXAMPLES:
     869             sage: A5 = SteenrodAlgebra(5)
     870             sage: cmp(A5.P(0,1), A5.P(0,2))
     871             -1
     872             sage: cmp(A5.P(0,1), A5.pst(0,2))
     873             0
     874        """
     875        difference = self - other
     876        if len(difference._raw['milnor']) == 0:
     877            return 0
     878        else:
     879            return -1
     880
     881
     882    def _basis_dictionary(self,basis):
     883        r"""
     884        Dictionary of terms of the form (mono: coeff), where mono
     885        is a monomial in the given basis.
     886
     887        INPUT:
     888            basis -- string, basis in which to work
     889
     890        EXAMPLES:
     891            sage: c = Sq(2) * Sq(1)
     892            sage: c._basis_dictionary('milnor')
     893            {(0, 1): 1, (3,): 1}
     894            sage: c
     895            Sq(0,1) + Sq(3)
     896            sage: c._basis_dictionary('serre-cartan')
     897            {(2, 1): 1}
     898            sage: c.basis('serre-cartan')
     899            Sq^{2} Sq^{1}
     900            sage: d = Sq(0,0,1)
     901            sage: d._basis_dictionary('arnonc')
     902            {(7,): 1, (2, 5): 1, (4, 3): 1, (4, 2, 1): 1}
     903            sage: d.basis('arnonc')
     904            Sq^{2} Sq^{5} + Sq^{4} Sq^{2} Sq^{1} + Sq^{4} Sq^{3} + Sq^{7}
     905
     906        At odd primes:
     907            sage: e = 2 * SteenrodAlgebra(3).P(1,2)
     908            sage: e._basis_dictionary('milnor')
     909            {((), (1, 2)): 2}
     910            sage: e
     911            2 P(1,2)
     912            sage: e._basis_dictionary('serre-cartan')
     913            {(0, 7, 0, 2, 0): 2}
     914            sage: e.basis('adem')
     915            2 P^{7} P^{2}
     916
     917        Implementation: to compute this, take the Milnor representation
     918        and change bases.  Store the result in self._raw[basis], for later
     919        use; this way, an element only needs to be converted once.
     920        """
     921        def is_power_of_two(n):
     922            while n != 0 and n%2 == 0:
     923                n = n >> 1
     924            return n == 1
     925
     926        from steenrod_algebra import _steenrod_serre_cartan_basis_names, \
     927            _steenrod_milnor_basis_names, get_basis_name
     928        from steenrod_algebra_bases import milnor_convert
     929
     930        p = self._prime
     931        basis_name = get_basis_name(basis, p)
     932        if basis_name == 'milnor':
     933            return self._raw['milnor']
     934
     935        if basis_name.find('long') >= 0:
     936            basis_name = basis_name.rsplit('_', 1)[0]
     937
     938        if self._raw.has_key(basis_name) and len(self._raw[basis_name])>0:
     939            return self._raw[basis_name]
     940        elif p == 2:
     941            dict = {}
     942            for mono in self._raw['milnor']:
     943                converted = False
     944                if dict.has_key(mono):
     945                    old_coeff = dict[mono]
     946                else:
     947                    old_coeff = 0
     948                new_coeff = old_coeff + self._raw['milnor'][mono]
     949                if len(mono) == 0:   # length 0: no conversion
     950                    if new_coeff != 0:
     951                        dict[mono] = new_coeff
     952                    else:
     953                        del dict[mono]
     954                    converted = True
     955                elif basis_name == 'serre-cartan':
     956                    if len(mono) == 1:   # length 1: Sq(n) = Sq^{n}, so no conversion
     957                        if dict.has_key(mono):
     958                            new_coeff = dict[mono] + self._raw['milnor'][mono]
     959                            if new_coeff != 0:
     960                                dict[mono] = new_coeff
     961                            else:
     962                                del dict[mono]
     963                        else:
     964                            dict[mono] = self._raw['milnor'][mono]
     965                        converted = True
     966                elif basis_name == 'woody':
     967                    if len(mono) == 1 and is_power_of_two(mono[0]):   # no conversion
     968                        if new_coeff != 0:
     969                            dict[((integer_base_2_log(mono[0]),0),)] = new_coeff
     970                        else:
     971                            del dict[((integer_base_2_log(mono[0]),0),)]
     972                        converted = True
     973                elif basis_name == 'woodz':
     974                    if len(mono) == 1 and is_power_of_two(mono[0]):   # no conversion
     975                        if new_coeff != 0:
     976                            dict[((integer_base_2_log(mono[0]),0),)] = new_coeff
     977                        else:
     978                            del dict[((integer_base_2_log(mono[0]),0),)]
     979                        converted = True
     980                elif basis_name == 'wall':
     981                    if len(mono) == 1 and is_power_of_two(mono[0]):   # no conversion
     982                        m = integer_base_2_log(mono[0])
     983                        if new_coeff != 0:
     984                            dict[((m,m),)] = new_coeff
     985                        else:
     986                            del dict[((m,m),)]
     987                        converted = True
     988                elif basis_name == 'arnona':
     989                    if len(mono) == 1 and is_power_of_two(mono[0]):   # no conversion
     990                        m = integer_base_2_log(mono[0])
     991                        if new_coeff != 0:
     992                            dict[((m,m),)] = new_coeff
     993                        else:
     994                            del dict[((m,m),)]
     995                        converted = True
     996                elif basis_name == 'arnonc':
     997                    if len(mono) == 1:   # no conversion
     998                        if dict.has_key(mono):
     999                            new_coeff = dict[mono] + self._raw['milnor'][mono]
     1000                            if new_coeff != 0:
     1001                                dict[mono] = new_coeff
     1002                            else:
     1003                                del dict[mono]
     1004                        else:
     1005                            dict[mono] = self._raw['milnor'][mono]
     1006                        converted = True
     1007                if not converted:
     1008                    conversion = milnor_convert(  # conversion required
     1009                        SteenrodAlgebraElement({mono: 1}),
     1010                        basis)
     1011                    for new_mono in conversion:
     1012                        if dict.has_key(new_mono):
     1013                            new_coeff = dict[new_mono] + conversion[new_mono]
     1014                            if new_coeff != 0:
     1015                                dict[new_mono] = new_coeff
     1016                            else:
     1017                                del dict[new_mono]
     1018                        else:
     1019                            dict[new_mono] = conversion[new_mono]
     1020            self._raw[basis] = dict
     1021            return dict
     1022        else:  # p odd
     1023            dict = {}
     1024            for mono in self._raw['milnor']:
     1025                converted = False
     1026                if dict.has_key(mono):
     1027                    old_coeff = dict[mono]
     1028                else:
     1029                    old_coeff = 0
     1030                new_coeff = old_coeff + self._raw['milnor'][mono]
     1031                if len(mono) == 0:   # length 0: no conversion
     1032                    if new_coeff != 0:
     1033                        dict[mono] = new_coeff
     1034                    else:
     1035                        del dict[mono]
     1036                    converted = True
     1037                elif basis in _steenrod_serre_cartan_basis_names:
     1038                    if len(mono[0]) == 0 and len(mono[1]) == 1:
     1039                        # length 1: Sq(n) = Sq^{n}, so no conversion
     1040                        new_mono = (0,mono[1][0], 0)
     1041                        if dict.has_key(new_mono):
     1042                            new_coeff = dict[new_mono] + self._raw['milnor'][mono]
     1043                            if new_coeff != 0:
     1044                                dict[new_mono] = new_coeff
     1045                            else:
     1046                                del dict[new_mono]
     1047                        else:
     1048                            dict[new_mono] = self._raw['milnor'][mono]
     1049                        converted = True
     1050                if not converted:
     1051                    conversion = milnor_convert(  # conversion required
     1052                        SteenrodAlgebraElement({mono: self._raw['milnor'][mono]},
     1053                                               p),
     1054                        basis)
     1055                    for new_mono in conversion:
     1056                        if dict.has_key(new_mono):
     1057                            new_coeff = dict[new_mono] + conversion[new_mono]
     1058                            if new_coeff != 0:
     1059                                dict[new_mono] = new_coeff
     1060                            else:
     1061                                del dict[new_mono]
     1062                        else:
     1063                            dict[new_mono] = conversion[new_mono]
     1064            self._raw[basis] = dict
     1065            return dict
     1066
     1067
     1068    def basis(self,basis):
     1069        r"""
     1070        Representation of element with respect to basis.
     1071
     1072        INPUT:
     1073            basis -- string, basis in which to work.  The choices are:
     1074            'milnor' or 'mil' for the Milnor basis.
     1075            'serre-cartan', 'serre_cartan', 'sc', 'adem', 'admissible' for
     1076                the Serre-Cartan basis.
     1077            'wood_y' for Wood's Y basis.
     1078            'wood_z' for Wood's Z basis.
     1079            'wall' for Wall's basis.
     1080            'wall_long' for Wall's basis, alternate representation
     1081            'arnon_a' for Arnon's A basis.
     1082            'arnon_a_long' for Arnon's A basis, alternate representation.
     1083            'arnon_c' for Arnon's C basis.
     1084            'pst', 'pst_rlex', 'pst_llex', 'pst_deg', 'pst_revz' for various
     1085                P^s_t-bases.
     1086            'comm', 'comm_rlex', 'comm_llex', 'comm_deg', 'comm_revz' for
     1087                various commutator bases.
     1088            'comm_long', 'comm_rlex_long', etc., for commutator bases, alternate
     1089                representations.
     1090
     1091        OUTPUT:
     1092            None
     1093
     1094        See documentation for the function 'steenrod_algebra_basis' for
     1095        descriptions of the different bases.
     1096
     1097        This prints the representation of element in the given basis.
     1098        Note that it only prints the representation; it does not
     1099        actually return a value.  Thus evaluating
     1100        "y = x.basis('milnor')" will set y to be None.
     1101
     1102        EXAMPLES:
     1103            sage: c = Sq(2) * Sq(1)
     1104            sage: c.basis('milnor')
     1105            Sq(0,1) + Sq(3)
     1106            sage: c.basis('serre-cartan')
     1107            Sq^{2} Sq^{1}
     1108            sage: d = Sq(0,0,1)
     1109            sage: d.basis('arnonc')
     1110            Sq^{2} Sq^{5} + Sq^{4} Sq^{2} Sq^{1} + Sq^{4} Sq^{3} + Sq^{7}
     1111        """
     1112        from sage.algebras.steenrod_algebra import SteenrodAlgebra
     1113        return SteenrodAlgebra(p=self._prime, basis=basis)(self)
     1114
     1115
     1116    def milnor(self):
     1117        r"""
     1118        Milnor representation of self.
     1119       
     1120        OUTPUT:
     1121            Milnor representation of self.
     1122
     1123        This gives the representation of x in the Milnor basis.
     1124
     1125        EXAMPLES:
     1126            sage: A = SteenrodAlgebra(2, 'adem')
     1127            sage: x = A (Sq(5) * Sq(2) * Sq(1)); x
     1128            Sq^{5} Sq^{2} Sq^{1}
     1129            sage: x.milnor()
     1130            Sq(1,0,1) + Sq(5,1)
     1131            """
     1132        return self.basis('milnor')
     1133
     1134
     1135    def serre_cartan(self):
     1136        r"""
     1137        Serre-Cartan representation of self.
     1138       
     1139        OUTPUT:
     1140            Serre-Cartan representation of self.
     1141
     1142        This gives the representation of x in the Serre-Cartan
     1143        (admissible) basis.
     1144
     1145        EXAMPLES:
     1146            sage: x = Sq(0,1); x
     1147            Sq(0,1)
     1148            sage: x.serre_cartan()
     1149            Sq^{2} Sq^{1} + Sq^{3}
     1150            sage: x.adem()  # 'adem' is a synomym for 'serre_cartan'
     1151            Sq^{2} Sq^{1} + Sq^{3}
     1152            """
     1153        return self.basis('serre-cartan')
     1154
     1155
     1156    adem = serre_cartan
     1157
     1158
     1159    def degree(self):
     1160        r"""
     1161        Degree of element.
     1162
     1163        The degree of $\text{Sq}(i_1,i_2,i_3,...)$ is
     1164        $i_1 + 3 i_2 + 7 i_3 + ... + (2^n - 1) i_n + ...$.
     1165        When $p$ is odd, the degree of
     1166        $Q_{0}^{\epsilon_0} Q_{1}^{\epsilon_1} ... \mathcal{P}(r_1, r_2, ...)$
     1167        is $\sum \epsilon_i (2p^i - 1) + \sum r_j (2p^j - 2)$.
     1168       
     1169        The degree of a sum is undefined, unless each summand has the
     1170        same degree: that is, unless the element is homogeneous.
     1171
     1172        EXAMPLES:
     1173            sage: a = Sq(1,2,1)
     1174            sage: a.degree()
     1175            14
     1176            sage: for a in Sq(3) + Sq(5,1): a.degree()
     1177            3
     1178            8
     1179            sage: (Sq(3) + Sq(5,1)).degree()
     1180            Element is not homogeneous.
     1181            sage: B = SteenrodAlgebra(3)
     1182            sage: x = B.Q(1,4)
     1183            sage: y = B.P(1,2,3)
     1184            sage: x.degree()
     1185            166
     1186            sage: y.degree()
     1187            192
     1188        """
     1189        def p_degree(m, mult=1, prime=2):
     1190            """
     1191            For m=(n_1, n_2, n_3, ...), Sum_i 2*n_i*(p^i - 1)
     1192            """
     1193            i = 0
     1194            deg = 0
     1195            for n in m:
     1196                i += 1
     1197                deg += n*mult*(prime**i - 1)
     1198            return deg
     1199       
     1200        def q_degree(m, prime=3):
     1201            """
     1202            For m=(n_0, n_1, n_2, ...), Sum_i 2*p^{n_i} - 1
     1203            """
     1204            deg = 0
     1205            for n in m:
     1206                deg += 2*prime**n - 1
     1207            return deg
     1208       
     1209        p = self._prime
     1210        if p == 2:
     1211            degrees = [p_degree(mono) for mono in self._raw['milnor']]
     1212        else:
     1213            degrees = [q_degree(mono1, prime=p)
     1214                           + p_degree(mono2, prime=p, mult=2)
     1215                           for (mono1, mono2) in self._raw['milnor']]
     1216        if min(degrees) == max(degrees):
     1217            return min(degrees)
     1218        else:
     1219            print "Element is not homogeneous."
     1220            return None
     1221
     1222
     1223    def excess(self):
     1224        r"""
     1225        Excess of element.
     1226
     1227        The excess of $\text{Sq}(a,b,c,...)$ is $a + b + c + ...$.
     1228        When $p$ is odd, the excess of
     1229        $Q_{0}^{\epsilon_0} Q_{1}^{\epsilon_1} ... \mathcal{P}(r_1, r_2, ...)$
     1230        is $\sum epsilon_i + 2 \sum r_i$.
     1231       
     1232        The excess of a linear combination of Milnor basis elements is
     1233        the minimum of the excesses of those basis elements.
     1234
     1235        See [Kra] for the proofs of these assertions.
     1236
     1237        EXAMPLES:
     1238            sage: a = Sq(1,2,3)
     1239            sage: a.excess()
     1240            6
     1241            sage: (Sq(0,0,1) + Sq(4,1) + Sq(7)).excess()
     1242            1
     1243            sage: [m.excess() for m in (Sq(0,0,1) + Sq(4,1) + Sq(7))]
     1244            [1, 5, 7]
     1245            sage: [m for m in (Sq(0,0,1) + Sq(4,1) + Sq(7))]
     1246            [Sq(0,0,1), Sq(4,1), Sq(7)]
     1247            sage: B = SteenrodAlgebra(7)
     1248            sage: a = B.Q(1,2,5)
     1249            sage: b = B.P(2,2,3)
     1250            sage: a.excess()
     1251            3
     1252            sage: b.excess()
     1253            14
     1254            sage: (a + b).excess()
     1255            3
     1256            sage: (a * b).excess()
     1257            17
     1258
     1259        REFERENCES:
     1260            [Kra] D. Kraines, "On excess in the Milnor basis," Bull. London
     1261                Math. Soc. 3 (1971), 363-365.
     1262        """
     1263        def excess_odd(mono):
     1264            if len(mono) == 0:
     1265                return 0
     1266            else:
     1267                return len(mono[0]) + 2 * sum(mono[1])
     1268           
     1269        p = self._prime
     1270        if p == 2:
     1271            excesses = [sum(mono) for mono in self._raw['milnor']]
     1272        else:
     1273            excesses = [excess_odd(mono) for mono in self._raw['milnor']]
     1274        return min(excesses)
     1275
     1276
     1277    def may_weight(self):
     1278        r"""
     1279        May's 'weight' of element.
     1280
     1281        If we let $F_* (A)$ be the May filtration of the Steenrod
     1282        algebra, the weight of an element $x$ is the integer $k$ so
     1283        that $x$ is in $F_k(A)$ and not in $F_{k+1}(A)$.  According to
     1284        Theorem 2.6 in May's thesis [May], the weight of a Milnor
     1285        basis element is computed as follows: first, to compute the
     1286        weight of $\mathcal{P}(r_1,r2, ...)$, write each $r_i$ in base
     1287        $p$ as $r_i = \sum_j p^j r_{ij}$.  Then each nonzero binary
     1288        digit $r_{ij}$ contributes $i$ to the weight: the weight is
     1289        $\sum_{i,j} i r_{ij}$.  When $p$ is odd, the weight of $Q_i$
     1290        is $i+1$, so the weight of a product $Q_{i_1} Q_{i_2} ...$ is
     1291        equal $(i_1+1) + (i_2+1) + ...$.  Then the weight of $Q_{i_1}
     1292        Q_{i_2} ...\mathcal{P}(r_1,r2, ...)$ is the sum of $(i_1+1) +
     1293        (i_2+1) + ...$ and $\sum_{i,j} i r_{ij}$.
     1294       
     1295        The weight of a sum of basis elements is the minimum of the
     1296        weights of the summands.
     1297
     1298        When $p=2$, we compute the weight on Milnor basis elements by
     1299        adding up the terms in their 'height' -- see the method
     1300        'wall_height' for documentation.  (When $p$ is odd, the height
     1301        of an element is not defined.)
     1302
     1303        EXAMPLES:
     1304            sage: Sq(0).may_weight()
     1305            0
     1306            sage: a = Sq(4)
     1307            sage: a.may_weight()
     1308            1
     1309            sage: b = Sq(4)*Sq(8) + Sq(8)*Sq(4)
     1310            sage: b.may_weight()
     1311            2
     1312            sage: Sq(2,1,5).wall_height()
     1313            [2, 3, 2, 1, 1]
     1314            sage: Sq(2,1,5).may_weight()
     1315            9
     1316            sage: A5 = SteenrodAlgebra(5)
     1317            sage: a = A5.Q(1,2,4)
     1318            sage: b = A5.P(1,2,1)
     1319            sage: a.may_weight()
     1320            10
     1321            sage: b.may_weight()
     1322            8
     1323            sage: (a * b).may_weight()
     1324            18
     1325            sage: A5.P(0,0,1).may_weight()
     1326            3
     1327
     1328        REFERENCES:
     1329            [May]: J. P. May, "The cohomology of restricted Lie algebras
     1330                and of Hopf algebras; application to the Steenrod
     1331                algebra." Thesis, Princeton Univ., 1964.
     1332        """
     1333        from sage.rings.infinity import Infinity
     1334        p = self._prime
     1335        if self == 0:
     1336            return Infinity
     1337        elif self.is_unit():
     1338            return 0
     1339        elif p == 2:
     1340            wt = Infinity
     1341            for mono in self:
     1342                wt = min(wt, sum(mono.wall_height()))
     1343            return wt
     1344        else: # p odd
     1345            wt = Infinity
     1346            for (mono1, mono2) in self._raw['milnor']:
     1347                P_wt = 0
     1348                index = 1
     1349                for n in mono2:
     1350                    P_wt += index * sum(base_p_expansion(n,p))
     1351                    index += 1
     1352                wt = min(wt, sum(mono1) + len(mono1) + P_wt)
     1353            return wt
     1354
     1355
     1356    def is_decomposable(self):
     1357        r"""
     1358        return True if element is decomposable, False otherwise.
     1359
     1360        That is, if element is in the square of the augmentation
     1361        ideal, return True; otherwise, return False.
     1362
     1363        EXAMPLES:
     1364            sage: a = Sq(6)
     1365            sage: a.is_decomposable()
     1366            True
     1367            sage: for i in range(9):
     1368            ...       if not Sq(i).is_decomposable():
     1369            ...           print Sq(i)
     1370            Sq(0)
     1371            Sq(1)
     1372            Sq(2)
     1373            Sq(4)
     1374            Sq(8)
     1375        """
     1376        return self.may_weight() > 1       
     1377
     1378
     1379    def wall_height(self):
     1380        r"""
     1381        Wall's 'height' of element.
     1382
     1383        The height of an element of the mod 2 Steenrod algebra is a
     1384        list of non-negative integers, defined as follows: if the
     1385        element is a monomial in the generators $\text{Sq}(2^i)$, then
     1386        the $i$th entry in the list is the number of times
     1387        $\text{Sq}(2^i)$ appears.  For an arbitrary element, write it
     1388        as a sum of such monomials; then its height is the maximum,
     1389        ordered right-lexicographically, of the heights of those
     1390        monomials.
     1391
     1392        When $p$ is odd, the height of an element is not defined.
     1393
     1394        According to Theorem 3 in [Wall], the height of the Milnor
     1395        basis element $\text{Sq}(r_1, r_2, ...)$ is obtained as
     1396        follows: write each $r_i$ in binary as $r_i = \sum_j 2^j r_{ij}$. 
     1397        Then each nonzero binary digit $r_{ij}$ contributes 1 to the
     1398        $k$th entry in the height, for $j \leq k \leq i+j-1$.
     1399
     1400        EXAMPLES:
     1401            sage: Sq(0).wall_height()
     1402            []
     1403            sage: a = Sq(4)
     1404            sage: a.wall_height()
     1405            [0, 0, 1]
     1406            sage: b = Sq(4)*Sq(8) + Sq(8)*Sq(4)
     1407            sage: b.wall_height()
     1408            [0, 0, 1, 1]
     1409            sage: Sq(0,0,3).wall_height()
     1410            [1, 2, 2, 1]
     1411
     1412        REFERENCES:
     1413            [Wall]: C. T. C. Wall, "Generators and relations for the
     1414                Steenrod algebra," Ann. of Math. (2) \textbf{72} (1960),
     1415                429--444.
     1416        """
     1417        def mono_degree(m):
     1418            i = 0
     1419            deg = 0
     1420            for n in m:
     1421                i += 1
     1422                deg += n*(2**i - 1)
     1423            return deg
     1424
     1425        if self._prime > 2:
     1426            raise NotImplementedError, "Wall height is not defined at odd primes."
     1427        if self == 0 or self == 1:
     1428            return []
     1429        result = []
     1430        for r in self._raw['milnor']:
     1431            h = [0]*(1+mono_degree(r))
     1432            i = 1
     1433            for x in r:
     1434                if x > 0:
     1435                    for j in range(1+integer_base_2_log(x)):
     1436                        if (2**j & x) != 0:
     1437                            for k in range(j,i+j):
     1438                                h[k] += 1
     1439                i=i+1
     1440            h.reverse()
     1441            result = max(h, result)
     1442        result.reverse()
     1443        return check_and_trim(result)
     1444           
     1445
     1446    def antipode(self):
     1447        """
     1448        Antipode of element.
     1449
     1450        Algorithm: according to a result of Milnor's, the antipode of
     1451        Sq(n) is the sum of all of the Milnor basis elements in
     1452        dimension n.  So: convert the element to the Serre-Cartan
     1453        basis and use this formula for the antipode of Sq(n), together
     1454        with the fact that the antipode is an antihomomorphism: if we
     1455        call the antipode c, then c(ab) = c(b) c(a).
     1456
     1457        At odd primes, a similar method is used: the antipode of P(n)
     1458        is the sum of the Milnor basis elements in dimension n*2(p-1),
     1459        and the antipode of beta = Q_0 is -Q_0.  So convert to the
     1460        Serre-Cartan basis, as in the p=2 case.
     1461
     1462        EXAMPLES:
     1463            sage: d = Sq(0,0,1); d
     1464            Sq(0,0,1)
     1465            sage: d.antipode()
     1466            Sq(0,0,1)
     1467            sage: Sq(4).antipode()
     1468            Sq(1,1) + Sq(4)
     1469            sage: (Sq(4) * Sq(2)).antipode()
     1470            Sq(6)
     1471            sage: A3 = SteenrodAlgebra(3)
     1472            sage: A3.P(2).antipode()
     1473            P(2)
     1474            sage: A3.P(2,1).antipode()
     1475            2 P(2,1)
     1476            sage: a = SteenrodAlgebra(7).P(3,1)
     1477            sage: a.antipode()
     1478            3 P(3,1) + 4 P(11)
     1479
     1480        Applying the antipode twice returns the original element:
     1481            sage: y = Sq(8)*Sq(4)
     1482            sage: y == (y.antipode()).antipode()
     1483            True
     1484        """
     1485        def sum_of_basis(n,p):
     1486            """
     1487            Antipode of P(n) (i.e., of Sq(n) when p=2).
     1488
     1489            INPUT:
     1490                n -- integer
     1491                p -- positive prime number
     1492           
     1493            OUTPUT:
     1494                elt -- element of the Steenrod algebra
     1495
     1496            This returns the sum of all of the elements P(...) in the
     1497            Milnor basis in dimension $n$ at the prime p
     1498            """
     1499            from steenrod_algebra_bases import steenrod_algebra_basis
     1500            return sum(steenrod_algebra_basis(n,'milnor',p=p))
     1501        from sage.algebras.steenrod_algebra import SteenrodAlgebra
     1502        from steenrod_algebra_bases import milnor_convert
     1503        result = 0
     1504        p = self._prime
     1505        if p == 2:
     1506            for mono in self._basis_dictionary('serre_cartan'):
     1507                antipode = Sq(0)
     1508                for n in mono:
     1509                    antipode = sum_of_basis(n, p) * antipode
     1510                result = result + antipode
     1511        else:
     1512            from sage.misc.functional import is_even
     1513            for mono in self._basis_dictionary('serre_cartan'):
     1514                antipode = SteenrodAlgebra(p).P(0)
     1515                index = 0
     1516                for n in mono:
     1517                    if is_even(index) and n != 0:
     1518                        antipode = -SteenrodAlgebra(p).Q(0) * antipode
     1519                    else:
     1520                        antipode = sum_of_basis(n*2*(p-1),p) * antipode
     1521                    index += 1
     1522                result = result + antipode
     1523        return result
     1524
     1525
     1526    def _repr_(self):
     1527        """
     1528        String representation of element.
     1529
     1530        The string depends on the basis over which the element is defined.
     1531
     1532        EXAMPLES:
     1533            sage: A7 = SteenrodAlgebra(7)
     1534            sage: x = A7.Q(0,3) * A7.P(2,2)
     1535            sage: x._repr_()
     1536            'Q_0 Q_3 P(2,2)'
     1537            sage: x
     1538            Q_0 Q_3 P(2,2)
     1539            sage: a = Sq(0,0,2)
     1540            sage: a
     1541            Sq(0,0,2)
     1542            sage: A2_adem = SteenrodAlgebra(2,'admissible')
     1543            sage: A2_adem(a)
     1544            Sq^{8} Sq^{4} Sq^{2} + Sq^{9} Sq^{4} Sq^{1} + Sq^{10} Sq^{3} Sq^{1} +
     1545            Sq^{10} Sq^{4} + Sq^{11} Sq^{2} Sq^{1} + Sq^{12} Sq^{2} + Sq^{13} Sq^{1}
     1546            + Sq^{14}
     1547            sage: SteenrodAlgebra(2, 'woodz')(a)
     1548            Sq^{6} Sq^{7} Sq^{1} + Sq^{14} + Sq^{4} Sq^{7} Sq^{3} + Sq^{4} Sq^{7}
     1549            Sq^{2} Sq^{1} + Sq^{12} Sq^{2} + Sq^{8} Sq^{6} + Sq^{8} Sq^{4} Sq^{2}
     1550            sage: SteenrodAlgebra(2, 'arnonc')(a)
     1551            Sq^{4} Sq^{2} Sq^{8} + Sq^{4} Sq^{4} Sq^{6} + Sq^{4} Sq^{6} Sq^{4} +
     1552            Sq^{6} Sq^{8} + Sq^{8} Sq^{4} Sq^{2} + Sq^{8} Sq^{6}
     1553            sage: SteenrodAlgebra(2, 'pst_llex')(a)
     1554            P^{1}_{3}
     1555            sage: SteenrodAlgebra(2, 'comm_revz')(a)
     1556            c_{0,1} c_{1,1} c_{0,3} c_{2,1} + c_{0,2} c_{0,3} c_{2,1} + c_{1,3}
     1557        """
     1558        if len(self._raw['milnor']) == 0:
     1559            return "0"
     1560        else:
     1561            return string_rep(self)
     1562
     1563
     1564    def _latex_(self):
     1565        """
     1566        LaTeX representation of element.
     1567       
     1568        The string depends on the basis over which the element is defined.
     1569
     1570        For any element x in the Steenrod algebra, use 'view(x)' to
     1571        see the typeset LaTeX representation.
     1572
     1573        EXAMPLES:
     1574            sage: A7 = SteenrodAlgebra(7)
     1575            sage: x = A7.Q(0,3) * A7.P(2,2)
     1576            sage: x._latex_()
     1577            'Q_{0} Q_{3} \\mathcal{P}(2,2)'
     1578            sage: latex(x)
     1579            Q_{0} Q_{3} \mathcal{P}(2,2)
     1580            sage: b = Sq(0,2)
     1581            sage: b.basis('adem')._latex_()
     1582            '\\text{Sq}^{4} \\text{Sq}^{2} + \\text{Sq}^{5} \\text{Sq}^{1} +
     1583            \\text{Sq}^{6}'
     1584            sage: b.basis('woody')._latex_()
     1585            '\\text{Sq}^{2} \\text{Sq}^{3} \\text{Sq}^{1} + \\text{Sq}^{6} +
     1586            \\text{Sq}^{4} \\text{Sq}^{2}'
     1587            sage: SteenrodAlgebra(2, 'arnona')(b)._latex_()
     1588            'X^{1}_{1} X^{2}_{2}  + X^{2}_{1}'
     1589        """
     1590        if len(self._raw['milnor']) == 0:
     1591            return "0"
     1592        else:
     1593            return string_rep(self,LaTeX=True)
     1594
     1595
     1596    def __iter__(self):
     1597        """
     1598        Iterator for looping through summands in an element of the
     1599        Steenrod algebra.
     1600
     1601        EXAMPLES:
     1602            sage: z = Sq(0,0,1) + Sq(4,1) + Sq(7)
     1603            sage: [m for m in z]
     1604            [Sq(0,0,1), Sq(4,1), Sq(7)]
     1605            sage: [m.excess() for m in z]
     1606            [1, 5, 7]
     1607            sage: for m in z: m * Sq(2)
     1608            Sq(2,0,1)
     1609            Sq(0,3) + Sq(6,1)
     1610            Sq(3,2)
     1611            sage: a = SteenrodAlgebra(5).P(5,5)
     1612            sage: a * a
     1613            P(3,6,1) + 2 P(4,11) + P(9,5,1) + 4 P(10,10)
     1614            sage: for m in a * a: m
     1615            P(3,6,1)
     1616            2 P(4,11)
     1617            P(9,5,1)
     1618            4 P(10,10)
     1619
     1620        This loops through the summands in the Milnor basis
     1621        representation of the element.  The element w defined below is
     1622        a single monomial in the Serre-Cartan basis, but a sum of four
     1623        monomials in the Milnor basis:
     1624            sage: w = Sq(4) * Sq(2) * Sq(1)
     1625            sage: A = SteenrodAlgebra(2, 'adem')
     1626            sage: w = A(Sq(4) * Sq(2) * Sq(1)); w
     1627            Sq^{4} Sq^{2} Sq^{1}
     1628            sage: for m in w: m.basis('adem')
     1629            Sq^{4} Sq^{2} Sq^{1} + Sq^{5} Sq^{2} + Sq^{6} Sq^{1} + Sq^{7}
     1630            Sq^{5} Sq^{2} + Sq^{7}
     1631            Sq^{6} Sq^{1} + Sq^{7}
     1632            Sq^{7}
     1633            sage: w.milnor()
     1634            Sq(0,0,1) + Sq(1,2) + Sq(4,1) + Sq(7)
     1635            sage: for m in w: m
     1636            Sq(0,0,1)
     1637            Sq(1,2)
     1638            Sq(4,1)
     1639            Sq(7)
     1640        """
     1641        for m in sorted(self._raw['milnor'].keys()):
     1642            yield SteenrodAlgebraElement({m: self._raw['milnor'][m]},
     1643                                         p = self._prime)
     1644       
     1645
     1646    def additive_order(self):
     1647        """
     1648        The additive order of any element of the mod p Steenrod algebra is p.
     1649
     1650        EXAMPLES:
     1651            sage: z = Sq(4) + Sq(6) + Sq(0)
     1652            sage: z.additive_order()
     1653            2
     1654        """
     1655        return self._prime
     1656
     1657
     1658def Sq(*nums):
     1659    """
     1660    Milnor element Sq(a,b,c,...).
     1661
     1662    INPUT:
     1663        nums -- list of non-negative integers
     1664       
     1665    OUTPUT:
     1666        element of the Steenrod algebra given by the single basis
     1667        element Sq(a, b, c, ...)
     1668   
     1669    EXAMPLES:
     1670        sage: Sq(5)
     1671        Sq(5)
     1672        sage: Sq(5) + Sq(2,1) + Sq(5)  # addition is mod 2:
     1673        Sq(2,1)   
     1674        sage: (Sq(4,3) + Sq(7,2)).degree()
     1675        13
     1676
     1677    Entries must be non-negative integers; otherwise, an error results.
     1678       
     1679    This function is a good way to define elements of the Steenrod algebra.
     1680    """
     1681    dict = {nums: 1}
     1682    return SteenrodAlgebraElement(dict, p=2)
     1683
     1684
     1685def pst(s,t,p=2):
     1686    """
     1687    The Margolis element P^s_t.
     1688
     1689    INPUT:
     1690        s -- non-negative integer
     1691        t -- positive integer
     1692        p (optional, default 2) -- positive prime number
     1693       
     1694    OUTPUT:
     1695        The Margolis element P^s_t of the mod p Steenrod algebra: the
     1696        element equal to P(0,0,...,0,p^s), where the p^s is in
     1697        position t.
     1698
     1699    EXAMPLES:
     1700        sage: from sage.algebras.steenrod_algebra_element import pst
     1701        sage: pst(3,5)
     1702        Sq(0,0,0,0,8)
     1703        sage: pst(1,2) + Sq(4)*Sq(2) + Sq(2)*Sq(4)
     1704        0
     1705        sage: pst(3,5,5)
     1706        P(0,0,0,0,125)
     1707        sage: pst(3,5,p=5)
     1708        P(0,0,0,0,125)
     1709    """
     1710    from sage.algebras.steenrod_algebra import SteenrodAlgebra
     1711    return SteenrodAlgebra(p).pst(s,t)
     1712
     1713
     1714def degree(x):
     1715    r"""
     1716    Degree of x.
     1717   
     1718    The degree of $\text{Sq}(i_1,i_2,i_3,...)$ is
     1719    $i_1 + 3 i_2 + 7 i_3 + ... + (2^n - 1) i_n + ...$.
     1720    When $p$ is odd, the degree of
     1721    $Q_{0}^{\epsilon_0} Q_{1}^{\epsilon_1} ... \mathcal{P}(r_1, r_2, ...)$
     1722    is $\sum \epsilon_i (2p^i - 1) + \sum r_j (2p^j - 2)$.
     1723       
     1724    The degree of a sum is undefined, unless each summand has the
     1725    same degree: that is, unless the element is homogeneous.
     1726   
     1727    INPUT:
     1728        x -- element of the Steenrod algebra
     1729
     1730    OUTPUT:
     1731        degree -- non-negative integer, or None if element is not
     1732        homogeneous
     1733   
     1734    EXAMPLES:
     1735        sage: from sage.algebras.steenrod_algebra_element import degree
     1736        sage: a = Sq(1,2,1)
     1737        sage: degree(a)
     1738        14
     1739        sage: degree(Sq(3) + Sq(5,1))
     1740        Element is not homogeneous.
     1741        sage: B = SteenrodAlgebra(3)
     1742        sage: x = B.Q(1,4)
     1743        sage: y = B.P(1,2,3)
     1744        sage: degree(x)
     1745        166
     1746        sage: degree(y)
     1747        192
     1748    """
     1749    return x.degree()
     1750
     1751
     1752def excess(x):
     1753    r"""
     1754    Excess of x.
     1755   
     1756    The excess of $\text{Sq}(a,b,c,...)$ is $a + b + c + ...$.
     1757    When $p$ is odd, the excess of
     1758    $Q_{0}^{\epsilon_0} Q_{1}^{\epsilon_1} ... \mathcal{P}(r_1, r_2, ...)$
     1759    is $\sum epsilon_i + 2 \sum r_i$.
     1760       
     1761    The excess of a linear combination of Milnor basis elements is
     1762    the minimum of the excesses of those basis elements.
     1763
     1764    INPUT:
     1765        x -- element of the Steenrod algebra
     1766
     1767    OUTPUT:
     1768        excess -- non-negative integer, the excess of x
     1769   
     1770    EXAMPLES:
     1771        sage: from sage.algebras.steenrod_algebra_element import excess
     1772        sage: a = Sq(1,2,3)
     1773        sage: excess(a)
     1774        6
     1775        sage: excess(Sq(0,0,1) + Sq(4,1) + Sq(7))
     1776        1
     1777        sage: [excess(m) for m in (Sq(0,0,1) + Sq(4,1) + Sq(7))]
     1778        [1, 5, 7]
     1779        sage: B = SteenrodAlgebra(7)
     1780        sage: a = B.Q(1,2,5)
     1781        sage: b = B.P(2,2,3)
     1782        sage: excess(a)
     1783        3
     1784        sage: excess(b)
     1785        14
     1786        sage: excess(a + b)
     1787        3
     1788        sage: excess(a * b)
     1789        17
     1790    """
     1791    return x.excess()
     1792
     1793
     1794def milnor(x):
     1795    r"""
     1796    Milnor representation of x.
     1797
     1798    INPUT:
     1799        x -- element of the Steenrod algebra
     1800
     1801    OUTPUT:
     1802        None
     1803
     1804    This prints the representation of x in the Milnor basis.  Note
     1805    that it only prints the representation; it does not actually
     1806    return a value.  Thus evaluating "y = milnor(x)" will set
     1807    y to be None.
     1808
     1809    EXAMPLES:
     1810        sage: from sage.algebras.steenrod_algebra_element import milnor
     1811        sage: x = Sq(5) * Sq(2) * Sq(1); x.adem()
     1812        Sq^{5} Sq^{2} Sq^{1}
     1813        sage: milnor(x)
     1814        Sq(1,0,1) + Sq(5,1)
     1815    """
     1816    return x.basis('milnor')
     1817
     1818
     1819def serre_cartan(x):
     1820    r"""
     1821    Serre-Cartan representation of x.
     1822
     1823    INPUT:
     1824        x -- element of the Steenrod algebra
     1825
     1826    OUTPUT:
     1827        None
     1828
     1829    This prints the representation of x in the Serre-Cartan basis.
     1830    Note that it only prints the representation; it does not actually
     1831    return a value.  Thus evaluating "y = serre_cartan(x)" will set y
     1832    to be None.
     1833
     1834    EXAMPLES:
     1835        sage: from sage.algebras.steenrod_algebra_element import serre_cartan
     1836        sage: x = Sq(3,2); x
     1837        Sq(3,2)
     1838        sage: serre_cartan(x)
     1839        Sq^{7} Sq^{2}
     1840    """
     1841    return x.basis('adem')
     1842
     1843adem = serre_cartan
     1844admissible = serre_cartan
     1845
     1846## string representations
     1847
     1848def string_rep(element, LaTeX=False, sort=True):
     1849    """
     1850    String representation of element.
     1851
     1852    INPUT:
     1853        element -- element of the Steenrod algebra
     1854        LaTeX (optional, default False) -- If True, output LaTeX string
     1855        sort (optional, default True) -- If True, sort output
     1856
     1857    OUTPUT:
     1858        string -- string representation of element in current basis
     1859
     1860    If LaTeX is True, output a string suitable for LaTeX; otherwise,
     1861    output a plain string.  If sort is True, sort element left
     1862    lexicographically; otherwise, no sorting is done, and so the
     1863    order in which the summands are printed may be unpredictable.
     1864   
     1865    EXAMPLES:
     1866        sage: from sage.algebras.steenrod_algebra_element import string_rep
     1867        sage: a = Sq(0,0,2)
     1868        sage: A = SteenrodAlgebra(2, 'admissible')
     1869        sage: string_rep(A(a))
     1870        'Sq^{8} Sq^{4} Sq^{2} + Sq^{9} Sq^{4} Sq^{1} + Sq^{10} Sq^{3} Sq^{1} +
     1871        Sq^{10} Sq^{4} + Sq^{11} Sq^{2} Sq^{1} + Sq^{12} Sq^{2} + Sq^{13} Sq^{1}
     1872        + Sq^{14}'
     1873        sage: b = Sq(0,2)
     1874        sage: string_rep(A(b),LaTeX=True)
     1875        '\\text{Sq}^{4} \\text{Sq}^{2} + \\text{Sq}^{5} \\text{Sq}^{1} +
     1876        \\text{Sq}^{6}'
     1877        sage: A_wood_z = SteenrodAlgebra(2, 'woodz')
     1878        sage: string_rep(A_wood_z(a))
     1879        'Sq^{6} Sq^{7} Sq^{1} + Sq^{14} + Sq^{4} Sq^{7} Sq^{3} + Sq^{4} Sq^{7}
     1880        Sq^{2} Sq^{1} + Sq^{12} Sq^{2} + Sq^{8} Sq^{6} + Sq^{8} Sq^{4} Sq^{2}'
     1881        sage: string_rep(SteenrodAlgebra(2, 'arnonc')(a), sort=False)
     1882        'Sq^{4} Sq^{4} Sq^{6} + Sq^{6} Sq^{8} + Sq^{4} Sq^{2} Sq^{8} + Sq^{4}
     1883        Sq^{6} Sq^{4} + Sq^{8} Sq^{4} Sq^{2} + Sq^{8} Sq^{6}'
     1884        sage: string_rep(SteenrodAlgebra(2, 'arnonc')(a))
     1885        'Sq^{4} Sq^{2} Sq^{8} + Sq^{4} Sq^{4} Sq^{6} + Sq^{4} Sq^{6} Sq^{4} +
     1886        Sq^{6} Sq^{8} + Sq^{8} Sq^{4} Sq^{2} + Sq^{8} Sq^{6}'
     1887        sage: string_rep(SteenrodAlgebra(2, 'pst_llex')(a))
     1888        'P^{1}_{3}'
     1889        sage: Ac = SteenrodAlgebra(2, 'comm_revz')
     1890        sage: string_rep(Ac(a),LaTeX=True,sort=False)
     1891        'c_{0,2} c_{0,3} c_{2,1} + c_{1,3} + c_{0,1} c_{1,1} c_{0,3} c_{2,1}'
     1892        sage: string_rep(Ac(a),LaTeX=True)
     1893        'c_{0,1} c_{1,1} c_{0,3} c_{2,1} + c_{0,2} c_{0,3} c_{2,1} + c_{1,3}'
     1894        sage: string_rep(a)
     1895        'Sq(0,0,2)'
     1896        sage: string_rep(a,LaTeX=True)
     1897        '\\text{Sq}(0,0,2)'
     1898
     1899    Some odd primary examples:
     1900        sage: A5 = SteenrodAlgebra(5)
     1901        sage: a = A5.P(5,1); b = A5.Q(0,1,3)
     1902        sage: string_rep(b)
     1903        'Q_0 Q_1 Q_3'
     1904        sage: string_rep(a, LaTeX=True)
     1905        '\\mathcal{P}(5,1)'
     1906        sage: A5sc = SteenrodAlgebra(5, 'serre-cartan')
     1907        sage: string_rep(A5sc(a))
     1908        'P^{10} P^{1} + 4 P^{11}'
     1909    """
     1910    if len(element._raw['milnor']) == 0:
     1911        return "0"
     1912    p = element._prime
     1913
     1914    basis = element._basis
     1915    dict = element._basis_dictionary(basis)
     1916
     1917    if basis == 'milnor':
     1918        mono_to_string = milnor_mono_to_string
     1919    elif basis == 'serre-cartan':
     1920        mono_to_string = serre_cartan_mono_to_string
     1921    elif basis.find('wood') >= 0:
     1922        mono_to_string = wood_mono_to_string
     1923    elif basis == 'wall':
     1924        mono_to_string = wall_mono_to_string
     1925    elif basis == 'wall_long':
     1926        mono_to_string = wall_long_mono_to_string
     1927    elif basis == 'arnona':
     1928        mono_to_string = arnonA_mono_to_string
     1929    elif basis == 'arnona_long':
     1930        mono_to_string = arnonA_long_mono_to_string
     1931    elif basis == 'arnonc':
     1932        mono_to_string = serre_cartan_mono_to_string
     1933    elif basis.find('pst') >= 0:
     1934        mono_to_string = pst_mono_to_string
     1935    elif basis.find('comm') >= 0 and basis.find('long') >= 0:
     1936        mono_to_string = comm_long_mono_to_string
     1937    elif basis.find('comm') >= 0:
     1938        mono_to_string = comm_mono_to_string
     1939   
     1940    output = ""
     1941    if sort:
     1942        sorted_list = sorted(dict.keys())
     1943    else:
     1944        sorted_list = dict
     1945    for mono in sorted_list:
     1946        if dict[mono] != 1:
     1947            coeff = str(dict[mono]) + " "
     1948        else:
     1949            coeff = ""
     1950        output = output + coeff + mono_to_string(mono, LaTeX,
     1951                                                 p=element._prime) + " + "
     1952    return output.strip(" +")
     1953
     1954
     1955def milnor_mono_to_string(mono,LaTeX=False,p=2):
     1956    """
     1957    String representation of element of the Milnor basis.
     1958
     1959    This is used by the _repr_ and _latex_ methods.
     1960
     1961    INPUT:
     1962        mono -- if p=2, tuple of non-negative integers (a,b,c,...);
     1963                if p>2, pair of tuples of non-negative integers
     1964                ((n0, n1, n2, ...), (r1, r2, ...))
     1965        LaTeX (optional, default False) -- if true, output LaTeX string
     1966        p (optional, default 2) -- work in the mod p Steenrod algebra
     1967
     1968    OUTPUT:
     1969        string -- string Sq(a,b,c,...) when p=2, or string
     1970                  Q_n0 Q_n1 Q_n2 ... P(r1, r2, ...) when p>2
     1971       
     1972    EXAMPLES:
     1973        sage: from sage.algebras.steenrod_algebra_element import milnor_mono_to_string
     1974        sage: milnor_mono_to_string((1,2,3,4))
     1975        'Sq(1,2,3,4)'
     1976        sage: milnor_mono_to_string((1,2,3,4),LaTeX=True)
     1977        '\\text{Sq}(1,2,3,4)'
     1978        sage: milnor_mono_to_string(((1,0), (2,3,1)), p=3)
     1979        'Q_1 Q_0 P(2,3,1)'
     1980        sage: milnor_mono_to_string(((1,0), (2,3,1)), LaTeX=True, p=3)
     1981        'Q_{1} Q_{0} \\mathcal{P}(2,3,1)'
     1982
     1983    The empty tuple represents the unit element Sq(0) (or P(0) at an odd prime):
     1984        sage: milnor_mono_to_string(())
     1985        'Sq(0)'
     1986        sage: milnor_mono_to_string((), p=5)
     1987        'P(0)'
     1988    """
     1989    if LaTeX:
     1990        if p == 2:
     1991            sq = "\\text{Sq}"
     1992            P = "\\text{Sq}"
     1993        else:
     1994            P = "\\mathcal{P}"
     1995    else:
     1996        if p == 2:
     1997            sq = "Sq"
     1998            P = "Sq"
     1999        else:
     2000            P = "P"
     2001    if len(mono) == 0 or (p > 2 and len(mono[0]) + len(mono[1]) == 0):
     2002        return P + "(0)"
     2003    else:
     2004        if p == 2:
     2005            string = sq + "(" + str(mono[0])
     2006            for n in mono[1:]:
     2007                string = string + "," + str(n)
     2008            string = string + ")"
     2009        else:
     2010            string = ""
     2011            if len(mono[0]) > 0:
     2012                for e in mono[0]:
     2013                    if LaTeX:
     2014                        string = string + "Q_{" + str(e) + "} "
     2015                    else:
     2016                        string = string + "Q_" + str(e) + " "
     2017            if len(mono[1]) > 0:
     2018                string = string + P + "(" + str(mono[1][0])
     2019                for n in mono[1][1:]:
     2020                    string = string + "," + str(n)
     2021                string = string + ")"
     2022        return string.strip(" ")
     2023   
     2024
     2025def serre_cartan_mono_to_string(mono,LaTeX=False,p=2):
     2026    """
     2027    String representation of element of the Serre-Cartan basis.
     2028
     2029    This is used by the _repr_ and _latex_ methods.
     2030
     2031    INPUT:
     2032        mono -- tuple of positive integers (a,b,c,...) when p=2, or tuple
     2033                (e0, n1, e1, n2, ...) when p>2, where each ei is 0 or 1, and
     2034                each ni is positive
     2035        LaTeX (optional, default False) -- if true, output LaTeX string
     2036        p (optional, default 2) -- work in the mod p Steenrod algebra
     2037
     2038    OUTPUT:
     2039        string -- string Sq^{a} Sq^{b} Sq^{c} ... when p=2, or string
     2040                  beta^{e0} P^{n1} beta^{e1} P^{n2} ...
     2041       
     2042    EXAMPLES:
     2043        sage: from sage.algebras.steenrod_algebra_element import serre_cartan_mono_to_string
     2044        sage: serre_cartan_mono_to_string((1,2,3,4))
     2045        'Sq^{1} Sq^{2} Sq^{3} Sq^{4}'
     2046        sage: serre_cartan_mono_to_string((1,2,3,4),LaTeX=True)
     2047        '\\text{Sq}^{1} \\text{Sq}^{2} \\text{Sq}^{3} \\text{Sq}^{4}'
     2048        sage: serre_cartan_mono_to_string((0,5,1,1,0), p=3)
     2049        'P^{5} beta P^{1}'
     2050        sage: serre_cartan_mono_to_string((0,5,1,1,0), p=3, LaTeX=True)
     2051        '\\mathcal{P}^{5} \\beta \\mathcal{P}^{1}'
     2052
     2053    The empty tuple represents the unit element Sq^0 (or P^0 at an odd prime):
     2054        sage: serre_cartan_mono_to_string(())
     2055        'Sq^{0}'
     2056        sage: serre_cartan_mono_to_string((), p=7)
     2057        'P^{0}'
     2058    """
     2059    if LaTeX:
     2060        if p == 2:
     2061            sq = "\\text{Sq}"
     2062            P = "\\text{Sq}"
     2063        else:
     2064            P = "\\mathcal{P}"
     2065    else:
     2066        if p == 2:
     2067            sq = "Sq"
     2068            P = "Sq"
     2069        else:
     2070            P = "P"
     2071    if len(mono) == 0:
     2072        return P + "^{0}"
     2073    else:
     2074        if p == 2:
     2075            string = ""
     2076            for n in mono:
     2077                string = string + sq + "^{" + str(n) + "} "
     2078        else:
     2079            string = ""
     2080            index = 0
     2081            for n in mono:
     2082                from sage.misc.functional import is_even
     2083                if is_even(index):
     2084                    if n == 1:
     2085                        if LaTeX:
     2086                            string = string + "\\beta "
     2087                        else:
     2088                            string = string + "beta "
     2089                else:
     2090                    string = string + P + "^{" + str(n) + "} "
     2091                index += 1
     2092        return string.strip(" ")
     2093
     2094
     2095def wood_mono_to_string(mono,LaTeX=False,p=2):
     2096    """
     2097    String representation of element of Wood's Y and Z bases.
     2098
     2099    This is used by the _repr_ and _latex_ methods.
     2100
     2101    INPUT:
     2102        mono -- tuple of pairs of non-negative integers (s,t)
     2103
     2104    OUTPUT:
     2105        string -- concatenation of 'Sq^{2^s (2^{t+1}-1)}' for each pair (s,t)
     2106       
     2107    EXAMPLES:
     2108        sage: from sage.algebras.steenrod_algebra_element import wood_mono_to_string
     2109        sage: wood_mono_to_string(((1,2),(3,0)))
     2110        'Sq^{14} Sq^{8}'
     2111        sage: wood_mono_to_string(((1,2),(3,0)),LaTeX=True)
     2112        '\\text{Sq}^{14} \\text{Sq}^{8}'
     2113
     2114    The empty tuple represents the unit element Sq(0):
     2115        sage: wood_mono_to_string(())
     2116        'Sq(0)'
     2117    """
     2118    if LaTeX:
     2119        sq = "\\text{Sq}"
     2120    else:
     2121        sq = "Sq"
     2122    if len(mono) == 0:
     2123        return sq + "(0)"
     2124    else:
     2125        string = ""
     2126        for (s,t) in mono:
     2127            string = string + sq + "^{" + \
     2128                str(2**s * (2**(t+1)-1)) + "} "
     2129        return string.strip(" ")
     2130
     2131
     2132def wall_mono_to_string(mono,LaTeX=False,p=2):
     2133    """
     2134    String representation of element of Wall's basis.
     2135
     2136    This is used by the _repr_ and _latex_ methods.
     2137
     2138    INPUT:
     2139        mono -- tuple of pairs of non-negative integers (m,k) with m >= k
     2140
     2141    OUTPUT:
     2142        string -- concatenation of 'Q^{m}_{k}' for each pair (m,k)
     2143       
     2144    EXAMPLES:
     2145        sage: from sage.algebras.steenrod_algebra_element import wall_mono_to_string
     2146        sage: wall_mono_to_string(((1,2),(3,0)))
     2147        'Q^{1}_{2} Q^{3}_{0}'
     2148        sage: wall_mono_to_string(((1,2),(3,0)),LaTeX=True)
     2149        'Q^{1}_{2} Q^{3}_{0}'
     2150
     2151    The empty tuple represents the unit element Sq(0):
     2152        sage: wall_mono_to_string(())
     2153        'Sq(0)'
     2154    """
     2155    if LaTeX:
     2156        sq = "\\text{Sq}"
     2157    else:
     2158        sq = "Sq"
     2159    if len(mono) == 0:
     2160        return sq + "(0)"
     2161    else:
     2162        string = ""
     2163        for (m,k) in mono:
     2164            string = string + "Q^{" + str(m) + "}_{" \
     2165                + str(k) + "} "
     2166        return string.strip(" ")
     2167
     2168
     2169def wall_long_mono_to_string(mono,LaTeX=False,p=2):
     2170    """
     2171    Alternate string representation of element of Wall's basis.
     2172
     2173    This is used by the _repr_ and _latex_ methods.
     2174
     2175    INPUT:
     2176        mono -- tuple of pairs of non-negative integers (m,k) with m >= k
     2177
     2178    OUTPUT:
     2179        string -- concatenation of terms of the form 'Sq^(2^m)'
     2180       
     2181    EXAMPLES:
     2182        sage: from sage.algebras.steenrod_algebra_element import wall_long_mono_to_string
     2183        sage: wall_long_mono_to_string(((1,2),(3,0)))
     2184        'Sq^{1} Sq^{2} Sq^{4} Sq^{8}'
     2185        sage: wall_long_mono_to_string(((1,2),(3,0)),LaTeX=True)
     2186        '\\text{Sq}^{1} \\text{Sq}^{2} \\text{Sq}^{4} \\text{Sq}^{8}'
     2187
     2188    The empty tuple represents the unit element Sq(0):
     2189        sage: wall_long_mono_to_string(())
     2190        'Sq(0)'
     2191    """
     2192    if LaTeX:
     2193        sq = "\\text{Sq}"
     2194    else:
     2195        sq = "Sq"
     2196    if len(mono) == 0:
     2197        return sq + "(0)"
     2198    else:
     2199        string = ""
     2200        for (m,k) in mono:
     2201            for i in range(k,m+1):
     2202                string = string + sq + "^{" + str(2**i) + "} "
     2203        return string.strip(" ")
     2204
     2205
     2206def arnonA_mono_to_string(mono,LaTeX=False,p=2):
     2207    """
     2208    String representation of element of Arnon's A basis.
     2209
     2210    This is used by the _repr_ and _latex_ methods.
     2211
     2212    INPUT:
     2213        mono -- tuple of pairs of non-negative integers (m,k) with m >= k
     2214
     2215    OUTPUT:
     2216        string -- concatenation of 'X^{m}_{k}' for each pair (m,k)
     2217       
     2218    EXAMPLES:
     2219        sage: from sage.algebras.steenrod_algebra_element import arnonA_mono_to_string
     2220        sage: arnonA_mono_to_string(((1,2),(3,0)))
     2221        'X^{1}_{2} X^{3}_{0}'
     2222        sage: arnonA_mono_to_string(((1,2),(3,0)),LaTeX=True)
     2223        'X^{1}_{2} X^{3}_{0}'
     2224
     2225    The empty tuple represents the unit element Sq(0):
     2226        sage: arnonA_mono_to_string(())
     2227        'Sq(0)'
     2228    """
     2229    if LaTeX:
     2230        sq = "\\text{Sq}"
     2231    else:
     2232        sq = "Sq"
     2233    if len(mono) == 0:
     2234        return sq + "(0)"
     2235    else:
     2236        string = ""
     2237        for (m,k) in mono:
     2238            string = string + "X^{" + str(m) + "}_{" \
     2239                + str(k) + "} "
     2240        return string.strip(" ")
     2241   
     2242
     2243def arnonA_long_mono_to_string(mono,LaTeX=False,p=2):
     2244    """
     2245    Alternate string representation of element of Arnon's A basis.
     2246
     2247    This is used by the _repr_ and _latex_ methods.
     2248
     2249    INPUT:
     2250        mono -- tuple of pairs of non-negative integers (m,k) with m >= k
     2251
     2252    OUTPUT:
     2253        string -- concatenation of strings of the form 'Sq(2^m)'
     2254       
     2255    EXAMPLES:
     2256        sage: from sage.algebras.steenrod_algebra_element import arnonA_long_mono_to_string
     2257        sage: arnonA_long_mono_to_string(((1,2),(3,0)))
     2258        'Sq^{8} Sq^{4} Sq^{2} Sq^{1}'
     2259        sage: arnonA_long_mono_to_string(((1,2),(3,0)),LaTeX=True)
     2260        '\\text{Sq}^{8} \\text{Sq}^{4} \\text{Sq}^{2} \\text{Sq}^{1}'
     2261
     2262    The empty tuple represents the unit element Sq(0):
     2263        sage: arnonA_long_mono_to_string(())
     2264        'Sq(0)'
     2265    """
     2266    if LaTeX:
     2267        sq = "\\text{Sq}"
     2268    else:
     2269        sq = "Sq"
     2270    if len(mono) == 0:
     2271        return sq + "(0)"
     2272    else:
     2273        string = ""
     2274        for (m,k) in mono:
     2275            for i in range(m,k-1,-1):
     2276                string = string + sq + "^{" + str(2**i) + "} "
     2277        return string.strip(" ")
     2278   
     2279
     2280def pst_mono_to_string(mono,LaTeX=False,p=2):
     2281    r"""
     2282    String representation of element of a $P^s_t$-basis.
     2283
     2284    This is used by the _repr_ and _latex_ methods.
     2285
     2286    INPUT:
     2287        mono -- tuple of pairs of integers (s,t) with s >= 0, t > 0
     2288
     2289    OUTPUT:
     2290        string -- concatenation of 'P^{s}_{t}' for each pair (s,t)
     2291       
     2292    EXAMPLES:
     2293        sage: from sage.algebras.steenrod_algebra_element import pst_mono_to_string
     2294        sage: pst_mono_to_string(((1,2),(0,3)))
     2295        'P^{1}_{2} P^{0}_{3}'
     2296        sage: pst_mono_to_string(((1,2),(0,3)),LaTeX=True)
     2297        'P^{1}_{2} P^{0}_{3}'
     2298
     2299    The empty tuple represents the unit element Sq(0):
     2300        sage: pst_mono_to_string(())
     2301        'Sq(0)'
     2302    """
     2303    if LaTeX:
     2304        sq = "\\text{Sq}"
     2305    else:
     2306        sq = "Sq"
     2307    if len(mono) == 0:
     2308        return sq + "(0)"
     2309    else:
     2310        string = ""
     2311        for (s,t) in mono:
     2312            string = string + "P^{" + str(s) + "}_{" \
     2313                + str(t) + "} "
     2314        return string.strip(" ")
     2315
     2316
     2317def comm_mono_to_string(mono,LaTeX=False,p=2):
     2318    r"""
     2319    String representation of element of a commutator basis.
     2320
     2321    This is used by the _repr_ and _latex_ methods.
     2322
     2323    INPUT:
     2324        mono -- tuple of pairs of integers (s,t) with s >= 0, t > 0
     2325
     2326    OUTPUT:
     2327        string -- concatenation of 'c_{s,t}' for each pair (s,t)
     2328       
     2329    EXAMPLES:
     2330        sage: from sage.algebras.steenrod_algebra_element import comm_mono_to_string
     2331        sage: comm_mono_to_string(((1,2),(0,3)))
     2332        'c_{1,2} c_{0,3}'
     2333        sage: comm_mono_to_string(((1,2),(0,3)),LaTeX=True)
     2334        'c_{1,2} c_{0,3}'
     2335
     2336    The empty tuple represents the unit element Sq(0):
     2337        sage: comm_mono_to_string(())
     2338        'Sq(0)'
     2339    """
     2340    if LaTeX:
     2341        sq = "\\text{Sq}"
     2342    else:
     2343        sq = "Sq"
     2344    if len(mono) == 0:
     2345        return sq + "(0)"
     2346    else:
     2347        string = ""
     2348        for (s,t) in mono:
     2349            string = string + "c_{" + str(s) + "," \
     2350                + str(t) + "} "
     2351        return string.strip(" ")
     2352
     2353
     2354def comm_long_mono_to_string(mono,LaTeX=False,p=2):
     2355    r"""
     2356    Alternate string representation of element of a commutator basis.
     2357
     2358    Okay in low dimensions, but gets unwieldy as the dimension increases.
     2359
     2360    INPUT:
     2361        mono -- tuple of pairs of integers (s,t) with s >= 0, t > 0
     2362
     2363    OUTPUT:
     2364        string -- concatenation of 's_{2^s ... 2^(s+t-1)}' for each pair (s,t)
     2365       
     2366    EXAMPLES:
     2367        sage: from sage.algebras.steenrod_algebra_element import comm_long_mono_to_string
     2368        sage: comm_long_mono_to_string(((1,2),(0,3)))
     2369        's_{24} s_{124}'
     2370        sage: comm_long_mono_to_string(((1,2),(0,3)),LaTeX=True)
     2371        's_{24} s_{124}'
     2372
     2373    The empty tuple represents the unit element Sq(0):
     2374        sage: comm_long_mono_to_string(())
     2375        'Sq(0)'
     2376    """
     2377    if LaTeX:
     2378        sq = "\\text{Sq}"
     2379    else:
     2380        sq = "Sq"
     2381    if len(mono) == 0:
     2382        return sq + "(0)"
     2383    else:
     2384        string = ""
     2385        for (s,t) in mono:
     2386            if s + t > 4:
     2387                comma = ","
     2388            else:
     2389                comma = ""
     2390            string = string + "s_{"
     2391            for i in range(t):
     2392                string = string + str(2**(s+i)) + comma
     2393            string = string.strip(",") + "} "
     2394        return string.strip(" ")
  • new file sage/algebras/steenrod_milnor_multiplication.py

    diff -r 96e35b9306b1 -r c7742f1ad322 sage/algebras/steenrod_milnor_multiplication.py
    - +  
     1r"""
     2Milnor multiplication for elements of the Steenrod algebra.
     3
     4AUTHORS:
     5    - John H. Palmieri (2008-07-17: version 0.8)
     6
     7See Milnor's paper [Mil] for proofs, etc.
     8
     9To multiply $\text{Sq}(r_1, r_2, ...)$ and $\text{Sq}(s_1,
     10s_2,...)$, form all possible matrices $M$ with rows and columns
     11indexed starting at 0, with position (0,0) deleted (or ignored), with
     12$s_i$ equal to the sum of column $i$ for each $i$, and with $r_j$
     13equal to the 'weighted' sum of row $j$.  The weights are as follows:
     14elements from column $i$ are multiplied by $2^i$.  For example, to
     15multiply $\text{Sq}(2)$ and $\text{Sq}(1,1)$, form the matrices
     16\[
     17\begin{Vmatrix}
     18* & 1 & 1 \\
     192 & 0 & 0
     20\end{Vmatrix}
     21\quad \text{and} \quad
     22\begin{Vmatrix}
     23* & 0 & 1 \\
     240 & 1 & 0
     25\end{Vmatrix}
     26\]
     27(The * is the ignored (0,0)-entry of the matrix.)  For each such
     28matrix $M$, compute a multinomial coefficient, mod 2: for each
     29diagonal $\{m_{ij}: i+j=n\}$, compute $(\sum m_{i,j}!) / (m_{0,n}!
     30m_{1,n-1}!  ... m_{n,0}!)$.  Multiply these together for all $n$.  (To
     31compute this mod 2, view the entries of the matrix as their base 2
     32expansions; then this coefficient is zero if and only if there is some
     33diagonal containing two numbers which have a summand in common in
     34their base 2 expansion.  For example, if 3 and 10 are in the same
     35diagonal, the coefficient is zero, because $3=1+2$ and $10=2+8$: they
     36both have a summand of 2.)
     37
     38Now, for each matrix with multinomial coefficient 1, let $t_n$ be
     39the sum of the nth diagonal in the matrix; then
     40\[
     41\text{Sq}(r_1, r_2, ...) \text{Sq}(s_1, s_2, ...) = \sum \text{Sq}(t_1, t_2, ...)
     42\]
     43
     44The function 'milnor_multiplication' takes as input two tuples of
     45non-negative integers, $r$ and $s$, which represent
     46$\text{Sq}(r)=\text{Sq}(r_1, r_2, ...)$ and
     47$\text{Sq}(s)=\text{Sq}(s_1, s_2, ...)$; it returns as output a
     48dictionary whose keys are tuples $t=(t_1, t_2, ...)$ of non-negative
     49integers, and for each tuple the associated value is the coefficient
     50of $\text{Sq}(t)$ in the product formula.  Since we are working mod 2,
     51this coefficient is 1 (if it is zero, the the element is omitted from
     52the dictionary altogether).
     53
     54EXAMPLES:
     55    sage: from sage.algebras.steenrod_milnor_multiplication import milnor_multiplication
     56    sage: milnor_multiplication((2,), (1,))
     57    {(0, 1): 1, (3,): 1}
     58    sage: milnor_multiplication((4,), (2,1))
     59    {(6, 1): 1, (0, 3): 1, (2, 0, 1): 1}
     60    sage: milnor_multiplication((2,4), (0,1))
     61    {(2, 5): 1, (2, 0, 0, 1): 1}
     62
     63These examples correspond to the following product computations:
     64\begin{gather*}
     65\text{Sq}(2) \text{Sq}(1) = \text{Sq}(0,1) + \text{Sq}(3)
     66\text{Sq}(4) \text{Sq}(2,1) = \text{Sq}(6,1) + \text{Sq}(0,3) + \text{Sq}(2,0,1)
     67\text{Sq}(2,4) \text{Sq}(0,1) = \text{Sq}(2, 5) + \text{Sq}(2, 0, 0, 1)
     68\end{gather*}
     69
     70REFERENCES:
     71    [Mil] J. W. Milnor, "The Steenrod algebra and its dual, Ann. of Math.
     72          (2) \textbf{67} (1958), 150--171.
     73"""
     74
     75#*****************************************************************************
     76#       Copyright (C) 2008 William Stein <wstein@gmail.com>
     77#       Copyright (C) 2008 John H. Palmieri <palmieri@math.washington.edu>
     78#  Distributed under the terms of the GNU General Public License (GPL)
     79#*****************************************************************************
     80
     81def milnor_multiplication(r,s):
     82    r"""
     83    Product of Milnor basis elements r and s.
     84
     85    INPUT:
     86        r -- tuple of non-negative integers
     87        s -- tuple of non-negative integers
     88
     89    OUTPUT:
     90        Dictionary of terms of the form (tuple: coeff), where 'tuple' is a
     91        tuple of non-negative integers and 'coeff' is 1.
     92
     93    This computes Milnor matrices for the product of $\text{Sq}(r)$
     94    and $\text{Sq}(s)$, computes their multinomial coefficients, and
     95    for each matrix whose coefficient is 1, add $\text{Sq}(t)$ to the
     96    output, where $t$ is the tuple formed by the diagonals sums from
     97    the matrix.
     98   
     99    EXAMPLES:
     100        sage: from sage.algebras.steenrod_milnor_multiplication import milnor_multiplication
     101        sage: milnor_multiplication((2,), (1,))
     102        {(0, 1): 1, (3,): 1}
     103        sage: milnor_multiplication((4,), (2,1))
     104        {(6, 1): 1, (0, 3): 1, (2, 0, 1): 1}
     105        sage: milnor_multiplication((2,4), (0,1))
     106        {(2, 5): 1, (2, 0, 0, 1): 1}
     107   
     108    This uses the same algorithm Monks does in his Maple package.
     109    """
     110    result = {}
     111    rows = len(r) + 1
     112    cols = len(s) + 1
     113    diags = len(r) + len(s)
     114    # initialize matrix
     115    M = range(rows)
     116    for i in range(rows):
     117        M[i] = [0]*cols
     118    for j in range(1,cols):
     119        M[0][j] = s[j-1]
     120    for i in range(1,rows):
     121        M[i][0] = r[i-1]
     122        for j in range(1,cols):
     123            M[i][j] = 0
     124    found = True
     125    while found:
     126        # check diagonals
     127        n = 1
     128        okay = 1
     129        diagonal = [0]*diags
     130        while n <= diags and okay is not None:
     131            nth_diagonal = [M[i][n-i] for i in range(max(0,n-cols+1), min(1+n,rows))]
     132            okay = multinomial(nth_diagonal)
     133            diagonal[n-1] = okay
     134            n = n + 1
     135        if okay is not None:
     136            i = diags - 1
     137            while i >= 0 and diagonal[i] == 0:
     138                i = i - 1
     139            t = tuple(diagonal[:i+1])
     140            # reduce mod two:
     141            if result.has_key(t):
     142                del result[t]
     143            else:
     144                result[t] = 1
     145        # now look for new matrices:
     146        found = False
     147        i = 1
     148        while not found and i < rows:
     149            sum = M[i][0]
     150            j = 1
     151            while not found and j < cols:
     152                # check to see if column index j is small enough
     153                if sum >= 2**j:
     154                    # now check to see if there's anything above this entry
     155                    # to add to it
     156                    temp_col_sum = 0
     157                    for k in range(i):
     158                        temp_col_sum += M[k][j]
     159                    if temp_col_sum != 0:
     160                        found = True
     161                        for row in range(1,i):
     162                            M[row][0] = r[row-1]
     163                            for col in range(1,cols):
     164                                M[0][col] = M[0][col] + M[row][col]
     165                                M[row][col] = 0
     166                        for col in range(1,j):
     167                            M[0][col] = M[0][col] + M[i][col]
     168                            M[i][col] = 0
     169                        M[0][j] = M[0][j] - 1
     170                        M[i][j] = M[i][j] + 1
     171                        M[i][0] = sum - 2**j
     172                    else:
     173                        sum = sum + M[i][j] * 2**j
     174                else:
     175                        sum = sum + M[i][j] * 2**j
     176                j = j + 1
     177            i = i + 1
     178    return result
     179
     180
     181def multinomial(list):
     182    """
     183    Multinomial coefficient of list, mod 2.
     184
     185    INPUT:
     186        list -- list of integers
     187
     188    OUTPUT:
     189        None if the multinomial coefficient is 0, or sum of list if it is 1
     190
     191    Given the input $[n_1, n_2, n_3, ...]$, this computes the
     192    multinomial coefficient $(n_1 + n_2 + n_3 + ...)! / (n_1! n_2!
     193    n_3! ...)$, mod 2.  The method is roughly this: expand each
     194    $n_i$ in binary.  If there is a 1 in the same digit for any $n_i$
     195    and $n_j$ with $i\neq j$, then the coefficient is 0; otherwise, it
     196    is 1.
     197
     198    EXAMPLES:
     199        sage: from sage.algebras.steenrod_milnor_multiplication import multinomial
     200        sage: multinomial([1,2,4])
     201        7
     202        sage: multinomial([1,2,5])
     203        sage: multinomial([1,2,12,192,256])
     204        463
     205
     206    This function does not compute any factorials, so the following are
     207    actually reasonable to do:
     208        sage: multinomial([1,65536])
     209        65537
     210        sage: multinomial([4,65535])
     211        sage: multinomial([32768,65536])
     212        98304
     213    """
     214    old_sum = list[0]
     215    okay = True
     216    i = 1
     217    while okay and i < len(list):
     218        j = 1
     219        while okay and j <= min(old_sum, list[i]):
     220            if j & old_sum == j:
     221                okay = (j & list[i] == 0)
     222            j = j << 1
     223        old_sum = old_sum + list[i]
     224        i = i + 1
     225    if okay:
     226        return old_sum
     227    else:
     228        return None
  • new file sage/algebras/steenrod_milnor_multiplication_odd.py

    diff -r 96e35b9306b1 -r c7742f1ad322 sage/algebras/steenrod_milnor_multiplication_odd.py
    - +  
     1r"""
     2Milnor multiplication for elements of the Steenrod algebra, odd primes.
     3
     4AUTHORS:
     5    - John H. Palmieri (2008-07-17: version 0.8)
     6
     7See Milnor's paper [Mil] for proofs, etc.
     8
     9There are three steps to multiply Milnor basis elements
     10$Q_{f_1} Q_{f_2} ... \mathcal{P}(q_1, q_2, ...)$ and
     11$Q_{g_1} Q_{g_2} ... \mathcal{P}(s_1, s_2,...)$: first, use the formula
     12\[
     13\mathcal{P}(q_1, q_2, ...) Q_k = Q_k \mathcal{P}(q_1, q_2, ...)
     14  + Q_{k+1} \mathcal{P}(q_1 - p^k, q_2, ...)
     15  + Q_{k+2} \mathcal{P}(q_1, q_2 - p^k, ...)
     16  + ...
     17\]
     18Second, use the fact that the $Q_k$'s form an exterior algebra: $Q_k^2 =
     190$ for all $k$, and if $i \neq j$, then $Q_i$ and $Q_j$ anticommute:
     20$Q_i Q_j = -Q_j Q_i$.  After these two steps, the product is of the form
     21\[
     22\sum Q_{e_1} Q_{e_2} ... \mathcal{P}(r_1, r_2, ...) \mathcal{P}(s_1, s_2, ...).
     23\]
     24Finally, use Milnor matrices to multiply the pairs of
     25$\mathcal{P}(...)$ terms: form all possible matrices $M$ with rows and
     26columns indexed starting at 0, with position (0,0) deleted (or
     27ignored), with $s_i$ equal to the sum of column $i$ for each $i$, and
     28with $r_j$ equal to the 'weighted' sum of row $j$.  The weights are as
     29follows: elements from column $i$ are multiplied by $p^i$.  For
     30example when $p=5$, to multiply $\mathcal{P}(5)$ and $\mathcal{P}(1,1)$,
     31form the matrices
     32\[
     33\begin{Vmatrix}
     34* & 1 & 1 \\
     355 & 0 & 0
     36\end{Vmatrix}
     37\quad \text{and} \quad
     38\begin{Vmatrix}
     39* & 0 & 1 \\
     400 & 1 & 0
     41\end{Vmatrix}
     42\]
     43(The $*$ is the ignored (0,0)-entry of the matrix.)  For each such
     44matrix $M$, compute a multinomial coefficient, mod $p$: for each
     45diagonal $\{m_{ij}: i+j=n\}$, compute $(\sum m_{i,j}!) / (m_{0,n}!
     46m_{1,n-1}!  ... m_{n,0}!)$.  Multiply these together for all $n$.
     47
     48Now, for each matrix with nonzero multinomial coefficient $b_M$, let
     49$t_n$ be the sum of the $n$th diagonal in the matrix; then
     50\[
     51\mathcal{P}(r_1, r_2, ...) \mathcal{P}(s_1, s_2, ...) = \sum b_M \mathcal{P}(t_1, t_2, ...)
     52\]
     53For example when $p=5$, we have
     54\[
     55\mathcal{P}(5) \mathcal{P}(1,1) = \mathcal{P}(6,1) + 2 \mathcal{P}(0,2).
     56\]
     57The function 'milnor_multiplication' takes as input two pairs of tuples of
     58non-negative integers, $(g,q)$ and $(f,s)$, which represent
     59$Q_{g_1} Q_{g_2} ... \mathcal{P}(q_1, q_2, ...)$ and
     60$Q_{f_1} Q_{f_2} ... \mathcal{P}(s_1, s_2, ...)$.  It returns as output a
     61dictionary whose keys are pairs of tuples $(e,t)$ of non-negative
     62integers, and for each tuple the associated value is the coefficient
     63in the product formula.
     64
     65EXAMPLES:
     66    sage: from sage.algebras.steenrod_milnor_multiplication_odd import milnor_multiplication_odd
     67    sage: milnor_multiplication_odd(((0,2),(5,)), ((1,),(1,)), 5)
     68    {((0, 1, 2), (0, 1)): 4, ((0, 1, 2), (6,)): 4}
     69    sage: milnor_multiplication_odd(((0,2,4),()), ((1,3),()), 7)
     70    {((0, 1, 2, 3, 4), ()): 6}
     71    sage: milnor_multiplication_odd(((0,2,4),()), ((1,5),()), 7)
     72    {((0, 1, 2, 4, 5), ()): 1}
     73    sage: milnor_multiplication_odd(((),(6,)), ((),(2,)), 3)
     74    {((), (4, 1)): 1, ((), (8,)): 1, ((), (0, 2)): 1}
     75
     76These examples correspond to the following product computations:
     77\begin{gather*}
     78p=5: \quad Q_0 Q_2 \mathcal{P}(5) Q_1 \mathcal{P}(1) = 4 Q_0 Q_1 Q_2 \mathcal{P}(0,1) + 4 Q_0 Q_1 Q_2 \mathcal{P}(6) \\
     79p=7: \quad (Q_0 Q_2 Q_4) (Q_1 Q_3) = 6 Q_0 Q_1 Q_2 Q_3 Q_4 \\
     80p=7: \quad (Q_0 Q_2 Q_4) (Q_1 Q_5) = Q_0 Q_1 Q_2 Q_3 Q_5 \\
     81p=3: \quad \mathcal{P}(6) \mathcal{P}(2) = \mathcal{P}(0,2) + \mathcal{P}(4,1) + \mathcal{P}(8)
     82\end{gather*}
     83
     84REFERENCES:
     85    [Mil] J. W. Milnor, "The Steenrod algebra and its dual, Ann. of Math.
     86          (2) \textbf{67} (1958), 150--171.
     87"""
     88
     89#*****************************************************************************
     90#       Copyright (C) 2008 William Stein <wstein@gmail.com>
     91#       Copyright (C) 2008 John H. Palmieri <palmieri@math.washington.edu>
     92#  Distributed under the terms of the GNU General Public License (GPL)
     93#*****************************************************************************
     94
     95def milnor_multiplication_odd(m1,m2,p):
     96    r"""
     97    Product of Milnor basis elements defined by m1 and m2.
     98
     99    INPUT:
     100        m1 -- pair of tuples (e,r), where e is an increasing tuple of
     101            non-negative integers and r is a tuple of non-negative integers
     102        m2 -- pair of tuples (f,s), same format as m1
     103        p -- odd prime number
     104
     105    OUTPUT:
     106        Dictionary of terms of the form (tuple: coeff), where 'tuple' is a
     107        pair of tuples, as for r and s, and 'coeff' is an integer mod p.
     108
     109    This computes the product of the Milnor basis elements
     110    $Q_e1 Q_e2 ... P(r_1, r_2, ...)$ and
     111    $Q_f1 Q_f2 ... P(s_1, s_2, ...)$.
     112   
     113    EXAMPLES:
     114        sage: from sage.algebras.steenrod_milnor_multiplication_odd import milnor_multiplication_odd
     115        sage: milnor_multiplication_odd(((0,2),(5,)), ((1,),(1,)), 5)
     116        {((0, 1, 2), (0, 1)): 4, ((0, 1, 2), (6,)): 4}
     117        sage: milnor_multiplication_odd(((0,2,4),()), ((1,3),()), 7)
     118        {((0, 1, 2, 3, 4), ()): 6}
     119        sage: milnor_multiplication_odd(((0,2,4),()), ((1,5),()), 7)
     120        {((0, 1, 2, 4, 5), ()): 1}
     121        sage: milnor_multiplication_odd(((),(6,)), ((),(2,)), 3)
     122        {((), (4, 1)): 1, ((), (8,)): 1, ((), (0, 2)): 1}
     123   
     124    This uses the same algorithm Monks does in his Maple package to
     125    iterate through the possible matrices.
     126    """
     127    from sage.rings.all import GF
     128    F = GF(p)
     129    (f,s) = m2
     130    # First compute Q_e0 Q_e1 ... P(r1, r2, ...) Q_f0 Q_f1 ...
     131    # Store results (as dictionary of pairs of tuples) in 'answer'.
     132    answer = {m1: F(1)}
     133    for k in f:
     134        old_answer = answer
     135        answer = {}
     136        for mono in old_answer:
     137            if k not in mono[0]:
     138                q_mono = set(mono[0])
     139                if len(q_mono) > 0:
     140                    ind = len(q_mono.intersection(range(k,1+max(q_mono))))
     141                else:
     142                    ind = 0
     143                coeff = (-1)**ind * old_answer[mono]
     144                lst = list(mono[0])
     145                if ind == 0:
     146                    lst.append(k)
     147                else:
     148                    lst.insert(-ind,k)
     149                q_mono = tuple(lst)
     150                p_mono = mono[1]
     151                answer[(q_mono, p_mono)] = F(coeff)
     152            for i in range(1,1+len(mono[1])):
     153                if (k+i not in mono[0]) and (p**k <= mono[1][i-1]):
     154                    q_mono = set(mono[0])
     155                    if len(q_mono) > 0:
     156                        ind = len(q_mono.intersection(range(k+i,1+max(q_mono))))
     157                    else:
     158                        ind = 0
     159                    coeff = (-1)**ind
     160                    lst = list(mono[0])
     161                    if ind == 0:
     162                        lst.append(k+i)
     163                    else:
     164                        lst.insert(-ind,k+i)
     165                    q_mono = tuple(lst)
     166                    p_mono = list(mono[1])
     167                    p_mono[i-1] = p_mono[i-1] - p**k
     168                    answer[(q_mono, tuple(p_mono))] = F(coeff)
     169    # Now for the Milnor matrices.  For each entry '(e,r): coeff' in answer,
     170    # multiply r with s.  Record coefficient for matrix and multiply by coeff. 
     171    # Store in 'result'.
     172    if len(s) == 0:
     173        result = answer
     174    else:
     175        result = {}
     176        for (e, r) in answer:
     177            old_coeff = answer[(e,r)]
     178            # Milnor multiplication for r and s
     179            rows = len(r) + 1
     180            cols = len(s) + 1
     181            diags = len(r) + len(s)
     182            # initialize matrix
     183            M = range(rows)
     184            for i in range(rows):
     185                M[i] = [0]*cols
     186            for j in range(1,cols):
     187                M[0][j] = s[j-1]
     188            for i in range(1,rows):
     189                M[i][0] = r[i-1]
     190                for j in range(1,cols):
     191                    M[i][j] = 0
     192            found = True
     193            while found:
     194                # check diagonals
     195                n = 1
     196                coeff = old_coeff
     197                diagonal = [0]*diags
     198                while n <= diags and coeff != 0:
     199                    nth_diagonal = [M[i][n-i] for i in range(max(0,n-cols+1), min(1+n,rows))]
     200                    coeff = coeff * multinomial_odd(nth_diagonal,p)
     201                    diagonal[n-1] = sum(nth_diagonal)
     202                    n = n + 1
     203                if coeff != 0:
     204                    i = diags - 1
     205                    while i >= 0 and diagonal[i] == 0:
     206                        i = i - 1
     207                    t = tuple(diagonal[:i+1])
     208                    if result.has_key((e,t)):
     209                        result[(e,t)] = F(coeff + result[t])
     210                    else:
     211                        result[(e,t)] = F(coeff)
     212                    # now look for new matrices:
     213                found = False
     214                i = 1
     215                while not found and i < rows:
     216                    temp_sum = M[i][0]
     217                    j = 1
     218                    while not found and j < cols:
     219                        # check to see if column index j is small enough
     220                        if temp_sum >= p**j:
     221                            # now check to see if there's anything above this entry
     222                            # to add to it
     223                            temp_col_sum = 0
     224                            for k in range(i):
     225                                temp_col_sum += M[k][j]
     226                            if temp_col_sum != 0:
     227                                found = True
     228                                for row in range(1,i):
     229                                    M[row][0] = r[row-1]
     230                                    for col in range(1,cols):
     231                                        M[0][col] = M[0][col] + M[row][col]
     232                                        M[row][col] = 0
     233                                for col in range(1,j):
     234                                    M[0][col] = M[0][col] + M[i][col]
     235                                    M[i][col] = 0
     236                                M[0][j] = M[0][j] - 1
     237                                M[i][j] = M[i][j] + 1
     238                                M[i][0] = temp_sum - p**j
     239                            else:
     240                                temp_sum += M[i][j] * p**j
     241                        else:
     242                            temp_sum += M[i][j] * p**j
     243                        j = j + 1
     244                    i = i + 1
     245    return result
     246
     247
     248def multinomial_odd(list,p):
     249    """
     250    Multinomial coefficient of list, mod p.
     251
     252    INPUT:
     253        list -- list of integers
     254        p -- a prime number
     255
     256    OUTPUT:
     257        Associated multinomial coefficient, mod p
     258
     259    Given the input $[n_1, n_2, n_3, ...]$, this computes the
     260    multinomial coefficient $(n_1 + n_2 + n_3 + ...)! / (n_1! n_2!
     261    n_3! ...)$, mod $p$.  The method is this: expand each $n_i$ in
     262    base $p$: $n_i = \sum_j p^j n_{ij}$.  Do the same for the sum of
     263    the $n_i$'s, which we call $m$: $m = \sum_j p^j m_j$.  Then the
     264    multinomial coefficient is congruent, mod $p$, to the product of
     265    the multinomial coefficients $m_j! / (n_{1j}! n_{2j}! ...)$.
     266
     267    Furthermore, any multinomial coefficient $m! / (n_1! n_2! ...)$
     268    can be computed as a product of binomial coefficients: it equals
     269    \[
     270    \binom{n_1}{n_1} \binom{n_1 + n_2}{n_2} \binom{n_1 + n_2 + n_3}{n_3} ...
     271    \]
     272    This is convenient because Sage's binomial function returns
     273    integers, not rational numbers (as would be produced just by
     274    dividing factorials).
     275   
     276    EXAMPLES:
     277        sage: from sage.algebras.steenrod_milnor_multiplication_odd import multinomial_odd
     278        sage: multinomial_odd([1,2,4], 2)
     279        1
     280        sage: multinomial_odd([1,2,4], 7)
     281        0
     282        sage: multinomial_odd([1,2,4], 11)
     283        6
     284        sage: multinomial_odd([1,2,4], 101)
     285        4
     286        sage: multinomial_odd([1,2,4], 107)
     287        105
     288    """
     289    def expand(k,p):
     290        """
     291        Expand k as a sum of powers of p.  Return list of coefficients.
     292        """
     293        index = 0
     294        answer = []
     295        while k > 0:
     296            answer.append(k%p)
     297            k = int(k / p)
     298            index += 1
     299        return answer
     300   
     301    from sage.rings.arith import factorial
     302    from sage.rings.all import GF
     303    from sage.rings.arith import binomial
     304    n = sum(list)
     305    answer = 1
     306    F = GF(p)
     307    n_expansion = expand(n,p)
     308    list_expansion = [expand(k,p) for k in list]
     309    index = 0
     310    while answer != 0 and index < len(n_expansion):
     311        multi = F(1)
     312        partial_sum = 0
     313        for exp in list_expansion:
     314            if index < len(exp):
     315                partial_sum = partial_sum + exp[index]
     316                multi = F(multi * binomial(partial_sum, exp[index]))
     317        answer = F(answer * multi)
     318        index += 1
     319    return answer