Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/simpcomp/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 18.2.2022 mit Größe 11 kB image not shown  

Quelle  isosig.gi   Sprache: unbekannt

 
###############################################################################
##
##  simpcomp / isosig.gi
##
##  Functions to compute the isomorphism signature of a complex
##
##  $Id$
##
################################################################################

################################################################################
##<#GAPDoc Label="SCExportIsoSig">
## <ManSection>
## <Meth Name="SCExportIsoSig" Arg="c"/>
## <Returns>string upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the isomorphism signature of a closed, strongly connected weak 
## pseudomanifold. The isomorphism signature is stored as an attribute of the
## complex.
## <Example><![CDATA[
## gap> c:=SCSeriesBdHandleBody(3,9);;
## gap> s:=SCExportIsoSig(c);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCExportIsoSig,
"for SCSimplicialComplex",
[SCIsSimplicialComplex],
function(c)
 local minl, i, j, k, n, nn, d, neighbors, facets, perm, l, queue, ctr, 
  ctr2, ctr3, labeling, current, face, s, isosig, done, next, 
  addNextValue;

 if SCIsEmpty(c) then
  return ".";
 fi;

 if SCHasBoundary(c) or not SCIsStronglyConnected(c) or not SCIsPseudoManifold(c) then
  Info(InfoSimpcomp,1,"SCExportIsoSig: argument must be a strongly connected closed pseudomanifold.");
  return fail;
 fi;

 addNextValue:=function(val)
  local lut,str,ctr,prefix;
  lut := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)!@#$%^&*(+.";
  str:="";
  if val = 0 then
   Add(str,lut[64]);
   return str;
  elif val > 0 and val < 64 then
   Add(str,lut[val]);
   return str;
  else
   ctr:=0;
   while val > 0 do
    ctr:=ctr+1;
    Add(str,lut[((val-1) mod 64)+1]);
    val := Int(val/64);
   od;
   prefix := ShallowCopy(String(ctr));
   str := Reversed(str);
   Append(prefix,str);
   return prefix;
  fi;
 end;

 facets := SCFacetsEx(c);
 if facets = fail then
  return fail;
 fi;
 n := Size(facets);
 s := Size(facets[1]);
 # build list of neighbors
 neighbors := [];
 for i in [1..n] do
  neighbors[i]:=[];
  for j in [1..n] do
   if i = j then continue; fi;
   if Size(Intersection(facets[i],facets[j])) = s-1 then
    Add(neighbors[i],j);
   fi;
  od;
 od;
 minl := [];
 for i in [1..n] do
  for perm in PermutationsList(facets[i]) do
   # for each "canonical labeling seed" calculate signature
   l := [];
   labeling := perm;
   queue := [i];
   done := [1];
   ctr := 0;
   ctr2 := 0;
   ctr3 := 0;
   next := false;
   while ctr2 < n-1 do
    ctr := ctr+1;
    current := queue[ctr];
    for j in labeling do
     if not j in facets[current] then continue; fi;
     face := ShallowCopy(facets[current]);
     Remove(face,Position(face,j));
     Sort(face);
     for nn in neighbors[current] do
      if nn in queue then continue; fi;
      if IsSubset(facets[nn],face) then
       Add(queue,nn);
       Add(done,0);
       break;
      fi;
     od;
     for k in neighbors[current] do
      if IsSubset(facets[k],face) then
       ctr3 := ctr3 + 1;
       if done[Position(queue,k)] = 1 then
        Add(l,0);
        continue;
       fi;
       d := Difference(facets[k],face)[1];
       if not d in labeling then
        Add(labeling,d);
        Add(l,Size(labeling));
        ctr2:=ctr2+1;
       else
        Add(l,Position(labeling,d));
        ctr2:=ctr2+1;
       fi;
       done[Position(queue,k)] := 1;
       if minl <> [] and l[ctr3] > minl[ctr3] then
        next:=true;
        break;
       elif minl <> [] and l[ctr3] < minl[ctr3] then
        minl := [];
       fi;
      fi;
     od;
     if next then
      break;
     fi;
    od;
    if next then
     break;
    fi;
   od;
   if not next and (minl = [] or l < minl) then
    minl := l;
   fi;
  od;
 od;
 isosig:="";
 # store dimension
 Append(isosig,addNextValue(s));
 # for first d facets skip is always zero: omit these zeros
 for i in [1..s] do
  Append(isosig,addNextValue(minl[i]));
 od;
 # store rest of minl
 ctr2 := 0;
 for i in [s+1..Size(minl)] do
  if minl[i] = 0 then 
   # if skip, count number of skips
   ctr2 := ctr2+1;
  else
   # add skip and next value to isosig
   Append(isosig,addNextValue(ctr2));
   Append(isosig,addNextValue(minl[i]));
   ctr2 := 0;
  fi;
 od;
 return isosig;
end);


################################################################################
##<#GAPDoc Label="SCExportToString">
## <ManSection>
## <Func Name="SCExportToString" Arg="c"/>
## <Returns>string upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes one string representation of a closed and strongly connected weak 
## pseudomanifold. Compare <Ref Func="SCExportIsoSig" />, which returns the
## lexicographically minimal string representation.
## <Example><![CDATA[
## gap> c:=SCSeriesBdHandleBody(3,9);;
## gap> s:=SCExportToString(c); time;
## gap> s:=SCExportIsoSig(c); time;
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCExportToString,
function(c)
 local i, j, k, n, nn, d, neighbors, facets, perm, l, queue, ctr, 
  ctr2, labeling, current, face, s, isosig, done,  
  addNextValue;

 if not SCIsSimplicialComplex(c) then
  Info(InfoSimpcomp,1,"SCExportToString: argument must be of type SCIsSimplicialComplex.");
  return fail;
 fi;

 if HasSCExportIsoSig(c) then
  return SCExportIsoSig(c);
 fi;

 if SCIsEmpty(c) then
  return ".";
 fi;

 if SCHasBoundary(c) or not SCIsStronglyConnected(c) or not SCIsPseudoManifold(c) then
  Info(InfoSimpcomp,1,"SCExportIsoSig: argument must be a strongly connected closed pseudomanifold.");
  return fail;
 fi;

 addNextValue:=function(val)
  local lut,str,ctr,prefix;
  lut := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)!@#$%^&*(+.";
  str:="";
  if val = 0 then
   Add(str,lut[64]);
   return str;
  elif val > 0 and val < 64 then
   Add(str,lut[val]);
   return str;
  else
   ctr:=0;
   while val > 0 do
    ctr:=ctr+1;
    Add(str,lut[((val-1) mod 64)+1]);
    val := Int(val/64);
   od;
   prefix := ShallowCopy(String(ctr));
   str := Reversed(str);
   Append(prefix,str);
   return prefix;
  fi;
 end;

 facets := SCFacetsEx(c);
 if facets = fail then
  return fail;
 fi;
 n := Size(facets);
 s := Size(facets[1]);
 # build list of neighbors
 neighbors := [];
 for i in [1..n] do
  neighbors[i]:=[];
  for j in [1..n] do
   if i = j then continue; fi;
   if Size(Intersection(facets[i],facets[j])) = s-1 then
    Add(neighbors[i],j);
   fi;
  od;
 od;
 # calculate signature for standard labeling of first facet
 l := [];
 labeling := ShallowCopy(facets[1]);
 queue := [1];
 done := [1];
 ctr := 0;
 ctr2 := 0;
 while ctr2 < n-1 do
  ctr := ctr+1;
  current := queue[ctr];
  for j in labeling do
   if not j in facets[current] then continue; fi;
   face := ShallowCopy(facets[current]);
   Remove(face,Position(face,j));
   Sort(face);
   for nn in neighbors[current] do
    if nn in queue then continue; fi;
    if IsSubset(facets[nn],face) then
     Add(queue,nn);
     Add(done,0);
     break;
    fi;
   od;
   for k in neighbors[current] do
    if IsSubset(facets[k],face) then
     if done[Position(queue,k)] = 1 then
      Add(l,0);
      continue;
     fi;
     d := Difference(facets[k],face)[1];
     if not d in labeling then
      Add(labeling,d);
      Add(l,Size(labeling));
      ctr2:=ctr2+1;
     else
      Add(l,Position(labeling,d));
      ctr2:=ctr2+1;
     fi;
     done[Position(queue,k)] := 1;
    fi;
   od;
  od;
 od;
 isosig:="";
 # store dimension
 Append(isosig,addNextValue(s));
 # for first d facets skip is always zero: omit these zeros
 for i in [1..s] do
  Append(isosig,addNextValue(l[i]));
 od;
 # store rest of minl
 ctr2 := 0;
 for i in [s+1..Size(l)] do
  if l[i] = 0 then 
   # if skip, count number of skips
   ctr2 := ctr2+1;
  else
   # add skip and next value to isosig
   Append(isosig,addNextValue(ctr2));
   Append(isosig,addNextValue(l[i]));
   ctr2 := 0;
  fi;
 od;
 return isosig;
