Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  blowups.gi   Sprache: unbekannt

 
################################################################################
##
##  simpcomp / blowups.gi
##
##  Functions for bistellar moves  
##
##  $Id: bistellar.gi 68 2010-04-23 14:08:15Z jonathan $
##
################################################################################

SCIntFunc.MapBoundaries:=function(lk,bd,pseudomanifold,singularity)

 local tmp,element,i,j,n,iso,c,
  dim_A,det_A,faces_A,F_A,F_B,
  mainDim,mainComplex,mainF,minComplex,
  raw_options,validOptions,options,randomelement,rounds,no_options_flag,
  flipsInBoundary,flipsInComplex,projectedFlips,validFlips ,
  heating,relaxation,f_min,F_min,ready_flag,numVerts,reduce,ctr;
 
 iso:=SCIsomorphism(bd,lk);
 if iso = fail then
  return fail;
 fi;
  
 # if boundaries are already isomorphic return isomorphism
 if iso <> [] then
  Info(InfoSimpcomp,1,"SCBlowup: boundaries isomorphic, no PL-homeomorphism ",
      "needed, continuing...");
  return [iso,pseudomanifold];
 fi;
 
 Info(InfoSimpcomp,1,"SCBlowup: boundaries not isomorphic, initializing ",
    "bistellar moves...");
 
 raw_options:=[];
 validOptions := [];
 # list of actual options for bistellar moves
 options:=[];
 # one element of options -> randomelement := [[element],[linkface]]
 randomelement:=[];
 # TECHNICAL VARIABLES #
 # number of rounds executed
 rounds:=0;
 # is set to "1" if no bistellar operations are left
 no_options_flag:=0;
 
 # comlpex A: lk
 dim_A:=SCDim(lk);
 det_A:=SCAltshulerSteinberg(lk);
 faces_A:=SCFaceLattice(lk);
 F_A:=SCFVector(lk); 
 if dim_A = fail or faces_A = fail or det_A = fail or F_A = fail then
  return fail;
 fi;
 
 # comlpex B: bd
 F_B:=SCFVector(bd); 
 if F_B = fail then
  return fail;
 fi;
 
 # main object: pseudomanifold
 # make face lattice and f-vector mutable
 mainComplex := ShallowCopy(SCFaceLattice(pseudomanifold));
 mainComplex:=List(mainComplex,x->ShallowCopy(x));
 mainF := ShallowCopy(SCFVector(pseudomanifold));
 numVerts := mainF[1];
 mainDim := SCDim(pseudomanifold);
 if mainComplex = fail or mainF = fail or mainDim = fail then
  return fail;
 fi;
 
 #############################################
 #                                           #
 #                                           #
 #   computing initial options for moves     #
 #                                           #
 #                                           #
 #############################################
 reduce := false;
 rounds:=1;
 f_min := ShallowCopy(F_A);
 minComplex:=SC(mainComplex[5]);
  
 while no_options_flag = 0 or rounds <= 100000 do
 
  ### computing possible flips in complex ###
  flipsInComplex := [];
  for i in [0..mainDim] do
   flipsInComplex[i+1] := SCIntFunc.IRawBistellarRMoves(i,mainComplex,(mainDim+1));
  od;
  
  if not reduce then
   ### computing possible flips in boundary ###
   flipsInBoundary := [];
   for i in [0..dim_A] do
    flipsInBoundary[i+1] := SCIntFunc.IRawBistellarRMoves(i,faces_A,(dim_A+1));
   od;
   # remove flips that DO NOT contain "singularity"
   tmp := [];
   n:=Size(flipsInComplex);
   for i in [1..n] do
    tmp[i] := [];
    for element in flipsInComplex[i] do
     if not singularity in element[1] and not singularity in element[2] then
      Add(tmp[i],element);
     fi;
    od;
   od;
   for i in [1..n] do
    flipsInComplex[i] := Difference(flipsInComplex[i],tmp[i]);
   od;
  else 
   # remove flips that DO contain "singularity"
   tmp := [];
   n:=Size(flipsInComplex);
   for i in [1..n] do
    tmp[i] := [];
    for element in flipsInComplex[i] do
     if singularity in element[1] or singularity in element[2] then
      Add(tmp[i],element);
     fi;
    od;
   od;
   for i in [1..n] do
    flipsInComplex[i] := Difference(flipsInComplex[i],tmp[i]);
   od;
  fi;
  
  # remove flips that aren't valid
  validFlips := [];
  for i in [0..mainDim] do
   validFlips[i+1] := SCIntFunc.IBistellarRMoves(i,(mainDim+1),flipsInComplex[i+1],mainComplex);
  od;
  flipsInComplex := ShallowCopy(validFlips);
  
  if not reduce then
   # compute projected flips
   projectedFlips := [];
   for i in [1..Size(flipsInComplex)] do
    projectedFlips[i] := [];
    for element in flipsInComplex[i] do
     tmp := [ Difference(element[1],[singularity]) , Difference(element[2],[singularity]) ];
     Add(projectedFlips[i],tmp);
    od;
   od;
   # computing intersection of projectedFlips and flipsInBoundary
   raw_options := [];
   for i in [1..Size(flipsInBoundary)] do
    raw_options[i] := [];
    for element in flipsInBoundary[i] do
     if element in projectedFlips[i] then
      Add(raw_options[i],element);
     fi;
    od;
   od;
  else
   raw_options := ShallowCopy(flipsInComplex);
  fi;
 
  ### initial parameters ###
  heating:=0;
  relaxation:=0;
  if reduce then
   ctr:=0;
  fi;
  
  while no_options_flag = 0 and rounds <= 100000 do    
   ### strategy for selecting options ###
   options:=[];
   if reduce then
    ctr:=ctr+1;
   fi;
   
   if reduce and (mainF[1] < 3/2*numVerts or ctr >= 5000) then
    reduce := false;
    # main object: pseudomanifold
    # make face lattice and f-vector mutable
    mainComplex := ShallowCopy(SCFaceLattice(minComplex));
    mainComplex:=List(mainComplex,x->ShallowCopy(x));
    mainF := ShallowCopy(SCFVector(minComplex));
    mainDim := SCDim(minComplex);
    if mainComplex = fail or mainF = fail or mainDim = fail then
     return fail;
    fi;
    lk:=SCLink(minComplex,singularity);
    dim_A:=SCDim(lk);
    det_A:=SCAltshulerSteinberg(lk);
    faces_A:=SCFaceLattice(lk);
    F_A:=SCFVector(lk); 
    if dim_A = fail or faces_A = fail or det_A = fail or F_A = fail then
     return fail;
    fi;
    break;
   fi;
   
   if not reduce and mainF[1] > 3*numVerts then
    reduce := true;
    # main object: pseudomanifold
    # make face lattice and f-vector mutable
    mainComplex := ShallowCopy(SCFaceLattice(minComplex));
    mainComplex:=List(mainComplex,x->ShallowCopy(x));
    mainF := ShallowCopy(SCFVector(minComplex));
    F_min := ShallowCopy(mainF);
    mainDim := SCDim(minComplex);
    if mainComplex = fail or mainF = fail or mainDim = fail then
     return fail;
    fi;
    break;
   fi;
   
   if not reduce then
    
    if heating > 0 then
     if IsInt(heating/15) = true and f_min > F_B then
      tmp := SCIntFunc.IBistellarRMoves(0,(dim_A+1),raw_options[1],faces_A);
      Append(options,tmp);
     else
      tmp := SCIntFunc.IBistellarRMoves(1,(dim_A+1),raw_options[2],faces_A);
      Append(options,tmp);
      if options = [] then
       tmp := SCIntFunc.IBistellarRMoves(2,(dim_A+1),raw_options[3],faces_A);
       Append(options,tmp);
       heating:=0;
      fi;
     fi;
     heating:=heating-1;
    else
     tmp := SCIntFunc.IBistellarRMoves(3,(dim_A+1),raw_options[4],faces_A);
     Append(options,tmp);
     if options = [] then
      tmp := SCIntFunc.IBistellarRMoves(2,(dim_A+1),raw_options[3],faces_A);
      Append(options,tmp);
      if options = [] then
       tmp := SCIntFunc.IBistellarRMoves(1,(dim_A+1),raw_options[2],faces_A);
       Append(options,tmp);
       if relaxation = 10 then
        heating:=15;
        relaxation:=0;
       fi;
       relaxation:=relaxation+1;
       if options = [] then
        tmp := SCIntFunc.IBistellarRMoves(0,(dim_A+1),raw_options[1],faces_A);
        options := Union(options,tmp);
       fi;
      fi;
     fi;
    fi;
    
    # choosing move at random
    if no_options_flag <> 0 then
     Info(InfoSimpcomp,1,"SCBlowup: no valid flip found.");
     return fail;
    fi;
    # check, if possible options are available
    if options = [] then
     Info(InfoSimpcomp,1,"SCBlowup: no options left for bistellar moves...");
     return fail;
    fi;
    
    # chose move in boundary
    tmp:=RandomList(options);
    
    # check, if there's a corresponding move in the main complex
    ready_flag := 0;
    for i in [1..Size(flipsInComplex)] do
     if ready_flag = 0 then
      for element in flipsInComplex[i] do
       if IsSubset(element[1],tmp[1]) and IsSubset(element[2],tmp[2]) then
        randomelement := element;
        ready_flag := 1;
        break;
       fi;
      od;
     else
      break;
     fi;
    od;
    
    # re-check existence of randomelement in complex
    ready_flag := 0;
    for i in [1..Size(flipsInComplex)] do
     if Intersection(flipsInComplex[i],[randomelement]) <> [] then
      ready_flag := 1;
      break;
     fi;
    od;
     
   else
    
    if heating > 0 then
     if IsInt(heating/20) = true then
       tmp := SCIntFunc.IBistellarRMoves(0,(mainDim+1),raw_options[1],mainComplex);
       Append(options,tmp);
     else
       tmp := SCIntFunc.IBistellarRMoves(1,(mainDim+1),raw_options[2],mainComplex);
       Append(options,tmp);
       tmp := SCIntFunc.IBistellarRMoves(2,(mainDim+1),raw_options[3],mainComplex);
       Append(options,tmp);
       if options = [] then
        tmp := SCIntFunc.IBistellarRMoves(3,(mainDim+1),raw_options[4],mainComplex);
        Append(options,tmp);
       fi;
     fi;
     heating:=heating-1;
    else
     tmp := SCIntFunc.IBistellarRMoves(4,(mainDim+1),raw_options[5],mainComplex);
     Append(options,tmp);
     if options = [] then
       tmp := SCIntFunc.IBistellarRMoves(3,(mainDim+1),raw_options[4],mainComplex);
       Append(options,tmp);
       if options = [] then
        tmp := SCIntFunc.IBistellarRMoves(1,(mainDim+1),raw_options[2],mainComplex);
        Append(options,tmp); 
        tmp := SCIntFunc.IBistellarRMoves(2,(mainDim+1),raw_options[3],mainComplex);
        Append(options,tmp); 
        if relaxation = 15 then 
          heating:=20;
          relaxation:=0;
        fi;
        relaxation:=relaxation+1;
        if options = [] then
          tmp := SCIntFunc.IBistellarRMoves(0,(mainDim+1),raw_options[1],mainComplex);
          Append(options,tmp);
        fi;
    
       fi;
     fi;
    fi;
    
    # choosing move at random
    if no_options_flag <> 0 then
     Info(InfoSimpcomp,1,"SCBlowup: no valid flip found.");
     return fail;
    fi;
    # check, if possible options are available
    if options = [] then
     Info(InfoSimpcomp,1,"SCBlowup: no options left for bistellar moves...");
     return fail;
    fi;
    # chose move in boundary
    randomelement:=RandomList(options);
    ready_flag:=1; 
   fi;
   
   # if valid flip exists in complex perform flip
   if ready_flag <> 1 then
    Info(InfoSimpcomp,1,"SCBlowup: no valid flip found.");
    return fail;
   fi;
       
   tmp := SCIntFunc.Move((mainDim+1)-Length(randomelement[1]),
   (mainDim+1),mainComplex,mainF,randomelement,flipsInComplex,0,[]);
   mainComplex := tmp[1];
   mainF := tmp[2];
   flipsInComplex := tmp[3];
   Info(InfoSimpcomp,2,"SCBlowup: ",mainDim+1-Length(randomelement[1]),"-Move   (",rounds," rounds)");
   if reduce then
    Info(InfoSimpcomp,2,"SCBlowup: ",mainF);
   fi;
   
   if not reduce then
   
    # remove flips that DO NOT contain "singularity"
    tmp := [];
    for i in [1..Size(flipsInComplex)] do
     for element in flipsInComplex[i] do
      if not singularity in element[1] and not singularity in element[2] then
       Add(tmp,element);
      fi;
     od;
     flipsInComplex[i] := Difference(flipsInComplex[i],tmp);
    od;
   
   else
   
    # remove flips that DOES contain "singularity"
    tmp := [];
    for i in [1..Size(flipsInComplex)] do
     for element in flipsInComplex[i] do
      if singularity in element[1] or singularity in element[2] then
       Add(tmp,element);
      fi;
     od;
     flipsInComplex[i] := Difference(flipsInComplex[i],tmp);
    od;
   
   fi;
   
   # remove flips that aren't valid
   validFlips := [];
   for i in [0..mainDim] do
    validFlips[i+1] := SCIntFunc.IBistellarRMoves(i,(mainDim+1),flipsInComplex[i+1],mainComplex);
   od;
   flipsInComplex := ShallowCopy(validFlips);
   
   if not reduce then
    # compute projected flips
    projectedFlips := [];
    for i in [1..Size(flipsInComplex)] do
     projectedFlips[i] := [];
     for element in flipsInComplex[i] do
      tmp := [ Difference(element[1],[singularity]) , Difference(element[2],[singularity]) ];
      Add(projectedFlips[i],tmp);
     od;
    od;
        
    # update boundary
    c:=SCLink(SC(mainComplex[mainDim+1]),singularity);
    faces_A := SCFaceLattice(c); 
    F_A := SCFVector(c); 
    det_A := SCAltshulerSteinberg(c);
    dim_A := SCDim(c);
    
    if faces_A = fail or F_A = fail or det_A = fail or dim_A = fail then
     return fail;
    fi;
    
    ### computing possible flips in boundary ###
    flipsInBoundary := [];
    for i in [0..dim_A] do
     flipsInBoundary[i+1] := SCIntFunc.IRawBistellarRMoves(i,faces_A,(dim_A+1));
    od;
    
    # computing intersection of projectedFlips and flipsInBoundary
    raw_options := [];
    for i in [1..Size(flipsInBoundary)] do
     raw_options[i] := [];
     for element in flipsInBoundary[i] do
      for j in [1..Size(projectedFlips)] do
       if element in projectedFlips[j] then
        Add(raw_options[i],element);
       fi;
      od;
     od;
    od;
    
    if F_A < f_min then
     f_min := ShallowCopy(F_A);
     minComplex:=SC(mainComplex[mainDim+1]);
     Info(InfoSimpcomp,1,"SCBlowup: found complex with smaller boundary: f = ",f_min,".");
    fi;
    
    Info(InfoSimpcomp,2,"SCBlowup: ",mainF," - ",F_A);
    
    
    ###########################
    ### test, if isomorphic ###
    ###########################
    
    iso:=SCIsomorphism(bd,SC(faces_A[dim_A+1]));
    if iso = fail then
     return fail;
    fi;
    
    # if boundaries are isomorphic return isomorphism
    if iso <> [] then
     Info(InfoSimpcomp,1,"SCBlowup: found complex with isomorphic boundaries.");
     return [iso,minComplex];
    fi;
   else
    
    if mainF < F_min then
     F_min := ShallowCopy(mainF);
     minComplex:=SC(mainComplex[mainDim+1]);
     Info(InfoSimpcomp,1,"SCBlowup: reduced complex: f = ",F_min,".");
    fi;
   
    raw_options:=ShallowCopy(flipsInComplex);      
   fi;
   rounds:=rounds+1;
  od; # end: map boundaries
  
 od; # end: no_options_flag = 0 and rounds <= 100000
 
 
 Info(InfoSimpcomp,1,"SCBlowup: no flip sequence found, stopping.");
 return fail;

