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


Quelle  Fan.gi   Sprache: unbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

# SPDX-License-Identifier: GPL-2.0-or-later
# NConvex: A Gap package to perform polyhedral computations
#
# Implementations
#


####################################
##
## Reps
##
####################################

DeclareRepresentation( "IsExternalFanRep",
                       IsFan and IsExternalConvexObjectRep,
                       [ ]
                      );

DeclareRepresentation( "IsConvexFanRep",
                       IsExternalFanRep,
                       [ ]
                      );

DeclareRepresentation( "IsInternalFanRep",
                       IsFan and IsInternalConvexObjectRep,
                       [ ]
                      );

####################################
##
## Types and Families
##
####################################


BindGlobal( "TheFamilyOfFans",
        NewFamily( "TheFamilyOfFans" , IsFan ) );

BindGlobal( "TheTypeExternalFan",
        NewType( TheFamilyOfFans,
                 IsFan and IsExternalFanRep ) );

BindGlobal( "TheTypeConvexFan",
        NewType( TheFamilyOfFans,
                 IsConvexFanRep ) );

BindGlobal( "TheTypeInternalFan",
        NewType( TheFamilyOfFans,
                 IsInternalFanRep ) );
                 
####################################
##
## Constructors
##
####################################

##
InstallMethod( Fan,
               " for cones",
               [ IsList ],
               
  function( cones )
    local newgens, i, point, extobj, type;
    
    if Length( cones ) = 0 then
        
        Error( " no empty fans allowed." );
        
    fi;
    
    newgens := [ ];
    
    for i in cones do
        
        if IsCone( i ) then
            
            if IsBound( i!.input_rays ) then
                
                Add( newgens, i!.input_rays );
                
            else
                
                Add( newgens, RayGenerators( i ) );
                
            fi;
            
        elif IsList( i ) then
            
            Add( newgens, i );
            
        else
            
            Error( " wrong cones inserted" );
            
        fi;
        
    od;
    
    point := rec( input_cone_list := newgens );
    
    ObjectifyWithAttributes(
        point, TheTypeInternalFan
        );
    
    SetAmbientSpaceDimension( point, Length( newgens[ 1 ][ 1 ] ) );
    
    return point;
    
end );

##
InstallMethod( Fan,
               " for homalg fans",
               [ IsFan ],
               
  IdFunc
  
);


##
InstallMethod( Fan,
               "for rays and cones.",
               [ IsList, IsList ],
               
  function( rays, cones )
    local point, indices;
    
    if Length( cones ) = 0 or Length( rays ) = 0 then
        
        Error( "fan has to have the trivial cone.\n" );
    
    fi;
    
    indices := Set( Flat( cones ) );
    
    if not ForAll( indices, i -> i > 0 and i<= Length( rays ) ) then 
      
      Error( "wrong cones inserted \n" );
    
    fi;
    
    point := rec( input_rays := rays, input_cones := cones );
    
    ObjectifyWithAttributes(
        point, TheTypeConvexFan
        );
    
    SetAmbientSpaceDimension( point, Length( rays[ 1 ] ) );
    
    return point;
  
end );

##
InstallMethod( FanWithFixedRays,
               "for rays and cones.",
               [ IsList, IsList ],
               
  Fan );

