gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
ChainComplex.h
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 //
6 // Contributed by Matti Pellikka <matti.pellikka@gmail.com>.
7 
8 #ifndef CHAINCOMPLEX_H
9 #define CHAINCOMPLEX_H
10 
11 #include "GmshConfig.h"
12 #if defined(HAVE_KBIPACK)
13 
14 #include <cstdio>
15 #include <string>
16 #include <algorithm>
17 #include <set>
18 #include <queue>
19 #include "CellComplex.h"
20 
21 #if defined(HAVE_GMP)
22 #include "gmp.h"
23 #include "gmp_normal_form.h"
24 #else
25 #include "mpz.h"
26 #include "gmp_normal_form.h"
27 #endif
28 
29 class CellComplex;
30 
31 // A class representing a chain complex of a cell complex.
32 // This should only be constructed for a reduced cell complex because of
33 // dense matrix representations and great computational complexity in
34 // its methods.
35 class ChainComplex {
36 private:
37  // boundary operator matrices for this chain complex
38  // h_k: C_k -> C_(k-1)
39  gmp_matrix *_hMatrix[5];
40 
41  // Basis matrices for the kernels and codomains of the boundary operator
42  // matrices
43  gmp_matrix *_kerH[5];
44  gmp_matrix *_codH[5];
45 
46  // matrix of the mapping B_k -> Z_k
47  gmp_matrix *_jMatrix[5];
48  // matrix of the mapping H_k -> Z_k
49  gmp_matrix *_qMatrix[5];
50 
51  // bases for homology groups
52  gmp_matrix *_hbasis[5];
53  // torsion coefficients of homology generators
54  // corresponding the columns of _hbasis
55  std::vector<long int> _torsion[5];
56 
57  int _dim;
58  CellComplex *_cellComplex;
59 
60  // index to cell map
61  // matrix indices correspond to these cells in _cellComplex
62  std::map<Cell *, int, CellPtrLessThan> _cellIndices[4];
63 
64  // set the matrices
65  void setHMatrix(int dim, gmp_matrix *matrix)
66  {
67  if(dim > -1 && dim < 5) _hMatrix[dim] = matrix;
68  }
69  void setKerHMatrix(int dim, gmp_matrix *matrix)
70  {
71  if(dim > -1 && dim < 5) _kerH[dim] = matrix;
72  }
73  void setCodHMatrix(int dim, gmp_matrix *matrix)
74  {
75  if(dim > -1 && dim < 5) _codH[dim] = matrix;
76  }
77  void setJMatrix(int dim, gmp_matrix *matrix)
78  {
79  if(dim > -1 && dim < 5) _jMatrix[dim] = matrix;
80  }
81  void setQMatrix(int dim, gmp_matrix *matrix)
82  {
83  if(dim > -1 && dim < 5) _qMatrix[dim] = matrix;
84  }
85  void setHbasis(int dim, gmp_matrix *matrix)
86  {
87  if(dim > -1 && dim < 5) _hbasis[dim] = matrix;
88  }
89 
90  // get the boundary operator matrix dim->dim-1
91  gmp_matrix *getHMatrix(int dim) const
92  {
93  if(dim > -1 && dim < 5)
94  return _hMatrix[dim];
95  else
96  return nullptr;
97  }
98  gmp_matrix *getKerHMatrix(int dim) const
99  {
100  if(dim > -1 && dim < 5)
101  return _kerH[dim];
102  else
103  return nullptr;
104  }
105  gmp_matrix *getCodHMatrix(int dim) const
106  {
107  if(dim > -1 && dim < 5)
108  return _codH[dim];
109  else
110  return nullptr;
111  }
112  gmp_matrix *getJMatrix(int dim) const
113  {
114  if(dim > -1 && dim < 5)
115  return _jMatrix[dim];
116  else
117  return nullptr;
118  }
119  gmp_matrix *getQMatrix(int dim) const
120  {
121  if(dim > -1 && dim < 5)
122  return _qMatrix[dim];
123  else
124  return nullptr;
125  }
126  gmp_matrix *getHbasis(int dim) const
127  {
128  if(dim > -1 && dim < 5)
129  return _hbasis[dim];
130  else
131  return nullptr;
132  }
133 
134  // local deformation tools for chains
135  bool deformChain(std::map<Cell *, int, CellPtrLessThan> &cells,
136  std::pair<Cell *, int> cell, bool bend);
137  bool deform(std::map<Cell *, int, CellPtrLessThan> &cells,
138  std::map<Cell *, int, CellPtrLessThan> &cellsInChain,
139  std::map<Cell *, int, CellPtrLessThan> &cellsNotInChain);
140  void smoothenChain(std::map<Cell *, int, CellPtrLessThan> &cells);
141  void eraseNullCells(std::map<Cell *, int, CellPtrLessThan> &cells);
142  void deImmuneCells(std::map<Cell *, int, CellPtrLessThan> &cells);
143 
144 public:
145  // domain = 0 : relative chain space
146  // domain = 1 : absolute chain space of all cells in cellComplex
147  // domain = 2 : absolute chain space of cells in subdomain
148  ChainComplex(CellComplex *cellComplex, int domain = 0);
149  ~ChainComplex();
150 
151  int getDim() const { return _dim; }
152 
153  // 1 : Z basis (cycles)
154  // 2 : B basis (boundaries)
155  // 3 : H basis (homology)
156  // get the bases for various spaces
157  gmp_matrix *getBasis(int dim, int basis);
158  gmp_matrix *getBoundaryOp(int dim)
159  {
160  if(dim > -1 && dim < 5)
161  return _hMatrix[dim];
162  else
163  return nullptr;
164  }
165 
166  // compute basis for kernel and codomain of boundary operator matrix
167  // of dimension dim (ie. ker(h_dim) and cod(h_dim) )
168  void KerCod(int dim);
169  // compute matrix representation J for inclusion relation from dim-cells
170  // who are boundary of dim+1-cells to cycles of dim-cells
171  // (ie. j: cod(h_(dim+1)) -> ker(h_dim) )
172  void Inclusion(int lowDim, int highDim);
173  // compute quotient problem for given inclusion relation j to find
174  // representatives of homology group generators and possible
175  // torsion coeffcients
176  void Quotient(int dim, int setDim);
177 
178  // transpose the boundary operator matrices, these are boundary operator
179  // matrices for the dual mesh
180  void transposeHMatrices();
181  void transposeHMatrix(int dim);
182 
183  // Compute bases for the homology groups of this chain complex
184  void computeHomology(bool dual = false);
185 
186  typedef std::map<Cell *, int, CellPtrLessThan>::iterator citer;
187  citer firstCell(int dim) { return _cellIndices[dim].begin(); }
188  citer lastCell(int dim) { return _cellIndices[dim].end(); }
189  // get the cell index
190  int getCellIndex(Cell *cell)
191  {
192  auto cit = _cellIndices[cell->getDim()].find(cell);
193  if(cit != lastCell(cell->getDim()))
194  return cit->second;
195  else
196  return 0;
197  }
198 
199  // get coefficient vector for dim-dimensional Hbasis chain chainNumber
200  std::vector<int> getCoeffVector(int dim, int chainNumber);
201  // get basis chain from a basis matrix
202  // (deform: with local deformations to make chain smoother and to have
203  // smaller support, deformed chain is homologous to the old one,
204  // only works for chains of the primary chain complex)
205  void getBasisChain(std::map<Cell *, int, CellPtrLessThan> &chain, int num,
206  int dim, int basis, bool deform = false);
207  // get rank of a basis
208  int getBasisSize(int dim, int basis);
209  // homology torsion coefficient for dim-dimensional chain num
210  int getTorsion(int dim, int num);
211 
212  // apply a transformation T to a basis (T should be unimodular)
213  void transformBasis(gmp_matrix *T, int dim, int basis)
214  {
215  if(basis == 3 && _hbasis[dim] != nullptr) {
216  gmp_matrix_right_mult(_hbasis[dim], T);
217  }
218  }
219  // void printBasisChain(std::map<Cell*, int, CellPtrLessThan>& chain);
220 
221  // debugging aid
222  int printMatrix(gmp_matrix *matrix)
223  {
224  printf("%d rows and %d columns\n", (int)gmp_matrix_rows(matrix),
225  (int)gmp_matrix_cols(matrix));
226  return gmp_matrix_printf(matrix);
227  }
228  void matrixTest();
229 };
230 
231 #endif
232 #endif
Cell::getDim
virtual int getDim() const
Definition: Cell.h:82
CellComplex
Definition: CellComplex.h:24
Cell
Definition: Cell.h:42
CellComplex.h