Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/polycyclic/gap/matrix/   (GAP Algebra Version 4.15.1©)  Datei vom 28.7.2025 mit Größe 10 kB image not shown  

Quelle  modules.gi   Sprache: Shell

 

#############################################################################
##
#W  modules.gi                   Polycyc                         Bettina Eick
##

#############################################################################
##
#F RadicalSeriesOfFiniteModule( mats, d, f )
##
BindGlobal( "RadicalSeriesOfFiniteModule", function( mats, d, f )
    local base, sers, modu, radb;
    if d = 0 then return []; fi;
    base := IdentityMat( d, f );
    sers := [base];
    modu := GModuleByMats( mats, d, f );
    repeat
        radb := SMTX.BasisRadical( modu );
        if Length( radb ) > 0 then
            base := radb * base;
        else
            base := [];
        fi;
        Add( sers, base );
        if Length( base ) > 0 then
            modu := SMTX.InducedActionSubmodule( modu, radb );
        fi;
    until Length( base ) = 0;
    return sers;
end );

#############################################################################
##
#F RadicalOfCongruenceModule( mats, d ) . . . . . . .for congruence subgroups
##
BindGlobal( "RadicalOfCongruenceModule", function( mats, d )
    local coms, i, j, new, base, full, nath, indm, l, algb, newv, tmpb, subb,
          f, g, h, mat;

    # get commutators
    coms := [];
    for i in [1..Length( mats )] do
        for j in [i+1..Length( mats )] do
            new := mats[i] * mats[j] - mats[j] * mats[i];
            Append(coms, new );
        od;
    od;
    base := SpinnUpEchelonBase( [], coms, mats, OnRight );
    full := IdentityMat( d );
    nath := NaturalHomomorphismBySemiEchelonBases( full, base );
    indm := List( mats, x -> InducedActionFactorByNHSEB( x, nath ) );
    #Print("found derived submodule of dimension ",Length(base),"\n");

    # start spinning up basis and look for nilpotent elements
    i := 1;
    algb := [];
    while i <= Length( indm ) do

        # add next element to algebra basis
        l := Length( algb );
        newv := Flat( indm[i] );
        tmpb := SpinnUpEchelonBase( algb, [newv], indm{[1..i]}, OnMatVector );

        # check whether we have added a non-semi-simple element
        subb := [];
        for j in [l+1..Length(tmpb)] do
            mat := MatByVector( tmpb[j], Length(indm[i]) );
            f := MinimalPolynomial( Rationals, mat );
            g := Collected( Factors( f ) );
            if ForAny( g, x -> x[2] > 1 ) then
                h := Product( List( g, x -> Value( x[1], mat ) ) );
                Append( subb, List( h, x -> ShallowCopy(x) ) );
            fi;
        od;
        #Print("found nilpotent submodule of dimension ", Length(subb),"\n");

        # spinn up new subspace of radical
        subb := SpinnUpEchelonBase( [], subb, indm, OnRight );
        if Length( subb ) > 0 then
            base := PreimageByNHSEB( subb, nath );
            nath := NaturalHomomorphismBySemiEchelonBases( full, base );
            indm := List( mats, x -> InducedActionFactorByNHSEB( x, nath ) );
            algb := [];
            i := 1;
        else
            i := i + 1;
        fi;
    od;
    return rec( radical := base, nathom := nath, algebra := algb );
end );

#############################################################################
##
#F TraceMatProd( m1, m2, d )
##
BindGlobal( "TraceMatProd", function( m1, m2, d )
    local t, i, j;
    t := 0;
    for i in [1..d] do
        for j in [1..d] do
            t := t + m1[i][j] * m2[j][i];
        od;
    od;
    return t;
end );

#############################################################################
##
#F AlgebraBase( mats )
##
InstallGlobalFunction( AlgebraBase, function( mats )
    local base, flat;
    if Length( mats ) = 0 then return []; fi;
    flat := List( mats, Flat );
    base := SpinnUpEchelonBase( [], flat, mats, OnMatVector);
    return List( base, x -> MatByVector( x, Length(mats[1]) ) );
end );

#############################################################################
##
#F RadicalOfRationalModule( mats, d ) . . . . . . . . . . . .general approach
##
BindGlobal( "RadicalOfRationalModule", function( mats, d )
    local base, trac, null, j;

    # get base
    base := AlgebraBase( mats );
    if Length(base) = 0 then return rec( radical := [] ); fi;

    # set up system of linear equations ( Tr( ai * aj ) )
    trac := List( base, b -> List( base, c -> TraceMatProd( b, c, d ) ) );

    # compute nullspace
    null := NullspaceMat( trac );
    if Length(null) = 0 then return rec( radical := [] ); fi;

    # translate
    null := List( null, x -> LinearCombination( x, base ) );
    null := Concatenation( null );
    TriangulizeMat( null );
    j := Position( null, 0 * null[1] );
    return rec( radical := null{[1..j-1]} );
end );

#############################################################################
##
#F RadicalSeriesOfRationalModule( mats, d ) . . . . . .compute radical series
##
BindGlobal( "RadicalSeriesOfRationalModule", function( mats, d )
    local acts, full, base, sers, radb, nath;
    if d = 0 then return []; fi;
    full := IdentityMat( d );
    sers := [full];
    base := full;
    acts := mats;
    repeat
        radb := RadicalOfRationalModule( acts, d ).radical;
        if Length(radb) > 0 then
            base := radb * base;
            nath := NaturalHomomorphismBySemiEchelonBases( full, base );
            acts := List( mats, x -> InducedActionSubspaceByNHSEB( x, nath ) );
        else
            base := [];
        fi;
        d := Length( base );
        Add( sers, base );
    until d = 0;
    return sers;
end );

#############################################################################
##
#F PrimitiveAlgebraElement( mats, base )
##
InstallGlobalFunction( PrimitiveAlgebraElement, function( mats, base )
    local d, mat, f, c, b, l;

    # set up
    d := Length( base );

    # first try one of mats
    for mat in mats do
        f := MinimalPolynomial( Rationals, mat );
        if Degree( f ) = d then return rec( elem := mat, poly := f ); fi;
    od;

    # otherwise try random elements
    l := Sqrt( Length( base[1] ) );
    repeat
        c := List( [1..d], x -> Random( Integers ) );
        b := MatByVector( c * base, l );
        f := MinimalPolynomial( Rationals, b );
        if Degree( f ) = d then return rec( elem := b, poly := f ); fi;
    until false;
end );

#############################################################################
##
#F SplitSemisimple( base )
##
BindGlobal( "SplitSemisimple", function( base )
    local d, b, f, s, i;

    d := Length( base );
    b := PrimitiveAlgebraElement( [], base );
    f := Factors( b.poly );

    # the trivial case
    if Length( f ) = 1 then
        return [rec( basis := IdentityMat(Length(base[1])), poly := f )];
    fi;

    # the non-trivial case
    s := List( f, x -> NullspaceRatMat( Value( x, b.elem ) ) );
    s := List( [1..Length(f)], x -> rec( basis := s[x], poly := f[x] ) );
    return s;
end );

#############################################################################
##
#F HomogeneousSeriesOfCongruenceModule( mats, d ). . for congruence subgroups
##
HomogeneousSeriesOfCongruenceModule := function( mats, d )
    local radb, splt, nath, l, sers, i, sub, full, acts, rads;

    # catch the trivial case and set up
    if d = 0 then return []; fi;
    full := IdentityMat( d );
    if Length( mats ) = 0 then return [full, []]; fi;
    sers := [full];

    # get the radical
    radb := RadicalOfCongruenceModule( mats, d );
    splt := SplitSemisimple( radb.algebra );
    nath := radb.nathom;

    # refine radical factor and initialize series
    l := Length( splt );
    for i in [2..l] do
        sub := Concatenation( List( [i..l], x -> splt[x].basis ) );
        TriangulizeMat( sub );
        Add( sers, PreimageByNHSEB( sub, nath ) );
    od;
    Add( sers, radb.radical );

    # induce action to radical
    nath := NaturalHomomorphismBySemiEchelonBases( full, radb.radical );
    acts := List( mats, x -> InducedActionSubspaceByNHSEB( x, nath ) );

    # use recursive call to refine radical
    rads := HomogeneousSeriesOfCongruenceModule( acts, Length(radb.radical) );
    for i in [2..Length(rads)] do
        if Length(rads[i]) > 0 then rads[i] := rads[i] * radb.radical; fi;
    od;
    Append( sers, rads{[2..Length(rads)]} );
    return sers;
end;
MakeReadOnlyGlobal( "HomogeneousSeriesOfCongruenceModule" );

#############################################################################
##
#F HomogeneousSeriesOfRationalModule( mats, cong, d ). . . . . use full space
##
HomogeneousSeriesOfRationalModule := function( mats, cong, d )
    local full, sers, radb, nath, fact, base, splt, l, i, sub, acts, subs,
          rads;

    # catch the trivial case and set up
    if d = 0 then return []; fi;
    full := IdentityMat( d );
    sers := [full];

    # other trivial case
    if Length( cong ) = 0 then return [full, []]; fi;

    # get the radical and split its factor
    radb := RadicalOfRationalModule( mats, d );
    nath := NaturalHomomorphismBySemiEchelonBases( full, radb.radical );
    fact := List( cong, x -> InducedActionFactorByNHSEB( x, nath ) );
    base := AlgebraBase( fact );
    splt := SplitSemisimple( List( base, Flat ) );

    # refine radical factor and initialize series
    l := Length( splt );
    for i in [2..l] do
        sub := Concatenation( List( [i..l], x -> splt[x].basis ) );
        TriangulizeMat( sub );
        Add( sers, PreimageByNHSEB( sub, nath ) );
    od;
    Add( sers, radb.radical );

    # use recursive call to refine radical
    l := Length( radb.radical );
    acts := List( mats, x -> InducedActionSubspaceByNHSEB( x, nath ) );
    subs := List( cong, x -> InducedActionSubspaceByNHSEB( x, nath ) );
    rads := HomogeneousSeriesOfRationalModule( acts, subs, l );
    for i in [2..Length(rads)] do
        if Length(rads[i]) > 0 then rads[i] := rads[i] * radb.radical; fi;
    od;
    Append( sers, rads{[2..Length(rads)]} );
    return sers;
end;
MakeReadOnlyGlobal( "HomogeneousSeriesOfRationalModule" );

#############################################################################
##
#F RefineSplitting( mats, subs ) . . . . . . . . . . for congruence subgroups
##
BindGlobal( "RefineSplitting", function( mats, subs )
    local i, full, news, dims, j, d, e, tmp;

    # refine each of the subspaces subs in turn by spinning
    for i in [1..Length(subs)] do
        full := subs[i];
        news := [];
        dims := 0;
        j := 1;
        d := Length( subs[i] );
        while dims < d do
            e := full[j];
            if ForAll( news, x -> MemberBySemiEchelonBase(e, x) = false ) then
                tmp := SpinnUpEchelonBase( [], [e], mats, OnRight );
                Add( news, tmp );
                dims := dims + Length( tmp );
            fi;
            j := j + 1;
        od;
        subs[i] := news;
    od;
    return Concatenation( subs );
end );


Messung V0.5 in Prozent
C=78 H=77 G=77

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-10-11) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.