Homology and cohomology with a basis¶
This module provides homology and cohomology vector spaces suitable for computing cup products and cohomology operations.
REFERENCES:
AUTHORS:
- John H. Palmieri, Travis Scrimshaw (2015-09) 
- class sage.homology.homology_vector_space_with_basis.CohomologyRing(base_ring, cell_complex, category=None)[source]¶
- Bases: - HomologyVectorSpaceWithBasis- The cohomology ring. - Note - This is not intended to be created directly by the user, but instead via the - cohomology ringof a- cell complex.- INPUT: - base_ring– must be a field
- cell_complex– the cell complex whose homology we are computing
- category– (optional) a subcategory of modules with basis
 - EXAMPLES: - sage: CP2 = simplicial_complexes.ComplexProjectivePlane() sage: H = CP2.cohomology_ring(QQ) sage: H.basis(2) Finite family {(2, 0): h^{2,0}} sage: x = H.basis(2)[2,0] - >>> from sage.all import * >>> CP2 = simplicial_complexes.ComplexProjectivePlane() >>> H = CP2.cohomology_ring(QQ) >>> H.basis(Integer(2)) Finite family {(2, 0): h^{2,0}} >>> x = H.basis(Integer(2))[Integer(2),Integer(0)] - The product structure is the cup product: - sage: x.cup_product(x) -h^{4,0} sage: x * x -h^{4,0} - >>> from sage.all import * >>> x.cup_product(x) -h^{4,0} >>> x * x -h^{4,0} - class Element[source]¶
- Bases: - Element- cup_product(other)[source]¶
- Return the cup product of this element and - other.- Algorithm: see González-Díaz and Réal [GDR2003], p. 88. Given two cohomology classes, lift them to cocycle representatives via the chain contraction for this complex, using - to_cycle(). In the sum of their dimensions, look at all of the homology classes \(\gamma\): lift each of those to a cycle representative, apply the Alexander-Whitney diagonal map to each cell in the cycle, evaluate the two cocycles on these factors, and multiply. The result is the value of the cup product cocycle on this homology class. After this has been done for all homology classes, since homology and cohomology are dual, one can tell which cohomology class corresponds to the cup product.- See also - EXAMPLES: - sage: RP3 = simplicial_complexes.RealProjectiveSpace(3) sage: H = RP3.cohomology_ring(GF(2)) sage: c = H.basis()[1,0] sage: c.cup_product(c) h^{2,0} sage: c * c * c h^{3,0} - >>> from sage.all import * >>> RP3 = simplicial_complexes.RealProjectiveSpace(Integer(3)) >>> H = RP3.cohomology_ring(GF(Integer(2))) >>> c = H.basis()[Integer(1),Integer(0)] >>> c.cup_product(c) h^{2,0} >>> c * c * c h^{3,0} - We can also take powers: - sage: RP2 = simplicial_complexes.RealProjectivePlane() sage: a = RP2.cohomology_ring(GF(2)).basis()[1,0] sage: a**0 h^{0,0} sage: a**1 h^{1,0} sage: a**2 h^{2,0} sage: a**3 0 - >>> from sage.all import * >>> RP2 = simplicial_complexes.RealProjectivePlane() >>> a = RP2.cohomology_ring(GF(Integer(2))).basis()[Integer(1),Integer(0)] >>> a**Integer(0) h^{0,0} >>> a**Integer(1) h^{1,0} >>> a**Integer(2) h^{2,0} >>> a**Integer(3) 0 - A non-connected example: - sage: K = cubical_complexes.Torus().disjoint_union(cubical_complexes.Sphere(2)) sage: a,b = K.cohomology_ring(QQ).basis(2) sage: a**0 h^{0,0} + h^{0,1} - >>> from sage.all import * >>> K = cubical_complexes.Torus().disjoint_union(cubical_complexes.Sphere(Integer(2))) >>> a,b = K.cohomology_ring(QQ).basis(Integer(2)) >>> a**Integer(0) h^{0,0} + h^{0,1} 
 
 - one()[source]¶
- The multiplicative identity element. - EXAMPLES: - sage: H = simplicial_complexes.Torus().cohomology_ring(QQ) sage: H.one() h^{0,0} sage: all(H.one() * x == x == x * H.one() for x in H.basis()) True - >>> from sage.all import * >>> H = simplicial_complexes.Torus().cohomology_ring(QQ) >>> H.one() h^{0,0} >>> all(H.one() * x == x == x * H.one() for x in H.basis()) True 
 - product_on_basis(li, ri)[source]¶
- The cup product of the basis elements indexed by - liand- riin this cohomology ring.- INPUT: - li,- ri– index of a cohomology class
 - See also - CohomologyRing.Element.cup_product()– the documentation for this method describes the algorithm.- EXAMPLES: - sage: RP3 = simplicial_complexes.RealProjectiveSpace(3) sage: H = RP3.cohomology_ring(GF(2)) sage: c = H.basis()[1,0] sage: c.cup_product(c).cup_product(c) # indirect doctest h^{3,0} sage: T = simplicial_complexes.Torus() sage: x,y = T.cohomology_ring(QQ).basis(1) sage: x.cup_product(y) -h^{2,0} sage: x.cup_product(x) 0 sage: one = T.cohomology_ring(QQ).basis()[0,0] sage: x.cup_product(one) h^{1,0} sage: one.cup_product(y) == y True sage: one.cup_product(one) h^{0,0} sage: x.cup_product(y) + y.cup_product(x) 0 - >>> from sage.all import * >>> RP3 = simplicial_complexes.RealProjectiveSpace(Integer(3)) >>> H = RP3.cohomology_ring(GF(Integer(2))) >>> c = H.basis()[Integer(1),Integer(0)] >>> c.cup_product(c).cup_product(c) # indirect doctest h^{3,0} >>> T = simplicial_complexes.Torus() >>> x,y = T.cohomology_ring(QQ).basis(Integer(1)) >>> x.cup_product(y) -h^{2,0} >>> x.cup_product(x) 0 >>> one = T.cohomology_ring(QQ).basis()[Integer(0),Integer(0)] >>> x.cup_product(one) h^{1,0} >>> one.cup_product(y) == y True >>> one.cup_product(one) h^{0,0} >>> x.cup_product(y) + y.cup_product(x) 0 - This also works with cubical complexes: - sage: T = cubical_complexes.Torus() sage: x,y = T.cohomology_ring(QQ).basis(1) sage: x.cup_product(y) h^{2,0} sage: x.cup_product(x) 0 - >>> from sage.all import * >>> T = cubical_complexes.Torus() >>> x,y = T.cohomology_ring(QQ).basis(Integer(1)) >>> x.cup_product(y) h^{2,0} >>> x.cup_product(x) 0 - \(\Delta\)-complexes: - sage: T_d = delta_complexes.Torus() sage: a,b = T_d.cohomology_ring(QQ).basis(1) sage: a.cup_product(b) h^{2,0} sage: b.cup_product(a) -h^{2,0} sage: RP2 = delta_complexes.RealProjectivePlane() sage: w = RP2.cohomology_ring(GF(2)).basis()[1,0] sage: w.cup_product(w) h^{2,0} - >>> from sage.all import * >>> T_d = delta_complexes.Torus() >>> a,b = T_d.cohomology_ring(QQ).basis(Integer(1)) >>> a.cup_product(b) h^{2,0} >>> b.cup_product(a) -h^{2,0} >>> RP2 = delta_complexes.RealProjectivePlane() >>> w = RP2.cohomology_ring(GF(Integer(2))).basis()[Integer(1),Integer(0)] >>> w.cup_product(w) h^{2,0} - and simplicial sets: - sage: from sage.topology.simplicial_set_examples import RealProjectiveSpace sage: RP5 = RealProjectiveSpace(5) # needs sage.groups sage: x = RP5.cohomology_ring(GF(2)).basis()[1,0] # needs sage.groups sage: x**4 # needs sage.groups h^{4,0} - >>> from sage.all import * >>> from sage.topology.simplicial_set_examples import RealProjectiveSpace >>> RP5 = RealProjectiveSpace(Integer(5)) # needs sage.groups >>> x = RP5.cohomology_ring(GF(Integer(2))).basis()[Integer(1),Integer(0)] # needs sage.groups >>> x**Integer(4) # needs sage.groups h^{4,0} - A non-connected example: - sage: K = cubical_complexes.Torus().disjoint_union(cubical_complexes.Torus()) sage: a,b,c,d = K.cohomology_ring(QQ).basis(1) sage: x,y = K.cohomology_ring(QQ).basis(0) sage: a.cup_product(x) == a True sage: a.cup_product(y) 0 - >>> from sage.all import * >>> K = cubical_complexes.Torus().disjoint_union(cubical_complexes.Torus()) >>> a,b,c,d = K.cohomology_ring(QQ).basis(Integer(1)) >>> x,y = K.cohomology_ring(QQ).basis(Integer(0)) >>> a.cup_product(x) == a True >>> a.cup_product(y) 0 
 
