void MalcevSet::makeNormalClosure() { if(isNormal == yes) return; const BasicCommutators& BC = theCollector.commutators(); int nilClass = BC.nilpotencyClass(); int upper_i = BC.theFirstOfWeight(nilClass); for(int i = 1; i <= upper_i; i++) { if( ! theSet.bound( Generator(i) ) ) continue; PolyWord Wi = theSet.valueOf( Generator(i) ); PolyWord WiInv = Wi.inverse(); // trying generators of the group for(int j = 1; j <= BC.numberOfGenerators(); j++) { Generator g(j); PolyWord comm = collect( Wi * Letter(g,-1) * WiInv * Letter(g,1) ); addWord(comm); } // trying basis elements int upper_j = BC.theFirstOfWeight(nilClass - BC.weightOf(i) + 1); if(upper_j > i) upper_j = i; for(int j = 1; j < upper_j; j++) { if( ! theSet.bound( Generator(j) ) ) continue; PolyWord Wj = theSet.valueOf( Generator(j) ); PolyWord comm = collect( Wi * Wj * WiInv * Wj.inverse() ); addWord(comm); } } isBasis = true; isNormal = yes; }
bool MalcevSet::reduceWords(PolyWord& pw1, PolyWord& pw2) const { if(pw1.isEmpty() || pw2.isEmpty()) error("MalcevSet::reduceWords: empty argument"); bool firstChanged = false; int power1 = absPower(pw1); int power2 = absPower(pw2); // make both PolyWords to be of distinct signs if( sign(pw1) ^ sign(pw2) == 0) // if they have the same sign pw2 = pw2.inverse(); // in fact, this is Euclid algorithm for finding GCD do { if( power1 > power2 ) { // swapping two words PolyWord tmp = pw1; pw1 = pw2; pw2 = tmp; int t = power1; power1 = power2; power2 = t; firstChanged = true; } power2 -= power1; pw2 = theCollector.multiply(pw1, pw2); } while(power2 != 0); return firstChanged; }