The ChainCon Software (Release 0.03)
ssquarescub.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file
4 ///
5 /// Computation of the Steenrod squares for cubical 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: January 17, 2016.
26 
27 
28 #ifndef _CHAINCON_SSQUARESCUB_H_
29 #define _CHAINCON_SSQUARESCUB_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/shuffles.h"
49 
50 
51 // --------------------------------------------------
52 // -------------- auxiliary procedures --------------
53 // --------------------------------------------------
54 
55 /// An auxiliary class for iterating all the possible disjoint subsets
56 /// A and B of integers in [0, ..., range - 1], both of the given length.
57 class STuples
58 {
59 public:
60  /// The only constructor allowed.
61  STuples (int length, int range);
62 
63  /// Gets a pair of sets A and B.
64  /// Returns true if more pairs are available,
65  /// or false if this was the last one (and rewinds the iterator).
66  template <class ArrayA, class ArrayB>
67  bool get (ArrayA &A, ArrayB &B);
68 
69 private:
70  /// The length of each tuple: A and B.
71  int _length;
72 
73  /// The range of numbers that may appear in the tuples.
74  /// The actual numbers are between 0 to _range - 1, inclusive.
75  int _range;
76 
77  /// The shuffle iterator that defines the current choice of A.
79 
80  /// Remembers if the next choice of A is available.
81  bool nextA;
82 
83  /// The current choice of A.
84  std::vector<int> curA;
85 
86  /// The current choice of the complement of A.
87  std::vector<int> curAcompl;
88 
89  /// The shuffle iterator that defines the current choice of B.
91 
92  /// Remembers if the next choice of B is available.
93  bool nextB;
94 
95  /// The current choice of B.
96  std::vector<int> curB;
97 
98  /// The current choice of the complement of B.
99  std::vector<int> curBcompl;
100 
101 }; /* class STuples */
102 
103 // --------------------------------------------------
104 
105 inline STuples::STuples (int length, int range):
106  _length (length), _range (range), sA (length, range - length),
107  curA (length), curAcompl (range - length),
108  sB (length, range - 2 * length), curB (length),
109  curBcompl (range - 2 * length)
110 {
111  // define the initial choice of the sets A and B
112  int junk (0);
113  nextA = sA. get (curA, curAcompl, junk);
114  nextB = sB. get (curB, curBcompl, junk);
115 
116  return;
117 } /* STuples::STuples */
118 
119 template <class ArrayA, class ArrayB>
120 inline bool STuples::get (ArrayA &A, ArrayB &B)
121 {
122  int length (A. size ());
123 
124  // extract the sets A and B from the current choice
125  for (int i = 0; i < length; ++ i)
126  {
127  A [i] = curA [i];
128  B [i] = curAcompl [curB [i]];
129  }
130 
131  // if this was the next choice of A and B then inform about this
132  if (!nextA && !nextB)
133  return false;
134 
135  // prepare the next choice of the sets A and B
136  int junk (0);
137  nextB = sB. get (curB, curBcompl, junk);
138  if (!nextB)
139  nextA = sA. get (curA, curAcompl, junk);
140 
141  // inform about the existence of the next choice
142  return true;
143 } /* STuples::get */
144 
145 // --------------------------------------------------
146 
147 /// Computes the sign that appears in the formula for the face.
148 /// Note that the indices in the code count from 0, not from 1.
149 /// Returns true if the sign is positive or false if it is negative.
150 inline bool ssquare_sign (int x, const std::vector<int> &A,
151  const std::vector<int> &B)
152 {
153  // count the number of elements in A and B smaller or equal x
154  int length (A. size ());
155  int countA (0);
156  while ((countA < length) && (A [countA] <= x))
157  ++ countA;
158  int countB (0);
159  while ((countB < length) && (B [countB] <= x))
160  ++ countB;
161  // if the number of elements in {0,...,x} \ (A u B) is even
162  // then return true, otherwise return false
163  return ((x + countA + countB) & 1);
164 } /* ssquare_sign */
165 
166 /// Computes a given face of a simplicial cell.
167 /// See the formula in the paper for details.
168 template <class CubCellT>
169 inline CubCellT ssquare_face (const CubCellT &xCell,
170  const std::vector<int> &A, const std::vector<int> &B,
171  int range, bool right_hand_side)
172 {
173  using chomp::homology::sbug;
174 
175  int length (A. size ());
176 
177  CubCellT face (xCell);
178  if (right_hand_side)
179  {
180  for (int i = length - 1; i >= 0; -- i)
181  {
182  bool sign (ssquare_sign (B [i], A, B));
183  face = CubCellT (face, sign ? B [i] :
184  (B [i] + face. dim ()));
185  }
186  }
187  else
188  {
189  for (int i = length - 1; i >= 0; -- i)
190  {
191  bool sign (!ssquare_sign (A [i], A, B));
192  face = CubCellT (face, sign ? A [i] :
193  (A [i] + face. dim ()));
194  }
195  }
196 
197  return face;
198 } /* ssquare_face */
199 
200 
201 // --------------------------------------------------
202 // ---------------- Steenrod squares ----------------
203 // --------------------------------------------------
204 
205 /// Computes a single Steenrod square.
206 /// Follows the formula provided by Marek Krcal.
207 template <class CubCellT, class CoefT>
208 inline CoefT ssquare (int i, int j,
209  const CubCellT &cCell, const tChain<CubCellT,CoefT> &xChain,
211 {
212  using chomp::homology::sbug;
213 
214  // prepare the zero coefficient to return if necessary
215  CoefT coef (0);
216  if ((i < 0) || (j < 0) || (i > j))
217  return coef;
218 
219  // define an iterator for the sets A and B
220 // sbug << "DEBUG: Creating sTuples (" << i << ", " << (i + j) << ").\n";
221  STuples sTuples (i, i + j);
222 
223  // for all the index combinations in the big sum
224  bool moreAvailable (true);
225  while (moreAvailable)
226  {
227  // get the current combination of A and B
228  std::vector<int> A (i);
229  std::vector<int> B (i);
230  moreAvailable = sTuples. get (A, B);
231 
232  // verify the tuples if they are appropriate
233  bool wrongTuple (false);
234  if (true)
235  {
236  for (int k = 0; k < i; ++ k)
237  {
238  if ((A [k] < i + j) && (B [k] < i + j))
239  continue;
240  sbug << "WRONG TUPLE: k = " << k <<
241  " and one of these: " <<
242  A [k] << " or " << B [k] <<
243  " is not < " << (i + j) << ".\n";
244  wrongTuple = true;
245  break;
246  }
247  }
248 
249  if ((false || wrongTuple) && (sbug. show || sbug. log))
250  {
251  sbug << "DEBUG: A = (";
252  for (size_t c = 0; c < A. size (); ++ c)
253  sbug << (c ? "," : "") << A [c];
254  sbug << "), B = (";
255  for (size_t c = 0; c < B. size (); ++ c)
256  sbug << (c ? "," : "") << B [c];
257  sbug << ").\n";
258  }
259 
260  // for all the elements of the chain "x"
261  int_t size = xChain. size ();
262  for (int_t s = 0; s < size; ++ s)
263  {
264  // take the cell at the given position, and the coef
265  const CubCellT &sCell (xChain. getCell (s));
266  CoefT xCoef (xChain. getCoef (s));
267 
268  // check the dimension of the cell
269  if (sCell. dim () != (i + j))
270  {
271  sbug << "WRONG CELL DIMENSION: s = " << s <<
272  ", sCell = " << sCell << ".\n";
273  sbug << "The dimension is " << sCell. dim () <<
274  ", and should be " << i << ".\n";
275  }
276  // sbug << "DEBUG: s = " << s << ", sCell = " << sCell << ".\n";
277 
278  // square the coef, because it appears twice in the product
279  xCoef *= xCoef;
280 
281  // apply the face operators for the first cell
282  CubCellT xFace1 (ssquare_face (sCell, A, B, j, false));
283 
284  // multiply by the corresponding coeficient
285  tChain<CubCellT,CoefT> xFace1proj (pi (xFace1));
286  int_t n1 (xFace1proj. position (cCell));
287  // sbug << "DEBUG: xFace1 = " << xFace1 << ", proj = " <<
288  // xFace1proj << ", pos = " << n1 <<
289  // ((n1 >= 0) ? "!" : ".") << "\n";
290  if (n1 < 0)
291  continue;
292  xCoef *= xFace1proj. getCoef (n1);
293 
294  // apply the face operators for the second cell
295  CubCellT xFace2 (ssquare_face (sCell, A, B, j, true));
296 
297  // multiply by the corresponding coeficient
298  tChain<CubCellT,CoefT> xFace2proj (pi (xFace2));
299  int_t n2 (xFace2proj. position (cCell));
300  // sbug << "DEBUG: xFace2 = " << xFace2 << ", proj = " <<
301  // xFace2proj << ", pos = " << n2 <<
302  // ((n2 >= 0) ? "!!" : ".") << "\n";
303  if (n2 < 0)
304  continue;
305  xCoef *= xFace2proj. getCoef (n2);
306 
307  sbug << "DEBUG: xFace1 = " << xFace1 << ", proj = " <<
308  xFace1proj << ", pos = " << n1 <<
309  ((n1 >= 0) ? "!" : ".") << "\n";
310  sbug << "DEBUG: xFace2 = " << xFace2 << ", proj = " <<
311  xFace2proj << ", pos = " << n2 <<
312  ((n2 >= 0) ? "!!" : ".") << "\n";
313 
314  // add the product to the result
315  coef += xCoef;
316  }
317  }
318 
319  // return the computed result
320  return coef;
321 } /* ssquare */
322 
323 /// Computes the Steenrod squares, given a minimal model
324 /// and cohomology representants. For cells of cubical type,
325 /// using the direct formula provided by Marek Krcal.
326 template <class CubCellT, class CoefT>
327 inline void ssquares
328  (const std::vector<std::vector<CubCellT> > &cohomRepresentants,
331  chomp::homology::hashedset<tPair<CubCellT,int> > &cellsSquares,
332  chomp::homology::multitable<tChain<CubCellT,CoefT> > &squareValues)
333 {
334  using chomp::homology::sbug;
335 
336  typedef tPair<CubCellT,int> CellSquareT;
337 
338  // iterate all the valid combinations of i, c, x;
339  // Sq^i maps from H^j to H^{j+i}, c is in H^j, x is in H_{j+i}
340  int maxDim = cohomRepresentants. size ();
341  // consider all the valid values of "j"
342  for (int j = 0; j < maxDim; ++ j)
343  {
344  if (cohomRepresentants [j]. empty ())
345  continue;
346 
347  // consider all the valid values of "i"
348  for (int i = 0; (i <= j) && (i + j < maxDim); ++ i)
349  {
350  if (cohomRepresentants [i + j]. empty ())
351  {
352  continue;
353  }
354 
355  // consider all the representants of H^j
356  int size_c = cohomRepresentants [j]. size ();
357  for (int n = 0; n < size_c; ++ n)
358  {
359  // take a representant of the cohomology generator
360  const CubCellT &cCell (cohomRepresentants [j] [n]);
361  sbug << "DEBUG: cCell " << cCell << ".\n";
362  tChain<CubCellT,CoefT> cChain (incl (cCell));
363 
364  // consider all the representants of H^{j+i}
365  int size_x = cohomRepresentants [j + i]. size ();
366  for (int m = 0; m < size_x; ++ m)
367  {
368  // take a representant of the cohomology generator
369  const CubCellT &xCell (cohomRepresentants [j + i] [m]);
370  sbug << "DEBUG: xCell " << xCell << ".\n";
371  tChain<CubCellT,CoefT> xChain (incl (xCell));
372 
373  // show a progress indicator
374  sbug << "DEBUG: i = " << i << ", j = " << j << ", j+i = " << (j + i) <<
375  ", c = " << cCell << ", x = " << xCell << "...\n";
376 
377  // compute the Steenrod square Sq^i (c) (x)
378  // following the formula provided by Marek Krcal
379  CoefT coef (ssquare (i, j, cCell, xChain, pi));
380  if (coef == 0)
381  continue;
382  int_t num = cellsSquares. add
383  (CellSquareT (cCell, i));
384  sbug << "DEBUG: Sq^" << i << " (" << cCell <<
385  ") += " << coef << " * " << xCell << ".\n";
386  squareValues [num]. add (xCell, coef);
387  }
388  }
389  }
390  }
391 
392  return;
393 } /* ssquares */
394 
395 /// Computes the Steenrod squares using the only procedure in this case.
396 template <class CubCellT, class CoefT>
397 inline void ssquares1
398  (const std::vector<std::vector<CubCellT> > &cohomRepresentants,
401  chomp::homology::hashedset<tPair<CubCellT,int> > &cellsSquares,
402  chomp::homology::multitable<tChain<CubCellT,CoefT> > &squareValues)
403 {
404  return ssquares (cohomRepresentants, pi, incl,
405  cellsSquares, squareValues);
406 } /* ssquares1 */
407 
408 /// Computes the Steenrod squares using the only procedure in this case.
409 template <class CubCellT, class CoefT>
410 inline void ssquares2
411  (const std::vector<std::vector<CubCellT> > &cohomRepresentants,
414  chomp::homology::hashedset<tPair<CubCellT,int> > &cellsSquares,
415  chomp::homology::multitable<tChain<CubCellT,CoefT> > &squareValues)
416 {
417  return ssquares (cohomRepresentants, pi, incl,
418  cellsSquares, squareValues);
419 } /* ssquares2 */
420 
421 
422 #endif // _CHAINCON_SSQUARESCUB_H_
423 
A pair of elements of two (possibly different) types.
Definition: pair.h:48
An iterator of shuffles.
A linear map for coefficients in an arbitrary commutative ring.
bool get(ArrayA &A, ArrayB &B)
Gets a pair of sets A and B.
Definition: ssquarescub.h:120
int _length
The length of each tuple: A and B.
Definition: ssquarescub.h:71
An iterator of all the (p,q)-shuffles.
Definition: shuffles.h:51
An auxiliary class for iterating all the possible disjoint subsets A and B of integers in [0...
Definition: ssquarescub.h:57
std::vector< int > curB
The current choice of B.
Definition: ssquarescub.h:96
bool nextA
Remembers if the next choice of A is available.
Definition: ssquarescub.h:81
A chain with coefficients in an arbitrary ring.
Definition: chain.h:50
Shuffles sB
The shuffle iterator that defines the current choice of B.
Definition: ssquarescub.h:90
CubCellT ssquare_face(const CubCellT &xCell, const std::vector< int > &A, const std::vector< int > &B, int range, bool right_hand_side)
Computes a given face of a simplicial cell.
Definition: ssquarescub.h:169
std::vector< int > curBcompl
The current choice of the complement of B.
Definition: ssquarescub.h:99
A tensor of chains with coefficients in an arbitrary commutative ring.
A linear map.
Definition: linmap.h:55
void ssquares1(const std::vector< std::vector< CubCellT > > &cohomRepresentants, const tLinMap< CubCellT, CubCellT, CoefT > &pi, const tLinMap< CubCellT, CubCellT, CoefT > &incl, chomp::homology::hashedset< tPair< CubCellT, int > > &cellsSquares, chomp::homology::multitable< tChain< CubCellT, CoefT > > &squareValues)
Computes the Steenrod squares using the only procedure in this case.
Definition: ssquarescub.h:398
void ssquares(const std::vector< std::vector< CubCellT > > &cohomRepresentants, const tLinMap< CubCellT, CubCellT, CoefT > &pi, const tLinMap< CubCellT, CubCellT, CoefT > &incl, chomp::homology::hashedset< tPair< CubCellT, int > > &cellsSquares, chomp::homology::multitable< tChain< CubCellT, CoefT > > &squareValues)
Computes the Steenrod squares, given a minimal model and cohomology representants.
Definition: ssquarescub.h:328
A chain with coefficients in an arbitrary commutative ring.
A pair of elements.
std::vector< int > curA
The current choice of A.
Definition: ssquarescub.h:84
std::vector< int > curAcompl
The current choice of the complement of A.
Definition: ssquarescub.h:87
STuples(int length, int range)
The only constructor allowed.
Definition: ssquarescub.h:105
bool nextB
Remembers if the next choice of B is available.
Definition: ssquarescub.h:93
void ssquares2(const std::vector< std::vector< CubCellT > > &cohomRepresentants, const tLinMap< CubCellT, CubCellT, CoefT > &pi, const tLinMap< CubCellT, CubCellT, CoefT > &incl, chomp::homology::hashedset< tPair< CubCellT, int > > &cellsSquares, chomp::homology::multitable< tChain< CubCellT, CoefT > > &squareValues)
Computes the Steenrod squares using the only procedure in this case.
Definition: ssquarescub.h:411
int _range
The range of numbers that may appear in the tuples.
Definition: ssquarescub.h:75
CoefT ssquare(int i, int j, const CubCellT &cCell, const tChain< CubCellT, CoefT > &xChain, const tLinMap< CubCellT, CubCellT, CoefT > &pi)
Computes a single Steenrod square.
Definition: ssquarescub.h:208
Shuffles sA
The shuffle iterator that defines the current choice of A.
Definition: ssquarescub.h:78
bool ssquare_sign(int x, const std::vector< int > &A, const std::vector< int > &B)
Computes the sign that appears in the formula for the face.
Definition: ssquarescub.h:150