##
InstallMethod( DeriveFansFromTriangulation,
               "for a list of rays.",
               [ IsList, IsBool ],
  function( rays, single_fan_desired )
    local triangulations, i, j, fans;
    
    # (0) Check if TopcomInterface is available
    if TestPackageAvailability( "TopcomInterface", ">=2019.06.15" ) = fail then
      Error( "The package TopcomInterface is not available " );
    fi;
    
    # (1) and marked to be loaded as suggested package
    if not IsPackageMarkedForLoading( "TopcomInterface", ">=2019.06.15" ) then
      Error( "The package TopcomInterface has not been marked to be loaded by NConvex if available " );
    fi;
    
    # (2) Check that the given rays are valid input
    
    # (2a) Are the rays all of the same length?
    if Length( DuplicateFreeList( List( [ 1 .. Length( rays ) ], i -> Length( rays[ i ] ) ) ) ) > 1 then
      Error( "The rays must be lists of the equal lengths " );
      return;
    fi;
    
    # (2b) Are the rays lists of integers?
    for i in [ 1 .. Length( rays ) ] do
      for j in [ 1 .. Length( rays[ i ] ) ] do
        if not IsInt( rays[ i ][ j ] ) then
          Error( "The rays must be lists of integers " );
          return;
        fi;
      od;
    od;
    
    # (3) compute all fine and regular triangulations
    triangulations := ValueGlobal( "points2allfinetriangs" )( rays, [], ["regular"] );
    
    # to match the conventions of NConvex, the counting of rays must start at 1
    # whilst topcom (in C++-standard) starts the counting at 0
    Apply( triangulations, i -> i + 1 );
    
    # (4) iterate over the obtained triangulations and turn them into fans
    if single_fan_desired then
      fans := Fan( rays, triangulations[ 1 ] );
    else
      fans := List( [ 1 .. Length( triangulations ) ], i -> Fan( rays, triangulations[ i ] ) );
    fi;
    
    # return the result
    return fans;
    
end );

##
InstallMethod( FansFromTriangulation,
               "for a list of rays.",
               [ IsList ],
  function( rays )
    
    return DeriveFansFromTriangulation( rays, false );
    
end );

##
InstallMethod( FanFromTriangulation,
               "for a list of rays.",
               [ IsList ],
  function( rays )
    
    return DeriveFansFromTriangulation( rays, true );
    
end );

##############################
##
##  Attributes
##
##############################


InstallMethod( RayGenerators, 
               "for fans",
               [ IsFan ], 
  function( fan )
    
    return RayGenerators( CanonicalizeFan( fan ) );
  
end );

InstallMethod( RaysInMaximalCones, 
               [ IsFan ],
  function( fan )
    
    return RaysInMaximalCones( CanonicalizeFan( fan ) );
  
end );

##
InstallMethod( GivenRayGenerators,
               "for external fans.",
               [ IsFan ],
               
  function( fan )
    
    if IsBound( fan!.input_rays ) then
        
        return fan!.input_rays;
    
    elif IsBound( fan!.input_cone_list ) then
        
        #return DuplicateFreeList( Concatenation( fan!.input_cone_list ) );
        return List( Set( Union( fan!.input_cone_list ) ) );
    
    else
        
        Error( "Something went wrong." );
    
    fi;
    
end );

##
InstallMethod( Rays,
               "for fans.",
               [ IsFan ],
               
  function( fan )
    local rays;
    
    rays := RayGenerators( fan );
    
    rays := List( rays, i -> Cone( [ i ] ) );
    
    List( rays, function( i ) SetContainingGrid( i, ContainingGrid( fan ) ); return 0; end );
    
    return rays;
    
end );

## This function ignore the small cones which live in some other cone.

InstallMethod( RaysInTheGivenMaximalCones,
               "for fans",
               [ IsFan ],
               
  function( fan )
    local rays, cones, i, j;
    
    if IsBound( fan!.input_cones ) and IsBound( fan!.input_rays ) then
        
        rays := GivenRayGenerators( fan );
        
        cones := List( [ 1 .. Length( fan!.input_cones ) ], i -> List( [ 1 .. Length( rays ) ], j -> 0 ) );
        
        for i in [ 1 .. Length( fan!.input_cones ) ] do
          
          for j in fan!.input_cones[ i ] do
            
            cones[ i ][ j ] := 1;
            
          od;
        
        od;
        
        return ListOfMaximalConesInList( cones );
    
    fi;
    
    if IsBound( fan!.input_cone_list ) then
      
      rays := GivenRayGenerators( fan );
      
      ## Dont use ListWithIdenticalEntries here since it has new sideeffects.
      cones := List( [ 1 .. Length( fan!.input_cone_list ) ], i -> List( [ 1 .. Length( rays ) ], j -> 0 ) );
      
      for i in [ 1 .. Length( fan!.input_cone_list ) ] do
        
        for j in [ 1 .. Length( rays ) ] do
          
          if rays[ j ] in fan!.input_cone_list[ i ] then
            
            cones[ i ][ j ] := 1;
          
          fi;
        
        od;
      
      od;
      
      return ListOfMaximalConesInList( cones );
      
    fi;
    
    if IsCone( fan ) then
      
      return RaysInMaximalCones( Fan( [ fan ] ) );
    
    fi;
    
    TryNextMethod(  );
  
end );

