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


Quelle  BettiTable.gi   Sprache: unbekannt

 
# SPDX-License-Identifier: GPL-2.0-or-later
# GradedModules: A homalg based package for the Abelian category of finitely presented graded modules over computable graded rings
#
# Implementations
#

##  Declarations for Betti diagrams.

####################################
#
# families and types:
#
####################################

# a new type:
BindGlobal( "TheTypeBettiTable",
        NewType(  TheFamilyOfHomalgDiagrams,
                IsHomalgDiagramRep and
                IsBettiTable ) );

####################################
#
# global variables:
#
####################################

HOMALG.SpectralSequenceConventionForBettiTablesOfComplexes := false;
HOMALG.SpectralSequenceConventionForBettiTablesOfCocomplexes := true;

####################################
#
# methods for operations:
#
####################################

##
InstallMethod( RowDegreesOfBettiTable,
        "for Betti diagrams",
        [ IsBettiTable ],
        
  function( diag )
    
    return diag!.row_range;
    
end );

##
InstallMethod( ColumnDegreesOfBettiTable,
        "for Betti diagrams",
        [ IsBettiTable ],
        
  function( diag )
    
    return diag!.column_range;
    
end );

####################################
#
# constructor functions and methods:
#
####################################

##
InstallGlobalFunction( HomalgBettiTable,
  function( arg )
    local betti, row_range, column_range, object, ar, nr_rows, nr_cols, diagram;
    
    betti := arg[1];
    row_range := arg[2];
    column_range := arg[3];
    object := arg[4];
    
    nr_rows := Length( row_range );
    nr_cols := Length( column_range );
    
    if nr_rows <> Length( betti ) then
        Error( "the Betti table and the row range are incompatible\n" );
    elif Length( betti ) > 0 and nr_cols <> Length( betti[1] ) then
        Error( "the Betti table and the column range are incompatible\n" );
    fi;
    
    diagram := rec(
                   object := object,
                   matrix := betti,
                   row_range := row_range,
                   column_range := column_range,
                   reverse := false ## read the row range upside down?: default value is false (might get reset below)
                   );
    
    ## search for options
    for ar in arg{[ 5 .. Length( arg ) ]} do
        if IsString( ar ) then
            diagram.( ar ) := true;
        elif IsList( ar ) and Length( ar ) = 2 and IsString( ar[1] ) then
            diagram.( ar[1] ) := ar[2];
        fi;
    od;
    
    ## Objectify:
    ObjectifyWithAttributes(
            diagram, TheTypeBettiTable,
            NumberRows, nr_rows,
            NumberColumns, nr_cols
            );
    
    return diagram;
    
end );

####################################
#
# View, Print, and Display methods:
#
####################################

##
InstallMethod( ViewObj,
        "for Betti diagrams",
        [ IsBettiTable ],
        
  function( o )
    
    Print( "<A Betti diagram of " );
    
    if HasBettiTable ( o!.object ) and IsIdenticalObj( o, BettiTable ( o!.object ) ) then
        ViewObj( o!.object );
        Print( ">" );
    else
        Print( "a homalg " );
        if IsBound( o!.object!.string ) then
            Print( o!.object!.string );
        else
            Print( "object" );
        fi;
        Print( ">" );
    fi;
    
end );

##
InstallMethod( homalgCreateDisplayString,
        "for Betti diagrams",
        [ IsBettiTable ],
        
  function( o )
    local SpectralSequenceConvention, betti, row_range, column_range,
          higher_vanish, twist, EulerCharacteristic, reverse,
          nr_rows, nr_cols, total, max, twist_range, chi,
          MAX, display, ar, i, pos, marker;
    
    ## the spectral sequence convention for Betti diagrams
    SpectralSequenceConvention := o!.SpectralSequenceConvention;
    
    ## collect the relevant data from the diagram
    betti := MatrixOfDiagram( o );
    
    row_range := RowDegreesOfBettiTable( o );
    column_range := ColumnDegreesOfBettiTable( o );
    
    if IsBound( o!.higher_vanish ) then
        higher_vanish := o!.higher_vanish;
    fi;
    
    if IsBound( o!.twist ) then
        twist := o!.twist;
    fi;
    
    if IsBound( o!.EulerCharacteristic ) and
       IsUnivariatePolynomial( o!.EulerCharacteristic ) then
        EulerCharacteristic := o!.EulerCharacteristic;
    fi;
    
    ## read the row range upside down?
    reverse := o!.reverse;
    
    nr_rows := NumberRows( o );
    nr_cols := NumberColumns( o );
    
    ## now prepare constructing the display string
    
    ## the list of total dimensions
    total := ListWithIdenticalEntries( nr_rows, 1 ) * betti;
    
    ## save it
    o!.total := total;
    
    ## get the maximum width in the matrix
    max := MaximumList( List( betti, r -> MaximumList( List( r, a -> Length( String( a ) ) ) ) ) );
    max := Maximum( MaximumList( List( column_range, a -> Length( String( a ) ) ) ), max );
    max := Maximum( MaximumList( List( total, a -> Length( String( a ) ) ) ), max );
    
    if SpectralSequenceConvention then
        ar := column_range[1];
        if nr_rows > 1 then
            max := Maximum( MaximumList( List( [ ar - ( nr_rows - 1 ) .. ar - 1 ], a -> Length( String( a ) ) ) ), max );
        fi;
    fi;
    
    if IsBound( twist ) then
        twist_range := column_range - ( nr_rows - 1 );
        max := Maximum( MaximumList( List( twist_range, a -> Length( String( a ) ) ) ), max );
        if IsBound( EulerCharacteristic ) then
            
            if SpectralSequenceConvention then
                twist_range := [ twist_range[1] .. twist_range[nr_cols] + ( nr_rows - 1 ) ];
                chi := List( twist_range, i -> Value( EulerCharacteristic, i ) );
            else
                chi := List( twist_range + ( nr_rows - 1 ), i -> Value( EulerCharacteristic, i ) );
            fi;
            
            ## save it
            o!.Euler := chi;
            
            max := Maximum( MaximumList( List( chi, a -> Length( String( a ) ) ) ), max );
            
        elif twist = row_range[nr_rows] then ## we might have computed the syzygies up to some degree bound only
            
            chi := List( [ 1 .. nr_cols - twist ], j -> Sum( [ 0 .. nr_rows - 1 ], i -> (-1)^i * betti[nr_rows-i][i+j] ) );
            
            ## save it
            o!.Euler := chi;
            
            if IsBound( higher_vanish ) and column_range[Length( column_range )] >= higher_vanish - 1 then
                Append( chi, List( [ Maximum( nr_cols - twist + 1, 1 ) .. nr_cols ],
                        j -> Sum( [ 0 .. nr_rows - 1 ],
                                function( i )
                                  if IsBound( betti[nr_rows-i][i+j] ) then
                                      return (-1)^i * betti[nr_rows-i][i+j];
                                  else
                                      return 0;
                                  fi; end ) ) );
                                  
                ## save it
                o!.Euler := chi;
            else
                Append( chi, ListWithIdenticalEntries( twist, "?" ) );
            fi;
            
            max := Maximum( MaximumList( List( chi, a -> Length( String( a ) ) ) ), max );
            
        fi;
    fi;
    
    ## finally add a space
    max := max + 1;
    
    ## the maximum of the legend column
    MAX := MaximumList( List( row_range, a -> Length( String( a ) ) ) );
    
    if IsBound( twist ) then
        MAX := Maximum( MAX, Length( "twist" ) );
    else
        MAX := Maximum( MAX, Length( "degree" ) );
    fi;
    
    ## create the display string:
    
    display := "";
    
    if SpectralSequenceConvention then
        nr_cols := nr_cols + nr_rows - 1;
    fi;
    
    ## total:
    if nr_rows > 1 then
        Append( display, String( "total", MAX ) );
        Append( display, ": " );
        Perform( total, function( i ) Append( display, String( i, max ) ); end );
        if SpectralSequenceConvention then
            Perform( [ 1 .. nr_rows - 1 ], function( i ) Append( display, String( "?", max ) ); end );
        fi;
        Append( display, "\n" );
        if SpectralSequenceConvention then
            Append( display, ListWithIdenticalEntries( MAX + 2, '-' ) );
            Append( display, Flat( ListWithIdenticalEntries( nr_cols, Concatenation( ListWithIdenticalEntries( max - 1, '-' ), "|" ) ) ) );
        else
            Append( display, ListWithIdenticalEntries( MAX + 2 + nr_cols * max, '-' ) );
        fi;
        Append( display, "\n" );
    fi;
    
    ## twist:
    if IsBound( twist ) and nr_rows > 1 and not SpectralSequenceConvention then
        Append( display, String( "twist", MAX ) );
        Append( display, ": " );
        Perform( twist_range, function( i ) Append( display, String( i, max ) ); end );
        Append( display, "\n" );
        Append( display, ListWithIdenticalEntries( MAX + 2, '-' ) );
        Append( display, Flat( ListWithIdenticalEntries( nr_cols, Concatenation( ListWithIdenticalEntries( max - 1, '-' ), "|" ) ) ) );
        Append( display, "\n" );
    fi;
    
    if reverse then
        row_range := Reversed( row_range );
    fi;
    
    ## betti:
    if SpectralSequenceConvention then
        for ar in [ 1 .. nr_rows ] do
            Append( display, String( String( row_range[ar] ), MAX ) );
            Append( display, ": " );
            Perform( [ 1 .. ar - 1 ], function( i ) Append( display, String( "*", max ) ); end );
            for i in [ 1 .. nr_cols - ( nr_rows - 1 ) ] do
                if IsZero( betti[ar][i] ) then
                    Append( display, String( ".", max ) );
                else
                    Append( display, String( String( betti[ar][i] ), max ) );
                fi;
            od;
            if IsBound( higher_vanish ) and column_range[Length( column_range )] >= higher_vanish - 1 then
                Perform( [ 1 .. nr_rows - ar ], function( i ) Append( display, String( "0", max ) ); end );
            else
                Perform( [ 1 .. nr_rows - ar ], function( i ) Append( display, String( "*", max ) ); end );
            fi;
            Append( display, "\n" );
        od;
    else
        for ar in [ 1 .. nr_rows ] do
            Append( display, String( String( row_range[ar] ), MAX ) );
            Append( display, ": " );
            for i in [ 1 .. nr_cols ] do
                if IsZero( betti[ar][i] ) then
                    Append( display, String( ".", max ) );
                else
                    Append( display, String( String( betti[ar][i] ), max ) );
                fi;
            od;
            Append( display, "\n" );
        od;
    fi;
    
    ## degree/twist:
    if IsBound( twist ) then
        Append( display, ListWithIdenticalEntries( MAX + 2, '-' ) );
        if IsBound( higher_vanish ) then
            pos := Position( column_range, higher_vanish );
            if IsBound( o!.markers ) and IsList( o!.markers ) then
                marker := First( o!.markers, i -> i[1] = higher_vanish );
                if IsList( marker ) then
                    marker := marker[2];
                fi;
            fi;
        fi;
        
        if IsBound( pos ) and IsPosInt( pos ) then
            pos := pos + nr_cols - Length( column_range );
            Append( display, Flat( ListWithIdenticalEntries( pos - 1, Concatenation( ListWithIdenticalEntries( max - 1, '-' ), "|" ) ) ) );
            if not IsString( marker ) then
                marker := "V";
            fi;
            Append( display, Concatenation( ListWithIdenticalEntries( max - 1, '-' ), marker ) );
            Append( display, Flat( ListWithIdenticalEntries( nr_cols - pos, Concatenation( ListWithIdenticalEntries( max - 1, '-' ), "|" ) ) ) );
        else
            Append( display, Flat( ListWithIdenticalEntries( nr_cols, Concatenation( ListWithIdenticalEntries( max - 1, '-' ), "|" ) ) ) );
        fi;
        Append( display, "\n" );
        Append( display, String( "twist", MAX ) );
    else
        Append( display, ListWithIdenticalEntries( MAX + 2 + nr_cols * max, '-' ) );
        Append( display, "\n" );
        Append( display, String( "degree", MAX ) );
    fi;
    
    Append( display, ": " );
    
    if SpectralSequenceConvention then
        ar := column_range[1];
        Perform( [ ar - ( nr_rows - 1 ) .. ar - 1 ], function( i ) Append( display, String( i, max ) ); end );
    fi;
    
    Perform( column_range, function( i ) Append( display, String( i, max ) ); end );
    
    Append( display, "\n" );
    
    ## Euler characteristic:
    if IsBound( chi ) then
        Append( display, ListWithIdenticalEntries( MAX + 2 + nr_cols * max, '-' ) );
        Append( display, "\n" );
        Append( display, String( "Euler", MAX ) );
        Append( display, ": " );
        if SpectralSequenceConvention and not IsBound( EulerCharacteristic ) then
            Perform( [ 1 .. nr_rows - 1 ], function( i ) Append( display, String( "?", max ) ); end );
        fi;
        Perform( chi, function( i ) Append( display, String( i, max ) ); end );
        Append( display, "\n" );
    fi;
    
    return display;
    
end );

