Пример #1
0
QList<int> FnWord::abelianization(const Basis &basis) const {

    // returns an integer list of basis elements exponent sums

    int rank = basis.getRank();
    QList<int> abelian_image;

    for(int i = 0; i < rank; i++)
        abelian_image.append(count(basis.at(2*i)) - count(basis.at(2*i+1)));

    return abelian_image;

}
Пример #2
0
QList<int> FnWord::stepTwoNilpotentNormalForm(const Basis & basis) const {
    
    // returns an integer list of the two step nilpotent normal form of the element

    int rank = basis.getRank();
    QList<int> nilpotent_image = abelianization(basis);
    QList<int> commutator_portion;

    int index = 0;
    for(int i = 0; i < rank; i++) {
        for(int j = i+1; j < rank; j++) {

            QString ijBasis(basis);
            ijBasis.remove(2*j,2);
            ijBasis.remove(2*i,2);

            FnWord ijWord(*this);
            ijWord.remove(QRegExp("["+ijBasis+"]"));
            ijWord.tighten();

            // integrate -y dx
            int integral = 0;
            commutator_portion.append(0);
            for(int k = 0; k < ijWord.length(); k++) {

                if(ijWord.at(k) == basis.at(2*i))
                    commutator_portion[index] += integral;
                if(ijWord.at(k) == basis.at(2*i + 1))
                    commutator_portion[index] -= integral;
                if(ijWord.at(k) == basis.at(2*j))
                    integral -= 1;
                if(ijWord.at(k) == basis.at(2*j + 1))
                    integral += 1;

            }

            index++;

        }

    }

    nilpotent_image.append(commutator_portion);

    return nilpotent_image;

}
Пример #3
0
FnGraph FnWord::whiteheadGraph(const Basis &basis) const {

    FnGraph whitehead;
    QString edge;
    int i;

    for(i = 0; i < 2*basis.getRank(); i++)
        whitehead.addVertex(basis.at(i));

    for(i = 0; i < length()-1; i++)
        whitehead.addEdge(edge.setNum(i),at(i),basis.inverse(at(i+1)));

    whitehead.addEdge(edge.setNum(i),at(i),basis.inverse(at(0)));

    return whitehead;

}
Пример #4
0
FnMap whiteheadProblem(const FnWord &u, const FnWord &v,
                         const Basis &basis)
{

  /* Determines if there is an automorphism phi such that u = phi(v).
     If yes, the map is returned.  Else, the Fail map is returned. */

  int i,r = basis.getRank();
  int min_len;
  FnWord tmp,v_tmp;
  FnWord u_min,v_min;
  FnMap phi(r);
  FnMap whAuto(r);
  FnMap rho(r),sigma(r),tau(r);
  FnMap phi_u(r),phi_v(r),phi_u_inv(r);

  // get minimal length representatives
  phi_u = minimizeLength(u,basis);
  phi_v = minimizeLength(v,basis);

  u_min = phi_u(u);
  v_min = phi_v(v);

  // easy case, minimum lengths are different
  if (u_min.length() != v_min.length()) { 
    phi.fail();
    return phi;
  }

  min_len = u_min.length();
  phi_u_inv = phi_u.isAutomorphism();

  // other easy case, u_min = v_min
  if (u_min == v_min) { // u = phi_u^-1 (phi_v(v))
    phi = phi_u_inv*phi_v;
    return phi;
  }

  // now the hard case... need to find all words of length u_min related
  // by Whitehead moves and permutations...

  // build Whitehead data
  QList<WhiteheadData> whAutos = whiteheadAutos(basis);
  QListIterator<WhiteheadData> move(whAutos);

  // define the permutation automorphisms
  for (i = 0; i < r-1; i++) { // i -> i+1
    rho.insert(basis.at(2*i),FnWord(basis.at(2*i + 2)));
    rho.insert(basis.at(2*i + 1),FnWord(basis.at(2*i + 3)));
  }
  rho.insert(basis.at(2*r - 2),FnWord(basis.at(0)));
  rho.insert(basis.at(2*r - 1),FnWord(basis.at(1)));

  sigma.insert(basis.at(0),FnWord(basis.at(1))); // a -> A
  sigma.insert(basis.at(1),FnWord(basis.at(0))); // A -> a

  tau.insert(basis.at(0),FnWord(basis.at(2))); // a -> b
  tau.insert(basis.at(1),FnWord(basis.at(3))); // A -> B
  tau.insert(basis.at(2),FnWord(basis.at(0))); // b -> a
  tau.insert(basis.at(3),FnWord(basis.at(1))); // B -> A

  int n = 0;
  QList<FnWord> v_rel;
  QHash<FnWord, FnMap> wh_v; // wh_v[x](v_min) = x

  v_rel.append(v_min);
  wh_v.insert(v_min,FnMap(r));

  // looped over words with the same length as v
  while (n < v_rel.size()) {

    v_tmp = v_rel.at(n++);
    move.toFront();

    // loop over Whitehead moves
    while (move.hasNext()) {
      whAuto = whitehead(move.next(),basis);
      tmp = whAuto(v_tmp);
      if (tmp.length() == min_len) {
        if (!v_rel.contains(tmp)) {
          v_rel.append(tmp);
          wh_v.insert(tmp,whAuto*wh_v.value(v_tmp));
        }
        if (tmp == u_min) { // found it!
          phi_v = wh_v.value(tmp)*phi_v; // phi_u(u) = tmp = phi_v(v)
          phi = phi_u_inv*phi_v; // u = phi_u^-1 phi_v(v)
          return phi;
        }
      }
    } // end while (move.hasNext())

    // loop over permutation moves, these don't change length
    tmp = rho(v_tmp);
    if (!v_rel.contains(tmp)) {
      v_rel.append(tmp);
      wh_v.insert(tmp,rho*wh_v.value(v_tmp));
    }
    if (tmp == u_min) { // found it!
      phi_v = wh_v.value(tmp)*phi_v; // phi_u(u) = tmp = phi_v(v)
      phi = phi_u_inv*phi_v; // u = phi_u^-1 phi_v(v)
      return phi;
    }

    tmp = sigma(v_tmp);
    if (!v_rel.contains(tmp)) {
      v_rel.append(tmp);
      wh_v.insert(tmp,sigma*wh_v.value(v_tmp));
    }
    if (tmp == u_min) { // found it!
      phi_v = wh_v.value(tmp)*phi_v; // phi_u(u) = tmp = phi_v(v)
      phi = phi_u_inv*phi_v; // u = phi_u^-1 phi_v(v)
      return phi;
    }

    tmp = tau(v_tmp);
    if (!v_rel.contains(tmp)) {
      v_rel.append(tmp);
      wh_v.insert(tmp,tau*wh_v.value(v_tmp));
    }
    if (tmp == u_min) { // found it!
      phi_v = wh_v.value(tmp)*phi_v; // phi_u(u) = tmp = phi_v(v)
      phi = phi_u_inv*phi_v; // u = phi_u^-1 phi_v(v)
      return phi;
    }

  } // end while (x.hasNext())

  // didn't find it
  phi.fail();

  return phi;

}