InstallMethod( MaximalCones,
               "for external fans.",
               [ IsFan ],
               
  function( fan )
    local raylist, rays, conelist, i, lis, j;
    
    raylist := RaysInMaximalCones( fan );
    
    rays := RayGenerators( fan );
    
    conelist := [ ];
    
    for i in [ 1..Length( raylist ) ] do
      
      lis := [ ];
      
      for j in [ 1 .. Length( raylist[ i ] ) ] do
        
        if raylist[ i ][ j ] = 1 then
          
          lis := Concatenation( lis, [ rays[ j ] ] );
        
        fi;
      
      od;
      
      conelist := Concatenation( conelist, [ lis ] );
      
    od;
    
    conelist := List( conelist, Cone );
    
    Perform( conelist, function( i ) SetContainingGrid( i, ContainingGrid( fan ) ); return 0; end );
    
    Perform( conelist, function( i ) SetSuperFan( i, fan ); return 0; end );
    
    return conelist;
    
end );

##
InstallMethod( MaximalCones,
               [ IsFan, IsInt],
               
  function( fan, n )
    local all_max_cones, new_list, i; 
    
    all_max_cones:= MaximalCones( fan );
    
    new_list:= [ ];
    
    for i in all_max_cones do
      
      if Dimension( i ) = n then Add( new_list, i ); fi;
    
    od;
    
    return new_list;
    
end );

##
InstallMethod( GivenMaximalCones,
               "for external fans.",
               [ IsFan ],
               
  function( fan )
    local raylist, rays, conelist, i, lis, j;
    
    raylist := RaysInTheGivenMaximalCones( fan );
    
    rays := GivenRayGenerators( fan );
    
    conelist := [ ];
    
    for i in [ 1..Length( raylist ) ] do
      
      lis := [ ];
      
      for j in [ 1 .. Length( raylist[ i ] ) ] do
        
        if raylist[ i ][ j ] = 1 then
          
          lis := Concatenation( lis, [ rays[ j ] ] );
          
        fi;
        
      od;
      
      conelist := Concatenation( conelist, [ lis ] );
      
    od;
    
    conelist := List( conelist, Cone );
    
    Perform( conelist, function( i ) SetContainingGrid( i, ContainingGrid( fan ) ); return 0; end );
    
    Perform( conelist, function( i ) SetSuperFan( i, fan ); return 0; end );
    
    return conelist;
    
end );

##
InstallMethod( CanonicalizeFan,
               [ IsFan ],
  
  function( fan )
    local list_of_max, new_gen, cones,i,j, F, max_cones, rays_in_max_cones; 
    
    list_of_max := GivenMaximalCones( fan );
    
    new_gen := [ ];
    
    for i in list_of_max do 
      
      Append( new_gen, RayGenerators( i ) );
    
    od;
    
    #new_gen := DuplicateFreeList( new_gen );
    
    new_gen:= List( Set( new_gen ) );
    
    cones := List( [ 1 .. Length( list_of_max ) ], i -> List( [ 1 .. Length( new_gen ) ], j -> 0 ) );
    
    for i in [ 1 .. Length( list_of_max ) ] do
      
      for j in [ 1 .. Length( new_gen ) ] do
        
        if new_gen[ j ] in RayGenerators( list_of_max[ i ] ) then
          
          cones[ i ][ j ] := 1;
          
        fi;
        
      od;
    
    od;
    
    max_cones:= ListOfMaximalConesInList( cones );
    
    rays_in_max_cones:= [ ];
    
    for i in [ 1 .. Length( max_cones ) ] do
      
      Add( rays_in_max_cones, [ ] );
      
      for j in [ 1..Length( new_gen ) ] do 
      
           if max_cones[ i ][ j ] =1 then Add( rays_in_max_cones[ i ], j ); fi;
            
      od;
      
    od;
    
    F := Fan( new_gen, rays_in_max_cones );
    
    SetRayGenerators( F, new_gen );
    
    SetRaysInMaximalCones( F, max_cones );
    
    return F;
  
end );