- class sage.homology.homology_vector_space_with_basis.CohomologyRing_mod2(base_ring, cell_complex)[source]¶
- Bases: - CohomologyRing- The mod 2 cohomology ring. - Based on - CohomologyRing, with Steenrod operations included.- Note - This is not intended to be created directly by the user, but instead via the - cohomology ringof a- cell complex.- Todo - Implement Steenrod operations on (co)homology at odd primes, and thereby implement this class over \(\GF{p}\) for any \(p\). - INPUT: - base_ring– must be the field- GF(2)
- cell_complex– the cell complex whose homology we are computing
 - EXAMPLES: - Mod 2 cohomology operations are defined on both the left and the right: - sage: CP2 = simplicial_complexes.ComplexProjectivePlane() sage: Hmod2 = CP2.cohomology_ring(GF(2)) sage: y = Hmod2.basis(2)[2,0] sage: y.Sq(2) h^{4,0} sage: # needs sage.groups sage: Y = simplicial_sets.RealProjectiveSpace(6).suspension() sage: H_Y = Y.cohomology_ring(GF(2)) sage: b = H_Y.basis()[2,0] sage: b.Sq(1) h^{3,0} sage: b.Sq(2) 0 sage: c = H_Y.basis()[4,0] sage: c.Sq(1) h^{5,0} sage: c.Sq(2) h^{6,0} sage: c.Sq(3) h^{7,0} sage: c.Sq(4) 0 - >>> from sage.all import * >>> CP2 = simplicial_complexes.ComplexProjectivePlane() >>> Hmod2 = CP2.cohomology_ring(GF(Integer(2))) >>> y = Hmod2.basis(Integer(2))[Integer(2),Integer(0)] >>> y.Sq(Integer(2)) h^{4,0} >>> # needs sage.groups >>> Y = simplicial_sets.RealProjectiveSpace(Integer(6)).suspension() >>> H_Y = Y.cohomology_ring(GF(Integer(2))) >>> b = H_Y.basis()[Integer(2),Integer(0)] >>> b.Sq(Integer(1)) h^{3,0} >>> b.Sq(Integer(2)) 0 >>> c = H_Y.basis()[Integer(4),Integer(0)] >>> c.Sq(Integer(1)) h^{5,0} >>> c.Sq(Integer(2)) h^{6,0} >>> c.Sq(Integer(3)) h^{7,0} >>> c.Sq(Integer(4)) 0 - Cohomology can be viewed as a left module over the Steenrod algebra, and also as a right module: - sage: # needs sage.groups sage: RP4 = simplicial_sets.RealProjectiveSpace(4) sage: H = RP4.cohomology_ring(GF(2)) sage: x = H.basis()[1,0] sage: Sq(0,1) * x h^{4,0} sage: Sq(3) * x 0 sage: x * Sq(3) h^{4,0} - >>> from sage.all import * >>> # needs sage.groups >>> RP4 = simplicial_sets.RealProjectiveSpace(Integer(4)) >>> H = RP4.cohomology_ring(GF(Integer(2))) >>> x = H.basis()[Integer(1),Integer(0)] >>> Sq(Integer(0),Integer(1)) * x h^{4,0} >>> Sq(Integer(3)) * x 0 >>> x * Sq(Integer(3)) h^{4,0} - class Element[source]¶
- Bases: - Element- Sq(i)[source]¶
- Return the result of applying \(Sq^i\) to this element. - INPUT: - i– nonnegative integer
 - Warning - The main implementation is only for simplicial complexes and simplicial sets; cubical complexes are converted to simplicial complexes first. Note that this converted complex may be large and so computations may be slow. There is no implementation for \(\Delta\)-complexes. - This cohomology operation is only defined in characteristic 2. Odd primary Steenrod operations are not implemented. - Algorithm: see González-Díaz and Réal [GDR1999], Corollary 3.2. - EXAMPLES: - sage: RP2 = simplicial_complexes.RealProjectiveSpace(2) sage: x = RP2.cohomology_ring(GF(2)).basis()[1,0] sage: x.Sq(1) h^{2,0} sage: K = RP2.suspension() sage: K.set_immutable() sage: y = K.cohomology_ring(GF(2)).basis()[2,0] sage: y.Sq(1) h^{3,0} sage: # long time sage: # needs sage.groups sage: RP4 = simplicial_complexes.RealProjectiveSpace(4) sage: H = RP4.cohomology_ring(GF(2)) sage: x = H.basis()[1,0] sage: y = H.basis()[2,0] sage: z = H.basis()[3,0] sage: x.Sq(1) == y True sage: z.Sq(1) h^{4,0} - >>> from sage.all import * >>> RP2 = simplicial_complexes.RealProjectiveSpace(Integer(2)) >>> x = RP2.cohomology_ring(GF(Integer(2))).basis()[Integer(1),Integer(0)] >>> x.Sq(Integer(1)) h^{2,0} >>> K = RP2.suspension() >>> K.set_immutable() >>> y = K.cohomology_ring(GF(Integer(2))).basis()[Integer(2),Integer(0)] >>> y.Sq(Integer(1)) h^{3,0} >>> # long time >>> # needs sage.groups >>> RP4 = simplicial_complexes.RealProjectiveSpace(Integer(4)) >>> H = RP4.cohomology_ring(GF(Integer(2))) >>> x = H.basis()[Integer(1),Integer(0)] >>> y = H.basis()[Integer(2),Integer(0)] >>> z = H.basis()[Integer(3),Integer(0)] >>> x.Sq(Integer(1)) == y True >>> z.Sq(Integer(1)) h^{4,0} - This calculation is much faster with simplicial sets (on one machine, 20 seconds with a simplicial complex, 4 ms with a simplicial set). - sage: RP4_ss = simplicial_sets.RealProjectiveSpace(4) # needs sage.groups sage: z_ss = RP4_ss.cohomology_ring(GF(2)).basis()[3,0] # needs sage.groups sage: z_ss.Sq(1) # needs sage.groups h^{4,0} - >>> from sage.all import * >>> RP4_ss = simplicial_sets.RealProjectiveSpace(Integer(4)) # needs sage.groups >>> z_ss = RP4_ss.cohomology_ring(GF(Integer(2))).basis()[Integer(3),Integer(0)] # needs sage.groups >>> z_ss.Sq(Integer(1)) # needs sage.groups h^{4,0} 
 
 - steenrod_module_map(deg_domain, deg_codomain, side='left')[source]¶
