Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/homalgtocas/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 6.8.2025 mit Größe 12 kB image not shown  

Quelle  HomalgExternalMatrix.gi   Sprache: unbekannt

 
# SPDX-License-Identifier: GPL-2.0-or-later
# HomalgToCAS: A window to the outer world
#
# Implementations
#

##  Implementation stuff for homalg matrices.

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

##
InstallMethod( homalgPointer,
        "for homalg external matrices",
        [ IsHomalgExternalMatrixRep ],
        
  function( M )
    
    return homalgPointer( Eval( M ) ); ## here we must evaluate
    
end );

##
InstallMethod( homalgExternalCASystem,
        "for homalg external matrices",
        [ IsHomalgExternalMatrixRep ],
        
  function( M )
    local R;
    
    R := HomalgRing( M );
    
    if IsHomalgExternalRingRep( R ) then
        return homalgExternalCASystem( R ); ## avoid evaluating the matrix
    else
        return homalgExternalCASystem( Eval( M ) );
    fi;
    
end );

##
InstallMethod( homalgExternalCASystemVersion,
        "for homalg external matrices",
        [ IsHomalgExternalMatrixRep ],
        
  function( M )
    local R;
    
    R := HomalgRing( M );
    
    if IsHomalgExternalRingRep( R ) then
        return homalgExternalCASystemVersion( R ); ## avoid evaluating the matrix
    else
        return homalgExternalCASystemVersion( Eval( M ) );
    fi;
    
end );

##
InstallMethod( homalgStream,
        "for homalg external matrices",
        [ IsHomalgExternalMatrixRep ],
        
  function( M )
    local R;
    
    R := HomalgRing( M );
    
    if IsHomalgExternalRingRep( R ) then
        return homalgStream( R ); ## avoid evaluating the matrix
    else
        return homalgStream( Eval( M ) );
    fi;
    
end );

##
InstallMethod( homalgExternalCASystemPID,
        "for homalg external matrices",
        [ IsHomalgExternalMatrixRep ],
        
  function( M )
    local R;
    
    R := HomalgRing( M );
    
    if IsHomalgExternalRingRep( R ) then
        return homalgExternalCASystemPID( R ); ## avoid evaluating the matrix
    else
        return homalgExternalCASystemPID( Eval( M ) );
    fi;
    
end );

##
InstallMethod( SetMatElm,
        "for homalg external matrices",
        [ IsHomalgMatrix and IsMutable, IsPosInt, IsPosInt, IsHomalgExternalRingElementRep ],
        
  function( M, r, c, s )
    
    SetMatElm( M, r, c, homalgPointer( s ), HomalgRing( M ) );
    
end );

##
InstallMethod( SetMatElm,
        "for homalg external matrices",
        [ IsHomalgMatrix and IsMutable, IsPosInt, IsPosInt, IsHomalgExternalRingElementRep, IsHomalgExternalRingRep ],
        
  function( M, r, c, s, R )
    
    SetMatElm( M, r, c, homalgPointer( s ), R );
    
end );

## MatrixBaseChange to an external ring
InstallMethod( \*,
        "for homalg matrices",
        [ IsHomalgExternalRingRep, IsHomalgMatrix ],
        
  function( R, m )
    local RP, mat;
    
    RP := homalgTable( R );
    
    if not IsIdenticalObj( HomalgRing( m ), R ) and
       IsHomalgExternalRingRep( HomalgRing( m ) ) and
       IsIdenticalObj( homalgStream( HomalgRing( m ) ), homalgStream( R ) ) and
       IsBound( RP!.CopyMatrix ) then ## make a "copy" over a different ring
        
        Eval( m ); ## enforce evaluation
        
        mat := HomalgMatrix( R );
        
        ## this is quicker and safer than calling the
        ## constructor HomalgMatrix with all arguments
        SetEval( mat, RP!.CopyMatrix( m, R ) );
        
        BlindlyCopyMatrixProperties( m, mat );
        
        return mat;
        
    fi;
    
    TryNextMethod( );
    
end );

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

##
InstallMethod( CreateHomalgMatrixFromList,
        "constructor for homalg matrices",
        [ IsList, IsHomalgExternalRingRep ],
        
  function( L, R )
    local M;
    
    if IsEmpty( L ) then
        return HomalgZeroMatrix( 0, 0, R );
    elif ForAll( L, IsList and IsEmpty ) then
        return HomalgZeroMatrix( Length( L ), 0, R );
    fi;
    
    if IsList( L[1] ) then
        if not ForAll( L[1], IsHomalgExternalRingElementRep ) then
            TryNextMethod( );
        elif not IsIdenticalObj( HomalgRing( L[1][1] ), R ) then
            TryNextMethod( );
        fi;
        M := List( L, r -> List( r, homalgPointer ) );
        M := Concatenation( "[[", JoinStringsWithSeparator( List( M, r -> JoinStringsWithSeparator( r ) ), "],[" ), "]]" );
    else
        if not ForAll( L, IsHomalgExternalRingElementRep ) then
            TryNextMethod( );
        elif not IsIdenticalObj( HomalgRing( L[1] ), R ) then
            TryNextMethod( );
        fi;
        ## this resembles NormalizeInput in Maple's homalg ( a legacy ;) )
        M := Concatenation( "[[", JoinStringsWithSeparator( List( L, homalgPointer ), "],[" ), "]]" );
        ## What is the use case for this? Wouldn't it be better to replace this by an error message?
        # Error( "the number of rows and columns must be specified to construct a matrix from a list" );
    fi;
    
    return CreateHomalgMatrixFromString( M, R );
    
end );

##
InstallMethod( CreateHomalgMatrixFromList,
        "constructor for homalg matrices",
        [ IsList, IsInt, IsInt, IsHomalgExternalRingRep ],
        
  function( L, r, c, R )
    local M;
    
    if r * c = 0 then
        return HomalgZeroMatrix( r, c, R );
    fi;
    
    if IsList( L[1] ) then
        if not ForAll( L[1], IsHomalgExternalRingElementRep ) then
            TryNextMethod( );
        elif not IsIdenticalObj( HomalgRing( L[1][1] ), R ) then
            TryNextMethod( );
        fi;
        M := List( Concatenation( L ), homalgPointer );
        M := Concatenation( "[", JoinStringsWithSeparator( M ), "]" );
    else
        if not ForAll( L, IsHomalgExternalRingElementRep ) then
            TryNextMethod( );
        elif not IsIdenticalObj( HomalgRing( L[1] ), R ) then
            TryNextMethod( );
        fi;
        M := Concatenation( "[", JoinStringsWithSeparator( List( L, homalgPointer ) ), "]" );
    fi;
    
    return CreateHomalgMatrixFromString( M, r, c, R );
    
end );

##
InstallMethod( ConvertHomalgMatrix,
        "for homalg matrices",
        [ IsHomalgMatrix, IsHomalgRing ],
        
  function( M, R )
    
    if IsBound( M!.ConvertHomalgMatrixViaFile ) and M!.ConvertHomalgMatrixViaFile = false then
        TryNextMethod( );
    elif IsBound( M!.ConvertHomalgMatrixViaSparseString ) and M!.ConvertHomalgMatrixViaSparseString = true then
        return ConvertHomalgMatrixViaSparseString( M, R );
    fi;
    
    return ConvertHomalgMatrixViaFile( M, R );
    
end );

##
InstallMethod( ConvertHomalgMatrix,
        "for homalg matrices",
        [ IsHomalgMatrix, IsInt, IsInt, IsHomalgRing ],
        
  function( M, r, c, R )
    
    if IsBound( M!.ConvertHomalgMatrixViaFile ) and M!.ConvertHomalgMatrixViaFile = false then
        TryNextMethod( );
    elif IsBound( M!.ConvertHomalgMatrixViaSparseString ) and M!.ConvertHomalgMatrixViaSparseString = true then
        return ConvertHomalgMatrixViaSparseString( M, r, c, R );
    fi;
    
    return ConvertHomalgMatrixViaFile( M, R );
    
end );