end;



################################################################################
##<#GAPDoc Label="SCBlowup">
## <ManSection>
## <Prop Name="SCBlowup" Arg="pseudomanifold,singularity[,mappingCyl]"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon 
## success, <K>fail</K> otherwise.</Returns>
## <Description>
## If <C>singularity</C> is an ordinary double point of a combinatorial 
## <M>4</M>-pseudomanifold <Arg>pseudomanifold</Arg> 
## (lk(<C>singularity</C><M>) = \mathbb{R}P^3</M>) the blowup of 
## <C>pseudomanifold</C> at <C>singularity</C> is computed. If it is a 
## singularity of type <M>S^2 \times S^1</M>, <M>S^2 \dtimes S^1</M> or 
## <M>L(k,1)</M>, <M>k \leq 4</M>, the canonical resolution of 
## <C>singularity</C> is computed using the bounded complexes provided in 
## the source code below. <P/>
##
## If the optional argument <C>mappingCyl</C> of type 
## <C>SCIsSimplicialComplex</C> is given, this complex will be used to to 
## resolve the singularity <C>singularity</C>.<P/>
##
## Note that bistellar moves do not necessarily preserve any orientation. 
## Thus, the orientation of the blowup has to be checked in order to verify 
## which type of blowup was performed. Normally, repeated computation results 
## in both versions.
## <Example><![CDATA[
## gap> SCLib.SearchByName("Kummer variety");
## [ [ 519, "4-dimensional Kummer variety (VT)" ] ]
## gap> c:=SCLib.Load(last[1][1]);;                
## gap> d:= SCBlowup(c,1);
## ]]></Example>
## <Example><![CDATA[ NOEXECUTE
## gap> # resolving the singularities of a 4 dimensional Kummer variety
## gap> SCLib.SearchByName("Kummer variety");
## [ [ 519, "4-dimensional Kummer variety (VT)" ] ]
## gap> c:=SCLib.Load(last[1][1]);;
## gap> for i in [1..16] do
##        for j in SCLabels(c) do 
##          lk:=SCLink(c,j);
##          if lk.Homology = [[0],[0],[0],[1]] then continue; fi; 
##          singularity := j; break;
##        od;
##        c:=SCBlowup(c,singularity); 
##      od;
## gap> d.IsManifold;
## true
## gap> d.Homology;
## [ [ 0, [ ] ], [ 0, [ ] ], [ 22, [ ] ], [ 0, [ ] ], [ 1, [ ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCBlowup,
 function(arg)

 local pseudomanifold,singularity,
  equivalent,labels,lk,mapCyl,bd,maniflag,iso,minComplex,tmp,i,
  facets,cylinder,c, maxRounds,infLvl,hom;
 
 if Size(arg) < 2 or Size(arg) > 3 then
  Info(InfoSimpcomp,1,"SCBlowup: number of arguments must be 2 or 3.");
  return fail;
 fi;
 
 pseudomanifold:=arg[1];
 singularity:=arg[2];
 if Size(arg) = 3 then
  mapCyl:=arg[3];
 fi;
 
 if(not SCIsSimplicialComplex(pseudomanifold) or SCDim(pseudomanifold) <> 4 or not SCIsMovableComplex(pseudomanifold)) then
  Info(InfoSimpcomp,1,"SCBlowup: first argument must be a combinatorial pseudomanifold of type SCSimplicialComplex and of dimension 4.");
  return fail;
 fi;
 
 labels:=SCLabels(pseudomanifold);
 if labels = fail then
  return fail;
 fi;
 if(not singularity in labels) then
  Info(InfoSimpcomp,1,"SCBlowup: second argument must be a vertex label of the first argument.");
  return fail;
 fi;
 
 if IsBound(mapCyl) and (not SCIsSimplicialComplex(mapCyl) or SCDim(pseudomanifold) <> 4 or not SCHasBoundary(mapCyl)) then
  Info(InfoSimpcomp,1,"SCBlowup: third argument must be a bounded combinatorial 4-manifold of type SCSimplicialComplex.");
  return fail;
 fi;
 
 lk:=SCLink(pseudomanifold,singularity);
 if lk = fail then
  return fail;
 fi;
 
 Info(InfoSimpcomp,1,"SCBlowup: checking if singularity is a combinatorial manifold...");
 
 maniflag:=SCIsManifold(lk);
 if maniflag = fail then
  return fail;
 fi;
 if not maniflag then
  Info(InfoSimpcomp,1,"SCBlowup: singularity is not a manifold.");
  return fail;
 fi;
 
 Info(InfoSimpcomp,1,"SCBlowup: ...true");
 
 Info(InfoSimpcomp,1,"SCBlowup: checking type of singularity...");
 
 hom:=SCHomology(lk);
 if hom = fail then
  return fail;
 fi;
 
 if not IsBound(mapCyl) then
   
  if hom = [ [ 0, [  ] ], [ 1, [  ] ], [ 0, [ 2 ] ], [ 0, [  ] ] ] then
   mapCyl:=SCFromDifferenceCycles([[1,1,1,1,5]]);
   bd:=SCBoundary(mapCyl);
   if bd = fail then
    return fail;
   fi;
   equivalent:=SCEquivalent(lk,bd);
   if equivalent = fail then
    return fail;
   fi;
   if not equivalent then
    Info(InfoSimpcomp,1,"SCBlowup: type of singularity not supported.");
    return fail;
   fi;
   Info(InfoSimpcomp,1,"SCBlowup: ...3-dimensional Klein bottle (supported type)."); 
  elif hom = [ [ 0, [  ] ], [ 1, [  ] ], [ 1, [  ] ], [ 1, [  ] ] ] then
   mapCyl:=SCFromDifferenceCycles([[1,1,1,1,6]]);
   bd:=SCBoundary(mapCyl);
   if bd = fail then
    return fail;
   fi;
   equivalent:=SCEquivalent(lk,bd);
   if equivalent = fail then
    return fail;
   fi;
   if not equivalent then
    Info(InfoSimpcomp,1,"SCBlowup: type of singularity not supported.");
    return fail;
   fi;
   Info(InfoSimpcomp,1,"SCBlowup: ...S^2 x S^1 (supported type)."); 
  elif hom = [ [ 0, [ ] ], [ 0, [ 2 ] ], [ 0, [ ] ], [ 1, [ ] ] ] then
   mapCyl:=SC([
   [1,2,3,5,8],[1,2,3,5,11],[1,2,3,8,11],[1,2,4,5,7],[1,2,4,5,11],
   [1,2,4,9,11],[1,2,5,7,8],[1,2,7,8,10],[1,2,8,10,11],[1,3,4,7,8],
   [1,3,5,6,11],[1,3,6,7,11], [1,3,7,8,11],[1,4,5,7,9],[1,4,5,9,11],
   [1,4,7,8,9],[1,5,7,8,9],[1,6,7,10,11],[1,7,8,10,11],[2,3,5,6,11],
   [2,3,6,9,11],[2,4,5,6,11],[2,4,6,9,11],[3,4,7,8,11],[3,6,7,9,11],
   [4,5,7,9,11],[4,6,8,9,11],[4,7,8,9,11],[6,7,8,9,11],[6,7,8,10,11]]);
   bd:=SCBoundary(mapCyl);
   if bd = fail then
    return fail;
   fi;
   equivalent:=SCEquivalent(lk,bd);
   if equivalent = fail then
    return fail;
   fi;
   if not equivalent then
    Info(InfoSimpcomp,1,"SCBlowup: type of singularity not supported.");
    return fail;
   fi;
   Info(InfoSimpcomp,1,"SCBlowup: ...ordinary double point (supported type).");
  elif hom = [ [ 0, [ ] ], [ 0, [ 3 ] ], [ 0, [ ] ], [ 1, [ ] ] ] then
   mapCyl:=SC([
    [1,2,3,5,7],[1,2,3,5,11],[1,2,3,7,12],[1,2,3,11,12],[1,2,4,5,6],
    [1,2,4,5,11],[1,2,4,6,12],[1,2,4,11,12],[1,2,5,6,7],[1,2,6,7,9],
    [1,2,7,8,9],[1,3,4,6,10],[1,3,4,6,11],[1,3,4,10,12],[1,3,4,11,12],
    [1,3,5,7,10],[1,3,7,10,12],[1,4,5,6,8],[1,4,6,7,8],[1,4,6,7,9],
    [1,4,6,9,11],[1,4,6,10,12],[1,4,7,8,9],[1,5,6,7,8],[1,5,7,10,12],
    [2,3,5,7,10],[2,5,6,7,9],[2,5,7,9,10],[2,7,8,9,10],[3,4,6,7,8],
    [3,4,6,7,11],[3,4,7,8,9],[3,4,7,10,11],[3,4,10,11,12],[3,6,7,8,11],
    [3,7,8,9,12],[3,7,8,10,11],[3,7,8,10,12],[3,8,10,11,12],[4,6,7,9,11],
    [5,7,9,10,12],[7,8,9,10,12]]);
   bd:=SCBoundary(mapCyl);
   if bd = fail then
    return fail;
   fi;
   equivalent:=SCEquivalent(lk,bd);
   if equivalent = fail then
    return fail;
   fi;
   if not equivalent then
    Info(InfoSimpcomp,1,"SCBlowup: type of singularity not supported.");
    return fail;
   fi;
   Info(InfoSimpcomp,1,"SCBlowup: ...L(3,1) (supported type).");
  elif hom = [ [ 0, [ ] ], [ 0, [ 4 ] ], [ 0, [ ] ], [ 1, [ ] ] ] then
   mapCyl:=SC([
    [1,2,4,5,6],[1,2,4,5,12],[1,2,4,6,8],[1,2,4,8,9],[1,2,4,9,12],
    [1,2,5,6,11],[1,2,5,11,12],[1,2,6,8,11],[1,2,7,11,14],[1,2,8,11,14],
    [1,2,9,11,12],[1,3,4,7,9],[1,3,4,7,10],[1,3,4,9,12],[1,3,4,10,12],
    [1,3,5,7,9],[1,3,5,7,12],[1,3,5,9,11],[1,3,5,11,12],[1,3,7,10,12],
    [1,3,9,11,12],[1,4,5,12,13],[1,4,6,8,11],[1,4,7,8,9],[1,4,7,8,11],
    [1,4,10,12,13],[1,5,6,9,11],[1,5,7,8,9],[1,5,7,8,13],[1,5,7,12,13],
    [1,7,8,11,14],[1,7,8,13,14],[1,7,12,13,14],[1,8,10,13,14],[1,10,12,13,14],
    [2,5,6,10,14],[2,5,6,11,14],[2,5,10,11,14],[2,6,8,11,14],[2,6,10,13,14],
    [2,7,11,13,14],[2,10,11,13,14],[3,4,9,12,13],[3,4,10,12,13],[3,5,6,9,11],
    [3,5,6,9,14],[3,5,6,11,14],[3,6,9,11,12],[3,6,9,12,13],[3,6,9,13,14],
    [3,6,10,12,13],[5,6,9,10,14],[6,9,10,12,13],[6,9,10,13,14],[7,8,11,13,14],
    [8,10,11,13,14],[9,10,12,13,14]]);
   bd:=SCBoundary(mapCyl);
   if bd = fail then
    return fail;
   fi;
   equivalent:=SCEquivalent(lk,bd);
   if equivalent = fail then
    return fail;
   fi;
   if not equivalent then
    Info(InfoSimpcomp,1,"SCBlowup: type of singularity not supported.");
    return fail;
   fi;
   Info(InfoSimpcomp,1,"SCBlowup: ...L(4,1) (supported type).");
  elif hom{[1,3,4]} = [ [ 0, [  ] ], [ 0, [  ] ], [ 1, [  ] ] ] and hom[2][1] = 0 and IsBound(hom[2][2]) and Size(hom[2][2]) = 1 and hom[2][2][1] in [5..11] then
   Info(InfoSimpcomp,1,"SCBlowup: Might be singularity of type L(",hom[2][2][1],",1), try loading the complex with the name \"Mapping cylinder L(",hom[2][2][1],",1)\" from the library.");   
  elif hom = [ [ 0, [  ] ], [ 0, [  ] ], [ 0, [  ] ], [ 1, [  ] ] ] then
   equivalent:=SCEquivalent(lk,SCBdSimplex(4));
   if equivalent = fail then
    return fail;
   fi;
   if equivalent then
    Info(InfoSimpcomp,1,"SCBlowup: singularity is a regular vertex, use SCConnectedSum(pseudomanifold,CP^2) or SCConnectedSumMinus(pseudomanifold,CP^2) to perform blowups of ordinary points. Returning SCConnectedSum(pseudomanifold,CP^2).");
    mapCyl:=SC([
     [1,2,3,4,5],[1,2,3,4,7],[1,2,3,5,8],[1,2,3,7,8],[1,2,4,5,6],
     [1,2,4,6,7],[1,2,5,6,8],[1,2,6,7,9],[1,2,6,8,9],[1,2,7,8,9],
     [1,3,4,5,9],[1,3,4,7,8],[1,3,4,8,9],[1,3,5,6,8],[1,3,5,6,9],
     [1,3,6,8,9],[1,4,5,6,7],[1,4,5,7,9],[1,4,7,8,9],[1,5,6,7,9],
     [2,3,4,5,9],[2,3,4,6,7],[2,3,4,6,9],[2,3,5,7,8],[2,3,5,7,9],
     [2,3,6,7,9],[2,4,5,6,8],[2,4,5,8,9],[2,4,6,8,9],[2,5,7,8,9],
     [3,4,6,7,8],[3,4,6,8,9],[3,5,6,7,8],[3,5,6,7,9],[4,5,6,7,8],
     [4,5,7,8,9]]);
    return SCConnectedSum(pseudomanifold,mapCyl);
   fi;
   Info(InfoSimpcomp,1,"SCBlowup: type of singularity not supported.");
   return fail;
  fi;
  
 else
  
  bd:=SCBoundary(mapCyl);
  if bd = fail then
   return fail;
  fi;
  
  equivalent:=SCEquivalent(lk,bd);
  if equivalent = fail then
   return fail;
  fi;
  if not equivalent then
   Info(InfoSimpcomp,1,"SCBlowup: mapping cylinder does not map link of singularity.");
   return fail;
  fi;
  Info(InfoSimpcomp,1,"SCBlowup: ...specified mapping cylinder PL-homeomorphic to link of singularity.");
  
 fi;
 
 Info(InfoSimpcomp,1,"SCBlowup: starting blowup...");
 
 Info(InfoSimpcomp,1,"SCBlowup: map boundaries...");
 
 tmp:=SCIntFunc.MapBoundaries(lk,bd,pseudomanifold,singularity);
 if tmp = fail then
  return fail;
 fi;
 
 Info(InfoSimpcomp,1,"SCBlowup: ...boundaries mapped succesfully.");
 
 Info(InfoSimpcomp,1,"SCBlowup: build complex...");
 
 iso:=tmp[1];
 minComplex:=tmp[2];
 if iso = fail or minComplex = fail then
  return fail;
 fi;

 labels:=[];
 for i in iso do
  labels[i[1]]:=[i[2]];
 od;
 SCRelabel(mapCyl,labels);
 facets:=ShallowCopy(SCFacets(mapCyl));
 if facets = fail then
  return fail;
 fi;
 facets:=List(facets,x->ShallowCopy(x));
 for i in facets do Sort(i); od;
 Sort(facets);
 mapCyl:=SC(facets);
 
 facets:=SCFacets(SCLink(minComplex,singularity));
 if facets = fail then
  return fail;
 fi;
 
 cylinder:=[];
 for i in [1..Size(facets)] do
  Add(cylinder,[facets[i][1],facets[i][2],facets[i][3],facets[i][4],[facets[i][1]]]);
  Add(cylinder,[facets[i][2],facets[i][3],facets[i][4],[facets[i][1]],[facets[i][2]]]);
  Add(cylinder,[facets[i][3],facets[i][4],[facets[i][1]],[facets[i][2]],[facets[i][3]]]);
  Add(cylinder,[facets[i][4],[facets[i][1]],[facets[i][2]],[facets[i][3]],[facets[i][4]]]);
 od;
 cylinder:=SC(cylinder);
 
 c:=Union(Union(Difference(minComplex,SCStar(minComplex,singularity)),cylinder),mapCyl);
 
 Info(InfoSimpcomp,1,"SCBlowup: ...done.");
 
 Info(InfoSimpcomp,1,"SCBlowup: ...blowup completed.");
 Info(InfoSimpcomp,1,"SCBlowup: You may now want to reduce the complex via 'SCReduceComplex'.");
 return c;
 