##
InstallMethod( Display,
        "for Betti diagrams",
        [ IsBettiTable ],
        
  function( o )
    local SpectralSequenceConvention;
    
    ## the spectral sequence convention for Betti diagrams
    if IsBound( HOMALG.SpectralSequenceConventionForBettiTables ) then
        SpectralSequenceConvention := HOMALG.SpectralSequenceConventionForBettiTables = true;
    elif IsComplexOfFinitelyPresentedObjectsRep( o!.object ) and
      IsBound( HOMALG.SpectralSequenceConventionForBettiTablesOfComplexes ) then
        SpectralSequenceConvention := HOMALG.SpectralSequenceConventionForBettiTablesOfComplexes = true;
    elif IsCocomplexOfFinitelyPresentedObjectsRep( o!.object ) and
      IsBound( HOMALG.SpectralSequenceConventionForBettiTablesOfCocomplexes ) then
        SpectralSequenceConvention := HOMALG.SpectralSequenceConventionForBettiTablesOfCocomplexes = true;
    else
        SpectralSequenceConvention := false;
    fi;
    
    if not IsBound( o!.display ) or
       o!.SpectralSequenceConvention <> SpectralSequenceConvention then
        
        o!.SpectralSequenceConvention := SpectralSequenceConvention;
        o!.display := homalgCreateDisplayString( o );
        
    fi;
    
    Print( o!.display );
    
end );


[ Dauer der Verarbeitung: 0.35 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