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


Quelle  algmat.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Thomas Breuer, Willem de Graaf.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  This file contains those functions that mainly deal with matrix algebras,
##  that is, associative matrix algebras and matrix Lie algebras.
##


#############################################################################
##
#M  RingByGenerators( <mats> )  . . . .  ring generated by a list of matrices
##
##  If <mats> is a list of matrices over a field then we construct a matrix
##  algebra over its prime field.
##
InstallOtherMethod( RingByGenerators,
    "for a list of matrices over a finite field",
    true,
    [ IsFFECollCollColl ], 0,
    mats -> FLMLORByGenerators( GF( Characteristic( mats ) ), mats ) );

InstallOtherMethod( RingByGenerators,
    "for a list of matrices over the Cyclotomics",
    true,
    [ IsCyclotomicCollCollColl ], 0,
    mats -> FLMLORByGenerators( Integers, mats ) );


#############################################################################
##
#M  DefaultRingByGenerators( <mats> )  . . ring containing a list of matrices
##
##  If <mats> is a list of matrices over a field then we construct a matrix
##  algebra over its prime field.
##  (So this may differ from the result of `RingByGenerators' if the
##  characteristic is zero.)
##
InstallOtherMethod( DefaultRingByGenerators,
    "for a list of matrices over a finite field",
    true,
    [ IsFFECollCollColl ], 0,
    mats -> FLMLORByGenerators( GF( Characteristic( mats ) ), mats ) );

InstallOtherMethod( DefaultRingByGenerators,
    "for a list of matrices over the Cyclotomics",
    true,
    [ IsCyclotomicCollCollColl ], 0,
    mats -> FLMLORByGenerators( Rationals, mats ) );


#############################################################################
##
#M  RingByGenerators( <mats> )  . .  ring generated by a list of Lie matrices
##
##  If <mats> is a list of Lie matrices over a finite field then we construct
##  a matrix Lie algebra over its prime field.
##
InstallOtherMethod( RingByGenerators,
    "for a list of Lie matrices over a finite field",
    true,
    [ IsLieObjectCollection and IsMatrixCollection ], 0,
    function( mats )

    local Fam;

    # Check whether the matrices lie in the Lie family of a family of
    # ordinary matrices.
    Fam:= UnderlyingFamily( ElementsFamily( FamilyObj( mats ) ) );
    if not HasElementsFamily( Fam ) then
      TryNextMethod();
    fi;
    Fam:= ElementsFamily( Fam );
    if not HasElementsFamily( Fam ) then
      TryNextMethod();
    fi;
    Fam:= ElementsFamily( Fam );

    # Handle the cases that the entries of the matrices
    # are FFEs or cyclotomics.
    if IsFFEFamily( Fam ) then
      return FLMLORByGenerators( GF( Characteristic( Fam ) ), mats );
    elif IsIdenticalObj( Fam, CyclotomicsFamily ) then
      return FLMLORByGenerators( Integers, mats );
    else
      TryNextMethod();
    fi;
    end );


#############################################################################
##
#M  DefaultRingByGenerators( <mats> )   . . ring cont. a list of Lie matrices
##
##  If <mats> is a list of Lie matrices over a field then we construct
##  a matrix Lie algebra over its prime field.
##  (So this may differ from the result of `RingByGenerators' if the
##  characteristic is zero.)
##
InstallOtherMethod( DefaultRingByGenerators,
    "for a list of Lie matrices",
    true,
    [ IsLieObjectCollection and IsMatrixCollection ], 0,
    function( mats )

    local Fam;

    # Check whether the matrices lie in the Lie family of a family of
    # ordinary matrices.
    Fam:= UnderlyingFamily( ElementsFamily( FamilyObj( mats ) ) );
    if not HasElementsFamily( Fam ) then
      TryNextMethod();
    fi;
    Fam:= ElementsFamily( Fam );
    if not HasElementsFamily( Fam ) then
      TryNextMethod();
    fi;
    Fam:= ElementsFamily( Fam );

    # Handle the cases that the entries of the matrices
    # are FFEs or cyclotomics.
    if IsFFEFamily( Fam ) then
      return AlgebraByGenerators( GF( Characteristic( Fam ) ), mats );
    elif IsIdenticalObj( Fam, CyclotomicsFamily ) then
      return AlgebraByGenerators( Rationals, mats );
    else
      TryNextMethod();
    fi;
    end );


#############################################################################
##
#M  RingWithOneByGenerators( <mats> )  ring-with-one gen. by list of matrices
##
##  If <mats> is a list of matrices over a field then we construct a matrix
##  algebra over its prime field.
##
InstallOtherMethod( RingWithOneByGenerators,
    "for a list of matrices over a finite field",
    true,
    [ IsFFECollCollColl ], 0,
    mats -> FLMLORWithOneByGenerators( GF( Characteristic(mats) ), mats ) );

InstallOtherMethod( RingWithOneByGenerators,
    "for a list of matrices over the Cyclotomics",
    true,
    [ IsCyclotomicCollCollColl ], 0,
    mats -> FLMLORWithOneByGenerators( Integers, mats ) );

#T how to formulate this for any field?


#############################################################################
##
#M  FLMLORByGenerators( <F>, <mats> )
#M  FLMLORByGenerators( <F>, <empty>, <zero> )
#M  FLMLORByGenerators( <F>, <mats>, <zero> )
##
InstallMethod( FLMLORByGenerators,
    "for division ring and list of ordinary matrices over it",
    IsElmsCollColls,
    [ IsDivisionRing, IsCollection and IsList ], 0,
    function( F, mats )
    local dims, A;

    # Check that all entries in `mats' are square matrices of the same shape.
    if not IsOrdinaryMatrix( mats[1] ) then
      TryNextMethod();
    fi;
    dims:= DimensionsMat( mats[1] );
    if    dims[1] <> dims[2]
       or not ForAll( mats, mat ->     IsOrdinaryMatrix( mat )
                                   and DimensionsMat( mat ) = dims ) then
      TryNextMethod();
    fi;

    if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    else
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsVectorSpace
                              and IsNonGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    fi;

    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) );
    SetDimensionOfVectors( A, dims );

    # If the generators are associative elements then so is `A'.
    if ForAll( mats, IsAssociativeElement ) then
      SetIsAssociative( A, true );
    fi;

    # Return the result.
    return A;
    end );