end);


################################################################################
##<#GAPDoc Label="SCMappingCylinder">
## <ManSection>
## <Func Name="SCMappingCylinder" Arg="k"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon 
## success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates a bounded version of <M>\mathbb{C}P^2</M> (a so-called mapping 
## cylinder for a simplicial blowup, compare 
## <Cite Key="Spreer09CombPorpsOfK3"/>) with boundary 
## <M>L(</M><C>k</C><M>,1)</M>.
## <Example><![CDATA[
## gap> mapCyl:=SCMappingCylinder(3);;
## gap> mapCyl.Homology;              
## [ [ 0, [  ] ], [ 0, [  ] ], [ 1, [  ] ], [ 0, [  ] ], [ 0, [  ] ] ]
## gap> l31:=SCBoundary(mapCyl);;
## gap> l31.Homology;
## [ [ 0, [  ] ], [ 0, [ 3 ] ], [ 0, [  ] ], [ 1, [  ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCMappingCylinder,
function(k)

 local gridtorus,CSsphere,identification,createlens,
  lens,facets,vertices,i,j,complex,
  cyl,simpcyl,idcyl,rencyl,redcyl;

  gridtorus:=function(k)
   local i,j,a,b,complex;
   complex:=[];
   for i in [1..3*k] do
    for j in [1..3*k] do
     if i = 3*k then
      a:=1;
     else
      a:=i+1;
     fi;
     if j = 3*k then
      b:=1;
     else
      b:=j+1;
     fi;
     Add(complex,[[i,j],[a,j],[a,b]]);
     Add(complex,[[i,j],[i,b],[a,b]]);
    od;
   od;
   return complex;
  end;;

  CSsphere:=function(k)
   local sphere, torus, element, a, b, i;
   sphere:=[];
   torus:=gridtorus(k);
   for element in torus do
    a:=Minimum([element[1][1],element[2][1],element[3][1]]);
    if 3*k in [element[1][1],element[2][1],element[3][1]] and a = 1 then
     Add(sphere,Union(element,[[3*k,0]]));
    else
     Add(sphere,Union(element,[[a,0]]));
    fi;
    if element[1][1] = element[2][1] then
     if element[1][1] = 1 then
      Add(sphere,[[3*k,0],[1,0],element[1],element[2]]);
     else
      Add(sphere,[[element[1][1]-1,0],[element[1][1],0],element[1],element[2]]);
     fi;
    fi;
    b:=Minimum([element[1][2],element[2][2],element[3][2]]);
    if 3*k in [element[1][2],element[2][2],element[3][2]] and b = 1 then
     Add(sphere,Union(element,[[0,3*k]]));
    else
     Add(sphere,Union(element,[[0,b]]));
    fi;
    if element[1][2] = element[2][2] then
     if element[1][2] = 1 then
      Add(sphere,[[0,3*k],[0,1],element[1],element[2]]);
     else
      Add(sphere,[[0,element[1][2]-1],[0,element[1][2]],element[1],element[2]]);
     fi;
    fi;
   od;
   for i in [1..Size(sphere)] do
    Sort(sphere[i]);
   od;
   Sort(sphere);
   return sphere;
  end;;


  identification:=function(sphereOrig)
   local i,j,l,max,sphere;
   sphere:=SCIntFunc.DeepCopy(sphereOrig);
   max:=0;
   for i in sphere do
    for j in i do
     for l in j do
      if l > max then
       max:=l;
      fi;
     od;
    od;
   od;
   for i in [1..Size(sphere)] do
    for j in [1..Size(sphere[i])] do
     if sphere[i][j][1] = 0 then    
      sphere[i][j][2]:=((sphere[i][j][2]-1) mod 3)+1;
     elif sphere[i][j][2] = 0 then
      sphere[i][j][1]:=((sphere[i][j][1]-1) mod 3)+1;
     else
      sphere[i][j]:=sphere[i][j]-1;
      while sphere[i][j][1] >= 3 do
       sphere[i][j]:=sphere[i][j]-3;
      od;
      sphere[i][j]:=(sphere[i][j] mod max) +1;
     fi;
    od;
    Sort(sphere[i]);
   od;
   Sort(sphere);
   return Set(sphere);
  end;;


  createlens:=function(k)
   return SC(identification(CSsphere(k)));
  end;;

 lens:=createlens(k);;
 facets:=lens.Facets;;
 cyl:=[]; 
 for i in [1..Size(facets)] do 
  Add(cyl,Union(facets[i],facets[i]+3*k+1)); 
 od;

 simpcyl:=[]; 
 for i in [1..Size(cyl)] do
  simpcyl:=Union(simpcyl,[cyl[i]{[1..5]},cyl[i]{[2..6]},cyl[i]{[3..7]},cyl[i]{[4..8]}]);
 od;
 idcyl:=[]; 
 for i in [1..Size(simpcyl)] do 
  idcyl[i]:=[]; 
  for j in [1..5] do 
   if Maximum(simpcyl[i][j]) <= 3*k then 
    if simpcyl[i][j][1] = 0 then 
     idcyl[i][j] := 3*k+1; 
    elif simpcyl[i][j][2] = 0 then 
     idcyl[i][j]:=3*k+2; 
    else 
     idcyl[i][j]:= (simpcyl[i][j][1]-simpcyl[i][j][2]) mod (3*k);
    fi; 
   else 
    idcyl[i][j]:=ShallowCopy(simpcyl[i][j]); 
   fi; 
  od; 
 od;
 vertices:=Union(idcyl);
 rencyl:=[]; 
 for i in [1..Size(idcyl)] do 
  rencyl[i]:=[]; 
  for j in [1..5] do 
   rencyl[i][j]:=Position(vertices,idcyl[i][j]); 
  od; 
 od;

 redcyl:=[]; 
 for i in rencyl do 
  if Size(Set(i)) = 5 then 
   AddSet(redcyl,i); 
  fi; 
 od;
 complex:=SCFromFacets(redcyl);
 
 SCRename(complex,Concatenation("Mapping cylinder Bd(CP^2) = L(",String(k),",1)")); 
 return complex;

end);


[ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge