コード例 #1
0
AbelianEquationsSolver::AbelianEquationsSolver( const AbelianGroup& a , 
						const VectorOf<Word>& v ,
						int numOfVar )
  : rawA( a ),
    A( FPGroup() ),
    rawSystem( v ),
    system( v.length() ),
    b( v.length() ),
    x( numOfVar ),
    torsion( numOfVar ),
    params( numOfVar ),
    numberOfVariables( numOfVar ),
    sysRank( 0 ),
    haveSol( -1 )
{
  FPGroup G( a.getFPGroup() );
  VectorOf<Chars> q( G.numberOfGenerators() - numberOfVariables );
  
  for( int i = numberOfVariables ; i < G.numberOfGenerators() ; i++ )
    q[ i - numberOfVariables ] = (G.namesOfGenerators())[i];
  
  if( G.getRelators().cardinality() )
    {
      SetOf<Word> s = G.getRelators();
      SetIterator<Word> I(s);
      SetOf<Word> news;
      
      while( !I.done() )
	{
	  Word w = I.value();
	  for( int j = 0 ; j < w.length() ; j++ )
	    {
	      int p = Generator( w[j] ).hash();
	      if( p > 0 )
		w[j] = Generator( p - numberOfVariables );
	      else
		w[j] = Generator( p + numberOfVariables );
	    }
	  
	  news.adjoinElement( w );
	  I.next();
	}
      
      FPGroup G1( q , news );
      
      A = AbelianGroup( G1 );
    }
  else
    A = AbelianGroup( FPGroup(q) );
  
}
コード例 #2
0
ファイル: MalcevSet.C プロジェクト: koudonojinchuu/magnus
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;
}
コード例 #3
0
ファイル: FPGroup.cpp プロジェクト: dpantele/crag
FPGroup FPGroup::triangulatePresentation( ) const
{
  int new_gen_num = numOfGenerators;
  char str[10];
  
  // rename old generators to avoid collisions
  vector< string > new_gen_names = initializeGenNames( numOfGenerators );
  vector< Word > new_relators;
  
  int new_gens_num = 0;
  for( vector< Word >::const_iterator r_it=theRelators.begin( ) ; r_it!=theRelators.end( ) ; ++r_it ) {
    
    const Word& rel = *r_it;
    int len = rel.length( );
    if( len>3 ) {

      // initial setup (first 3 letters)
      Word::const_iterator r_it = rel.begin( );
      int g1 = *r_it++;
      int g2 = *r_it++;
      int g3 = *r_it++;
      strstream(str,10) << (++new_gens_num) << ends;
      new_gen_names.push_back( string( "x" ).append( str ) );
      new_relators.push_back( Word( g1 )*Word( g2 )*Word( -new_gens_num ) );
      
      // iterations
      for( int i=0 ; i<len-4 ; ++i, ++r_it ) {
        strstream(str,10) << (++new_gens_num) << ends;
        new_gen_names.push_back( string( "x" ).append( str ) );
        int new_gen = new_gen_names.size( );
        new_relators.push_back( Word( new_gens_num-1 ) * Word(g3) * Generator( -new_gens_num ) );
        g3 = *r_it;
      }
      
      // the last relator
      new_relators.push_back( Word( g3 ) * Generator( *r_it ) * Word( -new_gens_num ) );
    } else
      new_relators.push_back( rel );
  }

  return FPGroup( FiniteAlphabet( new_gen_names) , new_relators );
}