InstallOtherMethod( FLMLORByGenerators,
    "for division ring, empty list, and square ordinary matrix",
    function( FamF, Famempty, Famzero )
        return IsElmsColls( FamF, Famzero );
    end,
    [ IsDivisionRing, IsList and IsEmpty, IsOrdinaryMatrix ], 0,
    function( F, empty, zero )
    local dims, A;

    # Check whether this method is the right one.
    dims:= DimensionsMat( zero );
    if dims[1] <> dims[2] then
      Error( "<zero> must be a square matrix" );
    fi;

    A:= Objectify( NewType( CollectionsFamily( FamilyObj( zero ) ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsTrivial
                            and IsAttributeStoringRep ),
                   rec() );
    SetDimension( A, 0 );
    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftModule( A, empty );
    SetZero( A, zero );
    SetDimensionOfVectors( A, dims );

    # Return the result.
    return A;
    end );

InstallOtherMethod( FLMLORByGenerators,
    "for division ring, list of matrices over it, and ordinary matrix",
    function( FamF, Fammats, Famzero )
        return IsElmsCollColls( FamF, Fammats );
    end,
    [ IsDivisionRing, IsCollection and IsList, IsOrdinaryMatrix ], 0,
    function( F, mats, zero )
    local dims, A;

    # Check that all entries in `mats' are matrices of the same shape.
    if not IsOrdinaryMatrix( mats[1] ) then
      TryNextMethod();
    fi;
    dims:= DimensionsMat( mats[1] );
    if    dims[1] <> dims[2]
       or not ForAll( mats, mat ->     IsOrdinaryMatrix( mat )
                                   and DimensionsMat( mat ) = dims ) then
      TryNextMethod();
    fi;

    if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    else
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsVectorSpace
                              and IsNonGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    fi;

    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) );
    SetZero( A, zero );
    SetDimensionOfVectors( A, dims );

    # If the generators are associative elements then so is `A'.
    if ForAll( mats, IsAssociativeElement ) then
      SetIsAssociative( A, true );
    fi;

    # Return the result.
    return A;
    end );


#############################################################################
##
#M  FLMLORByGenerators( <F>, <lie-mats> )
#M  FLMLORByGenerators( <F>, <empty>, <lie-zero> )
#M  FLMLORByGenerators( <F>, <lie-mats>, <lie-zero> )
##
InstallMethod( FLMLORByGenerators,
    "for division ring and list of Lie matrices over it",
    IsElmsCollLieColls,
    [ IsDivisionRing, IsLieObjectCollection and IsList ], 0,
    function( F, mats )
    local dims, A;

    # Check that all entries in `mats' are square matrices of the same shape.
    if not IsLieMatrix( mats[1] ) then
      TryNextMethod();
    fi;
    dims:= DimensionsMat( mats[1] );
    if    dims[1] <> dims[2]
       or not ForAll( mats, mat ->     IsLieMatrix( mat )
                                   and DimensionsMat( mat ) = dims ) then
      TryNextMethod();
    fi;

    if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    else
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsVectorSpace
                              and IsNonGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    fi;

    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) );
    SetDimensionOfVectors( A, dims );

    # `A' consists of Lie objects, so it is a Lie algebra.
    SetIsLieAlgebra( A, true );

    # Return the result.
    return A;
    end );

InstallOtherMethod( FLMLORByGenerators,
    "for division ring, empty list, and Lie matrix",
    function( FamF, Famempty, Famzero )
        return IsElmsLieColls( FamF, Famzero );
    end,
    [ IsDivisionRing, IsList and IsEmpty, IsLieMatrix and IsLieObject ], 0,
    function( F, empty, zero )
    local dims, A;

    # Check whether this method is the right one.
    dims:= DimensionsMat( zero );
    if dims[1] <> dims[2] then
      Error( "<zero> must be a square matrix" );
    fi;

    A:= Objectify( NewType( CollectionsFamily( FamilyObj( zero ) ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsTrivial
                            and IsAttributeStoringRep ),
                   rec() );
    SetDimension( A, 0 );
    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftModule( A, empty );
    SetZero( A, zero );
    SetDimensionOfVectors( A, dims );

    # Return the result.
    return A;
    end );

InstallOtherMethod( FLMLORByGenerators,
    "for division ring, list of Lie matrices over it, and Lie matrix",
    function( FamF, Fammats, Famzero )
        return IsElmsCollLieColls( FamF, Fammats );
    end,
    [ IsDivisionRing, IsLieObjectCollection and IsList,
      IsLieObject and IsLieMatrix ], 0,
    function( F, mats, zero )
    local dims, A;

    # Check that all entries in `mats' are matrices of the same shape.
    if not IsLieMatrix( mats[1] ) then
      TryNextMethod();
    fi;
    dims:= DimensionsMat( mats[1] );
    if    dims[1] <> dims[2]
       or not ForAll( mats, mat ->     IsLieMatrix( mat )
                                   and DimensionsMat( mat ) = dims ) then
      TryNextMethod();
    fi;

    if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    else
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLOR
                              and IsVectorSpace
                              and IsNonGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    fi;

    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) );
    SetZero( A, zero );
    SetDimensionOfVectors( A, dims );

    # `A' consists of Lie objects, so it is a Lie algebra.
    SetIsLieAlgebra( A, true );

    # Return the result.
    return A;
    end );


#############################################################################
##
#M  FLMLORWithOneByGenerators( <F>, <mats> )
#M  FLMLORWithOneByGenerators( <F>, <empty>, <zero> )
#M  FLMLORWithOneByGenerators( <F>, <mats>, <zero> )
##
InstallMethod( FLMLORWithOneByGenerators,
    "for division ring and list of ordinary matrices over it",
    IsElmsCollColls,
    [ IsDivisionRing, IsCollection and IsList ], 0,
    function( F, mats )
    local dims, A;

    # Check that all entries in `mats' are square matrices of the same shape.
    if not IsOrdinaryMatrix( mats[1] ) then
      TryNextMethod();
    fi;
    dims:= DimensionsMat( mats[1] );
    if    dims[1] <> dims[2]
       or not ForAll( mats, mat ->     IsOrdinaryMatrix( mat )
                                   and DimensionsMat( mat ) = dims ) then
      TryNextMethod();
    fi;

    if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLORWithOne
                              and IsGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    else
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLORWithOne
                              and IsVectorSpace
                              and IsNonGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    fi;

    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRingWithOne( A, AsList( mats ) );
    SetDimensionOfVectors( A, dims );

    # If the generators are associative elements then so is `A'.
    if ForAll( mats, IsAssociativeElement ) then
      SetIsAssociative( A, true );
    fi;

    # Return the result.
    return A;
    end );

InstallOtherMethod( FLMLORWithOneByGenerators,
    "for division ring, empty list, and square ordinary matrix",
    function( FamF, Famempty, Famzero )
        return IsElmsColls( FamF, Famzero );
    end,
    [ IsDivisionRing, IsList and IsEmpty, IsOrdinaryMatrix ], 0,
    function( F, empty, zero )
    local A;

    # Check whether this method is the right one.
    if Length( zero ) <> Length( zero[1] ) then
      Error( "<zero> must be a square matrix" );
    fi;

    A:= Objectify( NewType( CollectionsFamily( FamilyObj( zero ) ),
                                IsFLMLORWithOne
                            and IsGaussianMatrixSpace
                            and IsAssociative
                            and IsAttributeStoringRep ),
                   rec() );
    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRingWithOne( A, empty );
    SetZero( A, zero );
    SetDimensionOfVectors( A, DimensionsMat( zero ) );

    # Return the result.
    return A;
    end );

InstallOtherMethod( FLMLORWithOneByGenerators,
    "for division ring, list of matrices over it, and ordinary matrix",
    function( FamF, Fammats, Famzero )
        return     HasCollectionsFamily( FamF )
               and IsElmsColls( CollectionsFamily( FamF ), Fammats );
    end,
    [ IsDivisionRing, IsCollection and IsList, IsOrdinaryMatrix ], 0,
    function( F, mats, zero )
    local dims, A;

    # Check that all entries in `mats' are matrices of the same shape.
    if not IsOrdinaryMatrix( mats[1] ) then
      TryNextMethod();
    fi;
    dims:= DimensionsMat( mats[1] );
    if    dims[1] <> dims[2]
       or not ForAll( mats, mat ->     IsOrdinaryMatrix( mat )
                                   and DimensionsMat( mat ) = dims ) then
      TryNextMethod();
    fi;

    if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLORWithOne
                              and IsGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    else
      A:= Objectify( NewType( FamilyObj( mats ),
                                  IsFLMLORWithOne
                              and IsVectorSpace
                              and IsNonGaussianMatrixSpace
                              and IsAttributeStoringRep ),
                     rec() );
    fi;

    SetLeftActingDomain( A, F );
    SetGeneratorsOfLeftOperatorRingWithOne( A, AsList( mats ) );
    SetZero( A, zero );
    SetDimensionOfVectors( A, dims );

    # If the generators are associative elements then so is `A'.
    if ForAll( mats, IsAssociativeElement ) then
      SetIsAssociative( A, true );
    fi;

    # Return the result.
    return A;
    end );


#############################################################################
##
#M  TwoSidedIdealByGenerators( <A>, <mats> )
##
InstallMethod( TwoSidedIdealByGenerators,
    "for Gaussian matrix algebra and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsGaussianMatrixSpace,
      IsCollection and IsList ], 0,
    function( A, mats )
    local dims, I;

    # Check that all entries in `mats' are square matrices of the same shape.
    dims:= DimensionOfVectors( A );
    if not ForAll( mats, mat ->     IsMatrix( mat )
                                and DimensionsMat( mat ) = dims ) then
      Error( "entries of <mats> do not have the right dimension" );
    fi;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfTwoSidedIdeal( I, mats );
    SetLeftActingRingOfIdeal( I, A );
    SetRightActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, dims );

    # Return the result.
    return I;
    end );


InstallMethod( TwoSidedIdealByGenerators,
    "for non-Gaussian matrix algebra and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsNonGaussianMatrixSpace,
      IsCollection and IsList ], 0,
    function( A, mats )
    local dims, I;

    # Check that all entries in `mats' are square matrices of the same shape.
    dims:= DimensionOfVectors( A );
    if not ForAll( mats, mat ->     IsMatrix( mat )
                                and DimensionsMat( mat ) = dims ) then
      Error( "entries of <mats> do not have the right dimension" );
    fi;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsVectorSpace
                            and IsNonGaussianMatrixSpace
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfTwoSidedIdeal( I, mats );
    SetLeftActingRingOfIdeal( I, A );
    SetRightActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, dims );

    # Return the result.
    return I;
    end );


InstallMethod( TwoSidedIdealByGenerators,
    "for matrix algebra and empty list",
    true,
    [ IsMatrixFLMLOR, IsList and IsEmpty ], 0,
    function( A, mats )
    local I;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsTrivial
                            and IsAttributeStoringRep ),
                   rec() );

    SetDimension( I, 0 );
    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfTwoSidedIdeal( I, mats );
    SetGeneratorsOfLeftOperatorRing( I, mats );
    SetGeneratorsOfLeftModule( I, mats );
    SetLeftActingRingOfIdeal( I, A );
    SetRightActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, DimensionOfVectors( A ) );

    # Return the result.
    return I;
    end );


#############################################################################
##
#M  LeftIdealByGenerators( <A>, <mats> )
##
InstallMethod( LeftIdealByGenerators,
    "for Gaussian matrix algebra and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsGaussianMatrixSpace,
      IsCollection and IsList ], 0,
    function( A, mats )
    local dims, I;

    # Check that all entries in `mats' are square matrices of the same shape.
    dims:= DimensionOfVectors( A );
    if not ForAll( mats, mat ->     IsMatrix( mat )
                                and DimensionsMat( mat ) = dims ) then
      Error( "entries of <mats> do not have the right dimension" );
    fi;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfLeftIdeal( I, AsList( mats ) );
    SetLeftActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, dims );

    # Return the result.
    return I;
    end );


InstallMethod( LeftIdealByGenerators,
    "for non-Gaussian matrix algebra and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsNonGaussianMatrixSpace,
      IsCollection and IsList ], 0,
    function( A, mats )
    local dims, I;

    # Check that all entries in `mats' are square matrices of the same shape.
    dims:= DimensionOfVectors( A );
    if not ForAll( mats, mat ->     IsMatrix( mat )
                                and DimensionsMat( mat ) = dims ) then
      Error( "entries of <mats> do not have the right dimension" );
    fi;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsVectorSpace
                            and IsNonGaussianMatrixSpace
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfLeftIdeal( I, AsList( mats ) );
    SetLeftActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, dims );

    # Return the result.
    return I;
    end );


InstallMethod( LeftIdealByGenerators,
    "for matrix algebra and empty list",
    true,
    [ IsMatrixFLMLOR, IsList and IsEmpty ], 0,
    function( A, mats )
    local I;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsTrivial
                            and IsAttributeStoringRep ),
                   rec() );

    SetDimension( I, 0 );
    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfLeftIdeal( I, mats );
    SetGeneratorsOfLeftOperatorRing( I, mats );
    SetGeneratorsOfLeftModule( I, mats );
    SetLeftActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, DimensionOfVectors( A ) );

    # Return the result.
    return I;
    end );


#############################################################################
##
#M  RightIdealByGenerators( <A>, <mats> )
##
InstallMethod( RightIdealByGenerators,
    "for Gaussian matrix algebra and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsGaussianMatrixSpace,
      IsCollection and IsList ], 0,
    function( A, mats )
    local dims, I;

    # Check that all entries in `mats' are square matrices of the same shape.
    dims:= DimensionOfVectors( A );
    if not ForAll( mats, mat ->     IsMatrix( mat )
                                and DimensionsMat( mat ) = dims ) then
      Error( "entries of <mats> do not have the right dimension" );
    fi;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfRightIdeal( I, mats );
    SetRightActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, dims );

    # Return the result.
    return I;
    end );


InstallMethod( RightIdealByGenerators,
    "for non-Gaussian matrix algebra and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsNonGaussianMatrixSpace,
      IsCollection and IsList ], 0,
    function( A, mats )
    local dims, I;

    # Check that all entries in `mats' are square matrices of the same shape.
    dims:= DimensionOfVectors( A );
    if not ForAll( mats, mat ->     IsMatrix( mat )
                                and DimensionsMat( mat ) = dims ) then
      Error( "entries of <mats> do not have the right dimension" );
    fi;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsVectorSpace
                            and IsNonGaussianMatrixSpace
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfRightIdeal( I, mats );
    SetRightActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, dims );

    # Return the result.
    return I;
    end );


InstallMethod( RightIdealByGenerators,
    "for matrix algebra and empty list",
    true,
    [ IsMatrixFLMLOR, IsList and IsEmpty ], 0,
    function( A, mats )
    local I;

    I:= Objectify( NewType( FamilyObj( mats ),
                                IsFLMLOR
                            and IsGaussianMatrixSpace
                            and IsTrivial
                            and IsAttributeStoringRep ),
                   rec() );

    SetDimension( I, 0 );
    SetLeftActingDomain( I, LeftActingDomain( A ) );
    SetGeneratorsOfRightIdeal( I, mats );
    SetGeneratorsOfLeftOperatorRing( I, mats );
    SetGeneratorsOfLeftModule( I, mats );
    SetRightActingRingOfIdeal( I, A );
    SetDimensionOfVectors( I, DimensionOfVectors( A ) );

    # Return the result.
    return I;
    end );


#############################################################################
##
#M  IsUnit( <A>, <mat> )  . . . . . . . . . . .  for matrix FLMLOR and matrix
##
InstallMethod( IsUnit,
    "for matrix FLMLOR and matrix",
    IsCollsElms,
    [ IsMatrixFLMLOR, IsMatrix ], 0,
    function ( A, m )
    m:= m^-1;
    return m <> fail and m in A;
    end );


#############################################################################
##
#M  RadicalOfAlgebra( <A> ) . . . . . . . . for an associative matrix algebra
##
##  The radical of an associative algebra <A>  defined as the ideal of all
##  elements $x$ of <A> such that $x y$ is nilpotent for all $y$ in <A>.
##
##  For Gaussian matrix algebras this is easy to calculate,
##  for arbitrary associative algebras the task is reduced to the
##  Gaussian matrix algebra case.
##
##  The implementation of the characterisitc p>0 part is by Craig Struble.
##
InstallMethod( RadicalOfAlgebra,
    "for associative Gaussian matrix algebra",
    true,
    [ IsAlgebra and IsGaussianMatrixSpace and IsMatrixFLMLOR ], 0,
    function( A )

    local F,           # the field of A
          p,           # the characteristic of F
          q,           # the size of F
          n,           # the dimension of A
          ident,       # the identity matrix
          bas,         # a list of basis vectors of A
          minusOne,    # -1 in F
          eqs,         # equation set
          i,j,         # loop variables
          G,           # Gram matrix
          I,           # a list of basis vectors of an ideal of A
          I_prime,     # I \cup ident
          changed,     # flag denoted if $I_i <> I_{i-1}$ in ideal sequence
          pexp,        # a power of the prime p
          dim,         # the dimension of the vector space where A acts on
          charPoly,    # characteristic polynomials of elements in A
          invFrob,     # inverse of the Frobenius map of F
          invFrobexp,  # a power of the invFrob
          r, r_prime;  # the length of I and I_prime

    # Check associativity.
    if not IsAssociative( A ) then
      TryNextMethod();
    fi;

    if Dimension( A ) = 0 then return A; fi;

    F:= LeftActingDomain( A );
    p:= Characteristic( F );
    n:= Dimension( A );
    bas:= BasisVectors( Basis( A ) );

    if p = 0 then

      # First we treat the characteristic 0 case.
      # According to Dickson's theorem we have that in this case
      # the radical of `A' is $\{ x\in A \mid Tr(xy) = 0 \forall y \in A \}$,
      # so it can be computed by solving a system of linear equations.

      eqs:= List( [ 1 .. n ], x -> [] );

      for i in [1..n] do
        for j in [i..n] do
          eqs[i][j]:= TraceMat( bas[i] * bas[j] );
          eqs[j][i]:= eqs[i][j];
        od;
      od;

      return SubalgebraNC( A, List( NullspaceMat( eqs ),
                                    x -> LinearCombination( bas, x ) ),
                           "basis" );

    else

      # If `p' is greater than 0, then the situation is more difficult.
      # We implement the algorithm presented in
      # "Cohen, Arjeh M, G\'{a}bor Ivanyos, and David B. Wales,
      # 'Finding the radical of an algebra of linear transformations,'
      # Journal of Pure and Applied Algebra 117 & 118 (1997), 177-193".

      q := Size( F );
      dim := Length( bas[1] );
      pexp := 1;
      invFrob := InverseGeneralMapping(FrobeniusAutomorphism(F));
      invFrobexp := IdentityMapping(F);
      minusOne := -One(F);
      ident := IdentityMat( dim, F );
      changed := true;
      I := ShallowCopy( bas );

      # Compute the sequence of ideals $I_i$ (see the paper by Cohen, et.al.)
      while pexp <= dim do
          # These values need recomputation only when $I_i <> I_{i-1}$
          if changed then
              I_prime := ShallowCopy( I );
              if not ident in I_prime then
                  Add( I_prime, ident );
              fi;
              r := Length( I );
              r_prime := Length( I_prime );
              eqs := NullMat( r, r_prime, F );
              charPoly := List( [1..r], x -> [] );
              for i in [1..r] do
                  for j in [1..r_prime] do
                      charPoly[i][j] :=
                          CoefficientsOfUnivariatePolynomial( CharacteristicPolynomial( F, F, I[i]*I_prime[j] ) );
                  od;
              od;
              changed := false;
          fi;

          for i in [1..r] do
              for j in [1..r_prime] do
                  eqs[i][j] := minusOne^pexp * charPoly[i][j][dim-pexp+1];
              od;
          od;

          G := NullspaceMat( eqs );

          if Length( G ) = 0 then
              return TrivialSubalgebra( A );
          elif Length( G ) <> r then
              # $I_i <> I_{i-1}$, so compute the basis for $I_i$
              changed := true;
              G := List( G, x -> List( x, y -> y^invFrobexp ) );
              I := List( G, x -> LinearCombination( I, x ) );
          fi;

          # prepare for next step

          invFrobexp := invFrobexp * invFrob;
          pexp := pexp*p;
      od;

      return SubalgebraNC( A, I, "basis" );
    fi;
    end );




#############################################################################
##
#F  CentralizerInAssociativeGaussianMatrixAlgebra( <base>, <gens> )
##
##  is a list of basis vectors of the $R$-FLMLOR that is the centralizer
##  of the $R$-FLMLOR with generators <gens> in the $R$-FLMLOR
##  with $R$-basis vectors <base>.
##
##  View the centralizer condition for the matrix $a$ as an equation system
##  \[ \sum_{b\in B} c_b ( b a - a b ) = 0 \ , \]
##  where $B$ is a basis of <A> and $c_b$ in the coefficients field.
##  Then the centralizer is spanned by the matrices
##  $\sum_{b\in B} c_b b$ where the vector $c$ is a basis vector of
##  the solution space.
##
BindGlobal( "CentralizerInAssociativeGaussianMatrixAlgebra", function( base, gens )
#T better use structure constants ?

    local gen, mat, sol;

    for gen in gens do

      mat:= List( base, b -> Concatenation( b * gen - gen * b ) );
      sol:= NullspaceMat( mat );

      # Replace `base' by a vector space base of the centralizer.
      base:= List( sol, x -> LinearCombination( base, x ) );

    od;

    return base;
end );


#############################################################################
##
#M  Centralizer( <A>, <mat> ) . . . . . . . . .  for matrix FLMLOR and matrix
##
InstallMethod( CentralizerOp,
    "for associative Gaussian matrix FLMLOR, and ordinary matrix",
    IsCollsElms,
    [ IsMatrixFLMLOR and IsAssociative and IsGaussianSpace,
      IsOrdinaryMatrix ], 0,
    function( A, mat )
    return SubalgebraNC( A,
               CentralizerInAssociativeGaussianMatrixAlgebra(
                   BasisVectors( Basis( A ) ),
                   [ mat ] ),
               "basis" );
    end );


#############################################################################
##
#M  Centralizer( <A>, <C> ) . . . . . . . for matrix FLMLOR and matrix FLMLOR
##
InstallMethod( CentralizerOp,
    "for associative Gaussian matrix FLMLOR, and FLMLOR",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsAssociative and IsGaussianSpace,
      IsMatrixFLMLOR ], 0,
    function( A, C )
    return SubalgebraNC( A,
               CentralizerInAssociativeGaussianMatrixAlgebra(
                   BasisVectors( Basis( A ) ),
                   GeneratorsOfAlgebra( C ) ),
               "basis" );
    end );


#############################################################################
##
#M  Centralizer( <A>, <mat> ) . . . . . for matrix FLMLOR-with-one and matrix
##
InstallMethod( CentralizerOp,
    "for associative Gaussian matrix FLMLOR-with-one, and ordinary matrix",
    IsCollsElms,
    [ IsMatrixFLMLOR and IsFLMLORWithOne
                     and IsAssociative and IsGaussianSpace,
      IsOrdinaryMatrix ], 0,
    function( A, mat )
    return SubalgebraWithOneNC( A,
               CentralizerInAssociativeGaussianMatrixAlgebra(
                   BasisVectors( Basis( A ) ),
                   [ mat ] ),
               "basis" );
    end );


#############################################################################
##
#M  Centralizer( <A>, <C> ) . .  for matrix FLMLOR-with-one and matrix FLMLOR
##
InstallMethod( CentralizerOp,
    "for associative Gaussian matrix FLMLOR-with-one, and FLMLOR",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsFLMLORWithOne
                     and IsAssociative and IsGaussianSpace,
      IsMatrixFLMLOR ], 0,
    function( A, C )
    return SubalgebraWithOneNC( A,
               CentralizerInAssociativeGaussianMatrixAlgebra(
                   BasisVectors( Basis( A ) ),
                   GeneratorsOfAlgebra( C ) ),
               "basis" );
    end );


#############################################################################
##
#F  FullMatrixAlgebraCentralizer( <F>, <lst> )
##
##  Compute the centralizer of the list of matrices <lst> in the full
##  matrix algebra over <F>.
##
InstallGlobalFunction( FullMatrixAlgebraCentralizer, function( F, lst )
    local len,      # length of `lst'
          dims,     # dimensions of the matrices
          n,        # number of rows/columns
          n2,       # square of `n'
          eq,       # equation system
          u,i,j,k,  # loop variables
          bc,       # basis of solutions of the equation system
          Bcen,     # basis vectors of the centralizer
          M;        # one centralizing matrix

    len:= Length( lst );
    if len = 0 then
      Error( "cannot compute the centralizer of an empty set" );
    elif not (IsSubset( F, DefaultScalarDomainOfMatrixList( lst ) ) or
              IsSubset( F, FieldOfMatrixList( lst ) ) ) then
      Error( "not all entries of the matrices in <lst> lie in <F>" );
    fi;

    dims:= DimensionsMat( lst[1] );
    n:= dims[1];
    n2:= n*n;

    # In the equations matrices are viewed as vectors of length `n*n'.
    # Position `(i,j)' in the matrix corresponds with position `(i-1)*n+j'
    # in the vector.
    eq:= NullMat( n2, n2 * len, F );
    for u in [ 1 .. len ] do
      for i in [1..n] do
        for j in [1..n] do
          for k in [1..n] do
            eq[(i-1)*n+k][(u-1)*n2+(i-1)*n+j]:=
              eq[(i-1)*n+k][(u-1)*n2+(i-1)*n+j] + lst[u][k][j];
            eq[(k-1)*n+j][(u-1)*n2+(i-1)*n+j]:=
              eq[(k-1)*n+j][(u-1)*n2+(i-1)*n+j] - lst[u][i][k];
          od;
        od;
      od;
    od;

    # Translate the vectors back to matrices.
    bc:= NullspaceMat( eq );
    Bcen:= [];
    for i in bc do
      M:= [];
      for j in [ 1 .. n ] do
        M[j]:= i{ [ (j-1)*n+1 .. j*n ] };
      od;
      Add( Bcen, M );
    od;

    return AlgebraWithOne( F, Bcen, "basis" );
end );


#############################################################################
##
#M  CentralizerOp( <A>, <S> ) . . . . . . for full associative matrix algebra
##
InstallMethod( CentralizerOp,
    "for full (associative) matrix FLMLOR, and FLMLOR",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsFLMLORWithOne
                     and IsAssociative and IsGaussianSpace
                     and IsFullMatrixModule,
      IsMatrixFLMLOR ], 0,
    function( A, S )
    if not IsAssociative( A ) then
      TryNextMethod();
    fi;
    return FullMatrixAlgebraCentralizer( LeftActingDomain( A ),
                                         GeneratorsOfAlgebra( S ) );
    end );

InstallMethod( CentralizerOp,
    "for full (associative) matrix FLMLOR, and left module",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsFLMLORWithOne
                     and IsAssociative and IsGaussianSpace
                     and IsFullMatrixModule,
      IsLeftModule ], 0,
    function( A, S )
    if not IsAssociative( A ) then
      TryNextMethod();
    fi;
    return FullMatrixAlgebraCentralizer( LeftActingDomain( A ),
                                         GeneratorsOfLeftModule( S ) );
    end );

InstallMethod( CentralizerOp,
    "for full (associative) matrix FLMLOR, and list of matrices",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsFLMLORWithOne
                     and IsAssociative and IsGaussianSpace
                     and IsFullMatrixModule,
      IsCollection and IsList ], 0,
    function( A, S )
    if not IsAssociative( A ) then
      TryNextMethod();
    fi;
    return FullMatrixAlgebraCentralizer( LeftActingDomain( A ), S );
    end );

InstallMethod( CentralizerOp,
    "for full (associative) matrix FLMLOR, and empty list",
    true,
    [ IsMatrixFLMLOR and IsFullMatrixModule, IsList and IsEmpty ], 0,
    function( A, S )
    if not IsAssociative( A ) then
      TryNextMethod();
    fi;
    return A;
    end );


#############################################################################
##
#F  FullMatrixFLMLOR( <R>, <n> )  . . .  FLMLOR of <n>-dim. matrices over <R>
##
##  Let $E_{i,j}$ be the matrix with value 1 in row $i$ and $column $j$, and
##  zero otherwise.
##  Clearly the full associative matrix algebra is generated by all
##  $E_{i,j}$, $i$ and $j$ ranging from 1 to <n>.
##  Define the matrix $F$ as permutation matrix for the permutation
##  $(1, 2, \ldots, n)$.  Then $E_{i,j} = F^{i-1} E_{1,1} F^{1-j}$.
##  Thus $F$ and $E_{1,1}$ are sufficient to generate the algebra.
##
InstallGlobalFunction( FullMatrixFLMLOR, function( R, n )

    local i,      # loop over the rows
          gens,   # list of generators
          one,    # the identity of the field
          A;      # algebra, result

    gens:= NullMat( n, n, R );
    gens:= [ gens, MutableCopyMatrix( gens ) ];
    one:= One( R );

    # Construct the generators.
    gens[1][1,1]:= one;
    gens[2][1,n]:= one;
    for i in [ 2 .. n ] do
      gens[2][i,i-1]:= one;
    od;

    # Construct the FLMLOR.
    A:= AlgebraWithOneByGenerators( R, gens );
    SetIsFullMatrixModule( A, true );
    SetRadicalOfAlgebra( A, TrivialSubalgebra( A ) );

    # Return the FLMLOR.
    return A;
end );


#############################################################################
##
#F  FullMatrixLieAlgebra( <R>, <n> )
#F                  . . full matrix Lie algebra of <n>-dim. matrices over <R>
##
##  The set $\{ E_{1,j}, E_{k,1}; 1 \leq j, k \leq n \}$ is a generating
##  system.
#T  What is a nicer generating system ?
##
InstallGlobalFunction( FullMatrixLieFLMLOR, function( F, n )

    local null,   # null matrix
          one,    # identity of `F'
          gen,    # one generator
          gens,   # list of generators
          i,      # loop over the rows
          A;      # algebra, result

    # Construct the generators.
    null:= NullMat( n, n, F );
    one:= One( F );


    gen:= MutableCopyMatrix( null );
    gen[1,1]:= one;
    gens:= [ LieObject( gen ) ];

    for i in [ 2 .. n ] do

      gen:= MutableCopyMatrix( null );
      gen[1,i]:= one;
      Add( gens, LieObject( gen ) );

      gen:= MutableCopyMatrix( null );
      gen[i,1]:= one;
      Add( gens, LieObject( gen ) );

    od;

    # construct the algebra
    A:= AlgebraByGenerators( F, gens );

    SetIsFullMatrixModule( A, true );

    # return the algebra
    return A;
end );


#############################################################################
##
#M  DirectSumOfAlgebras( <A1>, <A2> ) . .  for two associative matrix FLMLORs
##
##  Construct an associative matrix FLMLOR.
##
#T embeddings/projections should be provided!
##
InstallOtherMethod( DirectSumOfAlgebras,
    "for two associative matrix FLMLORs",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsAssociative,
      IsMatrixFLMLOR and IsAssociative ], 0,
    function( A1, A2 )

    local b1,   # Basis vectors of `A1'.
          b2,   # Basis vectors of `A2'.
          p1,   # Length of the matrices of `b1'.
          p2,   # Length of the matrices of `b2'.
          B,    # A basis of `A1 \oplus A2'.
          i,    # Loop variable.
          Q,    # A matrix.
          A;    # result

    if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then
      Error( "<A1> and <A2> must be written over the same domain" );
    fi;

    # We do not really need a basis for the arguments
    # but if we have one then we use it.
#T Do we really have so many algebra generators? (distinguish from basis?)
    if HasBasis( A1 ) and HasBasis( A2 ) then
      b1:= BasisVectors( Basis( A1 ) );
      b2:= BasisVectors( Basis( A2 ) );
    else
      b1:= GeneratorsOfAlgebra( A1 );
      b2:= GeneratorsOfAlgebra( A2 );
    fi;

    p1:= DimensionOfVectors( A1 )[1];
    p2:= DimensionOfVectors( A2 )[1];

    B:= [];
    for i in b1 do
      Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) );
      Q{ [ 1 .. p1 ] }{ [ 1 .. p1 ] }:= i;
      Add( B, Q );
    od;
    for i in b2 do
      Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) );
      Q{ [ p1+1 .. p1+p2 ] }{ [ p1+1 .. p1+p2 ] }:= i;
      Add( B, Q );
    od;

    A:= AlgebraByGenerators( LeftActingDomain( A1 ), B );
    if HasBasis( A1 ) and HasBasis( A2 ) then
      UseBasis( A, B );
    fi;

    SetIsAssociative( A, true );
#T nec. ?

    return A;
    end );


#############################################################################
##
#M  DirectSumOfAlgebras( <A1>, <A2> ) . . . . . .  for two matrix Lie FLMLORs
##
##  Construct a matrix Lie FLMLOR.
##
#T embeddings/projections should be provided!
##
InstallOtherMethod( DirectSumOfAlgebras,
    "for two matrix Lie FLMLORs",
    IsIdenticalObj,
    [ IsMatrixFLMLOR and IsLieAlgebra,
      IsMatrixFLMLOR and IsLieAlgebra ], 0,
    function( A1, A2 )

    local b1,   # Basis vectors of `A1'.
          b2,   # Basis vectors of `A2'.
          p1,   # Length of the matrices of `b1'.
          p2,   # Length of the matrices of `b2'.
          B,    # A basis of `A1 \oplus A2'.
          i,    # Loop variable.
          Q,    # A matrix.
          A;    # result

    if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then
      Error( "<A1> and <A2> must be written over the same domain" );
    fi;

    # We do not really need a basis for the arguments
    # but if we have one then we use it.
#T Do we really have so many algebra generators? (distinguish from basis?)
    if HasBasis( A1 ) and HasBasis( A2 ) then
      b1:= BasisVectors( Basis( A1 ) );
      b2:= BasisVectors( Basis( A2 ) );
    else
      b1:= GeneratorsOfAlgebra( A1 );
      b2:= GeneratorsOfAlgebra( A2 );
    fi;

    p1:= DimensionOfVectors( A1 )[1];
    p2:= DimensionOfVectors( A2 )[1];

    B:= [];
    for i in b1 do
      Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) );
      Q{ [ 1 .. p1 ] }{ [ 1 .. p1 ] }:= i;
      Add( B, LieObject( Q ) );
    od;
    for i in b2 do
      Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) );
      Q{ [ p1+1 .. p1+p2 ] }{ [ p1+1 .. p1+p2 ] }:= i;
      Add( B, LieObject( Q ) );
    od;

    A:= AlgebraByGenerators( LeftActingDomain( A1 ), B );
    if HasBasis( A1 ) and HasBasis( A2 ) then
      UseBasis( A, B );
    fi;
    SetIsLieAlgebra( A, true );

    return A;
    end );


#############################################################################
##
#M  Units( <A> )  . . . . . . for a full matrix algebra (over a finite field)
##
InstallMethod( Units,
    "for a full matrix algebra (over a finite field)",
    [ IsAlgebra and IsFullMatrixModule and IsFFECollCollColl ],
    function( A )
    local F;
    F:= LeftActingDomain( A );
    if IsField( F ) and IsFinite( F ) then
      return GL( DimensionOfVectors( A )[1], Size( F ) );
    else
      TryNextMethod();
    fi;
    end );


#############################################################################
##
#F  EmptyMatrix( <char> )
##
InstallGlobalFunction( EmptyMatrix, function( char )

    local Fam, mat;

    # Get the right family.
    if char = 0 then
      Fam:= CollectionsFamily( CollectionsFamily( CyclotomicsFamily ) );
    else
      Fam:= CollectionsFamily( CollectionsFamily( FFEFamily( char ) ) );
    fi;

    # Construct the matrix.
    mat := ObjectifyWithAttributes( rec(),
             NewType( Fam,
                          IsList
                      and IsEmpty
                      and IsOrdinaryMatrix
                      and IsZero
                      and IsAssociativeElement
                      and IsCommutativeElement
                      and IsJacobianElement
                      and IsAttributeStoringRep ),
             Name,          Concatenation("EmptyMatrix( ", String(char), " )" ),
             DimensionsMat, [ 0, 0 ],
             Length,        0,
             NrRows,        0,
             NrCols,        0) ;
    SetInverse( mat, mat );
    SetAdditiveInverse( mat, mat );
    return mat;
end );


InstallMethod( \+,
    "for two empty matrices",
    IsIdenticalObj,
    [ IsMatrix and IsEmpty, IsMatrix and IsEmpty ], 0,
    function( m1, m2 ) return m1; end );

InstallOtherMethod( \*,
    "for two empty matrices",
    IsIdenticalObj,
    [ IsMatrix and IsEmpty, IsMatrix and IsEmpty ], 0,
    function( m1, m2 ) return m1; end );

InstallOtherMethod( \*,
    "for empty matrix, and empty list",
    true,
    [ IsMatrix and IsEmpty, IsList and IsEmpty ], 0,
    function( m1, m2 ) return []; end );

InstallOtherMethod( \*,
    "for empty list, and empty matrix",
    true,
    [ IsList and IsEmpty, IsMatrix and IsEmpty ], 0,
    function( m1, m2 ) return []; end );

InstallOtherMethod( \*,
    "for empty matrix, and ring element",
    true,
    [ IsMatrix and IsEmpty, IsRingElement ], 0,
    function( m, scalar ) return m; end );

InstallOtherMethod( \*,
    "for ring element, and empty matrix",
    true,
    [ IsRingElement, IsMatrix and IsEmpty ], 0,
    function( scalar, m ) return m; end );

InstallMethod( \^,
    "for empty matrix, and integer",
    true,
    [ IsMatrix and IsEmpty, IsInt ], 0,
    function( emptymat, n ) return emptymat; end );


#############################################################################
##
#M  NullAlgebra( <R> )  . . . . . . . . . . . . .  null algebra over ring <R>
##
InstallMethod( NullAlgebra,
    "for a ring",
    true,
    [ IsRing ], 0,
    R -> FLMLORByGenerators( R, [], EmptyMatrix( Characteristic( R ) ) ) );