##
InstallMethod( ConvertHomalgMatrixViaFile,
        "convert an external matrix into an external ring via file saving and loading",
        [ IsHomalgMatrix, IsHomalgRing ],
        
  function( M, RR )
    
    local R, r, c, separator, pointer, pid, file, filename, fs, remove, MM;
    
    R := HomalgRing( M ); # the source ring
    
    r := NumberRows( M );
    c := NumberColumns( M );
    
    if IsHomalgExternalMatrixRep( M ) then
        pointer := homalgPointer( M );
        pid := Concatenation( "_PID_", String( homalgExternalCASystemPID( R ) ) );
    else
        if IsBound( HOMALG_IO.FileNameCounter ) then
            pointer := Concatenation( "homalg_file_", String( HOMALG_IO.FileNameCounter ) );
            HOMALG_IO.FileNameCounter := HOMALG_IO.FileNameCounter + 1;
        else
            Error( "HOMALG_IO.FileNameCounter is not bound, filename creation for internal object failed.\n" );
        fi;
        
        if not IsBound( HOMALG_IO.PID ) or not IsInt( HOMALG_IO.PID ) then
            HOMALG_IO.PID := -1; #this is not the real PID!
        fi;
        
        pid := Concatenation( "_PID_", String( HOMALG_IO.PID ) );
        
    fi;
    
    file := Concatenation( pointer, pid );
    
    filename := Filename( HOMALG_IO.DirectoryForTemporaryFiles, file );
    
    remove := SaveHomalgMatrixToFile( filename, M );
    
    MM := LoadHomalgMatrixFromFile( filename, r, c, RR ); # matrix in target ring
    
    ResetFilterObj( MM, IsVoidMatrix );
    
    if not ( IsBound( HOMALG_IO.DoNotDeleteTemporaryFiles ) and HOMALG_IO.DoNotDeleteTemporaryFiles = true ) then
        if not IsBool( remove ) then
            if IsList( remove ) and ForAll( remove, IsString ) then
                for file in remove do
                    Exec( Concatenation( "/bin/rm -f \"", file, "\"" ) );
                od;
            else
                Error( "expecting a list of strings indicating file names to be deleted\n" );
            fi;
        else
            Exec( Concatenation( "/bin/rm -f \"", filename, "\"" ) );
        fi;
    fi;
    
    return MM;
    
end );

##
InstallMethod( SaveHomalgMatrixToFile,
        "for two arguments instead of three",
        [ IsString, IsHomalgMatrix ],
        
  function( filename, M )
    local fs;
    
    if IsExistingFile( filename ) then
        Error( "the file ", filename, " already exists, please delete it first and then type return; to continue\n" );
        return SaveHomalgMatrixToFile( filename, M );
    fi;
    
    return SaveHomalgMatrixToFile( filename, M, HomalgRing( M ) );
    
end );

##
InstallMethod( SaveHomalgMatrixToFile,
        "for an internal homalg matrix",
        [ IsString, IsHomalgInternalMatrixRep, IsHomalgInternalRingRep ],
        
  function( filename, M, R )
    local mode;
    
    if not IsBound( M!.SaveAs ) then
        mode := "ListList";
    else
        mode := M!.SaveAs; ## FIXME: not yet supported
    fi;
    
    if mode = "ListList" then
        
        if FileString( filename, GetListListOfHomalgMatrixAsString( M ) ) = fail then
            Error( "unable to write in the file ", filename, "\n" );
        fi;
        
    fi;
    
    return true;
    
end );

##
InstallMethod( LoadHomalgMatrixFromFile,
        "for an internal homalg ring",
        [ IsString, IsHomalgInternalRingRep ],
        
  function( filename, R )
    local mode, str, z, M;
    
    if not IsBound( R!.LoadAs ) then
        mode := "ListList";
    else
        mode := R!.LoadAs; ## FIXME: not yet supported
    fi;
    
    if mode = "ListList" then
        
        str := StringFile( filename );
        
        if str = fail then
            Error( "unable to read lines from the file ", filename, "\n" );
        fi;
        
        if IsBound( R!.NameOfPrimitiveElement ) and
           HasCharacteristic( R ) and Characteristic( R ) > 0 and
           HasDegreeOverPrimeField( R ) and DegreeOverPrimeField( R ) > 1 then
            z := R!.NameOfPrimitiveElement;
            
            if IsBoundGlobal( z ) then
                Error( z, " is globally bound\n" );
            fi;
            
            BindGlobal( z, Z( Characteristic( R ) ^ DegreeOverPrimeField( R ) ) );
            
            str := EvalString( str );
            
            MakeReadWriteGlobal( z );
            
            UnbindGlobal( z );
            
        else
            M := EvalString( str );
        fi;
        
        M := HomalgMatrix( str, R );
        
        #if HasCharacteristic( R ) and HasCharacteristic( R ) > 0 then
            M := One( R ) * M;
        #fi;
    fi;
    
    return M;
    
end );

##
InstallMethod( LoadHomalgMatrixFromFile,
        "for an internal homalg ring",
        [ IsString, IsInt, IsInt, IsHomalgRing ], 0, ## lowest rank method
        
  function( filename, r, c, R )
    
    return LoadHomalgMatrixFromFile( filename, R );
    
    ## do not set NumberRows and NumberColumns for safety reasons
    
end );

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

InstallMethod( Display,
        "for homalg external matrices",
        [ IsHomalgExternalMatrixRep ], 0, ## never higher!!!
        
  function( o )
    
    Print( homalgSendBlocking( [ o ], "need_display", "Display" ) );
    
end );


[ Dauer der Verarbeitung: 0.34 Sekunden  (vorverarbeitet)  ]