The ChainCon Software (Release 0.03)
ssquaressim.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file
4 ///
5 /// Computation of the Steenrod squares for simplicial cells.
6 ///
7 /////////////////////////////////////////////////////////////////////////////
8 
9 // Copyright (C) 2009-2016 by Pawel Pilarczyk.
10 //
11 // This file is part of my research software package. This is free software:
12 // you can redistribute it and/or modify it under the terms of the GNU
13 // General Public License as published by the Free Software Foundation,
14 // either version 3 of the License, or (at your option) any later version.
15 //
16 // This software is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this software; see the file "license.txt". If not,
23 // please, see <http://www.gnu.org/licenses/>.
24 
25 // Started on July 4, 2013. Last revision: December 10, 2015.
26 
27 
28 #ifndef _CHAINCON_SSQUARESSIM_H_
29 #define _CHAINCON_SSQUARESSIM_H_
30 
31 
32 // include some standard C++ header files
33 #include <istream>
34 #include <ostream>
35 #include <vector>
36 //#include <algorithm>
37 
38 // include selected header files from the CHomP library
39 #include "chomp/system/config.h"
40 #include "chomp/struct/hashsets.h"
41 #include "chomp/struct/multitab.h"
42 
43 // include relevant local header files
44 #include "chaincon/chain.h"
45 #include "chaincon/tensor.h"
46 #include "chaincon/linmap.h"
47 #include "chaincon/pair.h"
48 #include "chaincon/prodcell.h"
49 #include "chaincon/ez_aw.h"
50 //#include "chaincon/ez_eml.h"
51 #include "chaincon/ez_shi.h"
52 
53 
54 // --------------------------------------------------
55 // -------------- auxiliary procedures --------------
56 // --------------------------------------------------
57 
58 /// Swaps the components of all of the product cells in the chain.
59 /// Adds the result to the resulting chain (which is assumed to be empty).
60 /// Corresponds to the operator "t" in [CombSteenSq], pg. 94, for p=2.
61 template <class ProdCellT, class CoefT>
62 inline void swapProduct (const tChain<ProdCellT,CoefT> &input,
64 {
65  int_t length (input. size ());
66  for (int_t i = 0; i < length; ++ i)
67  {
68  result. add (ProdCellT (input. getCell (i). getRight (),
69  input. getCell (i). getLeft ()),
70  input. getCoef (i));
71  }
72  return;
73 } /* swapProduct */
74 
75 /// Computes the diagonal of a chain.
76 /// This corresponds to "(x,x)" in [CombSteenSq], pg. 95, formula (3).
77 template <class CellT, class ProdCellT, class CoefT>
78 inline void computeDiagonal (const tChain<CellT,CoefT> &x,
80 {
81  int_t xSize = x. size ();
82  for (int_t i = 0; i < xSize; ++ i)
83  {
84  const CellT &xCell (x. getCell (i));
85  const CoefT &xCoef (x. getCoef (i));
86  result. add (ProdCellT (xCell, xCell), xCoef);
87  }
88  return;
89 } /* computeDiagonal */
90 
91 /// Converts a chain of cells encoded as trivial product cells
92 /// to the chain of the actual cells.
93 template <class CellT, class ProdCellT, class CoefT>
94 inline void flattenProduct (const tChain<ProdCellT,CoefT> &chain,
95  tChain<CellT,CoefT> &result)
96 {
97  int_t size (chain. size ());
98  for (int_t i = 0; i < size; ++ i)
99  {
100  result. add (chain. getCell (i). getCell (),
101  chain. getCoef (i));
102  }
103  return;
104 } /* flattenProduct */
105 
106 /// Converts a chain of cells encoded as trivial product cells
107 /// to the chain of the actual cells.
108 template <class Cell1T, class Cell2T, class ProdCell1T, class ProdCell2T,
109  class CoefT>
110 inline void flattenProduct
113 {
114  int_t size (tensor. size ());
115  for (int_t i = 0; i < size; ++ i)
116  {
117  result. add (tensor. left (i). getCell (),
118  tensor. right (i). getCell (),
119  tensor. coef (i));
120  }
121  return;
122 } /* flattenProduct */
123 
124 
125 // --------------------------------------------------
126 // ---------------- Steenrod squares ----------------
127 // --------------------------------------------------
128 
129 /// Computes the Steenrod squares, given a minimal model
130 /// and cohomology representants. For cells of simplicial type.
131 /// Please, make sure to include the appropriate header file with the
132 /// definition of the Alexander-Whitney diagonal for the cells in use
133 /// before including the header file containing this procedure.
134 /// Follows Equation (3) in [CombSteenSq], pg. 95.
135 /// Warning: This procedure is very inefficient.
136 /// Please, use "ssquares2" instead.
137 template <class SimCellT, class CoefT>
138 inline void ssquares1
139  (const std::vector<std::vector<SimCellT> > &cohomRepresentants,
142  chomp::homology::hashedset<tPair<SimCellT,int> > &cellsSquares,
143  chomp::homology::multitable<tChain<SimCellT,CoefT> > &squareValues)
144 {
145  using chomp::homology::sbug;
146 
147  typedef tPair<SimCellT,int> CellSquareT;
148  typedef tProdCell<SimCellT> ProdCellT;
149 
150  // go through all the cohomology levels
151  int maxDim = cohomRepresentants. size ();
152  for (int dim = 0; dim < maxDim; ++ dim)
153  {
154  // show a progress indicator
155  // sbug << "DEBUG: ====== Considering dim " << dim << "...\n";
156 
157  // consider all the cohomology representants of the given dimension
158  int size = cohomRepresentants [dim]. size ();
159  for (int n = 0; n < size; ++ n)
160  {
161  // take a cell that represents the cohomology generator
162  const SimCellT &xCell (cohomRepresentants [dim] [n]);
163  // sbug << "DEBUG: xCell " << xCell << ".\n";
164 
165  // show a progress indicator
166  // sbug << "DEBUG: ==== Considering " << xCell <<
167  // "... ====\n";
168 
169  // compute (x, x), the diagonal Delta on the cycle x
170  // corresponding to this cohomology representant
171  tChain<SimCellT,CoefT> xChain (incl (xCell));
173  computeDiagonal (xChain, xx);
174  // sbug << "DEBUG: xChain = " << xChain << "\n";
175  // sbug << "DEBUG: Delta (xChain) = " << xx << "\n";
176 
177  // compute the components of all the i-th Steenrod squares
178  for (int k = 0; k <= dim; ++ k)
179  {
180  // apply the composition of t with EZ_SHI
181  // for the next round
182  if (k)
183  {
184  // sbug << "DEBUG: xx = " << xx << ".\n";
186  EZ_SHI (xx, shi_xx);
187  // sbug << "DEBUG: SHI (xx) = " << shi_xx << ".\n";
189  xx. swap (empty);
190  swapProduct (shi_xx, xx);
191  // sbug << "DEBUG: swapped = " << xx << ".\n";
192  }
193 
194  // if the parity of "k" is different from the parity
195  // of "dim" then skip this combination
196  if ((k + dim) & 1)
197  continue;
198 
199  // calculate the corresponding i and j
200  int squareOrder = (dim - k) / 2;
201  int dim1 = (dim + k) / 2;
202 
203  // show a progress indicator
204  // sbug << "DEBUG: === Computing for k = " <<
205  // k << " (i=" << squareOrder <<
206  // ", j=" << dim1 <<
207  // ")... ===\n";
208 
209  // apply the AW operator
211  EZ_AW (xx, awdiagProd);
213  flattenProduct (awdiagProd, awdiagFull);
214  // sbug << "DEBUG: awdiagFull = " << awdiagFull << ".\n";
215 
216  // project the computed tensor to the model
217  tTensor<SimCellT,SimCellT,CoefT> awdiag (pi (awdiagFull));
218  int_t awdiagSize = awdiag. size ();
219  // sbug << "DEBUG: awdiag = " << awdiag << ".\n";
220 
221  // consider all the cohomology representants
222  // that may appear in the computed formula
223  int size1 = cohomRepresentants [dim1]. size ();
224  for (int i1 = 0; i1 < size1; ++ i1)
225  {
226  const SimCellT &cell1 =
227  cohomRepresentants [dim1] [i1];
228  for (int_t j = 0; j < awdiagSize; ++ j)
229  {
230  if (!(awdiag. left (j) == cell1))
231  continue;
232  if (!(awdiag. right (j) == cell1))
233  continue;
234  CoefT coef (awdiag. coef (j));
235  if (coef == 0)
236  continue;
237  int_t n = cellsSquares. add
238  (CellSquareT (cell1, squareOrder));
239  // sbug << "DEBUG: Sq^" << squareOrder <<
240  // " (" << cell1 << ") += " <<
241  // coef << " * " << xCell << ".\n";
242  // sbug << "DEBUG: pi (awdiag) = " << awdiag << ".\n";
243  // sbug << "DEBUG: cChain = " << incl (cell1) << ".\n";
244  // sbug << "DEBUG: xChain = " << xChain << ".\n";
245  // sbug << "DEBUG: awdiagFull = " << awdiagFull << ".\n";
246  squareValues [n]. add (xCell, coef);
247  }
248  }
249  }
250  }
251  }
252 
253  return;
254 } /* ssquares1 */
255 
256 /// Computes the k-th value of the index S in the sum ranges
257 /// defined in Corollary 3.2 in [CombSteenSq], pg. 97.
258 inline int ssquare_S (int k, const std::vector<int> &ii, int n, int m)
259 {
260  using chomp::homology::sbug;
261 
262  int S (0);
263  bool add = true;
264  for (int a = k + 1; a <= n; ++ a)
265  {
266  if (add)
267  S += ii [a];
268  else
269  S -= ii [a];
270  add = !add;
271  }
272  if (!((k + n) & 1))
273  S += (m + 1) / 2;
274  else
275  S -= (m + 1) / 2;
276  S += k / 2;
277  if (S < 0)
278  throw "A negative value of S detected.";
279  return S;
280 } /* ssquare_S */
281 
282 /// Computes the faces of a simplicial cell. The faces appear
283 /// in the formulas in Corollary 3.2 in [CombSteenSq], pg. 97.
284 template <class SimCellT>
285 inline SimCellT ssquare_face (const SimCellT &xCell,
286  const std::vector<int> &ii, int n, int m, bool right_hand_side)
287 {
288  using chomp::homology::sbug;
289 
290  SimCellT face (xCell);
291 
292  // if i+j is even (and so is i-j)
293  if (!(m & 1))
294  {
295  // the first cell
296  if (!right_hand_side)
297  {
298  for (int a = n; a >= 0; a -= 2)
299  {
300  for (int b = ((a == n) ? m : (ii [a + 1] - 1));
301  b >= (ii [a] + 1); -- b)
302  {
303  face = SimCellT (face, b);
304  }
305  }
306  }
307  // the second cell
308  else
309  {
310  for (int a = n; a >= 0; a -= 2)
311  {
312  for (int b = ii [a] - 1; b >=
313  ((a == 0) ? 0 : (ii [a - 1] + 1));
314  -- b)
315  {
316  face = SimCellT (face, b);
317  }
318  }
319  }
320  }
321  // if i+j is odd (and so is i-j)
322  else
323  {
324  // the third cell
325  if (!right_hand_side)
326  {
327  for (int a = n; a >= 1; a -= 2)
328  {
329  for (int b = (ii [a] - 1);
330  b >= (ii [a - 1] + 1); -- b)
331  {
332  face = SimCellT (face, b);
333  }
334  }
335  }
336  // the fourth cell
337  else
338  {
339  for (int a = n; a >= -1; a -= 2)
340  {
341  for (int b = ((a == n) ? m : (ii [a + 1] - 1));
342  b >= ((a == -1) ? 0 : (ii [a] + 1));
343  -- b)
344  {
345  face = SimCellT (face, b);
346  }
347  }
348  }
349  }
350 
351  return face;
352 } /* ssquare_face */
353 
354 /// Computes a single Steenrod square.
355 /// Follows the formulas in Corollary 3.2 in [CombSteenSq], pg. 97.
356 template <class SimCellT, class CoefT>
357 inline CoefT ssquare (int i, int j,
358  const SimCellT &cCell, const tChain<SimCellT,CoefT> &xChain,
360 {
361  using chomp::homology::sbug;
362 
363  // prepare the zero coefficient to return if necessary
364  CoefT coef (0);
365  if ((i < 0) || (j < 0) || (i > j))
366  return coef;
367 
368  // determine the values of the auxiliary variables m and n
369  const int n = j - i;
370  const int m = i + j;
371 // sbug << "\nDEBUG: Computing Sq^" << i << " (c) (x):\nc = " <<
372 // cChain << ",\nx = " << xChain << ".\n";
373 
374  // prepare the iteration indices
375  std::vector<int> ii (n + 1);
376  for (int k = n; k >= 0; -- k)
377  {
378  ii [k] = ssquare_S (k, ii, n, m);
379  // sbug << "DEBUG: ii [" << k << "] = " << ii [k] << ".\n";
380  }
381 
382  // for all the index combinations in the big sum of sums
383  while (1)
384  {
385  // sbug << "DEBUG: Using ii = (";
386  // for (int a = 0; a <= n; ++ a)
387  // sbug << (a ? ", " : "") << ii [a];
388  // sbug << ").\n";
389 
390  // for all the elements of the chain "x"
391  int_t size = xChain. size ();
392  for (int_t s = 0; s < size; ++ s)
393  {
394  // take the cell at the given position, and the coef
395  const SimCellT &sCell (xChain. getCell (s));
396  CoefT xCoef (xChain. getCoef (s));
397  // sbug << "DEBUG: s = " << s << ", sCell = " << sCell << ".\n";
398 
399  // square the coef, because it appears twice in the product
400  xCoef *= xCoef;
401 
402  // apply the face operators for the first cell
403  SimCellT xFace1 (ssquare_face (sCell, ii,
404  n, m, false));
405 
406  // multiply by the corresponding coeficient
407  tChain<SimCellT,CoefT> xFace1proj (pi (xFace1));
408  int_t n1 (xFace1proj. position (cCell));
409  // sbug << "DEBUG: xFace1 = " << xFace1 << ", proj = " <<
410  // xFace1proj << ", pos = " << n1 << ".\n";
411  if (n1 < 0)
412  continue;
413  xCoef *= xFace1proj. getCoef (n1);
414 
415  // apply the face operators for the second cell
416  SimCellT xFace2 (ssquare_face (sCell, ii,
417  n, m, true));
418 
419  // multiply by the corresponding coeficient
420  tChain<SimCellT,CoefT> xFace2proj (pi (xFace2));
421  int_t n2 (xFace2proj. position (cCell));
422  // sbug << "DEBUG: xFace2 = " << xFace2 << ", proj = " <<
423  // xFace2proj << ", pos = " << n2 << ".\n";
424  if (n2 < 0)
425  continue;
426  xCoef *= xFace2proj. getCoef (n2);
427 
428  // add the product to the result
429  coef += xCoef;
430  }
431 
432  // take the next combination of indices or quit the loop
433  bool valid (true);
434  for (int k = n; k >= 1; -- k)
435  {
436  ++ (ii [k]);
437  if (ii [k] <= ((k == n) ? m : (ii [k + 1] - 1)))
438  {
439  ii [0] = ssquare_S (0, ii, n, m);
440  break;
441  }
442  ii [k] = ssquare_S (k, ii, n, m);
443  if (k == 1)
444  valid = false;
445  }
446  if (!n || !valid)
447  break;
448  }
449 
450  // return the computed result
451  return coef;
452 } /* ssquare */
453 
454 /// Computes the Steenrod squares, given a minimal model
455 /// and cohomology representants. For cells of simplicial type.
456 /// Please, make sure to include the appropriate header file with the
457 /// definition of the Alexander-Whitney diagonal for the cells in use
458 /// before including the header file containing this procedure.
459 /// Follows the formulas in Corollary 3.2 in [CombSteenSq], pg. 97.
460 template <class SimCellT, class CoefT>
461 inline void ssquares2
462  (const std::vector<std::vector<SimCellT> > &cohomRepresentants,
465  chomp::homology::hashedset<tPair<SimCellT,int> > &cellsSquares,
466  chomp::homology::multitable<tChain<SimCellT,CoefT> > &squareValues)
467 {
468  using chomp::homology::sbug;
469 
470  typedef tPair<SimCellT,int> CellSquareT;
471 
472  // iterate all the valid combinations of i, c, x;
473  // Sq^i maps from H^j to H^{j+i}, c is in H^j, x is in H_{j+i}
474  int maxDim = cohomRepresentants. size ();
475  // consider all the valid values of "j"
476  for (int j = 0; j < maxDim; ++ j)
477  {
478  if (cohomRepresentants [j]. empty ())
479  continue;
480 
481  // consider all the valid values of "i"
482  for (int i = 0; (i <= j) && (i + j < maxDim); ++ i)
483  {
484  if (cohomRepresentants [i + j]. empty ())
485  {
486  continue;
487  }
488 
489  // consider all the representants of H^j
490  int size_c = cohomRepresentants [j]. size ();
491  for (int n = 0; n < size_c; ++ n)
492  {
493  // take a representant of the cohomology generator
494  const SimCellT &cCell (cohomRepresentants [j] [n]);
495  // sbug << "DEBUG: cCell " << cCell << ".\n";
496  // tChain<SimCellT,CoefT> cChain (incl (cCell));
497 
498  // consider all the representants of H^{j+i}
499  int size_x = cohomRepresentants [j + i]. size ();
500  for (int m = 0; m < size_x; ++ m)
501  {
502  // take a representant of the cohomology generator
503  const SimCellT &xCell (cohomRepresentants [j + i] [m]);
504  // sbug << "DEBUG: xCell " << xCell << ".\n";
505  tChain<SimCellT,CoefT> xChain (incl (xCell));
506 
507  // show a progress indicator
508  // sbug << "DEBUG: j = " << j << ", j+i = " << (j + i) <<
509  // ", c = " << cCell << ", x = " << xCell << "...\n";
510 
511  // compute the Steenrod square Sq^i (c) (x)
512  // following the formula in Corollary 3.2 of the paper
513  CoefT coef (ssquare (i, j, cCell, xChain, pi));
514  if (coef == 0)
515  continue;
516  int_t num = cellsSquares. add
517  (CellSquareT (cCell, i));
518  // sbug << "DEBUG: Sq^" << i << " (" << cCell <<
519  // ") += " << coef << " * " << xCell << ".\n";
520  squareValues [num]. add (xCell, coef);
521  }
522  }
523  }
524  }
525 
526  return;
527 } /* ssquares2 */
528 
529 /// Computes the Steenrod squares, given a minimal model
530 /// and cohomology representants. For cells of simplicial type.
531 /// Please, make sure to include the appropriate header file with the
532 /// definition of the Alexander-Whitney diagonal for the cells in use
533 /// before including the header file containing this procedure.
534 /// Follows Corollary 3.2 in [CombSteenSq], pg. 97.
535 template <class SimCellT, class CoefT>
536 inline void ssquares
537  (const std::vector<std::vector<SimCellT> > &cohomRepresentants,
540  chomp::homology::hashedset<tPair<SimCellT,int> > &cellsSquares,
541  chomp::homology::multitable<tChain<SimCellT,CoefT> > &squareValues)
542 {
543  return ssquares2 (cohomRepresentants, pi, incl,
544  cellsSquares, squareValues);
545 } /* ssquares */
546 
547 
548 #endif // _CHAINCON_SSQUARESSIM_H_
549 
void computeDiagonal(const tChain< CellT, CoefT > &x, tChain< ProdCellT, CoefT > &result)
Computes the diagonal of a chain.
Definition: ssquaressim.h:78
void ssquares1(const std::vector< std::vector< SimCellT > > &cohomRepresentants, const tLinMap< SimCellT, SimCellT, CoefT > &pi, const tLinMap< SimCellT, SimCellT, CoefT > &incl, chomp::homology::hashedset< tPair< SimCellT, int > > &cellsSquares, chomp::homology::multitable< tChain< SimCellT, CoefT > > &squareValues)
Computes the Steenrod squares, given a minimal model and cohomology representants.
Definition: ssquaressim.h:139
A pair of elements of two (possibly different) types.
Definition: pair.h:48
void ssquares(const std::vector< std::vector< SimCellT > > &cohomRepresentants, const tLinMap< SimCellT, SimCellT, CoefT > &pi, const tLinMap< SimCellT, SimCellT, CoefT > &incl, chomp::homology::hashedset< tPair< SimCellT, int > > &cellsSquares, chomp::homology::multitable< tChain< SimCellT, CoefT > > &squareValues)
Computes the Steenrod squares, given a minimal model and cohomology representants.
Definition: ssquaressim.h:537
void flattenProduct(const tChain< ProdCellT, CoefT > &chain, tChain< CellT, CoefT > &result)
Converts a chain of cells encoded as trivial product cells to the chain of the actual cells...
Definition: ssquaressim.h:94
A linear map for coefficients in an arbitrary commutative ring.
void ssquares2(const std::vector< std::vector< SimCellT > > &cohomRepresentants, const tLinMap< SimCellT, SimCellT, CoefT > &pi, const tLinMap< SimCellT, SimCellT, CoefT > &incl, chomp::homology::hashedset< tPair< SimCellT, int > > &cellsSquares, chomp::homology::multitable< tChain< SimCellT, CoefT > > &squareValues)
Computes the Steenrod squares, given a minimal model and cohomology representants.
Definition: ssquaressim.h:462
void swapProduct(const tChain< ProdCellT, CoefT > &input, tChain< ProdCellT, CoefT > &result)
Swaps the components of all of the product cells in the chain.
Definition: ssquaressim.h:62
The Shih operator as a component of the Eilenberg-Zilber chain contraction.
A Cartesian product of simplicial cells of arbitrary type.
A chain with coefficients in an arbitrary ring.
Definition: chain.h:50
A tensor of chains with coefficients in an arbitrary commutative ring.
void EZ_SHI(const SimCellT &s1, const SimCellT &s2, tCombChain< ProdCellT > &t)
Computes the Shih operator on a product of two simplicial cells.
Definition: ez_shi.h:55
CoefT ssquare(int i, int j, const SimCellT &cCell, const tChain< SimCellT, CoefT > &xChain, const tLinMap< SimCellT, SimCellT, CoefT > &pi)
Computes a single Steenrod square.
Definition: ssquaressim.h:357
A linear map.
Definition: linmap.h:55
Tensor of chains.
Definition: tensor.h:52
void EZ_AW(const SimCellT &s1, const SimCellT &s2, tCombTensor< SimCellT, SimCellT > &t)
Computes the Alexander-Whitney operator on a product of simplicial cells.
Definition: ez_aw.h:76
A chain with coefficients in an arbitrary commutative ring.
The Alexander-Whitney operator as a component of the Eilenberg-Zilber chain contraction.
A pair of elements.
A Cartesian product of simplicial cells as a simplicial cell.
Definition: prodcell.h:48
int ssquare_S(int k, const std::vector< int > &ii, int n, int m)
Computes the k-th value of the index S in the sum ranges defined in Corollary 3.2 in [CombSteenSq]...
Definition: ssquaressim.h:258
SimCellT ssquare_face(const SimCellT &xCell, const std::vector< int > &ii, int n, int m, bool right_hand_side)
Computes the faces of a simplicial cell.
Definition: ssquaressim.h:285