#T #############################################################################
#T ##
#T #F  Fingerprint( <A> ) . . . . . . . . . . . . . . fingerprint of algebra <A>
#T #F  Fingerprint( <A>, <list> ) . . . . . . . . . . fingerprint of algebra <A>
#T ##
#T ##  If there is only one argument then the standard fingerprint is computed.
#T ##  This works for two-generator algebras acting only.
#T ##
#T Fingerprint := function( arg )
#T
#T     # Check the arguments.
#T     if Length( arg ) = 0 or Length( arg ) > 2 then
#T       Error( "usage: Fingerprint( <matalg> [, <list> ] )" );
#T     fi;
#T
#T     if   Length( arg ) = 2 then
#T
#T       return arg[1].operations.Fingerprint( arg[1], arg[2] );
#T
#T     elif Length( arg ) = 1 then
#T
#T       if not IsBound( arg[1].fingerprint ) then
#T         arg[1].fingerprint:=
#T                         arg[1].operations.Fingerprint( arg[1], "standard" );
#T       fi;
#T       return arg[1].fingerprint;
#T
#T     else
#T       Error( "number of generating matrices must be 2" );
#T     fi;
#T     end;
#T
#T #############################################################################
#T ##
#T #F  Nullity( <mat> )
#T ##
#T Nullity := function( mat )
#T     return Dimensions( BaseNullspace( mat ) )[1];
#T     end;
#T
#T #############################################################################
#T ##
#T #F  MatrixAssociativeAlgebraOps.Fingerprint( <A>, <list> )
#T ##
#T MatrixAssociativeAlgebraOps.Fingerprint := function( A, list )
#T
#T     local fp,     # fingerprint, result
#T           a,      # first generator
#T           b,      # second generator
#T           ab,     # product of `a' and `b'
#T           word;   # actual word
#T
#T     if list = "standard" then
#T
#T       if Length( AlgebraGenerators( A ) ) <> 2 then
#T         Error( "exactly two generators needed for standard finger print" );
#T       fi;
#T
#T       # Compute the nullities of the 6 standard elements.
#T       fp:= [];
#T       a:= AlgebraGenerators( A )[1];
#T       b:= AlgebraGenerators( A )[2];
#T       ab:= a * b;
#T       word:= ab + a + b;    fp[1]:= Nullity( word );
#T       word:= word + ab * b; fp[2]:= Nullity( word );
#T       word:= a + b * word;  fp[3]:= Nullity( word );
#T       word:= b + word;      fp[4]:= Nullity( word );
#T       word:= ab + word;     fp[5]:= Nullity( word );
#T       word:= a + word;      fp[6]:= Nullity( word );
#T
#T     else
#T
#T       # Compute the nullities of the words with numbers in the list.
#T       fp:= List( list, x -> Nullity( ElementAlgebra( A, x ) ) );
#T
#T     fi;
#T     return fp;
#T     end;


#############################################################################
##
#M  RepresentativeLinearOperation( <A>, <v>, <w>, <opr> ) . . for matrix alg.
##
##  Let <A> be a finite dimensional algebra over the ring $R$,
##  and <v> and <w> vectors such that <A> acts on them via the *linear*
##  operation <opr>.
##  We compute an element of <A> that maps <v> to <w>.
##
##  We compute the coefficients $a_i$ in the equation system
##  $\sum_{i=1}^n a_i <opr>( <v>, b_i ) = <w>$,
##  where $(b_1, b_2, \ldots, b_n)$ is a basis of <A>.
##
##  For a tuple $(v_1, \ldots, v_k)$ of vectors we simply replace $v b_i$ by
##  the concatenation of the $v_j b_i$ for all $j$, and replace $w$ by the
##  concatenation $(w_1, \ldots, w_k)$, and solve this system.
##
##  (Here we install methods for matrix algebras, acting on row vectors.
##  There are also generic algebra methods for algebras acting on themselves
##  or on their free modules via `OnRight' or `OnTuples'.)
##
InstallMethod( RepresentativeLinearOperation,
    "for a matrix FLMLOR, two row vectors, and `OnRight'",
    IsCollCollsElmsElmsX,
    [ IsMatrixFLMLOR, IsRowVector, IsRowVector, IsFunction ], 0,
    function( A, v, w, opr )

    local B, vectors, a;

    if not ( opr = OnRight or opr = OnPoints ) then
      TryNextMethod();
    fi;

    if IsTrivial( A ) then
      if IsZero( w ) then
        return Zero( A );
      else
        return fail;
      fi;
    fi;

    B:= Basis( A );
    vectors:= BasisVectors( B );

    # Compute the matrix of the equation system,
    # the coefficient vector $a$, \ldots
    a:= SolutionMat( List( vectors, x -> v * x ),
                     w );
    if a = fail then
      return fail;
    fi;

    # \ldots and the representative.
    return LinearCombination( B, a );
    end );

InstallMethod( RepresentativeLinearOperation,
    "for a matrix FLMLOR, two lists of row vectors, and `OnTuples'",
    IsCollsElmsElmsX,
    [ IsFLMLOR, IsMatrix, IsMatrix, IsFunction ], 0,
#T IsOrdinaryMatrix?
    function( A, vs, ws, opr )

    local B, vectors, a;

    if not ( opr = OnTuples or opr = OnPairs ) then
      TryNextMethod();
    fi;

    if IsTrivial( A ) then
      if IsZero( ws ) then
        return Zero( A );
      else
        return fail;
      fi;
    fi;

    B:= Basis( A );
    vectors:= BasisVectors( B );

    # Compute the matrix of the equation system,
    # the coefficient vector $a$, \ldots
    a:= SolutionMat( List( vectors, x -> Concatenation( vs * x ) ),
                     Concatenation( ws ) );
    if a = fail then
      return fail;
    fi;

    # \ldots and the representative.
    return LinearCombination( B, a );
    end );


#############################################################################
##
#M  IsomorphismMatrixFLMLOR( <A> )  . . . . . . . . . . . for a matrix FLMLOR
##
InstallMethod( IsomorphismMatrixFLMLOR,
    "for a matrix FLMLOR",
    true,
    [ IsMatrixFLMLOR ], 0,
    IdentityMapping );


#T #############################################################################
#T ##
#T #F  MatrixAssociativeAlgebraOps.NaturalModule( <A> )
#T ##
#T MatrixAssociativeAlgebraOps.NaturalModule := function( A )
#T
#T     local gens,   # module generators
#T           N;      # natural module, result
#T
#T     if Length( AlgebraGenerators( Parent( A ) ) ) = 0 then
#T       gens:= IdentityMat( A.field, Length( Zero( Parent( A ) ) ) );
#T     else
#T       gens:= Parent( A ).algebraGenerators[1]^0;
#T     fi;
#T #T wirklich Erzeuger angeben ?
#T     N:= Module( A, gens );
#T     N.isNaturalModule:= true;
#T     N.spaceGenerators:= gens;
#T     return N;
#T     end;

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