##
InstallMethod( RaysInAllCones,
            [ IsFan ],
  
  function( fan )
    local max_cones, cones, current_list_of_faces, rays, L, i;
    
    if IsCone( fan ) then
      
      max_cones := [ fan ];
    
    else
      
      max_cones:= MaximalCones( fan );
    
    fi;
    
    cones := [ ];
    
    for i in max_cones do 
      
      current_list_of_faces:= FacesOfCone( i );
      
      cones := Concatenation( cones, List( current_list_of_faces, RayGenerators ) );
    
    od;
    
    cones := DuplicateFreeList( cones );
    
    rays := RayGenerators( fan );
    
    if not ForAll( DuplicateFreeList( Concatenation( cones ) ), r -> r = [ ] or r in rays ) then
      
      # If this error happens, it means that r is a positive multiple of some element in rays,
      # which is not problem and can be fixed very easily.
      Error( "This should not happen, please report this error!" );
    
    fi;
    
    L := List( cones, cone ->
        List( rays, function( r )
                      if r in cone then
                        return 1;
                      else
                        return 0;
                      fi;
                    end ) );
    
    return DuplicateFreeList( L );
  
end );

##
InstallMethod( AllCones,
        [ IsFan ],
  function( fan )
    local n, rays, rays_in_all_cones;
    
    n := AmbientSpaceDimension( fan );
    
    rays := RayGenerators( fan );
    
    rays_in_all_cones := RaysInAllCones( fan );
    
    rays_in_all_cones := List( rays_in_all_cones, r -> rays{ Positions( r, 1 ) } );
    
    rays_in_all_cones[ Position( rays_in_all_cones, [  ] ) ] := [ ListWithIdenticalEntries( n, 0 ) ];
    
    return List( rays_in_all_cones, Cone );
  
end );

##
InstallMethod( FVector, 
               [ IsFan ], 
  function( fan )
    local dim_of_cones; 
    
    dim_of_cones := List( AllCones( fan ), Dimension );
    
    return List( [ 1.. Dimension( fan ) ], i-> Length( Positions( dim_of_cones, i ) ) );
  
end );
 
##
InstallMethod( Dimension,
               "for fans",
               [ IsFan ],
               
  function( fan )
    
    return Maximum( List(MaximalCones( fan ), i-> Dimension( i ) ) );
    
end );

##
InstallMethod( AmbientSpaceDimension,
               "for fans",
               [ IsFan ],
               
  function( fan )
    
    return Length( RayGenerators( fan )[ 1 ] );
    
end );

##
InstallMethod( PrimitiveCollections,
               "for fans",
               [ IsFan ],
  
  function( fan )
    local rays, max_cones, facets, all_points, d_max, primitive_collections, d, checked, facet,
         I_minus_j, scanner, j, I;
    
    # collect data of the fan
    rays := RayGenerators( fan );
    
    max_cones := MaximalCones( fan );
    
    facets := List( [ 1 .. Length( max_cones ) ],
                        i -> List( RayGenerators( max_cones[ i ] ), k -> Position( rays, k ) ) );
    
    all_points := [ 1 .. Length( rays ) ];
    
    d_max := Maximum( List( facets, i -> Length( i ) ) ) + 1;
    
    # identify and return the primitive collections
    primitive_collections := [];
    
    for d in [ 1 .. d_max ] do
      checked := [];
      
      for facet in facets do
        
        for I_minus_j in Combinations( facet, d ) do
          
          scanner := Difference( all_points, Flat( I_minus_j ) );
          
          for j in scanner do
            
            I := Concatenation( I_minus_j, [ j ] );
            
            if not I in checked then
              
              Add( checked, I );
              
              # (1) I is contained in the primitive collections iff it is not contained in any facet
              if ForAll( [ 1 .. Length( facets ) ],
                            i -> not IsSubsetSet( facets[ i ], I ) ) then
                
                # (2) I is generator of the primitive collections iff
                # primitive_collections does not contain a "smaller" generator
                if ForAll( [ 1 .. Length( primitive_collections ) ],
                              i -> not IsSubsetSet( I, primitive_collections[i] ) ) then
                  
                  # then add this new generator
                  Append( primitive_collections, [ I ] );
                
                fi;
              
              fi;
            
            fi;
          od;
          
        od;
      
      od;
    
    od;
    
    return primitive_collections;
  
end );

#########################
##
##  Properties
##
#########################

InstallMethod( IsWellDefinedFan, 
               [ IsFan ],
  
  function( fan )
    local max_cones, combi, n;
    
    max_cones := MaximalCones( fan );
    
    n := Length( max_cones );
    
    combi := Combinations( [ 1 .. n ], 2 );
    
    return ForAll( combi,
      function( two_indices )
        local C1, C2, U;
        
        C1 := max_cones[ two_indices[ 1 ] ];
        
        C2 := max_cones[ two_indices[ 2 ] ];
        
        U := IntersectionOfCones( C1, C2 );
        
        if U in FacesOfCone( C1 ) and U in FacesOfCone( C2 ) then
        
          return true ;
        
        else
        
          return false;
        
        fi;
      
      end );
  
end );

##
InstallMethod( IsComplete, 
              [ IsFan ],
  function( fan )
    local list_of_cones, facets, facets_without_duplicates, positions;
    
    if Dimension( fan ) < AmbientSpaceDimension( fan ) then
      
      return false;
    
    fi;
    
    list_of_cones := MaximalCones( fan );
    
    if not ForAll( list_of_cones, IsFullDimensional ) then
      
      return false;
    
    fi;
    
    facets := Concatenation( List( list_of_cones, Facets ) );
    
    facets_without_duplicates := DuplicateFreeList( facets );
    
    positions := List( facets_without_duplicates, 
                  facet -> Length( Positions( facets, facet ) ) );
    
    if Set( positions ) = Set( [ 2 ] ) then
      
      return true;
    
    elif Set( positions ) = Set( [ 1, 2 ] ) then
      
      return false;
    
    else
      
      Print( "This should not happen, This may be caused by a not well-defined fan!\n" );
      return false;
    
    fi;
    
end );
   
##
InstallMethod( IsPointed,
               "for fans",
               [ IsFan ],
               
  function( fan )
    
    return ForAll( MaximalCones( fan ), IsPointed );
    
end );

##
InstallMethod( IsSmooth,
               "for fans",
               [ IsFan ],
               
  function( fan )
    
    return ForAll( MaximalCones( fan ), IsSmooth );
    
end );

##
InstallMethod( IsRegularFan,
               "whether a fan is a normalfan or not",
               [ IsFan ],
  
  function( fan )
    local max_cones, ambient_dim, rays, max_cones_ineqs, embed, nr_rays, nd, equations,
      inequations, r, L1, L0, i, hyper_surface, cone, index_rays;
    
    if not IsComplete( fan ) then
      
      return false;
    
    fi;
    
    if AmbientSpaceDimension( fan ) <= 2 then
      
      return true;
    
    fi;
    
    ## Algorithm is taken from the Maple Convex package.
    rays := RayGenerators( fan );
    
    ambient_dim := AmbientSpaceDimension( fan );
    
    max_cones := MaximalCones( fan );
    
    max_cones_ineqs := List( max_cones, DefiningInequalities );
    
    nr_rays := Length( rays );
    
    nd := ambient_dim * Length( max_cones );
    
    embed := function( a, b, c, d, e )
              local return_list, e1, d1;
              if e < c then  
                 e1 := e;
                 e := c;
                 c := e1;
                 d1 := d;
                 d := b;
                 b := d1;
              fi;
              return_list := ListWithIdenticalEntries( c, 0 );
              return_list := Concatenation( return_list, b );
              return_list := Concatenation( return_list,
              ListWithIdenticalEntries( e - Length( b ) - c, 0 ) );
              return_list := Concatenation( return_list, d );
              return Concatenation( return_list,
                ListWithIdenticalEntries( a - Length( return_list ), 0 ) );
             end;
    
    ## FIXME: Our convention is to handle only pointed fans. 
    ## convex handles fans with lineality spaces, so the lines differ.
    equations := List( [ 1 .. Length( max_cones ) ],
                       i -> List( EqualitiesOfCone( max_cones[ i ] ), 
                                  r -> embed( nd, r, ambient_dim * ( i - 1 ), [ ], 0 ) ) );
    
    equations := Concatenation( equations );
    
    inequations := [ ];
    
    index_rays := [ 1 .. nr_rays ];
    
    for r in [ 1 .. nr_rays ] do
        
        L0 := [];
        
        L1 := [];
        
        for i in [ 1 .. Length( max_cones ) ] do
          
          if rays[ r ] in max_cones[ i ] then
            
            Add( L1, i );
            
          else
            
            Add( L0, i );
            
          fi;
          
        od;
        
        i := ambient_dim * ( L1[ 1 ] - 1 );
        
        index_rays[ r ] := i;
        
        Remove( L1, L1[ 1 ] );
        
        equations := Concatenation( equations,
                          List( L1,
                            j -> embed( nd, rays[ r ], i, - rays[ r ], ambient_dim * ( j - 1 ) ) ) );
        
        inequations := Concatenation( inequations,
                          List( L0,
                            j -> embed( nd, rays[ r ], i, - rays[ r ], ambient_dim * ( j - 1 ) ) ) );
        
    od;
    
    hyper_surface := ConeByEqualitiesAndInequalities( equations, [ ] );
    
    i := AmbientSpaceDimension( hyper_surface ) - Dimension( hyper_surface );
    
    cone := ConeByEqualitiesAndInequalities( equations, inequations );
    
    r := AmbientSpaceDimension( cone ) - Dimension( cone );
    
    return i = r;
    
end );

##
## This is implementation of the Shephard's criterion
## (Theorem 4.7, Combinatorial convexity and algebraic geometry, Ewald, Guenter)
##
InstallMethod( IsNormalFan,
          [ IsFan ],
  
  function( fan )
      local rays, cones, mat, G, polytopes, P, M;
      
      if not IsComplete( fan ) then
        
        return false;
      
      fi;
      
      if AmbientSpaceDimension( fan ) <= 2 then
        
        return true;
      
      fi;
      
      if HasIsRegularFan( fan ) then
        
        return IsRegularFan( fan );
      
      fi;
      
      rays := RayGenerators( fan );
      
      cones := ShallowCopy( RaysInAllCones( fan ) );
      
      Remove( cones, PositionProperty( cones, IsZero ) );
      
      mat := HomalgMatrix( rays, HOMALG_RATIONALS );
      
      G := GaleTransform( mat );
      
      if IsZero( G ) then
        
        return true;
      
      fi;
      
      G := EntriesOfHomalgMatrixAsListList( G );
      
      polytopes := List( cones, cone -> Set( DuplicateFreeList( G{ Positions( cone, 0 ) } ) ) );
      
      polytopes := DuplicateFreeList( polytopes );
      
      polytopes := List( polytopes, l -> Polytope( l ) );
      
      P := Iterated( polytopes, IntersectionOfPolytopes );
      
      if Dimension( P ) = -1 then
        
        return false;
      
      elif Dimension( P ) = 0 then
        
        M := Vertices( P )[ 1 ];
        
        return ForAll( polytopes, P -> IsInteriorPoint( M, P ) );
      
      else
        
        M := RandomInteriorPoint( P );
        
        if ForAll( polytopes, P -> IsInteriorPoint( M, P ) ) then
          
          return true;
        
        else
          
          return false;
        
        fi;
      
      fi;
  
end );

##
InstallMethod( IsRegularFan, [ IsFan ], IsNormalFan );

##
InstallMethod( IsFullDimensional,
               "for fans",
               [ IsFan ],
               
  function( fan )
    
    return ForAny( MaximalCones( fan ), i -> Dimension( i ) = AmbientSpaceDimension( i ) );
    
end );


##
InstallMethod( IsSimplicial,
               " for homalg fans",
               [ IsFan ],
               
  function( fan )
    
    fan := MaximalCones( fan );
    
    return ForAll( fan, IsSimplicial );
    
end );

##
InstallMethod( IsFanoFan,
            [ IsFan ],
  function( fan )
    local polyt;
    
    if HasIsComplete( fan ) and not IsComplete( fan ) then
      
      return false;
    
    fi;
    
    polyt := Polytope( RayGenerators( fan ) );
      
      if not IsFullDimensional( polyt ) or
            not IsInteriorPoint(
              ListWithIdenticalEntries( AmbientSpaceDimension( polyt ), 0 ), polyt ) then
        
        return false;
      
      fi;
    
    return fan = NormalFan( PolarPolytope( polyt ) );
  
end );