- Return a component of the module structure map \(A \otimes H \to H\), where \(H\) is this cohomology ring and \(A\) is the Steenrod algebra. - INPUT: - deg_domain– the degree of the domain in the cohomology ring
- deg_codomain– the degree of the codomain in the cohomology ring
- side– (default:- 'left') whether we are computing the action as a left module action or a right module
 - We will write this with respect to the left action; for the right action, just switch all of the tensors. Writing \(m\) for - deg_domainand \(n\) for- deg_codomain, this returns \(A^{n-m} \otimes H^{m} \to H^{n}\), one single component of the map making \(H\) into an \(A\)-module.- Warning - This is only implemented in characteristic two. The main implementation is only for simplicial complexes and simplicial sets; cubical complexes are converted to simplicial complexes first. Note that this converted complex may be large and so computations may be slow. There is no implementation for \(\Delta\)-complexes. - ALGORITHM: - Use the Milnor basis for the truncated Steenrod algebra \(A\), and for cohomology, use the basis with which it is equipped. For each pair of basis elements \(a\) and \(h\), compute the product \(a \otimes h\), and use this to assemble a matrix defining the action map via multiplication on the appropriate side. That is, if - sideis- 'left', return a matrix suitable for multiplication on the left, etc.- EXAMPLES: - sage: # needs sage.groups sage: RP4 = simplicial_sets.RealProjectiveSpace(4) sage: H = RP4.cohomology_ring(GF(2)) sage: H.steenrod_module_map(1, 2) [1] sage: H.steenrod_module_map(1, 3) [0] sage: H.steenrod_module_map(1, 4, 'left') [1 0] sage: H.steenrod_module_map(1, 4, 'right') [1] [1] - >>> from sage.all import * >>> # needs sage.groups >>> RP4 = simplicial_sets.RealProjectiveSpace(Integer(4)) >>> H = RP4.cohomology_ring(GF(Integer(2))) >>> H.steenrod_module_map(Integer(1), Integer(2)) [1] >>> H.steenrod_module_map(Integer(1), Integer(3)) [0] >>> H.steenrod_module_map(Integer(1), Integer(4), 'left') [1 0] >>> H.steenrod_module_map(Integer(1), Integer(4), 'right') [1] [1] - Products of projective spaces: - sage: RP3 = simplicial_sets.RealProjectiveSpace(3) sage: K = RP3.product(RP3) sage: H = K.cohomology_ring(GF(2)) sage: H Cohomology ring of RP^3 x RP^3 over Finite Field of size 2 - >>> from sage.all import * >>> RP3 = simplicial_sets.RealProjectiveSpace(Integer(3)) >>> K = RP3.product(RP3) >>> H = K.cohomology_ring(GF(Integer(2))) >>> H Cohomology ring of RP^3 x RP^3 over Finite Field of size 2 - There is one column for each element \(a \otimes b\), where \(a\) is a basis element for the Steenrod algebra and \(b\) is a basis element for the cohomology algebra. There is one row for each basis element of the cohomology algebra. Unfortunately, the chosen basis for this truncated polynomial algebra is not the monomial basis: - sage: x1, x2 = H.basis(1) sage: x1 * x1 h^{2,0} + h^{2,1} sage: x2 * x2 h^{2,2} sage: x1 * x2 h^{2,0} sage: H.steenrod_module_map(1, 2) [1 0] [1 0] [0 1] sage: H.steenrod_module_map(1, 3, 'left') [0 0] [0 0] [0 0] [0 0] sage: H.steenrod_module_map(1, 3, 'right') [0 0 0 0] [0 0 0 0] sage: H.steenrod_module_map(2, 3) [0 0 0] [1 1 0] [0 0 0] [0 0 0] - >>> from sage.all import * >>> x1, x2 = H.basis(Integer(1)) >>> x1 * x1 h^{2,0} + h^{2,1} >>> x2 * x2 h^{2,2} >>> x1 * x2 h^{2,0} >>> H.steenrod_module_map(Integer(1), Integer(2)) [1 0] [1 0] [0 1] >>> H.steenrod_module_map(Integer(1), Integer(3), 'left') [0 0] [0 0] [0 0] [0 0] >>> H.steenrod_module_map(Integer(1), Integer(3), 'right') [0 0 0 0] [0 0 0 0] >>> H.steenrod_module_map(Integer(2), Integer(3)) [0 0 0] [1 1 0] [0 0 0] [0 0 0] 
 