end);


################################################################################
##<#GAPDoc Label="SCFromIsoSig">
## <ManSection>
## <Meth Name="SCFromIsoSig" Arg="str"/>
## <Returns>a SCSimplicialComplex object upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes a simplicial complex from its isomorphism signature. If a file with
## isomorphism signatures is provided a list of all complexes is returned.
## <Example><![CDATA[
## gap> s:="deeee";;
## gap> c:=SCFromIsoSig(s);;
## gap> SCIsIsomorphic(c,SCBdSimplex(4));
## ]]></Example>
## <Example><![CDATA[
## gap> s:="deeee";;
## gap> PrintTo("tmp.txt",s,"\n");;
## gap> cc:=SCFromIsoSig("tmp.txt");
## gap> cc[1].F;
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFromIsoSig,
"for String",
[IsString],
function(str)
 local sig, i, size, ctr1, ctr2, done, new, facets, comb, skip, val, tmp,
  s, getNextValue, c, cc, l;

 if IsExistingFile(str) then
  s := InputTextFile(str);
  l := ReadLine(s);
  cc :=[];
  while l <> fail do
   if l{[Size(l)]} <> "\n" then
    Info(InfoSimpcomp,1,"SCFromIsoSig: cannot read file format, line ended without newline.\n");
    return fail;
   fi;
   l := l{[1..Size(l)-1]};
   Add(cc,SCFromIsoSig(l));
   l :=ReadLine(s);
  od;
  return cc;
 fi;

 getNextValue:=function(str,idx)
  local lut,val,ctr,power,tmp,pos;
  lut := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)!@#$%^&*(+.";
  if Int(str{[idx]}) = fail then
   pos:=Position(lut,str[idx]);
   if pos = fail then
    Info(InfoSimpcomp,1,"SCFromIsoSig: invalid isomorphism signature provided.\n");
    return fail;
   fi;
   return [pos mod 64,idx+1];
  else
   val:=0;
   ctr := idx;
   while Int(str{[ctr]}) <> fail do
    ctr:=ctr+1;
   od;
   power:=Int(str{[idx..ctr-1]});
   for i in [1..power] do
    pos:=Position(lut,str[ctr]);
    if pos = fail then
     Info(InfoSimpcomp,1,"SCFromIsoSig: invalid isomorphism signature provided.\n");
     return fail;
    fi;
    val := val + (pos mod 64)*64^(power-i);
    ctr:=ctr+1;
   od;
   return [val,ctr];
  fi;
 end;

 if str = "" then
  Info(InfoSimpcomp,1,"SCFromIsoSig: isomorphism signature is empty.\n");
  return fail;
 fi;

 if str = "." then
  return SCEmpty();
 fi;

 sig:=[];
 tmp:=getNextValue(str,1);
 if tmp = fail then
  return fail;
 fi;
 size := tmp[1];
 ctr1 := tmp[2];
 facets:=[[1..size]];
 for i in [1..size] do
  Add(sig,0);
  tmp:=getNextValue(str,ctr1);
  if tmp = fail then
   return fail;
  fi;
  val := tmp[1];
  ctr1 := tmp[2];
  Add(sig,val);
 od;
 while ctr1 <= Size(str) do
  tmp:=getNextValue(str,ctr1);
  if tmp = fail then
   return fail;
  fi;
  val := tmp[1];
  ctr1 := tmp[2];
  Add(sig,val);
 od;
 ctr1:=1;
 ctr2:=1;
 done:=false;
 skip:=true;
 while not done do
  for comb in Reversed(Combinations(facets[ctr1],size-1)) do
   if skip then
    if ctr2 >= Size(sig) then
     done:=true;
     break;
    fi;
    if sig[ctr2] > 0 then
     sig[ctr2] := sig[ctr2]-1;
     continue;
    else
     ctr2 := ctr2+1;
     skip := false;
    fi;
   fi;
   if not skip then
    new:=Concatenation(comb,[sig[ctr2]]);
        Sort(new);
    Add(facets,new);
    ctr2:=ctr2+1;
    skip := true;
    if ctr2 > Size(sig) then
     done:=true;
     break;
    fi;
   fi;
  od;
  if not done then ctr1:=ctr1+1; fi;
 od;

 c := SCFromFacets(facets);

  if c = fail then
    Print(facets,"\n");    
  fi;

 SetSCExportIsoSig(c,str);

 return c;
end);


[ Dauer der Verarbeitung: 0.33 Sekunden  (vorverarbeitet)  ]