AUTHORS:
This module defines the mod Steenrod algebra
, some
of its properties, and ways to define elements of it.
From a topological point of view, is the algebra of
stable cohomology operations on mod
cohomology; thus for any
topological space
, its mod
cohomology algebra
is a module over
.
From an algebraic point of view, is an
-algebra; when
, it is generated by elements
for
(the Steenrod squares), and when
is
odd, it is generated by elements
for
(the
Steenrod reduced pth powers) along with an element
(the mod
p Bockstein). The Steenrod algebra is graded:
is in
degree
for each
,
is in degree 1, and
is in degree
.
The unit element is when
and
when
is odd. The generating
elements also satisfy the Adem relations. At the prime 2, these
have the form
At odd primes, they are a bit more complicated; see Steenrod and
Epstein [SE] or sage.algebras.steenrod.steenrod_algebra_bases
for full details. These relations lead to the existence of the
Serre-Cartan basis for .
The mod Steenrod algebra has the structure of a Hopf
algebra, and Milnor [Mil] has a beautiful description of the dual,
leading to a construction of the Milnor basis for
. In this module, elements in the Steenrod
algebra are represented, by default, using the Milnor basis.
Bases for the Steenrod algebra
There are a handful of other bases studied in the literature; the paper by Monks is a good reference. Here is a quick summary:
The Milnor basis. When , the Milnor basis consists of symbols
of the form
, where each
is a
non-negative integer and if
, then the last entry
.
When
is odd, the Milnor basis consists of symbols of the form
, where
, each
is a non-negative integer, and if
, then the last entry
.
When , it can be convenient to use the notation
to mean
, so that there is consistent
notation for all primes.
The Serre-Cartan basis. This basis consists of ‘admissible
monomials’ in the Steenrod operations. Thus at the prime 2, it
consists of monomials with
for each
. At odd
primes, this basis consists of monomials
with each
either
0 or 1,
, and
.
Most of the rest of the bases are only defined when . The only
exceptions are the
-bases and the commutator bases, which are
defined at all primes.
Wood’s Y basis. For pairs of non-negative integers , let
. Wood’s
basis consists of
monomials
with
, in left lex order.
Wood’s Z basis. For pairs of non-negative integers , let
. Wood’s
basis consists of
monomials
with
, in left lex order.
Wall’s basis. For any pair of integers with
, let
. The elements of Wall’s basis are monomials
with
, ordered left lexicographically.
(Note that is the reverse of the element
used in
defining Arnon’s A basis.)
Arnon’s A basis. For any pair of integers with
, let
. The elements of Arnon’s A basis are monomials
with
, ordered left lexicographically.
(Note that is the reverse of the element
used in
defining Wall’s basis.)
Arnon’s C basis. The elements of Arnon’s C basis are monomials of
the form where for each
,
we have
and
.
bases. Let
. For integers
and
,
the element
is the Milnor basis element
, with the nonzero entry in position
. To obtain
a
-basis, for each set
of (distinct)
‘s, one chooses an ordering
and forms the monomials
for all exponents with
. When
, the set of
all such monomials then forms a basis, and when
is odd, if one
multiplies each such monomial on the left by products of the form
with
, one obtains a
basis.
Thus one gets a basis by choosing an ordering on each set of
‘s. There are infinitely many orderings possible, and we
have implemented four of them:
Commutator bases. Let , let
, and inductively define
. Thus
is a
-fold iterated
commutator of the elements
, ...,
. Note that
.
Commutator bases are obtained in much the same way as -bases:
for each set
of (distinct)
‘s, one chooses an ordering and forms the resulting
monomials
for all exponents with
. When
is odd, one
also needs to left-multiply by products of the
‘s. As for
-bases, every ordering on each set of iterated commutators
determines a basis, and the same four orderings have been defined
for these bases as for the
bases: ‘rlex’, ‘llex’, ‘deg’,
‘revz’.
Sub-Hopf algebras of the Steenrod algebra
The sub-Hopf algebras of the Steenrod algebra have been
classified. Milnor proved that at the prime 2, the dual of the
Steenrod algebra is isomorphic to a polynomial algebra
The Milnor basis is dual to the monomial basis. Furthermore, any sub-Hopf algebra corresponds to a quotient of this of the form
The list of exponents may be considered a function
from the positive integers to the extended non-negative integers
(the non-negative integers and
); this is called the profile
function for the sub-Hopf algebra. The profile function must satisfy
the condition
At odd primes, the situation is similar: the dual is isomorphic to the tensor product of a polynomial algebra and an exterior algebra,
and any sub-Hopf algebra corresponds to a quotient of this of the form
Here the profile function has two pieces, as at the prime 2, and
, which maps the non-negative integers to the set
.
These must satisfy the following conditions:
(See Adams-Margolis, for example, for these results on profile functions.)
This module allows one to construct the Steenrod algebra or any of its
sub-Hopf algebras, at any prime. When defining a sub-Hopf algebra,
you must work with the Milnor basis or a -basis.
Elements of the Steenrod algebra
Basic arithmetic, . To construct an element of the mod 2 Steenrod
algebra, use the function Sq:
sage: a = Sq(1,2)
sage: b = Sq(4,1)
sage: z = a + b
sage: z
Sq(1,2) + Sq(4,1)
sage: Sq(4) * Sq(1,2)
Sq(1,1,1) + Sq(2,3) + Sq(5,2)
sage: z**2 # non-negative exponents work as they should
Sq(1,2,1) + Sq(4,1,1)
sage: z**0
1
Basic arithmetic, . To construct an element of the mod
Steenrod algebra when
is odd, you should first define a Steenrod
algebra, using the SteenrodAlgebra command:
sage: A3 = SteenrodAlgebra(3)
Having done this, the newly created algebra A3 has methods Q and P which construct elements of A3:
sage: c = A3.Q(1,3,6); c
Q_1 Q_3 Q_6
sage: d = A3.P(2,0,1); d
P(2,0,1)
sage: c * d
Q_1 Q_3 Q_6 P(2,0,1)
sage: e = A3.P(3)
sage: d * e
P(5,0,1)
sage: e * d
P(1,1,1) + P(5,0,1)
sage: c * c
0
sage: e ** 3
2 P(1,2)
Note that one can construct an element like c above in one step, without first constructing the algebra:
sage: c = SteenrodAlgebra(3).Q(1,3,6)
sage: c
Q_1 Q_3 Q_6
And of course, you can do similar constructions with the mod 2 Steenrod algebra:
sage: A = SteenrodAlgebra(2); A
mod 2 Steenrod algebra, milnor basis
sage: A.Sq(2,3,5)
Sq(2,3,5)
sage: A.P(2,3,5) # when p=2, P = Sq
Sq(2,3,5)
sage: A.Q(1,4) # when p=2, this gives a product of Milnor primitives
Sq(0,1,0,0,1)
Associated to each element is its prime (the characteristic of the underlying base field) and its basis (the basis for the Steenrod algebra in which it lies):
sage: a = SteenrodAlgebra(basis='milnor').Sq(1,2,1)
sage: a.prime()
2
sage: a.basis_name()
'milnor'
sage: a.degree()
14
It can be viewed in other bases:
sage: a.milnor() # same as a
Sq(1,2,1)
sage: a.change_basis('adem')
Sq^9 Sq^4 Sq^1 + Sq^11 Sq^2 Sq^1 + Sq^13 Sq^1
sage: a.change_basis('adem').change_basis('milnor')
Sq(1,2,1)
Regardless of the prime, each element has an excess, and if the
element is homogeneous, a degree. The excess of
is
; when
is
odd, the excess of
is
. The excess of a linear combination
of Milnor basis elements is the minimum of the excesses of those basis
elements.
The degree of is
, and
when
is odd, the degree of
is
. The degree of a linear combination of such terms is
only defined if the terms all have the same degree.
Here are some simple examples:
sage: z = Sq(1,2) + Sq(4,1)
sage: z.degree()
7
sage: (Sq(0,0,1) + Sq(5,3)).degree()
Traceback (most recent call last):
...
ValueError: Element is not homogeneous.
sage: Sq(7,2,1).excess()
10
sage: z.excess()
3
sage: B = SteenrodAlgebra(3)
sage: x = B.Q(1,4)
sage: y = B.P(1,2,3)
sage: x.degree()
166
sage: x.excess()
2
sage: y.excess()
12
Elements have a weight in the May filtration, which (when )
is related to the height function defined by Wall:
sage: Sq(2,1,5).may_weight()
9
sage: Sq(2,1,5).wall_height()
[2, 3, 2, 1, 1]
sage: b = Sq(4)*Sq(8) + Sq(8)*Sq(4)
sage: b.may_weight()
2
sage: b.wall_height()
[0, 0, 1, 1]
Odd primary May weights:
sage: A5 = SteenrodAlgebra(5)
sage: a = A5.Q(1,2,4)
sage: b = A5.P(1,2,1)
sage: a.may_weight()
10
sage: b.may_weight()
8
sage: (a * b).may_weight()
18
sage: A5.P(0,0,1).may_weight()
3
Since the Steenrod algebra is a Hopf algebra, every element has a coproduct and an antipode.
sage: Sq(5).coproduct()
1 # Sq(5) + Sq(1) # Sq(4) + Sq(2) # Sq(3) + Sq(3) # Sq(2) + Sq(4) # Sq(1) + Sq(5) # 1
sage: Sq(5).antipode()
Sq(2,1) + Sq(5)
sage: d = Sq(0,0,1); d
Sq(0,0,1)
sage: d.antipode()
Sq(0,0,1)
sage: Sq(4).antipode()
Sq(1,1) + Sq(4)
sage: (Sq(4) * Sq(2)).antipode()
Sq(6)
sage: SteenrodAlgebra(7).P(3,1).antipode()
P(3,1)
Applying the antipode twice returns the original element:
sage: y = Sq(8)*Sq(4)
sage: y == (y.antipode()).antipode()
True
Internal representation: you can use any element as an iterator (for x in a: ...), and the method monomial_coefficients() returns a dictionary with keys tuples representing basis elements and with corresponding value representing the coefficient of that term:
sage: c = Sq(5).antipode(); c
Sq(2,1) + Sq(5)
sage: for mono, coeff in c: print coeff, mono
1 (5,)
1 (2, 1)
sage: c.monomial_coefficients()
{(5,): 1, (2, 1): 1}
sage: c.monomials()
[Sq(2,1), Sq(5)]
sage: c.support()
[(2, 1), (5,)]
sage: Adem = SteenrodAlgebra(basis='adem')
sage: (Adem.Sq(10) + Adem.Sq(9) * Adem.Sq(1)).monomials()
[Sq^9 Sq^1, Sq^10]
sage: A7 = SteenrodAlgebra(p=7)
sage: a = A7.P(1) * A7.P(1); a
2 P(2)
sage: a.leading_coefficient()
2
sage: a.leading_monomial()
P(2)
sage: a.leading_term()
2 P(2)
sage: a.change_basis('adem').monomial_coefficients()
{(0, 2, 0): 2}
The tuple in the previous output stands for the element , i.e.,
. Going in the other direction, if you
want to specify a basis element by giving the corresponding tuple,
you can use the monomial() method on the algebra:
sage: SteenrodAlgebra(p=7, basis='adem').monomial((0, 2, 0))
P^2
sage: 10 * SteenrodAlgebra(p=7, basis='adem').monomial((0, 2, 0))
3 P^2
In the following example, elements in Wood’s Z basis are certain
products of the elements .
Internally, each
is represented by the pair
, and
products of them are represented by tuples of such pairs.
sage: A = SteenrodAlgebra(basis='wood_z')
sage: t = ((2, 0), (0, 0))
sage: A.monomial(t)
Sq^4 Sq^1
See the documentation for SteenrodAlgebra() for more details and examples.
REFERENCES:
This returns the Steenrod algebra or its sub-Hopf algebra
.
INPUT:
OUTPUT: If is None, then return the full Steenrod algebra.
Otherwise, return
.
When ,
is the sub-Hopf algebra generated by the
elements
for
. Its profile function is
. When
is odd,
is the sub-Hopf
algebra generated by the elements
and
for
. Its profile function is
and
(length
).
EXAMPLES:
sage: from sage.algebras.steenrod.steenrod_algebra import AA as A
sage: A()
mod 2 Steenrod algebra, milnor basis
sage: A(2)
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [3, 2, 1]
sage: A(2, p=5)
sub-Hopf algebra of mod 5 Steenrod algebra, milnor basis, profile function ([2, 1], [2, 2, 2])
Milnor element Sq(a,b,c,...).
INPUT:
OUTPUT: element of the Steenrod algebra
This returns the Milnor basis element
.
EXAMPLES:
sage: Sq(5)
Sq(5)
sage: Sq(5) + Sq(2,1) + Sq(5) # addition is mod 2:
Sq(2,1)
sage: (Sq(4,3) + Sq(7,2)).degree()
13
Entries must be non-negative integers; otherwise, an error results.
This function is a good way to define elements of the Steenrod algebra.
The mod Steenrod algebra
INPUT:
OUTPUT: mod Steenrod algebra or one of its sub-Hopf algebras,
elements of which are printed using basis
See below for information about basis, profile, etc.
EXAMPLES:
Some properties of the Steenrod algebra are available:
sage: A = SteenrodAlgebra(2)
sage: A.order()
+Infinity
sage: A.is_finite()
False
sage: A.is_commutative()
False
sage: A.is_noetherian()
False
sage: A.is_integral_domain()
False
sage: A.is_field()
False
sage: A.is_division_algebra()
False
sage: A.category()
Category of graded hopf algebras with basis over Finite Field of size 2
There are methods for constructing elements of the Steenrod algebra:
sage: A2 = SteenrodAlgebra(2); A2
mod 2 Steenrod algebra, milnor basis
sage: A2.Sq(1,2,6)
Sq(1,2,6)
sage: A2.Q(3,4) # product of Milnor primitives Q_3 and Q_4
Sq(0,0,0,1,1)
sage: A2.pst(2,3) # Margolis pst element
Sq(0,0,4)
sage: A5 = SteenrodAlgebra(5); A5
mod 5 Steenrod algebra, milnor basis
sage: A5.P(1,2,6)
P(1,2,6)
sage: A5.Q(3,4)
Q_3 Q_4
sage: A5.Q(3,4) * A5.P(1,2,6)
Q_3 Q_4 P(1,2,6)
sage: A5.pst(2,3)
P(0,0,25)
You can test whether elements are contained in the Steenrod algebra:
sage: w = Sq(2) * Sq(4)
sage: w in SteenrodAlgebra(2)
True
sage: w in SteenrodAlgebra(17)
False
Different bases for the Steenrod algebra:
There are two standard vector space bases for the mod Steenrod
algebra: the Milnor basis and the Serre-Cartan basis. When
,
there are also several other, less well-known, bases. See the
documentation for this module (type
sage.algebras.steenrod.steenrod_algebra?) and the function
steenrod_algebra_basis
for full descriptions of each of the implemented bases.
This module implements the following bases at all primes:
It implements the following bases when :
When defining a Steenrod algebra, you can specify a basis. Then elements of that Steenrod algebra are printed in that basis:
sage: adem = SteenrodAlgebra(2, 'adem')
sage: x = adem.Sq(2,1) # Sq(-) always means a Milnor basis element
sage: x
Sq^4 Sq^1 + Sq^5
sage: y = Sq(0,1) # unadorned Sq defines elements w.r.t. Milnor basis
sage: y
Sq(0,1)
sage: adem(y)
Sq^2 Sq^1 + Sq^3
sage: adem5 = SteenrodAlgebra(5, 'serre-cartan')
sage: adem5.P(0,2)
P^10 P^2 + 4 P^11 P^1 + P^12
If you add or multiply elements defined using different bases, the left-hand factor determines the form of the output:
sage: SteenrodAlgebra(basis='adem').Sq(3) + SteenrodAlgebra(basis='pst').Sq(0,1)
Sq^2 Sq^1
sage: SteenrodAlgebra(basis='pst').Sq(3) + SteenrodAlgebra(basis='milnor').Sq(0,1)
P^0_1 P^1_1 + P^0_2
sage: SteenrodAlgebra(basis='milnor').Sq(2) * SteenrodAlgebra(basis='arnonc').Sq(2)
Sq(1,1)
You can get a list of basis elements in a given dimension:
sage: A3 = SteenrodAlgebra(3, 'milnor')
sage: A3.basis(13)
Family (Q_1 P(2), Q_0 P(3))
Algebras defined over different bases are not equal:
sage: SteenrodAlgebra(basis='milnor') == SteenrodAlgebra(basis='pst')
False
Bases have various synonyms, and in general Sage tries to figure out what basis you meant:
sage: SteenrodAlgebra(basis='MiLNOr')
mod 2 Steenrod algebra, milnor basis
sage: SteenrodAlgebra(basis='MiLNOr') == SteenrodAlgebra(basis='milnor')
True
sage: SteenrodAlgebra(basis='adem')
mod 2 Steenrod algebra, serre-cartan basis
sage: SteenrodAlgebra(basis='adem').basis_name()
'serre-cartan'
sage: SteenrodAlgebra(basis='wood---z---').basis_name()
'woodz'
As noted above, several of the bases (‘arnon_a’, ‘wall’, ‘comm’)
have alternate, sometimes longer, representations. These provide
ways of expressing elements of the Steenrod algebra in terms of
the .
sage: A_long = SteenrodAlgebra(2, 'arnon_a_long')
sage: A_long(Sq(6))
Sq^1 Sq^2 Sq^1 Sq^2 + Sq^2 Sq^4
sage: SteenrodAlgebra(2, 'wall_long')(Sq(6))
Sq^2 Sq^1 Sq^2 Sq^1 + Sq^2 Sq^4
sage: SteenrodAlgebra(2, 'comm_deg_long')(Sq(6))
s_1 s_2 s_12 + s_2 s_4
Sub-Hopf algebras of the Steenrod algebra:
These are specified using the argument profile, along with,
optionally, truncation_type and precision. The
profile argument specifies the profile function for this
algebra. Any sub-Hopf algebra of the Steenrod algebra is
determined by its profile function. When , this is a map
from the positive integers to the set of non-negative integers,
plus
, corresponding to the sub-Hopf algebra dual to this
quotient of the dual Steenrod algebra:
The profile function must satisfy the condition
This is specified via profile, and optionally precision and truncation_type. First, profile must have one of the following forms:
In the first and third cases, precision is ignored. In the second case, this function is converted to a tuple of length one less than precision, which has default value 100. The function is truncated at this point, and all remaining values are set to the value of truncation_type.
truncation_type may be 0, , or ‘auto’. If it’s
‘auto’, then it gets converted to 0 in the first case above (when
profile is a list), and otherwise (when profile is a
function, None, or Infinity) it gets converted to
.
For example, the sub-Hopf algebra has profile function
[3,2,1,0,0,0,...], so it can be defined by any of the
following:
sage: A2 = SteenrodAlgebra(profile=[3,2,1])
sage: B2 = SteenrodAlgebra(profile=[3,2,1,0,0]) # trailing 0's ignored
sage: A2 == B2
True
sage: C2 = SteenrodAlgebra(profile=lambda n: max(4-n, 0), truncation_type=0)
sage: A2 == C2
True
In the following case, the profile function is specified by a
function and truncation_type isn’t specified, so it defaults
to ; therefore this gives a different sub-Hopf algebra:
sage: D2 = SteenrodAlgebra(profile=lambda n: max(4-n, 0))
sage: A2 == D2
False
sage: D2.is_finite()
False
sage: E2 = SteenrodAlgebra(profile=lambda n: max(4-n, 0), truncation_type=Infinity)
sage: D2 == E2
True
The argument precision only needs to be specified if the profile function is defined by a function and you want to control when the profile switches from the given function to the truncation type. For example:
sage: D3 = SteenrodAlgebra(profile=lambda n: n, precision=3)
sage: D3
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [1, 2, +Infinity, +Infinity, +Infinity, ...]
sage: D4 = SteenrodAlgebra(profile=lambda n: n, precision=4); D4
sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [1, 2, 3, +Infinity, +Infinity, +Infinity, ...]
sage: D3 == D4
False
When is odd, profile is a pair of functions
and
,
corresponding to the quotient
Together, the functions and
must satisfy the conditions
Therefore profile must have one of the following forms:
You can also mix and match the first two, passing a pair with first entry a list and second entry a function, for instance. The values of precision and truncation_type are determined by the first entry.
More examples:
sage: E = SteenrodAlgebra(profile=lambda n: 0 if n<3 else 3, truncation_type=0)
sage: E.is_commutative()
True
sage: A2 = SteenrodAlgebra(profile=[3,2,1]) # the algebra A(2)
sage: Sq(7,3,1) in A2
True
sage: Sq(8) in A2
False
sage: Sq(8) in SteenrodAlgebra().basis(8)
True
sage: Sq(8) in A2.basis(8)
False
sage: A2.basis(8)
Family (Sq(1,0,1), Sq(2,2), Sq(5,1))
sage: A5 = SteenrodAlgebra(p=5)
sage: A51 = SteenrodAlgebra(p=5, profile=([1], [2,2]))
sage: A5.Q(0,1) * A5.P(4) in A51
True
sage: A5.Q(2) in A51
False
sage: A5.P(5) in A51
False
For sub-Hopf algebras of the Steenrod algebra, only the Milnor
basis or the various -bases may be used.
sage: SteenrodAlgebra(profile=[1,2,1,1], basis='adem')
Traceback (most recent call last):
...
NotImplementedError: For sub-Hopf algebras of the Steenrod algebra, only the Milnor basis and the pst bases are implemented.
The generic Steenrod algebra at the prime :
The structure formulas for the Steenrod algebra at odd primes also make sense
when
is set to
. We refer to the resulting algebra as the “generic Steenrod algebra” for
the prime
. The dual Hopf algebra is given by
The degree of is
and the degree of
is
.
The generic Steenrod algebra is an associated graded algebra of the usual Steenrod algebra
that is occasionally useful. Its cohomology, for example, is the -term of a spectral sequence
that computes the
-term of the Novikov spectral sequence. It can also be obtained as a
specialisation of Voevodsky’s “motivic Steenrod algebra”: in the notation of [VO], Remark 12.12,
it corresponds to setting
. The usual Steenrod algebra is given by
and
.
In Sage this algebra is constructed using the ‘generic’ keyword.
Example:
sage: EA = SteenrodAlgebra(p=2,generic=True) ; EA
generic mod 2 Steenrod algebra, milnor basis
sage: EA[8]
Vector space spanned by (Q_0 Q_2, Q_0 Q_1 P(2), P(1,1), P(4)) over Finite Field of size 2
TESTS:
Testing unique parents:
sage: S0 = SteenrodAlgebra(2)
sage: S1 = SteenrodAlgebra(2)
sage: S0 is S1
True
sage: S2 = SteenrodAlgebra(2, basis='adem')
sage: S0 is S2
False
sage: S0 == S2
False
sage: A1 = SteenrodAlgebra(profile=[2,1])
sage: B1 = SteenrodAlgebra(profile=[2,1,0,0])
sage: A1 is B1
True
Bases: sage.combinat.free_module.CombinatorialFreeModule
The mod Steenrod algebra.
Users should not call this, but use the function SteenrodAlgebra() instead. See that function for extensive documentation.
EXAMPLES:
sage: sage.algebras.steenrod.steenrod_algebra.SteenrodAlgebra_generic()
mod 2 Steenrod algebra, milnor basis
sage: sage.algebras.steenrod.steenrod_algebra.SteenrodAlgebra_generic(5)
mod 5 Steenrod algebra, milnor basis
sage: sage.algebras.steenrod.steenrod_algebra.SteenrodAlgebra_generic(5, 'adem')
mod 5 Steenrod algebra, serre-cartan basis
Bases: sage.combinat.free_module.CombinatorialFreeModuleElement
Class for elements of the Steenrod algebra. Since the Steenrod algebra class is based on CombinatorialFreeModule, this is based on CombinatorialFreeModuleElement. It has new methods reflecting its role, like degree() for computing the degree of an element.
EXAMPLES:
Since this class inherits from CombinatorialFreeModuleElement, elements can be used as iterators, and there are other useful methods:
sage: c = Sq(5).antipode(); c
Sq(2,1) + Sq(5)
sage: for mono, coeff in c: print coeff, mono
1 (5,)
1 (2, 1)
sage: c.monomial_coefficients()
{(5,): 1, (2, 1): 1}
sage: c.monomials()
[Sq(2,1), Sq(5)]
sage: c.support()
[(2, 1), (5,)]
See the documentation for this module (type sage.algebras.steenrod.steenrod_algebra?) for more information about elements of the Steenrod algebra.
The additive order of any nonzero element of the mod p Steenrod algebra is p.
OUTPUT: 1 (for the zero element) or p (for anything else)
EXAMPLES:
sage: z = Sq(4) + Sq(6) + 1
sage: z.additive_order()
2
sage: (Sq(3) + Sq(3)).additive_order()
1
Representation of element with respect to basis.
INPUT:
OUTPUT: Representation of self in given basis
Warning
Deprecated (December 2010). Use change_basis() instead.
EXAMPLES:
sage: c = Sq(2) * Sq(1)
sage: c.basis('milnor')
doctest:...: DeprecationWarning: The .basis() method is deprecated. Use .change_basis() instead.
See http://trac.sagemath.org/10052 for details.
Sq(0,1) + Sq(3)
The basis name associated to self.
EXAMPLES:
sage: a = SteenrodAlgebra().Sq(3,2,1)
sage: a.basis_name()
'milnor'
sage: a.change_basis('adem').basis_name()
'serre-cartan'
sage: a.change_basis('wood____y').basis_name()
'woody'
sage: b = SteenrodAlgebra(p=7).basis(36)[0]
sage: b.basis_name()
'milnor'
sage: a.change_basis('adem').basis_name()
'serre-cartan'
Representation of element with respect to basis.
INPUT:
OUTPUT: representation of self in given basis
The choices for basis are:
See documentation for this module (by browsing the reference manual or by typing sage.algebras.steenrod.steenrod_algebra?) for descriptions of the different bases.
EXAMPLES:
sage: c = Sq(2) * Sq(1)
sage: c.change_basis('milnor')
Sq(0,1) + Sq(3)
sage: c.change_basis('serre-cartan')
Sq^2 Sq^1
sage: d = Sq(0,0,1)
sage: d.change_basis('arnonc')
Sq^2 Sq^5 + Sq^4 Sq^2 Sq^1 + Sq^4 Sq^3 + Sq^7
The coproduct of this element.
INPUT:
See SteenrodAlgebra_generic.coproduct_on_basis() for more information on computing the coproduct.
EXAMPLES:
sage: a = Sq(2)
sage: a.coproduct()
1 # Sq(2) + Sq(1) # Sq(1) + Sq(2) # 1
sage: b = Sq(4)
sage: (a*b).coproduct() == (a.coproduct()) * (b.coproduct())
True
sage: c = a.change_basis('adem'); c.coproduct(algorithm='milnor')
1 # Sq^2 + Sq^1 # Sq^1 + Sq^2 # 1
sage: c = a.change_basis('adem'); c.coproduct(algorithm='adem')
1 # Sq^2 + Sq^1 # Sq^1 + Sq^2 # 1
sage: d = a.change_basis('comm_long'); d.coproduct()
1 # s_2 + s_1 # s_1 + s_2 # 1
sage: A7 = SteenrodAlgebra(p=7)
sage: a = A7.Q(1) * A7.P(1); a
Q_1 P(1)
sage: a.coproduct()
1 # Q_1 P(1) + P(1) # Q_1 + Q_1 # P(1) + Q_1 P(1) # 1
sage: a.coproduct(algorithm='adem')
1 # Q_1 P(1) + P(1) # Q_1 + Q_1 # P(1) + Q_1 P(1) # 1
The degree of self.
The degree of is
At an odd prime , the degree of
is
and the
degree of
is
ALGORITHM: If is_homogeneous() returns True, call SteenrodAlgebra_generic.degree_on_basis() on the leading summand.
EXAMPLES:
sage: Sq(0,0,1).degree()
7
sage: (Sq(0,0,1) + Sq(7)).degree()
7
sage: (Sq(0,0,1) + Sq(2)).degree()
Traceback (most recent call last):
...
ValueError: Element is not homogeneous.
sage: A11 = SteenrodAlgebra(p=11)
sage: A11.P(1).degree()
20
sage: A11.P(1,1).degree()
260
sage: A11.Q(2).degree()
241
TESTS:
sage: all([x.degree() == 10 for x in SteenrodAlgebra(basis='woody').basis(10)])
True
sage: all([x.degree() == 11 for x in SteenrodAlgebra(basis='woodz').basis(11)])
True
sage: all([x.degree() == x.milnor().degree() for x in SteenrodAlgebra(basis='wall').basis(11)])
True
sage: a = SteenrodAlgebra(basis='pst').basis(10)[0]
sage: a.degree() == a.change_basis('arnonc').degree()
True
sage: b = SteenrodAlgebra(basis='comm').basis(12)[1]
sage: b.degree() == b.change_basis('adem').change_basis('arnona').degree()
True
sage: all([x.degree() == 9 for x in SteenrodAlgebra(basis='comm').basis(9)])
True
sage: all([x.degree() == 8 for x in SteenrodAlgebra(basis='adem').basis(8)])
True
sage: all([x.degree() == 7 for x in SteenrodAlgebra(basis='milnor').basis(7)])
True
sage: all([x.degree() == 24 for x in SteenrodAlgebra(p=3).basis(24)])
True
sage: all([x.degree() == 40 for x in SteenrodAlgebra(p=5, basis='serre-cartan').basis(40)])
True
Excess of element.
OUTPUT: excess - non-negative integer
The excess of a Milnor basis element is
. When
is odd, the excess of
is
.
The excess of a linear combination of Milnor basis elements is
the minimum of the excesses of those basis elements.
See [Kra] for the proofs of these assertions.
REFERENCES:
EXAMPLES:
sage: a = Sq(1,2,3)
sage: a.excess()
6
sage: (Sq(0,0,1) + Sq(4,1) + Sq(7)).excess()
1
sage: [m.excess() for m in (Sq(0,0,1) + Sq(4,1) + Sq(7)).monomials()]
[1, 5, 7]
sage: [m for m in (Sq(0,0,1) + Sq(4,1) + Sq(7)).monomials()]
[Sq(0,0,1), Sq(4,1), Sq(7)]
sage: B = SteenrodAlgebra(7)
sage: a = B.Q(1,2,5)
sage: b = B.P(2,2,3)
sage: a.excess()
3
sage: b.excess()
14
sage: (a + b).excess()
3
sage: (a * b).excess()
17
Return True if element is decomposable, False otherwise. That is, if element is in the square of the augmentation ideal, return True; otherwise, return False.
OUTPUT: boolean
EXAMPLES:
sage: a = Sq(6)
sage: a.is_decomposable()
True
sage: for i in range(9):
... if not Sq(i).is_decomposable():
... print Sq(i)
1
Sq(1)
Sq(2)
Sq(4)
Sq(8)
sage: A3 = SteenrodAlgebra(p=3, basis='adem')
sage: [A3.P(n) for n in range(30) if not A3.P(n).is_decomposable()]
[1, P^1, P^3, P^9, P^27]
TESTS:
These all test changing bases and printing in various bases:
sage: A = SteenrodAlgebra(basis='milnor')
sage: [A.Sq(n) for n in range(9) if not A.Sq(n).is_decomposable()]
[1, Sq(1), Sq(2), Sq(4), Sq(8)]
sage: A = SteenrodAlgebra(basis='wall_long')
sage: [A.Sq(n) for n in range(9) if not A.Sq(n).is_decomposable()]
[1, Sq^1, Sq^2, Sq^4, Sq^8]
sage: A = SteenrodAlgebra(basis='arnona_long')
sage: [A.Sq(n) for n in range(9) if not A.Sq(n).is_decomposable()]
[1, Sq^1, Sq^2, Sq^4, Sq^8]
sage: A = SteenrodAlgebra(basis='woodz')
sage: [A.Sq(n) for n in range(20) if not A.Sq(n).is_decomposable()] # long time
[1, Sq^1, Sq^2, Sq^4, Sq^8, Sq^16]
sage: A = SteenrodAlgebra(basis='comm_long')
sage: [A.Sq(n) for n in range(25) if not A.Sq(n).is_decomposable()] # long time
[1, s_1, s_2, s_4, s_8, s_16]
Return True iff this element is homogeneous.
EXAMPLES:
sage: (Sq(0,0,1) + Sq(7)).is_homogeneous()
True
sage: (Sq(0,0,1) + Sq(2)).is_homogeneous()
False
True if element is not a unit, False otherwise.
EXAMPLES:
sage: z = Sq(4,2) + Sq(7,1) + Sq(3,0,1)
sage: z.is_nilpotent()
True
sage: u = 1 + Sq(3,1)
sage: u == 1 + Sq(3,1)
True
sage: u.is_nilpotent()
False
True if element has a nonzero scalar multiple of P(0) as a summand, False otherwise.
EXAMPLES:
sage: z = Sq(4,2) + Sq(7,1) + Sq(3,0,1)
sage: z.is_unit()
False
sage: u = Sq(0) + Sq(3,1)
sage: u == 1 + Sq(3,1)
True
sage: u.is_unit()
True
sage: A5 = SteenrodAlgebra(5)
sage: v = A5.P(0)
sage: (v + v + v).is_unit()
True
May’s ‘weight’ of element.
OUTPUT: weight - non-negative integer
If we let be the May filtration of the Steenrod
algebra, the weight of an element
is the integer
so
that
is in
and not in
. According to
Theorem 2.6 in May’s thesis [May], the weight of a Milnor
basis element is computed as follows: first, to compute the
weight of
, write each
in base
as
. Then each nonzero binary digit
contributes
to the weight: the weight is
. When
is odd, the weight of
is
, so the weight of a product
equals
. Then the weight of
is the sum of
and
.
The weight of a sum of Milnor basis elements is the minimum of the weights of the summands.
When , we compute the weight on Milnor basis elements by
adding up the terms in their ‘height’ - see
wall_height() for documentation. (When
is odd, the
height of an element is not defined.)
REFERENCES:
EXAMPLES:
sage: Sq(0).may_weight()
0
sage: a = Sq(4)
sage: a.may_weight()
1
sage: b = Sq(4)*Sq(8) + Sq(8)*Sq(4)
sage: b.may_weight()
2
sage: Sq(2,1,5).wall_height()
[2, 3, 2, 1, 1]
sage: Sq(2,1,5).may_weight()
9
sage: A5 = SteenrodAlgebra(5)
sage: a = A5.Q(1,2,4)
sage: b = A5.P(1,2,1)
sage: a.may_weight()
10
sage: b.may_weight()
8
sage: (a * b).may_weight()
18
sage: A5.P(0,0,1).may_weight()
3
Return this element in the Milnor basis; that is, as an element of the appropriate Steenrod algebra.
This just calls the method SteenrodAlgebra_generic.milnor().
EXAMPLES:
sage: Adem = SteenrodAlgebra(basis='adem')
sage: a = Adem.basis(4)[1]; a
Sq^3 Sq^1
sage: a.milnor()
Sq(1,1)
The prime associated to self.
EXAMPLES:
sage: a = SteenrodAlgebra().Sq(3,2,1)
sage: a.prime()
2
sage: a.change_basis('adem').prime()
2
sage: b = SteenrodAlgebra(p=7).basis(36)[0]
sage: b.prime()
7
sage: SteenrodAlgebra(p=3, basis='adem').one().prime()
3
Wall’s ‘height’ of element.
OUTPUT: list of non-negative integers
The height of an element of the mod 2 Steenrod algebra is a
list of non-negative integers, defined as follows: if the
element is a monomial in the generators , then
the
entry in the list is the number of times
appears. For an arbitrary element, write it
as a sum of such monomials; then its height is the maximum,
ordered right-lexicographically, of the heights of those
monomials.
When is odd, the height of an element is not defined.
According to Theorem 3 in [Wall], the height of the Milnor
basis element is obtained as
follows: write each
in binary as
. Then each nonzero binary digit
contributes 1
to the
entry in the height, for
.
REFERENCES:
EXAMPLES:
sage: Sq(0).wall_height()
[]
sage: a = Sq(4)
sage: a.wall_height()
[0, 0, 1]
sage: b = Sq(4)*Sq(8) + Sq(8)*Sq(4)
sage: b.wall_height()
[0, 0, 1, 1]
sage: Sq(0,0,3).wall_height()
[1, 2, 2, 1]
The element
INPUT:
OUTPUT: element of the Steenrod algebra given by the Milnor
single basis element
Note that at the prime 2, this is the same element as
.
EXAMPLES:
sage: A = SteenrodAlgebra(2)
sage: A.P(5)
Sq(5)
sage: B = SteenrodAlgebra(3)
sage: B.P(5,1,1)
P(5,1,1)
sage: B.P(1,1,-12,1)
Traceback (most recent call last):
...
TypeError: entries must be non-negative integers
sage: SteenrodAlgebra(basis='serre-cartan').P(0,1)
Sq^2 Sq^1 + Sq^3
sage: SteenrodAlgebra(generic=True).P(2,0,1)
P(2,0,1)
The element , given by specifying the
subscripts.
INPUT:
OUTPUT: The element
Note that at the prime 2, is the element
, where the 1 is in the
position.
Compare this to the method Q_exp(), which defines a similar element, but by specifying the tuple of exponents.
EXAMPLES:
sage: A2 = SteenrodAlgebra(2)
sage: A2.Q(2,3)
Sq(0,0,1,1)
sage: A5 = SteenrodAlgebra(5)
sage: A5.Q(1,4)
Q_1 Q_4
sage: A5.Q(1,4) == A5.Q_exp(0,1,0,0,1)
True
sage: H = SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]])
sage: H.Q(2)
Q_2
sage: H.Q(4)
Traceback (most recent call last):
...
ValueError: Element not in this algebra
The element , given by
specifying the exponents.
INPUT:
OUTPUT: The element
Note that at the prime 2, is the element
, where the 1 is in the
position.
Compare this to the method Q(), which defines a similar element, but by specifying the tuple of subscripts of terms with exponent 1.
EXAMPLES:
sage: A2 = SteenrodAlgebra(2)
sage: A5 = SteenrodAlgebra(5)
sage: A2.Q_exp(0,0,1,1,0)
Sq(0,0,1,1)
sage: A5.Q_exp(0,0,1,1,0)
Q_2 Q_3
sage: A5.Q(2,3)
Q_2 Q_3
sage: A5.Q_exp(0,0,1,1,0) == A5.Q(2,3)
True
sage: SteenrodAlgebra(2,generic=True).Q_exp(1,0,1)
Q_0 Q_2
Family of generators for this algebra.
OUTPUT: family of elements of this algebra
At the prime 2, the Steenrod algebra is generated by the
elements for
. At odd primes, it
is generated by the elements
and
for
. So if this algebra is the entire Steenrod
algebra, return an infinite family made up of these elements.
For sub-Hopf algebras of the Steenrod algebra, it is not
always clear what a minimal generating set is. The sub-Hopf
algebra is minimally generated by the elements
for
at the prime 2. At
odd primes,
is minimally generated by
along with
for
. So if this
algebra is
, return the appropriate list of generators.
For other sub-Hopf algebras: return a non-minimal generating
set: the family of ‘s and
‘s contained in the
algebra.
EXAMPLES:
sage: A3 = SteenrodAlgebra(3, 'adem')
sage: A3.gens()
Lazy family (<bound method SteenrodAlgebra_generic_with_category.gen of mod 3 Steenrod algebra, serre-cartan basis>(i))_{i in Non negative integers}
sage: A3.gens()[0]
beta
sage: A3.gens()[1]
P^1
sage: A3.gens()[2]
P^3
sage: SteenrodAlgebra(profile=[3,2,1]).gens()
Family (Sq(1), Sq(2), Sq(4))
In the following case, return a non-minimal generating set.
(It is not minimal because is the
commutator of
and
.)
sage: SteenrodAlgebra(profile=[1,2,1]).gens()
Family (Sq(1), Sq(0,1), Sq(0,2), Sq(0,0,1))
sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]]).gens()
Family (Q_0, P(1), P(5))
sage: SteenrodAlgebra(profile=lambda n: n).gens()
Lazy family (<bound method SteenrodAlgebra_mod_two_with_category.gen of sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [1, 2, 3, ..., 98, 99, +Infinity, +Infinity, +Infinity, ...]>(i))_{i in Non negative integers}
You may also use algebra_generators instead of gens:
sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]]).algebra_generators()
Family (Q_0, P(1), P(5))
An element of this Steenrod algebra. The element depends on the basis and whether there is a nontrivial profile function. (This is used by the automatic test suite, so having different elements in different bases may help in discovering bugs.)
EXAMPLES:
sage: SteenrodAlgebra().an_element()
Sq(2,1)
sage: SteenrodAlgebra(basis='adem').an_element()
Sq^4 Sq^2 Sq^1
sage: SteenrodAlgebra(p=5).an_element()
4 Q_1 Q_3 P(2,1)
sage: SteenrodAlgebra(basis='pst').an_element()
P^3_1
sage: SteenrodAlgebra(basis='pst', profile=[3,2,1]).an_element()
P^0_1
The antipode of a basis element of this algebra
INPUT:
OUTPUT: the antipode of the corresponding basis element, as an element of self.
ALGORITHM: according to a result of Milnor’s, the antipode of
is the sum of all of the Milnor basis elements
in dimension
. So: convert the element to the Serre-Cartan
basis, thus writing it as a sum of products of elements
, and use Milnor’s formula for the antipode of
, together with the fact that the antipode is an
antihomomorphism: if we call the antipode
, then
.
At odd primes, a similar method is used: the antipode of
is the sum of the Milnor P basis elements in dimension
, multiplied by
, and the antipode of
is
. So convert to the Serre-Cartan basis, as in
the
case.
EXAMPLES:
sage: A = SteenrodAlgebra()
sage: A.antipode_on_basis((4,))
Sq(1,1) + Sq(4)
sage: A.Sq(4).antipode()
Sq(1,1) + Sq(4)
sage: Adem = SteenrodAlgebra(basis='adem')
sage: Adem.Sq(4).antipode()
Sq^3 Sq^1 + Sq^4
sage: SteenrodAlgebra(basis='pst').Sq(3).antipode()
P^0_1 P^1_1 + P^0_2
sage: a = SteenrodAlgebra(basis='wall_long').Sq(10)
sage: a.antipode()
Sq^1 Sq^2 Sq^4 Sq^1 Sq^2 + Sq^2 Sq^4 Sq^1 Sq^2 Sq^1 + Sq^8 Sq^2
sage: a.antipode().antipode() == a
True
sage: SteenrodAlgebra(p=3).P(6).antipode()
P(2,1) + P(6)
sage: SteenrodAlgebra(p=3).P(6).antipode().antipode()
P(6)
TESTS:
sage: Milnor = SteenrodAlgebra()
sage: all([x.antipode().antipode() == x for x in Milnor.basis(11)]) # long time
True
sage: A5 = SteenrodAlgebra(p=5, basis='adem')
sage: all([x.antipode().antipode() == x for x in A5.basis(25)])
True
sage: H = SteenrodAlgebra(profile=[2,2,1])
sage: H.Sq(1,2).antipode() in H
True
Returns basis for self, either the whole basis or the basis in
degree .
INPUT:
OUTPUT: If is None, then return a basis of the algebra.
Otherwise, return the basis in degree
.
EXAMPLES:
sage: A3 = SteenrodAlgebra(3)
sage: A3.basis(13)
Family (Q_1 P(2), Q_0 P(3))
sage: SteenrodAlgebra(2, 'adem').basis(12)
Family (Sq^12, Sq^11 Sq^1, Sq^9 Sq^2 Sq^1, Sq^8 Sq^3 Sq^1, Sq^10 Sq^2, Sq^9 Sq^3, Sq^8 Sq^4)
sage: A = SteenrodAlgebra(profile=[1,2,1])
sage: A.basis(2)
Family ()
sage: A.basis(3)
Family (Sq(0,1),)
sage: SteenrodAlgebra().basis(3)
Family (Sq(0,1), Sq(3))
sage: A_pst = SteenrodAlgebra(profile=[1,2,1], basis='pst')
sage: A_pst.basis(3)
Family (P^0_2,)
sage: A7 = SteenrodAlgebra(p=7)
sage: B = SteenrodAlgebra(p=7, profile=([1,2,1], [1]))
sage: A7.basis(84)
Family (P(7),)
sage: B.basis(84)
Family ()
sage: C = SteenrodAlgebra(p=7, profile=([1], [2,2]))
sage: A7.Q(0,1) in C.basis(14)
True
sage: A7.Q(2) in A7.basis(97)
True
sage: A7.Q(2) in C.basis(97)
False
With no arguments, return the basis of the whole algebra. This doesn’t print in a very helpful way, unfortunately:
sage: A7.basis()
Lazy family (Term map from basis key family of mod 7 Steenrod algebra, milnor basis to mod 7 Steenrod algebra, milnor basis(i))_{i in basis key family of mod 7 Steenrod algebra, milnor basis}
sage: for (idx,a) in zip((1,..,9),A7.basis()):
... print idx, a
1 1
2 Q_0
3 P(1)
4 Q_1
5 Q_0 P(1)
6 Q_0 Q_1
7 P(2)
8 Q_1 P(1)
9 Q_0 P(2)
sage: D = SteenrodAlgebra(p=3, profile=([1], [2,2]))
sage: sorted(D.basis())
[1, P(1), P(2), Q_0, Q_0 P(1), Q_0 P(2), Q_0 Q_1, Q_0 Q_1 P(1), Q_0 Q_1 P(2), Q_1, Q_1 P(1), Q_1 P(2)]
The basis name associated to self.
EXAMPLES:
sage: SteenrodAlgebra(p=2, profile=[1,1]).basis_name()
'milnor'
sage: SteenrodAlgebra(basis='serre-cartan').basis_name()
'serre-cartan'
sage: SteenrodAlgebra(basis='adem').basis_name()
'serre-cartan'
Return the coproduct of an element x of this algebra.
INPUT:
This calls coproduct_on_basis() on the summands of x and extends linearly.
EXAMPLES:
sage: SteenrodAlgebra().Sq(3).coproduct()
1 # Sq(3) + Sq(1) # Sq(2) + Sq(2) # Sq(1) + Sq(3) # 1
The element is primitive:
sage: SteenrodAlgebra(basis='adem').Sq(0,1).coproduct()
1 # Sq^2 Sq^1 + 1 # Sq^3 + Sq^2 Sq^1 # 1 + Sq^3 # 1
sage: SteenrodAlgebra(basis='pst').Sq(0,1).coproduct()
1 # P^0_2 + P^0_2 # 1
sage: SteenrodAlgebra(p=3).P(4).coproduct()
1 # P(4) + P(1) # P(3) + P(2) # P(2) + P(3) # P(1) + P(4) # 1
sage: SteenrodAlgebra(p=3).P(4).coproduct(algorithm='serre-cartan')
1 # P(4) + P(1) # P(3) + P(2) # P(2) + P(3) # P(1) + P(4) # 1
sage: SteenrodAlgebra(p=3, basis='serre-cartan').P(4).coproduct()
1 # P^4 + P^1 # P^3 + P^2 # P^2 + P^3 # P^1 + P^4 # 1
sage: SteenrodAlgebra(p=11, profile=((), (2,1,2))).Q(0,2).coproduct()
1 # Q_0 Q_2 + Q_0 # Q_2 + Q_0 Q_2 # 1 - Q_2 # Q_0
The coproduct of a basis element of this algebra
INPUT:
ALGORITHM: The coproduct on a Milnor basis element is
, summed over all
for each
. At odd
primes, each element
is primitive: its coproduct is
.
One can deduce a coproduct formula for the Serre-Cartan basis
from this: the coproduct on each is
and at odd primes
is primitive. Since the
coproduct is an algebra map, one can then compute the
coproduct on any Serre-Cartan basis element.
Which of these methods is used is controlled by whether algorithm is ‘milnor’ or ‘serre-cartan’.
OUTPUT: the coproduct of the corresponding basis element, as an element of self tensor self.
EXAMPLES:
sage: A = SteenrodAlgebra()
sage: A.coproduct_on_basis((3,))
1 # Sq(3) + Sq(1) # Sq(2) + Sq(2) # Sq(1) + Sq(3) # 1
TESTS:
sage: all([A.coproduct_on_basis((n,1), algorithm='milnor') == A.coproduct_on_basis((n,1), algorithm='adem') for n in range(9)]) # long time
True
sage: A7 = SteenrodAlgebra(p=7, basis='adem')
sage: all([A7.coproduct_on_basis((0,n,1), algorithm='milnor') == A7.coproduct_on_basis((0,n,1), algorithm='adem') for n in range(9)]) # long time
True
The counit sends all elements of positive degree to zero.
INPUT:
EXAMPLES:
sage: A2 = SteenrodAlgebra(p=2)
sage: A2.counit_on_basis(())
1
sage: A2.counit_on_basis((0,0,1))
0
sage: parent(A2.counit_on_basis((0,0,1)))
Finite Field of size 2
sage: A3 = SteenrodAlgebra(p=3)
sage: A3.counit_on_basis(((1,2,3), (1,1,1)))
0
sage: A3.counit_on_basis(((), ()))
1
sage: A3.counit(A3.P(10,5))
0
sage: A3.counit(A3.P(0))
1
The degree of the monomial specified by the tuple t.
INPUT:
OUTPUT: integer, the degree of the corresponding element.
The degree of is
At an odd prime , the degree of
is
and the
degree of
is
ALGORITHM: Each basis element is represented in terms relevant
to the particular basis: ‘milnor’ basis elements (at the prime
2) are given by tuples (a,b,c,...) corresponding to the
element , while ‘pst’ basis elements are
given by tuples of pairs ((a, b), (c, d), ...),
corresponding to the product
. The other
bases have similar descriptions. The degree of each basis
element is computed from this data, rather than converting the
element to the Milnor basis, for example, and then computing
the degree.
EXAMPLES:
sage: SteenrodAlgebra().degree_on_basis((0,0,1))
7
sage: Sq(7).degree()
7
sage: A11 = SteenrodAlgebra(p=11)
sage: A11.degree_on_basis(((), (1,1)))
260
sage: A11.degree_on_basis(((2,), ()))
241
The dimension of this algebra as a vector space over .
If the algebra is infinite, return +Infinity. Otherwise,
the profile function must be finite. In this case, at the
prime 2, its dimension is , where
is the sum of the
entries in the profile function. At odd primes, the dimension
is
where
is the sum of the
component of
the profile function and
is the number of 2’s in the
component of the profile function.
EXAMPLES:
sage: SteenrodAlgebra(p=7).dimension()
+Infinity
sage: SteenrodAlgebra(profile=[3,2,1]).dimension()
64
sage: SteenrodAlgebra(p=3, profile=([1,1], [])).dimension()
9
sage: SteenrodAlgebra(p=5, profile=([1], [2,2])).dimension()
20
The ith generator of this algebra.
INPUT:
OUTPUT: the ith generator of this algebra
For the full Steenrod algebra, the generator is
at the prime 2; when
is odd, the 0th generator
is
, and for
, the
generator is
.
For sub-Hopf algebras of the Steenrod algebra, it is not
always clear what a minimal generating set is. The sub-Hopf
algebra is minimally generated by the elements
for
at the prime 2. At
odd primes,
is minimally generated by
along with
for
. So if this
algebra is
, return the appropriate generator.
For other sub-Hopf algebras: they are generated (but not
necessarily minimally) by the ‘s (and
‘s, if
is odd) that they contain. So order the
‘s (and
‘s) in the algebra by degree and return the
-th one.
EXAMPLES:
sage: A = SteenrodAlgebra(2)
sage: A.gen(4)
Sq(16)
sage: A.gen(200)
Sq(1606938044258990275541962092341162602522202993782792835301376)
sage: SteenrodAlgebra(2, basis='adem').gen(2)
Sq^4
sage: SteenrodAlgebra(2, basis='pst').gen(2)
P^2_1
sage: B = SteenrodAlgebra(5)
sage: B.gen(0)
Q_0
sage: B.gen(2)
P(5)
sage: SteenrodAlgebra(profile=[2,1]).gen(1)
Sq(2)
sage: SteenrodAlgebra(profile=[1,2,1]).gen(1)
Sq(0,1)
sage: SteenrodAlgebra(profile=[1,2,1]).gen(5)
Traceback (most recent call last):
...
ValueError: This algebra only has 4 generators, so call gen(i) with 0 <= i < 4
sage: D = SteenrodAlgebra(profile=lambda n: n)
sage: [D.gen(n) for n in range(5)]
[Sq(1), Sq(0,1), Sq(0,2), Sq(0,0,1), Sq(0,0,2)]
sage: D3 = SteenrodAlgebra(p=3, profile=(lambda n: n, lambda n: 2))
sage: [D3.gen(n) for n in range(9)]
[Q_0, P(1), Q_1, P(0,1), Q_2, P(0,3), P(0,0,1), Q_3, P(0,0,3)]
sage: D3 = SteenrodAlgebra(p=3, profile=(lambda n: n, lambda n: 1 if n<1 else 2))
sage: [D3.gen(n) for n in range(9)]
[P(1), Q_1, P(0,1), Q_2, P(0,3), P(0,0,1), Q_3, P(0,0,3), P(0,0,0,1)]
sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]], basis='pst').gen(2)
P^1_1
Family of generators for this algebra.
OUTPUT: family of elements of this algebra
At the prime 2, the Steenrod algebra is generated by the
elements for
. At odd primes, it
is generated by the elements
and
for
. So if this algebra is the entire Steenrod
algebra, return an infinite family made up of these elements.
For sub-Hopf algebras of the Steenrod algebra, it is not
always clear what a minimal generating set is. The sub-Hopf
algebra is minimally generated by the elements
for
at the prime 2. At
odd primes,
is minimally generated by
along with
for
. So if this
algebra is
, return the appropriate list of generators.
For other sub-Hopf algebras: return a non-minimal generating
set: the family of ‘s and
‘s contained in the
algebra.
EXAMPLES:
sage: A3 = SteenrodAlgebra(3, 'adem')
sage: A3.gens()
Lazy family (<bound method SteenrodAlgebra_generic_with_category.gen of mod 3 Steenrod algebra, serre-cartan basis>(i))_{i in Non negative integers}
sage: A3.gens()[0]
beta
sage: A3.gens()[1]
P^1
sage: A3.gens()[2]
P^3
sage: SteenrodAlgebra(profile=[3,2,1]).gens()
Family (Sq(1), Sq(2), Sq(4))
In the following case, return a non-minimal generating set.
(It is not minimal because is the
commutator of
and
.)
sage: SteenrodAlgebra(profile=[1,2,1]).gens()
Family (Sq(1), Sq(0,1), Sq(0,2), Sq(0,0,1))
sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]]).gens()
Family (Q_0, P(1), P(5))
sage: SteenrodAlgebra(profile=lambda n: n).gens()
Lazy family (<bound method SteenrodAlgebra_mod_two_with_category.gen of sub-Hopf algebra of mod 2 Steenrod algebra, milnor basis, profile function [1, 2, 3, ..., 98, 99, +Infinity, +Infinity, +Infinity, ...]>(i))_{i in Non negative integers}
You may also use algebra_generators instead of gens:
sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]]).algebra_generators()
Family (Q_0, P(1), P(5))
Return the nth homogeneous piece of the Steenrod algebra.
INPUT:
OUTPUT: a vector space spanned by the basis for this algebra
in dimension
EXAMPLES:
sage: A = SteenrodAlgebra()
sage: A.homogeneous_component(4)
Vector space spanned by (Sq(1,1), Sq(4)) over Finite Field of size 2
sage: SteenrodAlgebra(profile=[2,1,0]).homogeneous_component(4)
Vector space spanned by (Sq(1,1),) over Finite Field of size 2
The notation A[n] may also be used:
sage: A[5]
Vector space spanned by (Sq(2,1), Sq(5)) over Finite Field of size 2
sage: SteenrodAlgebra(basis='wall')[4]
Vector space spanned by (Q^1_0 Q^0_0, Q^2_2) over Finite Field of size 2
sage: SteenrodAlgebra(p=5)[17]
Vector space spanned by (Q_1 P(1), Q_0 P(2)) over Finite Field of size 5
Note that A[n] is just a vector space, not a Hopf algebra, so its elements don’t have products, coproducts, or antipodes defined on them. If you want to use operations like this on elements of some A[n], then convert them back to elements of A:
sage: A[5].basis()
Finite family {(5,): milnor[(5,)], (2, 1): milnor[(2, 1)]}
sage: a = list(A[5].basis())[1]
sage: a # not in A, doesn't print like an element of A
milnor[(5,)]
sage: A(a) # in A
Sq(5)
sage: A(a) * A(a)
Sq(7,1)
sage: a * A(a) # only need to convert one factor
Sq(7,1)
sage: a.antipode() # not defined
Traceback (most recent call last):
...
AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode'
sage: A(a).antipode() # convert to elt of A, then compute antipode
Sq(2,1) + Sq(5)
sage: G = SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]], basis='pst')
TESTS:
The following sort of thing is also tested by the function steenrod_basis_error_check:
sage: H = SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]])
sage: G = SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]], basis='pst')
sage: max([H[n].dimension() - G[n].dimension() for n in range(100)])
0
True if self is graded commutative, as determined by the
profile function. In particular, a sub-Hopf algebra of the
mod 2 Steenrod algebra is commutative if and only if there is
an integer so that its profile function
satisfies
When is odd, there must be an integer
so that
the profile functions
and
satisfy
EXAMPLES:
sage: A = SteenrodAlgebra(p=3)
sage: A.is_commutative()
False
sage: SteenrodAlgebra(profile=[2,1]).is_commutative()
False
sage: SteenrodAlgebra(profile=[0,2,2,1]).is_commutative()
True
Note that if the profile function is specified by a function, then by default it has infinite truncation type: the profile function is assumed to be infinite after the 100th term.
sage: SteenrodAlgebra(profile=lambda n: 1).is_commutative()
False
sage: SteenrodAlgebra(profile=lambda n: 1, truncation_type=0).is_commutative()
True
sage: SteenrodAlgebra(p=5, profile=([0,2,2,1], [])).is_commutative()
True
sage: SteenrodAlgebra(p=5, profile=([0,2,2,1], [1,1,2])).is_commutative()
True
sage: SteenrodAlgebra(p=5, profile=([0,2,1], [1,2,2,2])).is_commutative()
False
The only way this algebra can be a division algebra is if it
is the ground field .
EXAMPLES:
sage: SteenrodAlgebra(11).is_division_algebra()
False
sage: SteenrodAlgebra(profile=lambda n: 0, truncation_type=0).is_division_algebra()
True
The only way this algebra can be a field is if it is the
ground field .
EXAMPLES:
sage: SteenrodAlgebra(11).is_field()
False
sage: SteenrodAlgebra(profile=lambda n: 0, truncation_type=0).is_field()
True
True if this algebra is finite-dimensional.
Therefore true if the profile function is finite, and in particular the truncation_type must be finite.
EXAMPLES:
sage: A = SteenrodAlgebra(p=3)
sage: A.is_finite()
False
sage: SteenrodAlgebra(profile=[3,2,1]).is_finite()
True
sage: SteenrodAlgebra(profile=lambda n: n).is_finite()
False
The algebra is generic if it is based on the odd-primary relations, i.e. if its dual is a quotient of
Sage also allows this for . Only the usual Steenrod algebra at the prime
and
its sub algebras are non-generic.
EXAMPLES:
sage: SteenrodAlgebra(3).is_generic()
True
sage: SteenrodAlgebra(2).is_generic()
False
sage: SteenrodAlgebra(2,generic=True).is_generic()
True
The only way this algebra can be an integral domain is if it
is the ground field .
EXAMPLES:
sage: SteenrodAlgebra(11).is_integral_domain()
False
sage: SteenrodAlgebra(profile=lambda n: 0, truncation_type=0).is_integral_domain()
True
This algebra is noetherian if and only if it is finite.
EXAMPLES:
sage: SteenrodAlgebra(3).is_noetherian()
False
sage: SteenrodAlgebra(profile=[1,2,1]).is_noetherian()
True
sage: SteenrodAlgebra(profile=lambda n: n+2).is_noetherian()
False
Convert an element of this algebra to the Milnor basis
INPUT:
OUTPUT: x converted to the Milnor basis
ALGORITHM: use the method _milnor_on_basis and linearity.
EXAMPLES:
sage: Adem = SteenrodAlgebra(basis='adem')
sage: a = Adem.Sq(2) * Adem.Sq(1)
sage: Adem.milnor(a)
Sq(0,1) + Sq(3)
Number of generators of self.
OUTPUT: number or Infinity
The Steenrod algebra is infinitely generated. A sub-Hopf
algebra may be finitely or infinitely generated; in general,
it is not clear what a minimal generating set is, nor the
cardinality of that set. So: if the algebra is
infinite-dimensional, this returns Infinity. If the algebra
is finite-dimensional and is equal to one of the sub-Hopf
algebras , then their minimal generating set is known,
and this returns the cardinality of that set. Otherwise, any
sub-Hopf algebra is (not necessarily minimally) generated by
the
‘s that it contains (along with the
‘s it
contains, at odd primes), so this returns the number of
‘s and
‘s in the algebra.
EXAMPLES:
sage: A = SteenrodAlgebra(3)
sage: A.ngens()
+Infinity
sage: SteenrodAlgebra(profile=lambda n: n).ngens()
+Infinity
sage: SteenrodAlgebra(profile=[3,2,1]).ngens() # A(2)
3
sage: SteenrodAlgebra(profile=[3,2,1], basis='pst').ngens()
3
sage: SteenrodAlgebra(p=3, profile=[[3,2,1], [2,2,2,2]]).ngens() # A(3) at p=3
4
sage: SteenrodAlgebra(profile=[1,2,1,1]).ngens()
5
The index of the element 1 in the basis for the Steenrod algebra.
EXAMPLES:
sage: SteenrodAlgebra(p=2).one_basis()
()
sage: SteenrodAlgebra(p=7).one_basis()
((), ())
The order of this algebra.
This is computed by computing its vector space dimension
and then returning
.
EXAMPLES:
sage: SteenrodAlgebra(p=7).order()
+Infinity
sage: SteenrodAlgebra(profile=[2,1]).dimension()
8
sage: SteenrodAlgebra(profile=[2,1]).order()
256
sage: SteenrodAlgebra(p=3, profile=([1], [])).dimension()
3
sage: SteenrodAlgebra(p=3, profile=([1], [])).order()
27
sage: SteenrodAlgebra(p=5, profile=([], [2, 2])).dimension()
4
sage: SteenrodAlgebra(p=5, profile=([], [2, 2])).order() == 5**4
True
The prime associated to self.
EXAMPLES:
sage: SteenrodAlgebra(p=2, profile=[1,1]).prime()
2
sage: SteenrodAlgebra(p=7).prime()
7
The product of two basis elements of this algebra
INPUT:
OUTPUT: the product of the two corresponding basis elements, as an element of self
ALGORITHM: If the two elements are represented in the Milnor basis, use Milnor multiplication as implemented in sage.algebras.steenrod.steenrod_algebra_mult. If the two elements are represented in the Serre-Cartan basis, then multiply them using Adem relations (also implemented in sage.algebras.steenrod.steenrod_algebra_mult). This provides a good way of checking work – multiply Milnor elements, then convert them to Adem elements and multiply those, and see if the answers correspond.
If the two elements are represented in some other basis, then convert them both to the Milnor basis and multiply.
EXAMPLES:
sage: Milnor = SteenrodAlgebra()
sage: Milnor.product_on_basis((2,), (2,))
Sq(1,1)
sage: Adem = SteenrodAlgebra(basis='adem')
sage: Adem.Sq(2) * Adem.Sq(2) # indirect doctest
Sq^3 Sq^1
When multiplying elements from different bases, the left-hand factor determines the form of the output:
sage: Adem.Sq(2) * Milnor.Sq(2)
Sq^3 Sq^1
sage: Milnor.Sq(2) * Adem.Sq(2)
Sq(1,1)
TESTS:
sage: all([Adem(Milnor.Sq(n) ** 3)._repr_() == (Adem.Sq(n) ** 3)._repr_() for n in range(10)])
True
sage: Wall = SteenrodAlgebra(basis='wall')
sage: Wall(Adem.Sq(4,4) * Milnor.Sq(4)) == Adem(Wall.Sq(4,4) * Milnor.Sq(4))
True
sage: A3 = SteenrodAlgebra(p=3, basis='adem')
sage: M3 = SteenrodAlgebra(p=3, basis='milnor')
sage: all([A3(M3.P(n) * M3.Q(0) * M3.P(n))._repr_() == (A3.P(n) * A3.Q(0) * A3.P(n))._repr_() for n in range(5)])
True
sage: EA = SteenrodAlgebra(generic=True)
sage: EA.product_on_basis(((1, 3), (2, 1)), ((2, ), (0, 0, 1)))
Q_1 Q_2 Q_3 P(2,1,1)
sage: EA2 = SteenrodAlgebra(basis='serre-cartan', generic=True)
sage: EA2.product_on_basis((1, 2, 0, 1, 0), (1, 2, 0, 1, 0))
beta P^4 P^2 beta + beta P^5 beta P^1
Profile function for this algebra.
INPUT:
OUTPUT: integer or
See the documentation for sage.algebras.steenrod.steenrod_algebra and SteenrodAlgebra() for information on profile functions.
This applies the profile function to the integer . Thus
when
,
must be a positive integer. When
is odd,
there are two profile functions,
and
(in the notation
of the aforementioned documentation), corresponding,
respectively to component=0 and component=1. So when
is odd and component is 0,
must be positive, while
when component is 1,
must be non-negative.
EXAMPLES:
sage: SteenrodAlgebra().profile(3)
+Infinity
sage: SteenrodAlgebra(profile=[3,2,1]).profile(1)
3
sage: SteenrodAlgebra(profile=[3,2,1]).profile(2)
2
When the profile is specified by a list, the default behavior is to return zero values outside the range of the list. This can be overridden if the algebra is created with an infinite truncation_type:
sage: SteenrodAlgebra(profile=[3,2,1]).profile(9)
0
sage: SteenrodAlgebra(profile=[3,2,1], truncation_type=Infinity).profile(9)
+Infinity
sage: B = SteenrodAlgebra(p=3, profile=(lambda n: n, lambda n: 1))
sage: B.profile(3)
3
sage: B.profile(3, component=1)
1
sage: EA = SteenrodAlgebra(generic=True, profile=(lambda n: n, lambda n: 1))
sage: EA.profile(4)
4
sage: EA.profile(2, component=1)
1
The Margolis element .
INPUT:
OUTPUT: element of the Steenrod algebra
This returns the Margolis element of the mod
Steenrod algebra: the element equal to
, where the
is in position
.
EXAMPLES:
sage: A2 = SteenrodAlgebra(2)
sage: A2.pst(3,5)
Sq(0,0,0,0,8)
sage: A2.pst(1,2) == Sq(4)*Sq(2) + Sq(2)*Sq(4)
True
sage: SteenrodAlgebra(5).pst(3,5)
P(0,0,0,0,125)
Highest dimensional basis element. This is only defined if the algebra is finite.
EXAMPLES:
sage: SteenrodAlgebra(2,profile=(3,2,1)).top_class()
Sq(7,3,1)
sage: SteenrodAlgebra(3,profile=((2,2,1),(1,2,2,2,2))).top_class()
Q_1 Q_2 Q_3 Q_4 P(8,8,2)
TESTS:
sage: SteenrodAlgebra(2,profile=(3,2,1),basis='pst').top_class()
P^0_1 P^0_2 P^1_1 P^0_3 P^1_2 P^2_1
sage: SteenrodAlgebra(5,profile=((0,),(2,1,2,2))).top_class()
Q_0 Q_2 Q_3
sage: SteenrodAlgebra(5).top_class()
Traceback (most recent call last):
...
ValueError: the algebra is not finite dimensional
Currently, we create the top class in the Milnor basis version and transform this result back into the requested basis. This approach is easy to implement but far from optimal for the ‘pst’ basis. Occasionally, it also gives an awkward leading coefficient:
sage: SteenrodAlgebra(3,profile=((2,1),(1,2,2)),basis='pst').top_class()
2 Q_1 Q_2 (P^0_1)^2 (P^0_2)^2 (P^1_1)^2
TESTS:
sage: A=SteenrodAlgebra(2,profile=(3,2,1),basis='pst')
sage: A.top_class().parent() is A
True
Bases: sage.algebras.steenrod.steenrod_algebra.SteenrodAlgebra_generic
The mod 2 Steenrod algebra.
Users should not call this, but use the function SteenrodAlgebra() instead. See that function for extensive documentation. (This differs from SteenrodAlgebra_generic only in that it has a method Sq() for defining elements.)
Milnor element .
INPUT:
OUTPUT: element of the Steenrod algebra
This returns the Milnor basis element
.
EXAMPLES:
sage: A = SteenrodAlgebra(2)
sage: A.Sq(5)
Sq(5)
sage: A.Sq(5,0,2)
Sq(5,0,2)
Entries must be non-negative integers; otherwise, an error results.