- class sage.homology.homology_vector_space_with_basis.HomologyVectorSpaceWithBasis(base_ring, cell_complex, cohomology=False, category=None)[source]¶
- Bases: - CombinatorialFreeModule- Homology (or cohomology) vector space. - This provides enough structure to allow the computation of cup products and cohomology operations. See the class - CohomologyRing(which derives from this) for examples.- It also requires field coefficients (hence the “VectorSpace” in the name of the class). - Note - This is not intended to be created directly by the user, but instead via the methods - homology_with_basis()and- cohomology_ring()for the class of- cell complexes.- INPUT: - base_ring– must be a field
- cell_complex– the cell complex whose homology we are computing
- cohomology– boolean (default:- False); if- True, return the cohomology as a module
- category– (optional) a subcategory of modules with basis
 - EXAMPLES: - Homology classes are denoted by - h_{d,i}where- dis the degree of the homology class and- iis their index in the list of basis elements in that degree. Cohomology classes are denoted- h^{1,0}:- sage: RP2 = cubical_complexes.RealProjectivePlane() sage: RP2.homology_with_basis(GF(2)) Homology module of Cubical complex with 21 vertices and 81 cubes over Finite Field of size 2 sage: RP2.cohomology_ring(GF(2)) Cohomology ring of Cubical complex with 21 vertices and 81 cubes over Finite Field of size 2 sage: simplicial_complexes.Torus().homology_with_basis(QQ) Homology module of Minimal triangulation of the torus over Rational Field - >>> from sage.all import * >>> RP2 = cubical_complexes.RealProjectivePlane() >>> RP2.homology_with_basis(GF(Integer(2))) Homology module of Cubical complex with 21 vertices and 81 cubes over Finite Field of size 2 >>> RP2.cohomology_ring(GF(Integer(2))) Cohomology ring of Cubical complex with 21 vertices and 81 cubes over Finite Field of size 2 >>> simplicial_complexes.Torus().homology_with_basis(QQ) Homology module of Minimal triangulation of the torus over Rational Field - To access a basis element, use its degree and index (0 or 1 in the 1st cohomology group of a torus): - sage: H = simplicial_complexes.Torus().cohomology_ring(QQ) sage: H.basis(1) Finite family {(1, 0): h^{1,0}, (1, 1): h^{1,1}} sage: x = H.basis()[1,0]; x h^{1,0} sage: y = H.basis()[1,1]; y h^{1,1} sage: 2*x-3*y 2*h^{1,0} - 3*h^{1,1} - >>> from sage.all import * >>> H = simplicial_complexes.Torus().cohomology_ring(QQ) >>> H.basis(Integer(1)) Finite family {(1, 0): h^{1,0}, (1, 1): h^{1,1}} >>> x = H.basis()[Integer(1),Integer(0)]; x h^{1,0} >>> y = H.basis()[Integer(1),Integer(1)]; y h^{1,1} >>> Integer(2)*x-Integer(3)*y 2*h^{1,0} - 3*h^{1,1} - You can compute cup products of cohomology classes: - sage: x.cup_product(y) -h^{2,0} sage: y.cup_product(x) h^{2,0} sage: x.cup_product(x) 0 - >>> from sage.all import * >>> x.cup_product(y) -h^{2,0} >>> y.cup_product(x) h^{2,0} >>> x.cup_product(x) 0 - This works with simplicial, cubical, and \(\Delta\)-complexes, and also simplicial sets: - sage: Torus_c = cubical_complexes.Torus() sage: H = Torus_c.cohomology_ring(GF(2)) sage: x,y = H.basis(1) sage: x.cup_product(x) 0 sage: x.cup_product(y) h^{2,0} sage: y.cup_product(y) 0 sage: Klein_d = delta_complexes.KleinBottle() sage: H = Klein_d.cohomology_ring(GF(2)) sage: u,v = sorted(H.basis(1)) sage: u.cup_product(u) h^{2,0} sage: u.cup_product(v) 0 sage: v.cup_product(v) h^{2,0} - >>> from sage.all import * >>> Torus_c = cubical_complexes.Torus() >>> H = Torus_c.cohomology_ring(GF(Integer(2))) >>> x,y = H.basis(Integer(1)) >>> x.cup_product(x) 0 >>> x.cup_product(y) h^{2,0} >>> y.cup_product(y) 0 >>> Klein_d = delta_complexes.KleinBottle() >>> H = Klein_d.cohomology_ring(GF(Integer(2))) >>> u,v = sorted(H.basis(Integer(1))) >>> u.cup_product(u) h^{2,0} >>> u.cup_product(v) 0 >>> v.cup_product(v) h^{2,0} - An isomorphism between the rings for the cubical model and the \(\Delta\)-complex model can be obtained by sending \(x\) to \(u+v\), \(y\) to \(v\). - sage: # needs sage.groups sage: X = simplicial_sets.RealProjectiveSpace(6) sage: H_X = X.cohomology_ring(GF(2)) sage: a = H_X.basis()[1,0] sage: a**6 h^{6,0} sage: a**7 0 - >>> from sage.all import * >>> # needs sage.groups >>> X = simplicial_sets.RealProjectiveSpace(Integer(6)) >>> H_X = X.cohomology_ring(GF(Integer(2))) >>> a = H_X.basis()[Integer(1),Integer(0)] >>> a**Integer(6) h^{6,0} >>> a**Integer(7) 0 - All products of positive-dimensional elements in a suspension should be zero: - sage: # needs sage.groups sage: Y = X.suspension() sage: H_Y = Y.cohomology_ring(GF(2)) sage: b = H_Y.basis()[2,0] sage: b**2 0 sage: B = sorted(H_Y.basis())[1:] sage: B [h^{2,0}, h^{3,0}, h^{4,0}, h^{5,0}, h^{6,0}, h^{7,0}] sage: import itertools sage: [a*b for (a,b) in itertools.combinations(B, 2)] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - >>> from sage.all import * >>> # needs sage.groups >>> Y = X.suspension() >>> H_Y = Y.cohomology_ring(GF(Integer(2))) >>> b = H_Y.basis()[Integer(2),Integer(0)] >>> b**Integer(2) 0 >>> B = sorted(H_Y.basis())[Integer(1):] >>> B [h^{2,0}, h^{3,0}, h^{4,0}, h^{5,0}, h^{6,0}, h^{7,0}] >>> import itertools >>> [a*b for (a,b) in itertools.combinations(B, Integer(2))] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - The basis elements in the simplicial complex case have been chosen differently; apply the change of basis \(x \mapsto a + b\), \(y \mapsto b\) to see the same product structure. - sage: Klein_s = simplicial_complexes.KleinBottle() sage: H = Klein_s.cohomology_ring(GF(2)) sage: a,b = H.basis(1) sage: a.cup_product(a) 0 sage: a.cup_product(b) h^{2,0} sage: (a+b).cup_product(a+b) h^{2,0} sage: b.cup_product(b) h^{2,0} - >>> from sage.all import * >>> Klein_s = simplicial_complexes.KleinBottle() >>> H = Klein_s.cohomology_ring(GF(Integer(2))) >>> a,b = H.basis(Integer(1)) >>> a.cup_product(a) 0 >>> a.cup_product(b) h^{2,0} >>> (a+b).cup_product(a+b) h^{2,0} >>> b.cup_product(b) h^{2,0} - class Element[source]¶
- Bases: - IndexedFreeModuleElement- eval(other)[source]¶
- Evaluate - selfat- other.- INPUT: - other– an element of the dual space; if- selfis an element of cohomology in dimension \(n\), then- othershould be an element of homology in dimension \(n\), and vice versa
 - This just calls the - eval()method on the representing chains and cochains.- EXAMPLES: - sage: T = simplicial_complexes.Torus() sage: homology = T.homology_with_basis(QQ) sage: cohomology = T.cohomology_ring(QQ) sage: a1, a2 = homology.basis(1) sage: alpha1, alpha2 = cohomology.basis(1) sage: a1.to_cycle() (0, 3) - (0, 6) + (3, 6) sage: alpha1.to_cycle() -\chi_(1, 3) - \chi_(1, 4) - \chi_(2, 3) - \chi_(2, 4) - \chi_(2, 5) + \chi_(3, 6) sage: a1.eval(alpha1) 1 sage: alpha2.to_cycle() \chi_(1, 3) + \chi_(1, 4) + \chi_(1, 6) + \chi_(2, 4) - \chi_(4, 5) + \chi_(5, 6) sage: alpha2.eval(a1) 0 sage: (2 * alpha2).eval(a1 + a2) 2 - >>> from sage.all import * >>> T = simplicial_complexes.Torus() >>> homology = T.homology_with_basis(QQ) >>> cohomology = T.cohomology_ring(QQ) >>> a1, a2 = homology.basis(Integer(1)) >>> alpha1, alpha2 = cohomology.basis(Integer(1)) >>> a1.to_cycle() (0, 3) - (0, 6) + (3, 6) >>> alpha1.to_cycle() -\chi_(1, 3) - \chi_(1, 4) - \chi_(2, 3) - \chi_(2, 4) - \chi_(2, 5) + \chi_(3, 6) >>> a1.eval(alpha1) 1 >>> alpha2.to_cycle() \chi_(1, 3) + \chi_(1, 4) + \chi_(1, 6) + \chi_(2, 4) - \chi_(4, 5) + \chi_(5, 6) >>> alpha2.eval(a1) 0 >>> (Integer(2) * alpha2).eval(a1 + a2) 2 
 - to_cycle()[source]¶
- (Co)cycle representative of this homogeneous (co)homology class. - EXAMPLES: - sage: S2 = simplicial_complexes.Sphere(2) sage: H = S2.homology_with_basis(QQ) sage: h20 = H.basis()[2,0]; h20 h_{2,0} sage: h20.to_cycle() -(0, 1, 2) + (0, 1, 3) - (0, 2, 3) + (1, 2, 3) - >>> from sage.all import * >>> S2 = simplicial_complexes.Sphere(Integer(2)) >>> H = S2.homology_with_basis(QQ) >>> h20 = H.basis()[Integer(2),Integer(0)]; h20 h_{2,0} >>> h20.to_cycle() -(0, 1, 2) + (0, 1, 3) - (0, 2, 3) + (1, 2, 3) - Chains are written as linear combinations of simplices \(\sigma\). Cochains are written as linear combinations of characteristic functions \(\chi_{\sigma}\) for those simplices: - sage: S2.cohomology_ring(QQ).basis()[2,0].to_cycle() \chi_(1, 2, 3) sage: S2.cohomology_ring(QQ).basis()[0,0].to_cycle() \chi_(0,) + \chi_(1,) + \chi_(2,) + \chi_(3,) - >>> from sage.all import * >>> S2.cohomology_ring(QQ).basis()[Integer(2),Integer(0)].to_cycle() \chi_(1, 2, 3) >>> S2.cohomology_ring(QQ).basis()[Integer(0),Integer(0)].to_cycle() \chi_(0,) + \chi_(1,) + \chi_(2,) + \chi_(3,) 
 
 - basis(d=None)[source]¶
- Return (the degree - dhomogeneous component of) the basis of this graded vector space.- INPUT: - d– (optional) the degree
 - EXAMPLES: - sage: RP2 = simplicial_complexes.ProjectivePlane() sage: H = RP2.homology_with_basis(QQ) sage: H.basis() Finite family {(0, 0): h_{0,0}} sage: H.basis(0) Finite family {(0, 0): h_{0,0}} sage: H.basis(1) Finite family {} sage: H.basis(2) Finite family {} - >>> from sage.all import * >>> RP2 = simplicial_complexes.ProjectivePlane() >>> H = RP2.homology_with_basis(QQ) >>> H.basis() Finite family {(0, 0): h_{0,0}} >>> H.basis(Integer(0)) Finite family {(0, 0): h_{0,0}} >>> H.basis(Integer(1)) Finite family {} >>> H.basis(Integer(2)) Finite family {} 
 - complex()[source]¶
- The cell complex whose homology is being computed. - EXAMPLES: - sage: H = simplicial_complexes.Simplex(2).homology_with_basis(QQ) sage: H.complex() The 2-simplex - >>> from sage.all import * >>> H = simplicial_complexes.Simplex(Integer(2)).homology_with_basis(QQ) >>> H.complex() The 2-simplex 
 - contraction()[source]¶
- The chain contraction associated to this homology computation. - That is, to work with chain representatives of homology classes, we need the chain complex \(C\) associated to the cell complex, the chain complex \(H\) of its homology (with trivial differential), chain maps \(\pi: C \to H\) and \(\iota: H \to C\), and a chain contraction \(\phi\) giving a chain homotopy between \(1_C\) and \(\iota \circ \pi\). - OUTPUT: \(\phi\) - See - ChainContractionfor information about chain contractions, and see- algebraic_topological_model()for the construction of this particular chain contraction \(\phi\).- EXAMPLES: - sage: H = simplicial_complexes.Simplex(2).homology_with_basis(QQ) sage: H.contraction() Chain homotopy between: Chain complex endomorphism of Chain complex with at most 3 nonzero terms over Rational Field and Chain complex endomorphism of Chain complex with at most 3 nonzero terms over Rational Field - >>> from sage.all import * >>> H = simplicial_complexes.Simplex(Integer(2)).homology_with_basis(QQ) >>> H.contraction() Chain homotopy between: Chain complex endomorphism of Chain complex with at most 3 nonzero terms over Rational Field and Chain complex endomorphism of Chain complex with at most 3 nonzero terms over Rational Field - From the chain contraction, one can also recover the maps \(\pi\) and \(\iota\): - sage: phi = H.contraction() sage: phi.pi() Chain complex morphism: From: Chain complex with at most 3 nonzero terms over Rational Field To: Chain complex with at most 1 nonzero terms over Rational Field sage: phi.iota() Chain complex morphism: From: Chain complex with at most 1 nonzero terms over Rational Field To: Chain complex with at most 3 nonzero terms over Rational Field - >>> from sage.all import * >>> phi = H.contraction() >>> phi.pi() Chain complex morphism: From: Chain complex with at most 3 nonzero terms over Rational Field To: Chain complex with at most 1 nonzero terms over Rational Field >>> phi.iota() Chain complex morphism: From: Chain complex with at most 1 nonzero terms over Rational Field To: Chain complex with at most 3 nonzero terms over Rational Field 
 - degree_on_basis(i)[source]¶
- Return the degree of the basis element indexed by - i.- EXAMPLES: - sage: H = simplicial_complexes.Torus().homology_with_basis(GF(7)) sage: H.degree_on_basis((2,0)) 2 - >>> from sage.all import * >>> H = simplicial_complexes.Torus().homology_with_basis(GF(Integer(7))) >>> H.degree_on_basis((Integer(2),Integer(0))) 2 
 - dual()[source]¶
- Return the dual space. - If - selfis homology, return the cohomology ring. If- selfis cohomology, return the homology as a vector space.- EXAMPLES: - sage: T = simplicial_complexes.Torus() sage: hom = T.homology_with_basis(GF(2)) sage: coh = T.cohomology_ring(GF(2)) sage: hom.dual() is coh True sage: coh.dual() is hom True - >>> from sage.all import * >>> T = simplicial_complexes.Torus() >>> hom = T.homology_with_basis(GF(Integer(2))) >>> coh = T.cohomology_ring(GF(Integer(2))) >>> hom.dual() is coh True >>> coh.dual() is hom True 
 
- class sage.homology.homology_vector_space_with_basis.HomologyVectorSpaceWithBasis_mod2(base_ring, cell_complex, category=None)[source]¶
- Bases: - HomologyVectorSpaceWithBasis- Homology vector space mod 2. - Based on - HomologyVectorSpaceWithBasis, with Steenrod operations included.- Note - This is not intended to be created directly by the user, but instead via the method - homology_with_basis()for the class of- cell complexes.- Todo - Implement Steenrod operations on (co)homology at odd primes, and thereby implement this class over \(\GF{p}\) for any \(p\). - INPUT: - base_ring– must be the field- GF(2)
- cell_complex– the cell complex whose homology we are computing
- category– (optional) a subcategory of modules with basis
 - This does not include the - cohomologyargument present for- HomologyVectorSpaceWithBasis: use- CohomologyRing_mod2for cohomology.- EXAMPLES: - Mod 2 cohomology operations are defined on both the left and the right: - sage: # needs sage.groups sage: RP4 = simplicial_sets.RealProjectiveSpace(5) sage: H = RP4.homology_with_basis(GF(2)) sage: x4 = H.basis()[4,0] sage: x4 * Sq(1) h_{3,0} sage: Sq(1) * x4 h_{3,0} sage: Sq(2) * x4 h_{2,0} sage: Sq(3) * x4 h_{1,0} sage: Sq(0,1) * x4 h_{1,0} sage: x4 * Sq(0,1) h_{1,0} sage: Sq(3) * x4 h_{1,0} sage: x4 * Sq(3) 0 - >>> from sage.all import * >>> # needs sage.groups >>> RP4 = simplicial_sets.RealProjectiveSpace(Integer(5)) >>> H = RP4.homology_with_basis(GF(Integer(2))) >>> x4 = H.basis()[Integer(4),Integer(0)] >>> x4 * Sq(Integer(1)) h_{3,0} >>> Sq(Integer(1)) * x4 h_{3,0} >>> Sq(Integer(2)) * x4 h_{2,0} >>> Sq(Integer(3)) * x4 h_{1,0} >>> Sq(Integer(0),Integer(1)) * x4 h_{1,0} >>> x4 * Sq(Integer(0),Integer(1)) h_{1,0} >>> Sq(Integer(3)) * x4 h_{1,0} >>> x4 * Sq(Integer(3)) 0 
- sage.homology.homology_vector_space_with_basis.is_GF2(R)[source]¶
- Return - Trueiff- Ris isomorphic to the field \(\GF{2}\).- EXAMPLES: - sage: from sage.homology.homology_vector_space_with_basis import is_GF2 sage: is_GF2(GF(2)) True sage: is_GF2(GF(2, impl='ntl')) True sage: is_GF2(GF(3)) False - >>> from sage.all import * >>> from sage.homology.homology_vector_space_with_basis import is_GF2 >>> is_GF2(GF(Integer(2))) True >>> is_GF2(GF(Integer(2), impl='ntl')) True >>> is_GF2(GF(Integer(3))) False 
- sage.homology.homology_vector_space_with_basis.sum_indices(k, i_k_plus_one, S_k_plus_one)[source]¶
- This is a recursive function for computing the indices for the nested sums in González-Díaz and Réal [GDR1999], Corollary 3.2. - In the paper, given indices \(i_n\), \(i_{n-1}\), …, \(i_{k+1}\), given \(k\), and given \(S(k+1)\), the number \(S(k)\) is defined to be \[S(k) = -S(k+1) + floor(k/2) + floor((k+1)/2) + i_{k+1},\]- and \(i_k\) ranges from \(S(k)\) to \(i_{k+1}-1\). There are two special cases: if \(k=0\), then \(i_0 = S(0)\). Also, the initial case of \(S(k)\) is \(S(n)\), which is set in the method - Sq()before calling this function. For this function, given \(k\), \(i_{k+1}\), and \(S(k+1)\), return a list consisting of the allowable possible indices \([i_k, i_{k-1}, ..., i_1, i_0]\) given by the above formula.- INPUT: - k– nonnegative integer
- i_k_plus_one– the positive integer \(i_{k+1}\)
- S_k_plus_one– the integer \(S(k+1)\)
 - EXAMPLES: - sage: from sage.homology.homology_vector_space_with_basis import sum_indices sage: sum_indices(1, 3, 3) [[1, 0], [2, 1]] sage: sum_indices(0, 4, 2) [[2]] - >>> from sage.all import * >>> from sage.homology.homology_vector_space_with_basis import sum_indices >>> sum_indices(Integer(1), Integer(3), Integer(3)) [[1, 0], [2, 1]] >>> sum_indices(Integer(0), Integer(4), Integer(2)) [[2]]