VectorOf<Word> SGOfFreeNilpotentGroupRep::normalClosureBasis() const { //@ep I have found that the process is slower with the full basis, // so I form it from the scratch. MalcevSet newBasis(theGenerators, theParentGroup.collector()); newBasis.makeNormalClosure(); // The basis is found. Now we try to reduce it to make further // processing easier. VectorOf<Word> basis = newBasis.getCommutatorWords(); // First, we reduce words in terms of basic commutators. // We could proceed without this step, but it helps // to reduce the second one greatly. FreeGroup F( theParentGroup.theHirschNumber() ); basis = F.nielsenBasis(basis); // Convert words in terms of basic commutators to group // generators. for(int i = 0; i < basis.length(); i++) { PolyWord pw = basis.val(i); basis[i] = theParentGroup.commutators().wordForm().toWord(pw); } // Now reduce this vector FreeGroup F1( theParentGroup.numberOfGenerators() ); basis = F1.nielsenBasis(basis); return basis; }
void Homology::findCompatibleBasisPair(int master, std::vector<int> dim) { if(!this->isHomologyComputed(dim)) this->findHomologyBasis(dim); if(!this->isCohomologyComputed(dim)) this->findCohomologyBasis(dim); for(unsigned int idim = 0 ; idim < dim.size(); idim++) { int d = dim.at(idim); if(d < 1 || d > 2) continue; int n = this->betti(d); if(n < 2) continue; if((int)_chains[d].size() != n || (int)_cochains[d].size() != n) { Msg::Warning("Cannot produce compatible %d-(co)homology bases.", d); Msg::Debug("%d basis %d-chains and %d basis %d-cochains.", (int)_chains[d].size(), d, (int)_cochains[d].size(), d); continue; } fullMatrix<double> m(n,n); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(master==0) m(i,j) = incidence(*_cochains[d].at(i), *_chains[d].at(j)); else m(i,j) = incidence(*_chains[d].at(i), *_cochains[d].at(j)); } } int det = m.determinant(); if(abs(det) != 1 || !m.invertInPlace()) { Msg::Warning("Cannot produce compatible %d-(co)homology bases.", d); Msg::Debug("Incidence matrix: "); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) Msg::Debug("(%d, %d) = %d", i, j, m(i,j)); continue; } std::vector<Chain<int>*> newBasis(n); if(master==0) { for(int i = 0; i < n; i++) { newBasis.at(i) = new Chain<int>(); for(int j = 0; j < n; j++) { *newBasis.at(i) += (int)m(i,j)*(*_cochains[d].at(j)); } } for(int i = 0; i < n; i++) { newBasis.at(i)->setName(_cochains[d].at(i)->getName()); delete _cochains[d].at(i); _cochains[d].at(i) = newBasis.at(i); } } else { for(int i = 0; i < n; i++) { newBasis.at(i) = new Chain<int>(); for(int j = 0; j < n; j++) { *newBasis.at(i) += (int)m(i,j)*(*_chains[d].at(j)); } } for(int i = 0; i < n; i++) { newBasis.at(i)->setName(_chains[d].at(i)->getName()); delete _chains[d].at(i); _chains[d].at(i) = newBasis.at(i); } } } }