#########################
##
##  Methods
##
#########################

##
InstallMethod( \=,
            [ IsFan, IsFan ],
  function( fan1, fan2 )
    
    if RayGenerators( fan1 ) = RayGenerators( fan2 ) and
        Set( RaysInMaximalCones( fan1 ) ) = Set( RaysInMaximalCones( fan2 ) ) then
          
          return true;
    
    fi;
    
    if RayGenerators( fan1 ) <> RayGenerators( fan2 ) and
        Set( RayGenerators( fan1 ) ) = Set( RayGenerators( fan2 ) ) then
          
          Error( "This should not happen! Please report this error." );
    
    fi;
    
    return false;
  
end );

##
InstallMethod( \*,
               "for fans.",
               [ IsFan, IsFan ],
               
  function( fan1, fan2 )
    local rays1, rays2, m1, m2, new_m, new_rays, cones1, cones2, i, j, k, new_cones, akt_cone, new_fan;
    
    rays1 := RayGenerators( fan1 );
    
    rays2 := RayGenerators( fan2 );
    
    m1 := Rank( ContainingGrid( fan1 ) );
    
    m2 := Rank( ContainingGrid( fan2 ) );
    
    m1 := List( [ 1 .. m1 ], i -> 0 );
    
    m2 := List( [ 1 .. m2 ], i -> 0 );
    
    rays1 := List( rays1, i -> Concatenation( i, m2 ) );
    
    rays2 := List( rays2, i -> Concatenation( m1, i ) );
    
    new_rays := Concatenation( rays1, rays2 );
    
    cones1 := RaysInMaximalCones( fan1 );
    
    cones2 := RaysInMaximalCones( fan2 );
    
    new_cones := [ ];
    
    m1 := Length( rays1 );
    
    m2 := Length( rays2 );
    
    for i in cones1 do
      
      for j in cones2 do
        
        akt_cone := [ ];
        
        for k in [ 1 .. m1 ] do
          
          if i[ k ] = 1 then
            
            Add( akt_cone, k );
          
          fi;
        
        od;
        
        for k in [ 1 .. m2 ] do
          
          if j[ k ] = 1 then
            
            Add( akt_cone, k + m1 );
          
          fi;
        
        od;
        
        Add( new_cones, akt_cone );
      
      od;
    
    od;
    
    new_fan := FanWithFixedRays( new_rays, new_cones );
    
    SetContainingGrid( new_fan, ContainingGrid( fan1 ) + ContainingGrid( fan2 ) );
    
    return new_fan;
    
end );

##
InstallMethod( ToricStarFan,
               "for fans",
               [ IsFan, IsCone ],
               
  function( fan, cone )
    local maximal_cones, rays_of_cone, defining_inequalities, value_list, cone_list, i, j, breaker;
    
    maximal_cones := MaximalCones( fan );
    
    rays_of_cone := RayGenerators( cone );
    
    cone_list := [ ];
    
    breaker := false;
    
    for i in maximal_cones do
      
      defining_inequalities := DefiningInequalities( i );
      
      for j in rays_of_cone do
        
        value_list := List( defining_inequalities, k -> k * j );
        
        if not ForAll( value_list, k -> k >= 0 ) or not 0 in value_list then
          
          breaker := true;
          
          continue;
          
        fi;
        
      od;
      
      if breaker then
        
        breaker := false;
        
        continue;
        
      fi;
      
      Add( cone_list, cone );
      
    od;
    
    cone_list := Fan( cone_list );
    
    SetContainingGrid( cone_list, ContainingGrid( fan ) );
    
end );
##
InstallMethod( \*,
               "for homalg fans.",
               [ IsCone, IsFan ],
               
  function( cone, fan )
    
    return Fan( [ cone ] ) * fan;
    
end );

##
InstallMethod( \*,
               "for homalg fans.",
               [ IsFan, IsCone ],
               
  function( fan, cone )
    
    return fan * Fan( [ cone ] );
    
end );

