AbelianGroup MalcevSet::mapToQuotient(int k) const { if( ! isBasis ) error("MalcevSet::mapToQuotient: the set must be full"); // The generators of the quotient are basic commutators of weight k. const BasicCommutators& bc = theCollector.commutators(); int numGen = bc.numberOfWeight(k); int firstGen = bc.theFirstOfWeight(k) - 1; // The relators are Malcev basis words of weight k SetOf<Word> relsForAbelian; QuickAssociationsIterator< Generator, PolyWord > iter(theSet); for( ; ! iter.done(); iter.next() ) { // take a word from Malcev basis PolyWord pw = iter.value(); Letter first = pw.firstLetter(); if( ord(first.gen) != firstGen ) continue; //Ok, this is a word from the quotient. Abelianize it. ConstPolyWordIterator iter( pw ); Word w; for(iter.startFromLeft(); ! iter.done(); iter.stepRight() ) { Letter s = iter.thisLetter(); int newgen = ord(s.gen) - firstGen; if( newgen > numGen ) break; s.gen = Generator( newgen ); w *= Word(s); } relsForAbelian.adjoinElement(w); } // make the abelian quotient AbelianGroup abel( FPGroup(numGen, relsForAbelian) ); abel.computeCyclicDecomposition(); return abel; }
main() { int i,n=N; float f[N],g[N],e[N],a,r,k,dr,dk; void *at; a = 1.0; dr = dk = 1.0/n; for (i=0,r=0.0; i<n; ++i,r+=dr) { f[i] = a-r; } at = abelalloc(n); abel(at,f,g); for (i=0,k=0.0; i<n; ++i,k+=dk) { g[i] *= dr; e[i] = (k!=0.0 ? a*sqrt(a*a-k*k)-k*k*acosh(a/k) : a*a); } abelfree(at); fwrite(g,sizeof(float),n,stdout); fwrite(e,sizeof(float),n,stdout); }