The ChainCon Software (Release 0.03)
awdiagcub.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 ///
3 /// \file
4 ///
5 /// A cubical version of the Alexander-Whitney diagonal.
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 March 24, 2009. Last revision: April 11, 2013.
26 
27 
28 #ifndef _CHAINCON_AWDIAGCUB_H_
29 #define _CHAINCON_AWDIAGCUB_H_
30 
31 
32 // include some standard C++ header files
33 #include <istream>
34 #include <ostream>
35 
36 // include selected header files from the CHomP library
37 #include "chomp/system/config.h"
38 
39 // include relevant local header files
40 #include "chaincon/cubcell.h"
41 #include "chaincon/combtensor.h"
42 #include "chaincon/tensor.h"
43 
44 
45 // --------------------------------------------------
46 // ------------------ AW diagonal -------------------
47 // --------------------------------------------------
48 
49 /// Computes the Alexander-Whitney diagonal of a cubical cell
50 /// using the formula from Serre's paper. A purely combinatorial version.
51 template <class CoordT, class WrapT, class EmptyT>
55 {
56  typedef tCubCell<CoordT,WrapT,EmptyT> CubeType;
57 
58  // determine the dimension of the cell and of the space
59  int dim = c. dim ();
60  if (dim > static_cast<int> (8 * sizeof (long) - 2))
61  throw "Dimension too high for cubical A-W diagonal.";
62  int spaceDim = c. spaceDim ();
63 
64  // prepare buffers for coordinates of pairs of new cubes
65  CoordT *coordBuffer = new CoordT [6 * spaceDim + 1];
66  CoordT *cLeft = coordBuffer;
67  CoordT *cRight = cLeft + spaceDim;
68  CoordT *leftLeft = cRight + spaceDim;
69  CoordT *leftRight = leftLeft + spaceDim;
70  CoordT *rightLeft = leftRight + spaceDim;
71  CoordT *rightRight = rightLeft + spaceDim;
72 
73  // determine the indices of nonzero width of the cubical cell
74  int *indices = new int [dim + 1];
75  int indCur = 0;
76  for (int i = 0; i < spaceDim; ++ i)
77  {
78  cLeft [i] = c. left (i);
79  cRight [i] = c. right (i);
80  if (cLeft [i] == cRight [i])
81  continue;
82  indices [indCur ++] = i;
83  }
84  if (indCur != dim)
85  throw "Wrong dimension of a cubical cell detected in AW.";
86 
87  // go through all the subsets and add up the tensor products
88  const long subsetMax = 1 << dim;
89  for (long subset = 0; subset < subsetMax; ++ subset)
90  {
91  // create the two cubical cells
92  for (int i = 0; i < spaceDim; ++ i)
93  {
94  leftLeft [i] = cLeft [i];
95  leftRight [i] = cRight [i];
96  rightLeft [i] = cLeft [i];
97  rightRight [i] = cRight [i];
98  }
99  for (int i = 0; i < dim; ++ i)
100  {
101  int index = indices [i];
102  if (subset & (1 << i))
103  {
104  rightLeft [index] = rightRight [index];
105  }
106  else
107  {
108  leftRight [index] = leftLeft [index];
109  }
110  }
111  t. add (CubeType (spaceDim, leftLeft, leftRight),
112  CubeType (spaceDim, rightLeft, rightRight));
113  }
114 
115  // release the allocated memory
116  delete [] indices;
117  delete [] coordBuffer;
118 
119  return;
120 } /* AWdiagonal */
121 
122 /// Returns the sign rho of a term in the A-W diagonal
123 /// (see the paper for details).
124 inline int AW_rho (long subset, int dim)
125 {
126  // TODO: more efficient
127  int nu = 0;
128  for (int i = 0; i < dim; ++ i)
129  {
130  for (int j = 0; j < i; ++ j)
131  {
132  if (!(subset & (1 << i)))
133  continue;
134  if (subset & (1 << j))
135  continue;
136  ++ nu;
137  }
138  }
139  return (nu & 1) ? -1 : 1;
140 } /* AW_rho */
141 
142 /// Computes the Alexander-Whitney diagonal of a cubical cell
143 /// using the formula from Serre's paper. A general version.
144 template <class CoordT, class WrapT, class EmptyT, class CoefT>
148 {
149  typedef tCubCell<CoordT,WrapT,EmptyT> CubeType;
150 
151  // determine the dimension of the cell and of the space
152  int dim = c. dim ();
153  if (dim > static_cast<int> (8 * sizeof (long) - 2))
154  throw "Dimension too high for cubical A-W diagonal.";
155  int spaceDim = c. spaceDim ();
156 
157  // prepare buffers for coordinates of pairs of new cubes
158  CoordT *coordBuffer = new CoordT [6 * spaceDim + 1];
159  CoordT *cLeft = coordBuffer;
160  CoordT *cRight = cLeft + spaceDim;
161  CoordT *leftLeft = cRight + spaceDim;
162  CoordT *leftRight = leftLeft + spaceDim;
163  CoordT *rightLeft = leftRight + spaceDim;
164  CoordT *rightRight = rightLeft + spaceDim;
165 
166  // determine the indices of nonzero width of the cubical cell
167  int *indices = new int [dim + 1];
168  int indCur = 0;
169  for (int i = 0; i < spaceDim; ++ i)
170  {
171  cLeft [i] = c. left (i);
172  cRight [i] = c. right (i);
173  if (cLeft [i] == cRight [i])
174  continue;
175  indices [indCur ++] = i;
176  }
177  if (indCur != dim)
178  throw "Wrong dimension of a cubical cell detected in AW.";
179 
180  // go through all the subsets and add up the tensor products
181  const long subsetMax = 1 << dim;
182  for (long subset = 0; subset < subsetMax; ++ subset)
183  {
184  // create the two cubical cells
185  for (int i = 0; i < spaceDim; ++ i)
186  {
187  leftLeft [i] = cLeft [i];
188  leftRight [i] = cRight [i];
189  rightLeft [i] = cLeft [i];
190  rightRight [i] = cRight [i];
191  }
192  for (int i = 0; i < dim; ++ i)
193  {
194  int index = indices [i];
195  if (subset & (1 << i))
196  {
197  rightLeft [index] = rightRight [index];
198  }
199  else
200  {
201  leftRight [index] = leftLeft [index];
202  }
203  }
204  CoefT coef (1);
205  if (AW_rho (subset, dim) == -1)
206  coef. negate ();
207  t. add (CubeType (spaceDim, leftLeft, leftRight),
208  CubeType (spaceDim, rightLeft, rightRight), coef);
209  }
210 
211  // release the allocated memory
212  delete [] indices;
213  delete [] coordBuffer;
214 
215  return;
216 } /* AWdiagonal */
217 
218 
219 #endif // _CHAINCON_AWDIAGCUB_H_
220 
A tensor of chains with coefficients in an arbitrary commutative ring.
A cubical cell.
Tensor of chains.
Definition: tensor.h:52
Combinatorial tensor of cells.
Definition: combtensor.h:53
A combinatorial tensor (for coefficients in Z_2).
int AW_rho(long subset, int dim)
Returns the sign rho of a term in the A-W diagonal (see the paper for details).
Definition: awdiagcub.h:124
void AWdiagonal(const tCubCell< CoordT, WrapT, EmptyT > &c, tCombTensor< tCubCell< CoordT, WrapT, EmptyT >, tCubCell< CoordT, WrapT, EmptyT > > &t)
Computes the Alexander-Whitney diagonal of a cubical cell using the formula from Serre&#39;s paper...
Definition: awdiagcub.h:52
An elementary cubical cell with vertex coordinates of integer type.
Definition: cubcell.h:63