##
InstallMethod( ToricStarFan,
               "for fans",
               [ IsFan, IsCone ],
               
  function( fan, cone )
    local maximal_cones, rays_of_cone, defining_inequalities, value_list, cone_list, i, j, breaker;
    
    maximal_cones := MaximalCones( fan );
    
    rays_of_cone := RayGenerators( cone );
    
    cone_list := [ ];
    
    breaker := false;
    
    for i in maximal_cones do
      
      defining_inequalities := DefiningInequalities( i );
      
      for j in rays_of_cone do
        
        value_list := List( defining_inequalities, k -> k * j );
        
        if not ForAll( value_list, k -> k >= 0 ) or not 0 in value_list then
          
          breaker := true;
          
          continue;
          
        fi;
        
      od;
      
      if breaker then
        
        breaker := false;
        
        continue;
        
      fi;
      
      Add( cone_list, cone );
      
    od;
    
    cone_list := Fan( cone_list );
    
    SetContainingGrid( cone_list, ContainingGrid( fan ) );
    
    return cone_list;
    
end );

#########################
##
##  Simple functions
##
#########################

InstallMethod( FirstLessTheSecond,
               [ IsList, IsList],
               
  function( u, v )
    
    if Length( u ) <> Length( v ) then
      
      Error( "The two lists should have the same length!" );
    
    fi;
    
    return ForAll( [ 1 .. Length( u ) ], i-> u[ i ] <= v[ i ] );
  
end );

InstallMethod( OneMaximalConeInList,
              [ IsList ],
  function( u )
    local list, max, new_u, i;
    
    #new_u:= DuplicateFreeList( ShallowCopy( u ) );
    new_u:= List( Set( u ) );
    
    max := new_u[ 1 ];
    
    for i in new_u do
      
      if FirstLessTheSecond( max, i ) then 
        
        max := i;
      
      fi;
    
    od;
    
    list := [ ];
    
    for i in new_u do 
      
      if FirstLessTheSecond( i, max ) then 
        
        Add( list, i );
      
      fi;
    
    od;
    
    return [ max, list ];
    
 end );

##
InstallMethod( ListOfMaximalConesInList,
               [ IsList ],
               
  function( L )
    local l, list_of_max, current, new_L;
    
    list_of_max := [ ];
    
    #new_L:= DuplicateFreeList( L );
    new_L := Set( L );
    
    while Length( new_L )<> 0 do
      
      current := OneMaximalConeInList( new_L );
      
      Add( list_of_max, current[ 1 ] );
      
      SubtractSet( new_L, current[ 2] );
    
    od;
    
    return list_of_max;
    
end );

####################################
##
## Display Methods
##
####################################

##
InstallMethod( ViewObj,
               "for homalg fans",
               [ IsFan ],
               
  function( fan )
    local str;
    
    Print( "<A" );
    
    if HasIsComplete( fan ) then
      
      if IsComplete( fan ) then
          
          Print( " complete" );
          
      fi;
    
    fi;
    
    if HasIsPointed( fan ) then
      
      if IsPointed( fan ) then
          
          Print( " pointed" );
          
      fi;
    
    fi;
      
    if HasIsSmooth( fan ) then
      
      if IsSmooth( fan ) then
          
          Print( " smooth" );
          
      fi;
    
    fi;
    
    Print( " fan in |R^" );
    
    Print( String( AmbientSpaceDimension( fan ) ) );
    
    if HasRays( fan ) then
      
      Print( " with ", String( Length( Rays( fan ) ) )," rays" );
      
    fi;
    
    Print( ">" );
    
end );

##
InstallMethod( Display,
               "for homalg polytopes",
               [ IsFan ],
               
  function( fan )
    local str;
    
    Print( "A" );
    
    if HasIsComplete( fan ) then
      
      if IsComplete( fan ) then
        
        Print( " complete" );
        
      fi;
    
    fi;
    
    Print( " fan in |R^" );
    
    Print( String( AmbientSpaceDimension( fan ) ) );
    
    if HasRays( fan ) then
      
      Print( " with ", String( Length( Rays( fan ) ) )," rays" );
      
    fi;
    
    Print( ".\n" );
    
end );


[ Dauer der Verarbeitung: 0.52 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


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