Skip to content
Snippets Groups Projects
Commit 0a68c5ef authored by Matti Pellika's avatar Matti Pellika
Browse files

Building ChainComplex class, should be functional now.

Squeezed #if defined(HAVE_KBIPACK) preprocessor instructions only around
those parts where kbipack is really needed. It seems some homology fun
can be done without it when using coreduction algorithm.
parent b4d6f0b8
No related branches found
No related tags found
No related merge requests found
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include "CellComplex.h" #include "CellComplex.h"
#if defined(HAVE_KBIPACK)
CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain ){ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain ){
_domain = domain; _domain = domain;
...@@ -65,6 +63,10 @@ void CellComplex::insertCells(bool subdomain){ ...@@ -65,6 +63,10 @@ void CellComplex::insertCells(bool subdomain){
} }
void CellComplex::insertCell(Cell* cell){
_cells[cell->getDim()].insert(cell);
}
int Simplex::kappa(Cell* tau) const{ int Simplex::kappa(Cell* tau) const{
for(int i=0; i < tau->getNumVertices(); i++){ for(int i=0; i < tau->getNumVertices(); i++){
if( !(this->hasVertex(tau->getVertex(i))) ) return 0; if( !(this->hasVertex(tau->getVertex(i))) ) return 0;
...@@ -184,9 +186,9 @@ std::vector< std::set<Cell*, Less_Cell>::iterator > CellComplex::cbdIt(Cell* tau ...@@ -184,9 +186,9 @@ std::vector< std::set<Cell*, Less_Cell>::iterator > CellComplex::cbdIt(Cell* tau
} }
void CellComplex::removeCell(Cell* cell){ void CellComplex::removeCell(Cell* cell, bool deleteCell){
_cells[cell->getDim()].erase(cell); _cells[cell->getDim()].erase(cell);
delete cell; if(deleteCell) delete cell;
} }
void CellComplex::removeCellIt(std::set<Cell*, Less_Cell>::iterator cell){ void CellComplex::removeCellIt(std::set<Cell*, Less_Cell>::iterator cell){
Cell* c = *cell; Cell* c = *cell;
...@@ -272,7 +274,7 @@ int CellComplex::coreductionMrozek(Cell* generator){ ...@@ -272,7 +274,7 @@ int CellComplex::coreductionMrozek(Cell* generator){
} }
int CellComplex::coreduction(int dim){ int CellComplex::coreduction(int dim, bool deleteCells){
if(dim < 0 || dim > 2) return 0; if(dim < 0 || dim > 2) return 0;
...@@ -287,8 +289,8 @@ int CellComplex::coreduction(int dim){ ...@@ -287,8 +289,8 @@ int CellComplex::coreduction(int dim){
bd_c = bd(cell); bd_c = bd(cell);
if(bd_c.size() == 1 && inSameDomain(cell, bd_c.at(0)) ){ if(bd_c.size() == 1 && inSameDomain(cell, bd_c.at(0)) ){
removeCell(cell); removeCell(cell, deleteCells);
removeCell(bd_c.at(0)); removeCell(bd_c.at(0), deleteCells);
count++; count++;
coreduced = true; coreduced = true;
} }
...@@ -300,8 +302,39 @@ int CellComplex::coreduction(int dim){ ...@@ -300,8 +302,39 @@ int CellComplex::coreduction(int dim){
} }
int CellComplex::coreduction(int dim, std::set<Cell*, Less_Cell>& removedCells){
int CellComplex::reduction(int dim){ if(dim < 0 || dim > 2) return 0;
std::vector<Cell*> bd_c;
int count = 0;
bool coreduced = true;
while (coreduced){
coreduced = false;
for(citer cit = firstCell(dim+1); cit != lastCell(dim+1); cit++){
Cell* cell = *cit;
bd_c = bd(cell);
if(bd_c.size() == 1 && inSameDomain(cell, bd_c.at(0)) ){
removedCells.insert(cell);
removedCells.insert(bd_c.at(0));
removeCell(cell, false);
removeCell(bd_c.at(0), false);
count++;
coreduced = true;
}
}
}
return count;
}
int CellComplex::reduction(int dim, bool deleteCells){
if(dim < 1 || dim > 3) return 0; if(dim < 1 || dim > 3) return 0;
std::vector<Cell*> cbd_c; std::vector<Cell*> cbd_c;
...@@ -314,8 +347,8 @@ int CellComplex::reduction(int dim){ ...@@ -314,8 +347,8 @@ int CellComplex::reduction(int dim){
Cell* cell = *cit; Cell* cell = *cit;
cbd_c = cbd(cell); cbd_c = cbd(cell);
if(cbd_c.size() == 1 && inSameDomain(cell, cbd_c.at(0)) ){ if(cbd_c.size() == 1 && inSameDomain(cell, cbd_c.at(0)) ){
removeCell(cell); removeCell(cell, deleteCells);
removeCell(cbd_c.at(0)); removeCell(cbd_c.at(0), deleteCells);
count++; count++;
reduced = true; reduced = true;
} }
...@@ -334,36 +367,79 @@ void CellComplex::reduceComplex(){ ...@@ -334,36 +367,79 @@ void CellComplex::reduceComplex(){
printf("Cell complex after reduction: %d volumes, %d faces, %d edges and %d vertices.\n", printf("Cell complex after reduction: %d volumes, %d faces, %d edges and %d vertices.\n",
getSize(3), getSize(2), getSize(1), getSize(0)); getSize(3), getSize(2), getSize(1), getSize(0));
} }
void CellComplex::coreduceComplex(int generatorDim, std::set<Cell*, Less_Cell>& removedCells){
std::set<Cell*, Less_Cell> generatorCells[4];
printf("Cell complex before coreduction: %d volumes, %d faces, %d edges and %d vertices.\n",
getSize(3), getSize(2), getSize(1), getSize(0));
int i = generatorDim;
while (getSize(i) != 0){
citer cit = firstCell(i);
Cell* cell = *cit;
while(!cell->inSubdomain() && cit != lastCell(i)){
cell = *cit;
cit++;
}
generatorCells[i].insert(cell);
removedCells.insert(cell);
removeCell(cell, false);
coreduction(0, removedCells);
coreduction(1, removedCells);
coreduction(2, removedCells);
}
for(citer cit = generatorCells[i].begin(); cit != generatorCells[i].end(); cit++){
Cell* cell = *cit;
if(!cell->inSubdomain()) _cells[i].insert(cell);
if(!cell->inSubdomain()) removedCells.insert(cell);
}
printf("Cell complex after coreduction: %d volumes, %d faces, %d edges and %d vertices.\n",
getSize(3), getSize(2), getSize(1), getSize(0));
return;
}
void CellComplex::coreduceComplex(){ void CellComplex::coreduceComplex(){
std::set<Cell*, Less_Cell> removedCells[4]; std::set<Cell*, Less_Cell> generatorCells[4];
printf("Cell complex before coreduction: %d volumes, %d faces, %d edges and %d vertices.\n", printf("Cell complex before coreduction: %d volumes, %d faces, %d edges and %d vertices.\n",
getSize(3), getSize(2), getSize(1), getSize(0)); getSize(3), getSize(2), getSize(1), getSize(0));
for(int i = 0; i < 3; i++){ for(int i = 0; i < 4; i++){
while (getSize(i) != 0){ while (getSize(i) != 0){
citer cit = firstCell(i); citer cit = firstCell(i);
Cell* cell = *cit; Cell* cell = *cit;
removedCells[i].insert(cell); while(!cell->inSubdomain() && cit != lastCell(i)){
_cells[i].erase(cell); cell = *cit;
//removeCell(cell); cit++;
//complex.coreductionMrozek(kaka); }
generatorCells[i].insert(cell);
removeCell(cell, false);
coreduction(0); coreduction(0);
coreduction(1); coreduction(1);
coreduction(2); coreduction(2);
} }
} }
for(int i = 0; i < 3; i++){ for(int i = 0; i < 4; i++){
for(citer cit = removedCells[i].begin(); cit != removedCells[i].end(); cit++){ for(citer cit = generatorCells[i].begin(); cit != generatorCells[i].end(); cit++){
Cell* cell = *cit; Cell* cell = *cit;
_cells[i].insert(cell); if(!cell->inSubdomain()) _cells[i].insert(cell);
} }
} }
printf("Cell complex after coreduction: %d volumes, %d faces, %d edges and %d vertices.\n", printf("Cell complex after coreduction: %d volumes, %d faces, %d edges and %d vertices.\n",
getSize(3), getSize(2), getSize(1), getSize(0)); getSize(3), getSize(2), getSize(1), getSize(0));
return;
} }
#if defined(HAVE_KBIPACK)
std::vector<gmp_matrix*> CellComplex::constructHMatrices(){ std::vector<gmp_matrix*> CellComplex::constructHMatrices(){
// h_dim: C_dim -> C_(dim-1) // h_dim: C_dim -> C_(dim-1)
...@@ -418,7 +494,7 @@ std::vector<gmp_matrix*> CellComplex::constructHMatrices(){ ...@@ -418,7 +494,7 @@ std::vector<gmp_matrix*> CellComplex::constructHMatrices(){
} }
return HMatrix; return HMatrix;
} }
#endif
void CellComplex::getDomainVertices(std::set<MVertex*, Less_MVertex>& domainVertices, bool subdomain){ void CellComplex::getDomainVertices(std::set<MVertex*, Less_MVertex>& domainVertices, bool subdomain){
...@@ -541,6 +617,8 @@ void CellComplex::printComplex(int dim, bool subcomplex){ ...@@ -541,6 +617,8 @@ void CellComplex::printComplex(int dim, bool subcomplex){
} }
} }
#if defined(HAVE_KBIPACK)
void ChainComplex::KerCod(int dim){ void ChainComplex::KerCod(int dim){
if(dim < 1 || dim > 3 || _HMatrix[dim] == NULL) return; if(dim < 1 || dim > 3 || _HMatrix[dim] == NULL) return;
...@@ -580,11 +658,16 @@ void ChainComplex::KerCod(int dim){ ...@@ -580,11 +658,16 @@ void ChainComplex::KerCod(int dim){
return; return;
} }
/*
//j:B->Z //j:B_(k+1)->Z_k
void ChainComplex::Inclusion(int dim){ void ChainComplex::Inclusion(int dim){
if(dim < 1 || dim > 3 || _kerH[dim] == NULL || _codH[dim] == NULL) return; if(dim < 1 || dim > 2 || _kerH[dim] == NULL || _codH[dim+1] == NULL) return;
gmp_matrix* Zbasis = copy_gmp_matrix(_kerH[dim], 1, 1,
gmp_matrix_rows(_kerH[dim]), gmp_matrix_cols(_kerH[dim]));
gmp_matrix* Bbasis = copy_gmp_matrix(_codH[dim+1], 1, 1,
gmp_matrix_rows(_codH[dim+1]), gmp_matrix_cols(_codH[dim+1]));
int rows = gmp_matrix_rows(Zbasis); int rows = gmp_matrix_rows(Zbasis);
int cols = gmp_matrix_cols(Zbasis); int cols = gmp_matrix_cols(Zbasis);
...@@ -594,18 +677,13 @@ void ChainComplex::Inclusion(int dim){ ...@@ -594,18 +677,13 @@ void ChainComplex::Inclusion(int dim){
cols = gmp_matrix_cols(Bbasis); cols = gmp_matrix_cols(Bbasis);
if(rows < cols) return; if(rows < cols) return;
gmp_matrix* Zbasis = copy_gmp_matrix(_ker[dim], 1, 1,
gmp_matrix_rows(_kerH[dim]), gmp_matrix_cols(_kerH[dim]));
gmp_matrix* Bbasis = copy_gmp_matrix(_cod[dim], 1, 1,
gmp_matrix_rows(_codH[dim]), gmp_matrix_cols(_codH[dim]));
// A*inv(V) = U*S // A*inv(V) = U*S
normalForm = create_gmp_Smith_normal_form(Zbasis, NOT_INVERTED, INVERTED); gmp_normal_form* normalForm = create_gmp_Smith_normal_form(Zbasis, INVERTED, INVERTED);
mpz_t elem; mpz_t elem;
mpz_init(elem); mpz_init(elem);
for(int i = 1; i < cols; i++){ for(int i = 1; i <= cols; i++){
gmp_matrix_get_elem(elem, i, i, normalForm->canonical); gmp_matrix_get_elem(elem, i, i, normalForm->canonical);
if(mpz_cmp_si(elem,0) == 0){ if(mpz_cmp_si(elem,0) == 0){
destroy_gmp_normal_form(normalForm); destroy_gmp_normal_form(normalForm);
...@@ -617,8 +695,144 @@ void ChainComplex::Inclusion(int dim){ ...@@ -617,8 +695,144 @@ void ChainComplex::Inclusion(int dim){
gmp_matrix* LB = copy_gmp_matrix(Bbasis, 1, 1, gmp_matrix_cols(Zbasis), gmp_matrix_cols(Bbasis));
destroy_gmp_matrix(Bbasis);
rows = gmp_matrix_rows(LB);
cols = gmp_matrix_cols(LB);
mpz_t divisor;
mpz_init(divisor);
mpz_t remainder;
mpz_init(remainder);
mpz_t result;
mpz_init(result);
for(int i = 1; i <= rows; i++){
gmp_matrix_get_elem(divisor, i, i, normalForm->canonical);
for(int j = 1; j <= cols; j++){
gmp_matrix_get_elem(elem, i, j, LB);
mpz_cdiv_qr(result, remainder, elem, divisor);
if(mpz_cmp_si(remainder, 0) == 0){
gmp_matrix_set_elem(result, i, j, LB);
} }
*/ else return;
}
}
gmp_matrix_left_mult(normalForm->right, LB);
_JMatrix[dim] = LB;
mpz_clear(elem);
mpz_clear(divisor);
mpz_clear(result);
destroy_gmp_normal_form(normalForm);
return;
}
void ChainComplex::Quotient(int dim){
if(dim < 1 || dim > 3 || _JMatrix[dim] == NULL) return;
gmp_matrix* JMatrix = copy_gmp_matrix(_JMatrix[dim], 1, 1,
gmp_matrix_rows(_JMatrix[dim]), gmp_matrix_cols(_JMatrix[dim]));
int rows = gmp_matrix_rows(JMatrix);
int cols = gmp_matrix_cols(JMatrix);
gmp_normal_form* normalForm = create_gmp_Smith_normal_form(JMatrix, NOT_INVERTED, NOT_INVERTED);
mpz_t elem;
mpz_init(elem);
for(int i = 1; i <= cols; i++){
gmp_matrix_get_elem(elem, i, i, normalForm->canonical);
if(mpz_cmp_si(elem,0) == 0){
destroy_gmp_normal_form(normalForm);
return;
}
if(mpz_cmp_si(elem,1) > 0){
_torsion[dim].push_back(mpz_get_si(elem));
}
}
int rank = cols - _torsion[dim].size();
if(rows - rank > 0){
gmp_matrix* Hbasis = copy_gmp_matrix(normalForm->left, 1, rank+1, rows, rows);
_QMatrix[dim] = Hbasis;
}
mpz_clear(elem);
destroy_gmp_normal_form(normalForm);
return;
}
void ChainComplex::computeHomology(){
for(int i=0; i < 4; i++){
KerCod(i+1);
// 1) no edges, but zero cells
if(i == 0 && gmp_matrix_cols(getHMatrix(0)) > 0 && getHMatrix(1) == NULL) {
_Hbasis[i] = create_gmp_matrix_identity(gmp_matrix_cols(getHMatrix(0)));
}
// 2) this dimension is empty
else if(getHMatrix(i) == NULL && getHMatrix(i+1) == NULL){
_Hbasis[i] = NULL;
}
// 3) No higher dimension cells -> none of the cycles are boundaries
else if(getHMatrix(i+1) == NULL){
_Hbasis[i] = copy_gmp_matrix(getKerHMatrix(i), 1, 1,
gmp_matrix_rows(getKerHMatrix(i)), gmp_matrix_cols(getKerHMatrix(i)));
}
// 5) General case:
// 1) Find the bases of boundaries B and cycles Z
// 2) find j: B -> Z and
// 3) find quotient Z/j(B)
else {
// 4) No lower dimension cells -> all chains are cycles
if(getHMatrix(i) == NULL){
_kerH[i] = create_gmp_matrix_identity(gmp_matrix_rows(getHMatrix(i+1)));
}
Inclusion(i);
Quotient(i);
if(getCodHMatrix(i+1) == NULL){
_Hbasis[i] = getKerHMatrix(i);
}
else if(getJMatrix(i) == NULL || getQMatrix(i) == NULL){
_Hbasis[i] = NULL;
}
else{
_Hbasis[i] = copy_gmp_matrix(getKerHMatrix(i), 1, 1,
gmp_matrix_rows(getKerHMatrix(i)), gmp_matrix_cols(getKerHMatrix(i)));
gmp_matrix_right_mult(_Hbasis[i], getQMatrix(i));
}
}
destroy_gmp_matrix(_kerH[i]);
destroy_gmp_matrix(_codH[i]);
destroy_gmp_matrix(_JMatrix[i]);
destroy_gmp_matrix(_QMatrix[i]);
_kerH[i] = NULL;
_codH[i] = NULL;
_JMatrix[i] = NULL;
_QMatrix[i] = NULL;
}
return;
}
void ChainComplex::matrixTest(){ void ChainComplex::matrixTest(){
......
...@@ -28,6 +28,8 @@ extern "C" { ...@@ -28,6 +28,8 @@ extern "C" {
#include "gmp_normal_form.h" // perhaps make c++ headers instead? #include "gmp_normal_form.h" // perhaps make c++ headers instead?
} }
#endif
// Abstract class representing a cell of a cell complex. // Abstract class representing a cell of a cell complex.
class Cell class Cell
{ {
...@@ -364,9 +366,12 @@ class CellComplex ...@@ -364,9 +366,12 @@ class CellComplex
virtual void insertCells(bool subdomain); virtual void insertCells(bool subdomain);
public: public:
CellComplex( std::set<Cell*, Less_Cell>* cells ) { CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain, std::set<Cell*, Less_Cell> cells ) {
for(int i = 0; i < 4; i++){ _domain = domain;
//_cells[i] = cells[i]; _subdomain = subdomain;
for(citer cit = cells.begin(); cit != cells.end(); cit++){
Cell* cell = *cit;
_cells[cell->getDim()].insert(cell);
} }
} }
CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain ); CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain );
...@@ -396,24 +401,32 @@ class CellComplex ...@@ -396,24 +401,32 @@ class CellComplex
virtual std::vector< std::set<Cell*, Less_Cell>::iterator > cbdIt(Cell* tau); virtual std::vector< std::set<Cell*, Less_Cell>::iterator > cbdIt(Cell* tau);
// remove a cell from this cell complex // remove a cell from this cell complex
virtual void removeCell(Cell* cell); virtual void removeCell(Cell* cell, bool deleteCell=true);
virtual void removeCellIt(std::set<Cell*, Less_Cell>::iterator cell); virtual void removeCellIt(std::set<Cell*, Less_Cell>::iterator cell);
virtual void insertCell(Cell* cell);
// check whether two cells both belong to subdomain or if neither one does // check whether two cells both belong to subdomain or if neither one does
virtual bool inSameDomain(Cell* c1, Cell* c2) const { return virtual bool inSameDomain(Cell* c1, Cell* c2) const { return
( (!c1->inSubdomain() && !c2->inSubdomain()) || (c1->inSubdomain() && c2->inSubdomain()) ); } ( (!c1->inSubdomain() && !c2->inSubdomain()) || (c1->inSubdomain() && c2->inSubdomain()) ); }
// coreduction of this cell complex // coreduction of this cell complex
// removes corection pairs of cells of dimension dim and dim+1 // removes corection pairs of cells of dimension dim and dim+1
virtual int coreduction(int dim); virtual int coreduction(int dim, bool deleteCells=true);
// stores removed cells
virtual int coreduction(int dim, std::set<Cell*, Less_Cell>& removedCells);
// reduction of this cell complex // reduction of this cell complex
// removes reduction pairs of cell of dimension dim and dim-1 // removes reduction pairs of cell of dimension dim and dim-1
virtual int reduction(int dim); virtual int reduction(int dim, bool deleteCells=true);
// useful functions for (co)reduction of cell complex // useful functions for (co)reduction of cell complex
virtual void reduceComplex(); virtual void reduceComplex();
virtual void coreduceComplex(); virtual void coreduceComplex();
// stores cells removed after removal of generatos of dimension generatorDim
virtual void coreduceComplex(int generatorDim, std::set<Cell*, Less_Cell>& removedCells);
// queued coreduction presented in Mrozek's paper // queued coreduction presented in Mrozek's paper
// slower, but produces cleaner result // slower, but produces cleaner result
virtual int coreductionMrozek(Cell* generator); virtual int coreductionMrozek(Cell* generator);
...@@ -429,15 +442,19 @@ class CellComplex ...@@ -429,15 +442,19 @@ class CellComplex
// get the boundary operator matrix dim->dim-1 // get the boundary operator matrix dim->dim-1
//virtual gmp_matrix* getHMatrix(int dim) { return _HMatrix[dim]; } //virtual gmp_matrix* getHMatrix(int dim) { return _HMatrix[dim]; }
#if defined(HAVE_KBIPACK)
// construct boundary operator matrices of this cell complex // construct boundary operator matrices of this cell complex
// used to construct a chain complex // used to construct a chain complex
virtual std::vector<gmp_matrix*> constructHMatrices(); virtual std::vector<gmp_matrix*> constructHMatrices();
#endif
}; };
#if defined(HAVE_KBIPACK)
// A class representing a chain complex of a cell complex. // A class representing a chain complex of a cell complex.
// This should only be constructed for a reduced cell complex because of // This should only be constructed for a reduced cell complex because of
// dense matrix reprentations and great computational complexity in its methods. // dense matrix representations and great computational complexity in its methods.
class ChainComplex{ class ChainComplex{
private: private:
// boundary operator matrices for this chain complex // boundary operator matrices for this chain complex
...@@ -450,7 +467,10 @@ class ChainComplex{ ...@@ -450,7 +467,10 @@ class ChainComplex{
gmp_matrix* _JMatrix[4]; gmp_matrix* _JMatrix[4];
gmp_matrix* _QMatrix[4]; gmp_matrix* _QMatrix[4];
std::vector<int> _torsion[4]; std::vector<long int> _torsion[4];
// bases for homology groups
gmp_matrix* _Hbasis[4];
public: public:
...@@ -463,6 +483,7 @@ class ChainComplex{ ...@@ -463,6 +483,7 @@ class ChainComplex{
_codH[i] = NULL; _codH[i] = NULL;
_JMatrix[i] = NULL; _JMatrix[i] = NULL;
_QMatrix[i] = NULL; _QMatrix[i] = NULL;
_Hbasis[i] = NULL;
} }
} }
...@@ -473,25 +494,30 @@ class ChainComplex{ ...@@ -473,25 +494,30 @@ class ChainComplex{
_codH[i] = NULL; _codH[i] = NULL;
_JMatrix[i] = NULL; _JMatrix[i] = NULL;
_QMatrix[i] = NULL; _QMatrix[i] = NULL;
_Hbasis[i] = NULL;
} }
} }
virtual ~ChainComplex(){} virtual ~ChainComplex(){}
// get the boundary operator matrix dim->dim-1 // get the boundary operator matrix dim->dim-1
virtual gmp_matrix* getHMatrix(int dim) { return _HMatrix[dim]; } virtual gmp_matrix* getHMatrix(int dim) { if(dim > -1 || dim < 4) return _HMatrix[dim]; else return NULL;}
virtual gmp_matrix* getKerHMatrix(int dim) { return _kerH[dim]; } virtual gmp_matrix* getKerHMatrix(int dim) { if(dim > -1 || dim < 4) return _kerH[dim]; else return NULL;}
virtual gmp_matrix* getCodHMatrix(int dim) { return _codH[dim]; } virtual gmp_matrix* getCodHMatrix(int dim) { if(dim > -1 || dim < 4) return _codH[dim]; else return NULL;}
virtual gmp_matrix* getJMatrix(int dim) { return _JMatrix[dim]; } virtual gmp_matrix* getJMatrix(int dim) { if(dim > -1 || dim < 4) return _JMatrix[dim]; else return NULL;}
virtual gmp_matrix* getQMatrix(int dim) { return _QMatrix[dim]; } virtual gmp_matrix* getQMatrix(int dim) { if(dim > -1 || dim < 4) return _QMatrix[dim]; else return NULL;}
virtual gmp_matrix* getHbasis(int dim) { if(dim > -1 || dim < 4) return _Hbasis[dim]; else return NULL;}
// Compute basis for kernel and codomain of boundary operator matrix of dimension dim (ie. ker(h_dim) and cod(h_dim) ) // Compute basis for kernel and codomain of boundary operator matrix of dimension dim (ie. ker(h_dim) and cod(h_dim) )
virtual void KerCod(int dim); virtual void KerCod(int dim);
// Compute matrix representation J for inclusion relation from dim-cells who are boundary of dim+1-cells // Compute matrix representation J for inclusion relation from dim-cells who are boundary of dim+1-cells
// to cycles of dim-cells (ie. j: cod(h_(dim+1)) -> ker(h_dim) ) // to cycles of dim-cells (ie. j: cod(h_(dim+1)) -> ker(h_dim) )
virtual void Inclusion(int dim){} virtual void Inclusion(int dim);
// Compute quotient problem for given inclusion relation j to find representatives of homology groups // Compute quotient problem for given inclusion relation j to find representatives of homology groups
// and possible torsion coeffcients // and possible torsion coeffcients
virtual void Quotient(int dim){} virtual void Quotient(int dim);
// Compute bases for the homology groups of this chain complex
virtual void computeHomology();
virtual int printMatrix(gmp_matrix* matrix){ virtual int printMatrix(gmp_matrix* matrix){
printf("%d rows and %d columns\n", gmp_matrix_rows(matrix), gmp_matrix_cols(matrix)); printf("%d rows and %d columns\n", gmp_matrix_rows(matrix), gmp_matrix_cols(matrix));
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
P.O.Box 692, FIN-33101 Tampere, Finland P.O.Box 692, FIN-33101 Tampere, Finland
saku.suuriniemi@tut.fi saku.suuriniemi@tut.fi
$Id: gmp_matrix.c,v 1.2 2009-04-03 11:06:12 matti Exp $ $Id: gmp_matrix.c,v 1.3 2009-04-14 10:02:22 matti Exp $
*/ */
...@@ -281,6 +281,24 @@ gmp_matrix_get_elem(mpz_t elem, size_t row, size_t col, ...@@ -281,6 +281,24 @@ gmp_matrix_get_elem(mpz_t elem, size_t row, size_t col,
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* (matrix(row, col)) <- elem */
int
gmp_matrix_set_elem(mpz_t elem, size_t row, size_t col,
const gmp_matrix * m)
{
#ifdef DEBUG
if(m == NULL)
{
return EXIT_FAILURE;
}
#endif
mpz_set(m -> storage[(col-1)*(m -> rows)+row-1], elem);
return EXIT_SUCCESS;
}
int int
gmp_matrix_swap_rows(size_t row1, size_t row2, gmp_matrix * m) gmp_matrix_swap_rows(size_t row1, size_t row2, gmp_matrix * m)
{ {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
P.O.Box 692, FIN-33101 Tampere, Finland P.O.Box 692, FIN-33101 Tampere, Finland
saku.suuriniemi@tut.fi saku.suuriniemi@tut.fi
$Id: gmp_matrix.h,v 1.2 2009-04-03 11:06:13 matti Exp $ $Id: gmp_matrix.h,v 1.3 2009-04-14 10:02:22 matti Exp $
*/ */
#ifndef __GMP_MATRIX_H__ #ifndef __GMP_MATRIX_H__
...@@ -72,6 +72,11 @@ int ...@@ -72,6 +72,11 @@ int
gmp_matrix_get_elem(mpz_t elem, size_t row, size_t col, gmp_matrix_get_elem(mpz_t elem, size_t row, size_t col,
const gmp_matrix *); const gmp_matrix *);
/* (matrix(row, col)) <- elem */
int
gmp_matrix_set_elem(mpz_t elem, size_t row, size_t col,
const gmp_matrix *);
int int
gmp_matrix_swap_rows(size_t row1, size_t row2, gmp_matrix *); gmp_matrix_swap_rows(size_t row1, size_t row2, gmp_matrix *);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment