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


Quelle  pcpelms.gi   Sprache: unbekannt

 
#############################################################################
##
#W  pcpelms.gi                   Polycyc                         Bettina Eick
##

InstallGlobalFunction( PcpElementConstruction,
function( coll, list, word )
    local   elm;
    elm := rec( collector := coll,
                exponents := Immutable(list),
                word      := Immutable(word),
                name      := "g" );

    # objectify and return
    return Objectify( coll![PC_PCP_ELEMENTS_TYPE], elm );
end );

#############################################################################
##
## Functions to create pcp elements by exponent vectors or words.
## In the NC versions we assume that elements are in normal form.
## In the other versions we collect before we return an element.
##
InstallGlobalFunction( PcpElementByExponentsNC,
function( coll, list )
    local   i,  word;
    word := ObjByExponents( coll, list );
    return PcpElementConstruction( coll, list, word );
end );

InstallGlobalFunction( PcpElementByExponents, function( coll, list )
    local h, k;

    if Length(list) > NumberOfGenerators(coll) then
        Error( "more exponents than generators" );
    fi;

    h := ObjByExponents( coll, list );
    k := list * 0;
    while CollectWordOrFail( coll, k, h ) = fail do od;
    return PcpElementByExponentsNC( coll, k );
end );

InstallGlobalFunction( PcpElementByGenExpListNC,
function( coll, word )
    local   list,  i;
    list := ExponentsByObj( coll, word );
    word := ObjByExponents( coll, list );
    return PcpElementConstruction( coll, list, word );
end );

InstallGlobalFunction( PcpElementByGenExpList, function( coll, word )
    local k;
    k := [1..coll![PC_NUMBER_OF_GENERATORS]] * 0;
    while CollectWordOrFail( coll, k, word ) = fail do od;
    return PcpElementByExponentsNC( coll, k );
end );

#############################################################################
##
#A Basic attributes of pcp elements - for IsPcpElementRep
##
InstallMethod( Collector,
        "for pcp groups",
        [ IsPcpGroup ],
        G -> Collector( One(G) ) );


InstallMethod( Collector,
        "for pcp elements",
        [ IsPcpElementRep ],
        g -> g!.collector );

InstallMethod( Exponents,
        "for pcp elements",
        [ IsPcpElementRep ],
        g -> g!.exponents );

InstallMethod( NameTag,
        "for pcp elements",
        [ IsPcpElementRep ],
        g -> g!.name );

InstallMethod( GenExpList,
        "for pcp elements",
        [ IsPcpElementRep ],
        g -> g!.word );

InstallMethod( Depth,
        "for pcp elements",
        [ IsPcpElementRep ],
function( elm )
    if Length(elm!.word) = 0 then
        return elm!.collector![PC_NUMBER_OF_GENERATORS] + 1;
    else
        return elm!.word[1];
    fi;
end );

InstallMethod( TailOfElm,
        "for pcp elements",
        [ IsPcpElement and IsPcpElementRep ],
function( elm )
    if Length( elm!.word ) = 0 then
        return 0;
    else
        return elm!.word[ Length(elm!.word) - 1 ];
    fi;
end );

InstallMethod( LeadingExponent,
        "for pcp elements",
        [ IsPcpElementRep ],
function( elm )
    if Length(elm!.word) = 0 then
        return fail;
    else
        return elm!.word[2];
    fi;
end );

##  Note, that inverses of generators with relative order > 0 are not treated
##  as inverses as they should never appear here with a negative exponent.
BindGlobal( "IsGeneratorOrInverse", function( elm )
    return Length(elm!.word) = 2 and
           (elm!.word[2] = 1 or elm!.word[2] = -1);
end );

##
## Is elm the power of a generator modulo depth d?
## If so, then return the power, otherwise return fail;
##
BindGlobal( "IsPowerOfGenerator", function( elm, d )
    if Length( elm!.word ) = 0 or
       (Length( elm!.word ) > 2 and elm!.word[3] <= d) then
        return fail;
    fi;
    return elm!.word[2];
end );

#############################################################################
##
#F FactorOrder( g )
##
InstallMethod( FactorOrder, [IsPcpElement],
function( g )
    if Length( g!.word ) = 0 then return fail; fi;
    return RelativeOrders( Collector(g) )[Depth(g)];
end );

#############################################################################
##
#F RelativeOrderPcp( g )
##
InstallMethod( RelativeOrderPcp, [IsPcpElement],
function( g )
    local r, l;
    if Length( g!.word ) = 0 then return fail; fi;
    r := FactorOrder( g );

    # the infinite case
    if r = 0 then return 0; fi;

    # the finite case
    l := LeadingExponent( g );
    if l = 1 then
       return r;
    elif IsBound( g!.normed ) and g!.normed then
        return r / LeadingExponent(g);
    elif IsPrime( r ) then
        return r;
    else
        return r / Gcd( r, l );
    fi;
end );
# TODO: Replace this by something like DeclareSynonymAttr.
# However, we cannot use DeclareSynonymAttr directly, because for
# collectors there is already an operation SetRelativeOrder.
BindGlobal( "RelativeOrder", function( g )
    return RelativeOrderPcp(g);
end );

#############################################################################
##
#F RelativeIndex( g )
##
InstallMethod( RelativeIndex, [IsPcpElement],
function( g )
    local r, l;
    if Length( g!.word ) = 0 then return fail; fi;
    r := FactorOrder( g );
    l := LeadingExponent( g );

    if IsBound( g!.normed ) and g!.normed then
        return l;
    elif r > 0 then
        return Gcd( r, l );
    else
        return AbsInt( l );
    fi;
end );

#############################################################################
##
#F Order( g )
##
InstallMethod( Order, [IsPcpElement],
function( g )
    local o, r;
    o := 1;
    while g <> g^0 do
        r := RelativeOrderPcp( g );
        if r = 0 then return infinity; fi;
        o := o*r;
        g := g^r;
    od;
    return o;
end );

#############################################################################
##
#F NormingExponent( g ) . . . . . . . . .returns f such that g^f is normed
##
## Note that g is normed, if the LeadingExponent of g is its RelativeIndex.
##
BindGlobal( "NormingExponent", function( g )
    local r, l, e;
    r := FactorOrder( g );
    l := LeadingExponent( g );
    if IsBool( l ) then
        return 1;
    elif r = 0 and l < 0 then
        return -1;
    elif r = 0 then
        return 1;
    elif IsPrime( r ) then
        return l^-1 mod r;
    else
        e := Gcdex( r, l );     # = RelativeIndex
        return e.coeff2 mod r;  # l * c2 = e mod r
    fi;
end );

#############################################################################
##
#F NormedPcpElement( g )
##
BindGlobal( "NormedPcpElement", function( g )
    local h;
    h := g^NormingExponent( g );
    h!.normed := true;
    return h;
end );

#############################################################################
##
#M Print pcp elements
##
InstallMethod( PrintObj,
               "for pcp elements",
               [IsPcpElement],
function( elm )
    local g, l, e, d;
    g := NameTag( elm );
    e := Exponents( elm );
    d := Depth( elm );
    if d > Length( e ) then
        Print("id");
    elif e[d] = 1 then
        Print(Concatenation(g,String(d)));
    else
        Print(Concatenation(g,String(d)),"^",e[d]);
    fi;
    for l in [d+1..Length(e)] do
        if e[l] = 1 then
            Print("*",Concatenation(g,String(l)));
        elif e[l] <> 0 then
            Print("*",Concatenation(g,String(l)),"^",e[l]);
        fi;
    od;
end );

InstallMethod( String,
               "for pcp elements",
               [IsPcpElement],
function( elm )
    local g, l, e, d, str;
    g := NameTag( elm );
    e := Exponents( elm );
    d := Depth( elm );
    if d > Length( e ) then
        return "id";
    fi;
 str := Concatenation(g,String(d));
    if e[d] <> 1 then
        Append(str, Concatenation("^",String(e[d])));
    fi;
    for l in [d+1..Length(e)] do
     if e[l] = 0 then continue; fi;
        Append(str, Concatenation("*",g,String(l)));
  if e[l] <> 1 then
   Append(str, Concatenation("^",String(e[l])));
  fi;
    od;
    return str;
end );

#############################################################################
##
#M g * h
##
InstallMethod( \*,
               "for pcp elements",
               IsIdenticalObj,
               [IsPcpElement, IsPcpElement],
               20,
function( g1, g2 )
    local clt, e, f;

    clt := Collector( g1 );
    if TailOfElm( g1 ) < Depth( g2 ) then
        e := Exponents( g1 ) + Exponents( g2 );

    else
        e  := ShallowCopy( Exponents( g1 ) );
        f  := GenExpList( g2 );
        while CollectWordOrFail( clt, e, f ) = fail do
            e  := ShallowCopy( Exponents( g1 ) );
        od;
    fi;

    return PcpElementByExponentsNC( clt, e );
end );

#############################################################################
##
#M Inverse
##
InstallMethod( Inverse,
               "for pcp elements",
               [IsPcpElement],
function( g )
    local   clt,  k;

    clt := Collector( g );
    if IsGeneratorOrInverse( g ) and RelativeOrderPcp(g) = 0 then
        if LeadingExponent( g ) = 1 then
            k := clt![PC_INVERSES][ Depth(g) ];
        else
            k := clt![PC_GENERATORS][ Depth(g) ];
        fi;

    else

        k := FromTheLeftCollector_Inverse( clt, GenExpList(g) );
    fi;

    return PcpElementByGenExpListNC( clt, k );
end );

InstallMethod( InverseMutable,
               "for pcp elements",
               [IsPcpElement],
function( g )
    local   clt,  k;

    clt := Collector( g );
    if IsGeneratorOrInverse( g ) and RelativeOrderPcp(g) = 0 then
        if LeadingExponent( g ) = 1 then
            k := clt![PC_INVERSES][ Depth(g) ];
        else
            k := clt![PC_GENERATORS][ Depth(g) ];
        fi;

    else

        k := FromTheLeftCollector_Inverse( clt, GenExpList(g) );
    fi;

    return PcpElementByGenExpListNC( clt, k );
end );

#############################################################################
##
#M \^
##
InstallMethod( \^,
               "for a pcp element and an integer",
               [IsPcpElement, IsInt],
               SUM_FLAGS + 10,
function( g, d )
    local   res;

    # first catch the trivial cases
    if d = 0 then
        return PcpElementByExponentsNC( Collector(g), 0*Exponents(g) );
    elif d = 1 then
        return g;
    elif d = -1 then
        return Inverse(g);
    fi;

#    # use collector function
#    c := Collector(g);
#    k := FromTheLeftCollector_Power(c, ObjByExponents(c, Exponents(g)), d);
#    return PcpElementByGenExpListNC( c, k );

    # set up for computation
    if d < 0 then
        g := Inverse(g);
        d := -d;
    fi;

    # compute power
    res := g^0;
    while d > 0 do
        if d mod 2 = 1 then   res := res * g;   fi;

        d := QuoInt( d, 2 );
        if d <> 0 then   g := g * g;    fi;
    od;

    return res;
end );

InstallMethod( \^,
               "for two pcp elements",
               IsIdenticalObj,
               [IsPcpElement, IsPcpElement],
function( h, g )
    local   clt,  conj;

    clt := Collector( g );
    if IsGeneratorOrInverse( h ) and IsGeneratorOrInverse( g ) then

        if Depth( g ) = Depth( h ) then

            conj := h;

        elif Depth( g ) < Depth( h ) then

            conj := GetConjugateNC( clt,
                            Depth( h ) * LeadingExponent( h ),
                            Depth( g ) * LeadingExponent( g ) );

            conj := PcpElementByGenExpListNC( clt, conj );

        elif Depth( g ) > Depth( h ) then
            #  h^g = g^-1 * h * g

            conj := ShallowCopy( Exponents( g^-1 ) );
            while CollectWordOrFail( clt, conj,
                    [ Depth(h), LeadingExponent( h ),
                      Depth(g), LeadingExponent( g ) ] ) = fail do

                conj := ShallowCopy( Exponents( g^-1 ) );
            od;

            conj := PcpElementByExponentsNC( clt, conj );
        fi;

    elif Depth(g) = TailOfElm(g) and Depth( g ) < Depth( h ) then

        ##
        ## nicht klar ob dies etwas bringt
        ##
        g := [ Depth(g), LeadingExponent(g) ];
        conj := ShallowCopy( Exponents( h ) );
        while CollectWordOrFail( clt, conj, g ) = fail do
            conj := ShallowCopy( Exponents( h ) );
        od;

        conj[ g[1] ] := 0;
        conj := PcpElementByExponentsNC( clt, conj );

    else
        conj := g^-1 * h * g;
    fi;

    return conj;

end );


InstallMethod( GetCommutatorNC,
        "for from the left collector",
        [ IsFromTheLeftCollectorRep, IsInt, IsInt ],
function( coll, h, g )

    if g > 0 then
        if h > 0 then
            if IsBound( coll![PC_COMMUTATORS][h] ) and
               IsBound( coll![PC_COMMUTATORS][h][g] ) then
                return coll![PC_COMMUTATORS][h][g];
            else
                return fail;
            fi;
        else
            h := -h;
            if IsBound( coll![PC_INVERSECOMMUTATORS][h] ) and
               IsBound( coll![PC_INVERSECOMMUTATORS][h][g] ) then
                return coll![PC_INVERSECOMMUTATORS][h][g];
            else
                return fail;
            fi;
        fi;
    else
        g := -g;
        if h > 0 then
            if IsBound( coll![PC_COMMUTATORSINVERSE][h] ) and
               IsBound( coll![PC_COMMUTATORSINVERSE][h][g] ) then
                return coll![PC_COMMUTATORSINVERSE][h][g];
            else
                return fail;
            fi;
        else
            h := -h;
            if IsBound( coll![PC_INVERSECOMMUTATORSINVERSE][h] ) and
               IsBound( coll![PC_INVERSECOMMUTATORSINVERSE][h][g] ) then
                return coll![PC_INVERSECOMMUTATORSINVERSE][h][g];
            else
                return fail;
            fi;
        fi;

    fi;
end );

#############################################################################
##
#M Comm
##
InstallMethod( Comm,
               "for two pcp elements",
               [ IsPcpElement, IsPcpElement ],
function( h, g )
    local   clt,  conj,  ev;

    clt := Collector( g );

    if IsGeneratorOrInverse( h ) and IsGeneratorOrInverse( g ) then

        if Depth( g ) = Depth( h ) then return g^0; fi;


        if Depth( g ) < Depth( h ) then

            ##  Do we know the commutator?

            conj := GetCommutatorNC( clt, Depth( h ) * LeadingExponent( h ),
                                          Depth( g ) * LeadingExponent( g ) );
            if conj  <> fail then
                return conj;
            fi;

            ##  [h,g] = h^-1 h^g

            conj := GetConjugateNC( clt, Depth( h ) * LeadingExponent( h ),
                                         Depth( g ) * LeadingExponent( g ) );

            ev := ShallowCopy( Exponents( h^-1 ) );
            while CollectWordOrFail( clt, ev, conj ) = fail do
                ev := ShallowCopy( Exponents( h^-1 ) );
            od;

            return PcpElementByExponentsNC( clt, ev );
        fi;

        if Depth( g ) > Depth( h ) and RelativeOrderPcp( g ) = 0 then
            ##  [h,g] = (g^-1)^h * g

            conj := GetConjugateNC( clt, Depth( g ) *  -LeadingExponent( g ),
                                         Depth( h ) *   LeadingExponent( h ) );

            ev := ExponentsByObj( clt, conj );
            while CollectWordOrFail( clt, ev, GenExpList(g) ) = fail do
                ev := ExponentsByObj( clt, conj );
            od;

            return PcpElementByExponentsNC( clt, ev );
        fi;

    fi;

    return PcpElementByGenExpListNC( clt,
                   FromTheLeftCollector_Solution( clt,
                   GenExpList(g*h),GenExpList(h*g) ) );

end );



#############################################################################
##
#M One
##
InstallMethod( One, "for pcp elements", [IsPcpElement],
g -> PcpElementByExponentsNC( Collector(g), 0*Exponents(g) ) );

#############################################################################
##
#M \=
##
InstallMethod( \=,
               "for pcp elements",
               IsIdenticalObj,
               [IsPcpElement, IsPcpElement],
function( g, h )
    return Exponents( g ) = Exponents( h );
end );

#############################################################################
##
#M \<
##
InstallMethod( \<,
               "for pcp elements",
               IsIdenticalObj,
               [IsPcpElement, IsPcpElement],
function( g, h )
    return Exponents( g ) > Exponents( h );
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