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


Quelle  fplie.gi   Sprache: unbekannt

 
#####################################################################################
#
#  fplie.gi                                      Serena Cicalo' and Willem de Graaf
#
#
# The package LieRing is free software; you can redistribute it and/or modify it under the 
# terms of the GNU General Public License as published by the Free Software Foundation; 
# either version 2 of the License, or (at your option) any later version. 


# Functions for working with free algebras.
# first we install the record containing all 
# sorts of functions we want to write protect

InstallValue( LRPrivateFunctions, rec() );

############################################################################
##
#M  ObjByExtRep( <fam>, <list> )
#M  ExtRepOfObj( <obj> )
#
InstallMethod( ObjByExtRep,
   "for family of FAlg elements, and list",
   true, [ IsFAlgElementFamily, IsList ], 0,
   function( fam, list )

    return Objectify( fam!.defaultType,
                    [ Immutable(list) ] );
end );

InstallMethod( ExtRepOfObj,
   "for an FAlg element",
   true, [ IsFAlgElement ], 0,
   function( obj )

   return obj![1];

end );

InstallMethod( PrintObj,
    "for FAlg element",
    [ IsFAlgElement ],
    function( elm )

    local names, print, e, i, len;

    names:= FamilyObj( elm )!.names;
    print:= function( expr )

      if IsBound(expr.var) then
        Print( names[ expr.var ] );
      else
        Print( "(" );
        print( expr.left );
        Print( "," );
        print( expr.right );
        Print( ")" );
      fi;
    end;

    e:= elm![1];
    len:= Length( e );
    for i in [ 1, 3 .. len - 1 ] do
        if not IsOne( e[i+1] )  then
           Print( "(",e[i+1],")*");
        fi;
        if i < len-1 then
           print( e[i] ); Print("+");
        else
           print( e[i] );
        fi;
    od;
    if len = 0 then
      Print( "0" );
    fi;
    end );

#############################################################################
##
#M  ZeroOp( <m> ) . . . . . . . . . . . . . . .  for a Falg element
#M  \<( <m1>, <m2> ) . . . . . . . . . . . . . . for two Falg elements
#M  \=( <m1>, <m2> ) . . . . . . . . . . . . . . for two Falg elements
#M  \+( <m1>, <m2> ) . . . . . . . . . . . . . . for two Falg elements
#M  \-( <m> )     . . . . . . . . . . . . . . for a Falg element
#M  \in( <U>, <u> )  . . . . . . . . . . . . . . for Free algebra, and element
##
InstallMethod( ZeroOp,
        "for FAlg element",
        true, [ IsFAlgElement ], 0,
        function( x )

    return ObjByExtRep( FamilyObj( x ), [ ] );

end );


InstallMethod( \<,
                "for two FAlg elements",
        IsIdenticalObj, [ IsFAlgElement, IsFAlgElement ], 0,
        function( x, y )
    return x![1]< y![1];
end );

InstallMethod( \=,
                "for two FAlg elements",
        IsIdenticalObj, [ IsFAlgElement, IsFAlgElement], 0,
        function( x, y )

    local len, i;
    return x![1] = y![1];
end );


LRPrivateFunctions.direct_sum:= function( F, x, y )

    local sum,z,mons,o,ord;

    o:= F!.ordering;

    ord:= function( a, b )
       return o[a.no] < o[b.no];
    end;

    sum:= ZIPPED_SUM_LISTS( x, y, F!.zeroCoefficient, [ ord, \+ ] ); 
    return sum;

end;

InstallMethod( \+,
        "for two FAlg elements",
        true, [ IsFAlgElement, IsFAlgElement ], 0, 
        function( x, y )
    local F;
    F:= FamilyObj(x);
    return ObjByExtRep( F, LRPrivateFunctions.direct_sum( F, x![1], y![1] ) );

end );

LRPrivateFunctions.dir_monmult:= function( F, x, y )

    local T, mons, o, ord_1, a, b, c, i, j, t1, t2, s1, r, pos, num, p, s; 

    T:= F!.multTable;
    mons:= F!.monomials;
    o:= F!.ordering;

    ord_1:= function( mon1, mon2 )


         if mon1.no = mon2.no then return false; fi;
         if mon1.deg <> mon2.deg then return mon1.deg < mon2.deg; fi;
         if mon1.left.no <> mon2.left.no then return o[mon1.left.no] < o[mon2.left.no]; fi;
         return o[mon1.right.no] < o[mon2.right.no]; 

    end;

    a:= x[1]; b:= y[1];
    c:= x[2]*y[2];
    i:= a.no; j:= b.no;

    if F!.sign = -1 then

        if i = j then return [ a, 0*c ]; fi; 
        if i > j then
           t1:= j; t2:= i;
           s1:= -1;
        else
           t1:= i; t2:= j;
           s1:= 1;
        fi;
        if IsBound( T[t1] ) and IsBound( T[t1][t2] ) then
           r:= T[t1][t2];
           pos:= o[ r[1] ];
           return [ mons[pos], s1*r[2]*c ];
        fi;
        # If we arrive here then the product is not known yet.
        num:= Length( mons ) + 1; # number of new monomial...

        if o[i] < o[j] then
           # i.e., a < b
           p:= rec( no:= num, deg:= a.deg+b.deg, left:= a, right:= b );
           s:= 1;
        else   
           p:= rec( no:= num, deg:= a.deg+b.deg, left:= b, right:= a );
           c:= -c;
           s:= -1;
        fi;

        if not IsBound( T[t1] ) then T[t1]:= [ ]; fi;
        T[t1][t2]:= [ num, s*s1 ]; 
        F!.multTable:= T;

        # now we have to insert p in the sorted list of monomials...
        
        pos:= POSITION_SORTED_LIST_COMP( mons, p, ord_1 );
        for i in [pos..Length(o)] do o[ mons[i].no ]:= o[ mons[i].no ]+1; od;
        Add( o, pos );

        CopyListEntries(mons,pos,1,mons,pos+1,1,Length(mons)-pos+1);
        mons[pos]:= p;

        F!.monomials:= mons;
        F!.ordering:= o;

        return [ p, c ]; 

    else
       # The extremely free multiplication...

       if IsBound( T[i] ) and IsBound( T[i][j] ) then
          r:= T[i][j];
          pos:= o[ r ];
          return [ mons[pos], c ];
       fi;
       # If we arrive here then the product is not known yet.
       num:= Length( mons ) + 1; # number of new monomial...
       p:= rec( no:= num, deg:= a.deg+b.deg, left:= a, right:= b );

       if not IsBound( T[i] ) then T[i]:= [ ]; fi;
       T[i][j]:= num; 
       F!.multTable:= T;

       # now we have to insert p in the sorted list of monomials...
       pos:= POSITION_SORTED_LIST_COMP( mons, p, ord_1 );

       for i in [pos..Length(o)] do o[ mons[i].no ]:= o[ mons[i].no ]+1; od;
       Add( o, pos );

       CopyListEntries(mons,pos,1,mons,pos+1,1,Length(mons)-pos+1);
       mons[pos]:= p;

       F!.monomials:= mons;
       F!.ordering:= o;

       return [ p, c ]; 
       
    fi;

end;

LRPrivateFunctions.monmult:= function( x, y )

    local F;

    F:= FamilyObj(x);
    return ObjByExtRep( F, LRPrivateFunctions.dir_monmult( F, x![1], y![1] ) );
       
end;


LRPrivateFunctions.dir_mult:= function( F, x, y )

    local o, ord, mns, cfs, i, j, l, res, len;

    o:= F!.ordering;

    ord:= function( a, b )
       return o[a.no] < o[b.no];
    end;

# Keeping it sorted might make it faster!!

    mns:= []; cfs:= [];
    for i in [1,3..Length(x)-1] do
        for j in [1,3..Length(y)-1] do
            l:= LRPrivateFunctions.dir_monmult( F, [x[i],x[i+1]], [y[j],y[j+1]] );
            if not IsZero( l[2] ) then
               Add( mns, l[1] ); Add(cfs, l[2] );
            fi;
        od;
    od;

    SortParallel( mns, cfs, ord );

    res:= [];
    len:= -1;
    for i in [1..Length(mns)] do
        if len > 0 and mns[i].no = res[len].no then
           res[len+1]:= res[len+1]+cfs[i];
        else
           Add( res, mns[i] ); Add( res, cfs[i] );
           len:= len+2;
        fi;
    od; 
    for i in [2,4..Length(res)] do
        if IsZero(res[i]) then
           Unbind( res[i-1] ); Unbind( res[i] );
        fi;
    od;
    res:= Filtered( res, x -> IsBound(x) );

    return res;

end;

InstallMethod( \*,
        "for two FAlg elements",
        true, [ IsFAlgElement, IsFAlgElement ], 0, 
        function( x, y )
    local F;
    F:= FamilyObj(x);
    return ObjByExtRep( F, LRPrivateFunctions.dir_mult( F, x![1], y![1] ) ); 
end);

LRPrivateFunctions.special_mult:= function( F, x1, f1, x2, f2, x3, f3 )

    # compute x1f1 + x2f2 + x3f3, where the xi are monomials

    local T, mons, o, ord_1, mon_prod, ord, mns, cfs, i, j, l, res, len,t, e1, e2;

    T:= F!.multTable;
    mons:= F!.monomials;
    o:= F!.ordering;

    ord_1:= function( mon1, mon2 )


         if mon1.no = mon2.no then return false; fi;
         if mon1.deg <> mon2.deg then return mon1.deg < mon2.deg; fi;
         if mon1.left.no <> mon2.left.no then return o[mon1.left.no] < o[mon2.left.no]; fi;
         return o[mon1.right.no] < o[mon2.right.no]; 

    end;

    if F!.sign = -1 then

       mon_prod:= function( a, b, ca, cb )
           local c, p, i, j, r, pos, num, pi, pj, s, mmm, t1, t2, s1;
           c:= ca*cb;
           i:= a.no; j:= b.no;
           if i = j then return [ a, 0*c ]; fi; 
           if i > j then
              t1:= j; t2:= i;
              s1:= -1;
           else
              t1:= i; t2:= j;
              s1:= 1;
           fi;

           if IsBound( T[t1] ) and IsBound( T[t1][t2] ) then
              r:= T[t1][t2];
              pos:= o[ r[1] ];
              return [ mons[pos], s1*r[2]*c ];
           fi;
           # If we arrive here then the product is not known yet.
           num:= Length( mons ) + 1; # number of new monomial...

           if o[i] < o[j] then
              # i.e., a < b
              p:= rec( no:= num, deg:= a.deg+b.deg, left:= a, right:= b );
              s:= 1;
           else   
              p:= rec( no:= num, deg:= a.deg+b.deg, left:= b, right:= a );
              c:= -c;
              s:= -1;
           fi;

           if not IsBound( T[t1] ) then T[t1]:= [ ]; fi;
           T[t1][t2]:= [ num, s*s1 ]; 
           F!.multTable:= T;

           # now we have to insert p in the sorted list of monomials...
           pos:= POSITION_SORTED_LIST_COMP( mons, p, ord_1 );

           for i in [pos..Length(o)] do o[ mons[i].no ]:= o[ mons[i].no ]+1; od;
           Add( o, pos );

           CopyListEntries(mons,pos,1,mons,pos+1,1,Length(mons)-pos+1);
           mons[pos]:= p;

           F!.monomials:= mons;
           F!.ordering:= o;

           return [ p, c ]; 
       end;

    fi;

    ord:= function( a, b )
       return o[a.no] < o[b.no];
    end;

    e1:= [ ];
    for i in [1,3..Length(f1)-1] do
        l:= mon_prod( x1[1], f1[i], x1[2], f1[i+1] );
        if not IsZero( l[2] ) then
           Append( e1, l );
        fi;
    od;
    e2:= [ ];
    for i in [1,3..Length(f2)-1] do
        l:= mon_prod( x2[1], f2[i], x2[2], f2[i+1] );
        if not IsZero( l[2] ) then
           Append( e2, l );
        fi;
    od;
    res:= ZIPPED_SUM_LISTS( e1, e2, F!.zeroCoefficient, [ ord, \+ ] ); 
    e2:= [ ];
    for i in [1,3..Length(f3)-1] do
        l:= mon_prod( x3[1], f3[i], x3[2], f3[i+1] );
        if not IsZero( l[2] ) then
           Append( e2, l );
        fi;
    od;

    return ZIPPED_SUM_LISTS( res, e2, F!.zeroCoefficient, [ ord, \+ ] ); 


end;


InstallMethod( AdditiveInverseSameMutability,
        "for FAlg element",
        true, [ IsFAlgElement ], 0,
        function( x )

    local   ex,  i;

    ex:= ShallowCopy(x![1]);
    for i in [2,4..Length(ex)] do
        ex[i]:= -ex[i];
    od;
    return ObjByExtRep( FamilyObj(x), ex );
end );

InstallMethod( AdditiveInverseMutable,
        "for FAlg element",
        true, [ IsFAlgElement ], 0,
        function( x )

    local   ex,  i;

    ex:= ShallowCopy(x![1]);
    for i in [2,4..Length(ex)] do
        ex[i]:= -ex[i];
    od;
    return ObjByExtRep( FamilyObj(x), ex );
end );

#############################################################################
##
#M  \*( <scal>, <m> ) . . . . . . . . .for a scalar and a FAlg element
#M  \*( <m>, <scal> ) . . . . . . . . .for a scalar and a FAlg element
##
InstallMethod( \*,
        "for scalar and FAlg element",
        true, [ IsScalar, IsFAlgElement ], 0,
        function( scal, x )

    local   ex,  i;
    
    if IsZero( scal ) then return Zero(x); fi;
    ex:= ShallowCopy( x![1] );
    for i in [2,4..Length(ex)] do
        ex[i]:= scal*ex[i];
    od;
    return ObjByExtRep( FamilyObj(x), ex );
end);

InstallMethod( \*,
        "for FAlg element and scalar",
        true, [ IsFAlgElement, IsScalar ], 0,
        function( x, scal )

    local   ex,  i;
    
    if IsZero( scal ) then return Zero(x); fi;
    ex:= ShallowCopy( x![1] );
    for i in [2,4..Length(ex)] do
        ex[i]:= scal*ex[i];
    od;
    return ObjByExtRep( FamilyObj(x), ex );
end);

InstallMethod( \in,
        "for FAlg element and free algebra",
        true, [ IsFAlgElement, IsFreeNAAlgebra ], 0,
        function( u, U )
    return IsIdenticalObj( ElementsFamily( FamilyObj(U) ), FamilyObj(u) );
end );


InstallMethod( Degree, "FAlg elements", true, [ IsFAlgElement ], 0, 
   function(x) 
    x:= x![1];
    return x[ Length(x)-1 ].deg ;
end );



LRPrivateFunctions.FreeNonassociativeAlgebra:= function( arg )

    local R,          # coefficients ring
          names,      # names of the algebra generators
          F,          # family of elements
          one,        # identity of `R'
          zero,       # zero of `R'
          A, sign, g, gr, ord;          


    R:= arg[1];

    # Construct names of generators.
    if IsInt( arg[2] ) then

      names:= List( [ 1 .. arg[2] ],
                    i -> Concatenation( "x", String(i) ) );
    elif IsList( arg[2] ) then
      names:= arg[2];
    else
      Error( "The second argument to FreeNonassociativeAlgebra has to be an integer, or a list" ); 
    fi;

    if Length(arg) >= 3 then
       if arg[3] in [1,-1] then
          sign:= arg[3];
       else
          Error("The third argument to FreeNonassociativeAlgebra must be 1, or -1 ");
       fi;
    else
       sign:= 1;
    fi;

    if Length( arg ) = 4 then
       gr:= arg[4];
    else
       gr:= List( names, x -> 1 );
    fi;

    F:= NewFamily( "FreeAlgebraEltFamily", IsFAlgElement );

    if IsField(R) then
       F!.isfield_basering:= true;
    elif R=Integers then
       F!.isfield_basering:= false;
    else
       Error("The only allowed base rings are fields and the Integers");
    fi;
       

    one:= One( R );
    zero:= Zero( R );

    F!.defaultType := NewType( F, IsFAlgElement );
    F!.zeroCoefficient    := zero;
    F!.names       := names;
    F!.sign:= sign;

    A:= Objectify( NewType( CollectionsFamily( F ),
                                IsFreeNAAlgebra
                            and IsAttributeStoringRep ),
                   rec() );

    SetLeftActingDomain( A, R );
    g:= List( [1..Length(names)],
              x -> ObjByExtRep( F, [ rec( no:= x, deg:=gr[x], var:= x ), one ] ) );
    F!.monomials:= List( g, u -> ExtRepOfObj( u )[1] );
    F!.multTable:= [];
    ord:= List( [1..Length(names)], x -> x );
    SortParallel( gr, ord );
    F!.ordering:= ord; 
    SetGeneratorsOfLeftOperatorRing( A, g );

    return A;

end;

InstallAccessToGenerators( IsFreeNAAlgebra,
                           "free algebra",
                           GeneratorsOfLeftOperatorRing );

InstallMethod( FreeLieRing,
    "for a ring and list",
    true,
    [ IsRing, IsList ], 0,
    function( R, names )

    # Check the argument list.
    if not IsRing( R ) then
      Error( "first argument must be a ring" );
    fi;

    if not ForAll( names, IsString ) then
       Error("second argument must be a list of strings");
    fi;

    return LRPrivateFunctions.FreeNonassociativeAlgebra( R, names, -1 );

end );

InstallOtherMethod( FreeLieRing,
    "for a ring and list and list",
    true,
    [ IsRing, IsList, IsList ], 0,
    function( R, names, grad )

    # Check the argument list.
    if not IsRing( R ) then
      Error( "first argument must be a ring" );
    fi;

    if not ForAll( names, IsString ) then
       Error("second argument must be a list of strings");
    fi;

    return LRPrivateFunctions.FreeNonassociativeAlgebra( R, names, -1, grad );

end );

InstallOtherMethod( FreeLieRing,
    "for a ring and an integer",
    true,
    [ IsRing, IsInt ], 0,
    function( R, k )

    # Check the argument list.
    if not IsRing( R ) then
      Error( "first argument must be a ring" );
    fi;

    return LRPrivateFunctions.FreeNonassociativeAlgebra( R, k, -1 );

end );

InstallOtherMethod( FreeLieRing,
    "for a ring and an integer",
    true,
    [ IsRing, IsInt, IsList ], 0,
    function( R, k, grad )

    # Check the argument list.
    if not IsRing( R ) then
      Error( "first argument must be a ring" );
    fi;

    return LRPrivateFunctions.FreeNonassociativeAlgebra( R, k, -1, grad );

end );


InstallMethod( PrintObj,
    "for a nonassociative algebra",
    true,
    [ IsFreeNAAlgebra ], 0,
    function( A )

    local g, i; 

    Print("<Free algebra over ",LeftActingDomain(A)," generators: " );
    g:= GeneratorsOfAlgebra(A);
    for i in [1..Length(g)-1] do 
        Print( g[i], ", " ); 
    od;
    Print( g[ Length(g) ], " >" );
    

end );


InstallMethod( ViewObj,
    "for a nonassociative algebra",
    true,
    [ IsFreeNAAlgebra ], 0,
    function( A )

    local g, i; 

    Print("<Free algebra over ",LeftActingDomain(A)," generators: " );
    g:= GeneratorsOfAlgebra(A);
    for i in [1..Length(g)-1] do 
        Print( g[i], ", " ); 
    od;
    Print( g[ Length(g) ], " >" );
    

end );

InstallMethod( PrintObj,
    "for a reduced set",
    true,
    [ IsReducedSetOfFAE ], 0,
    function( G )

    Print("<Reduced set of free algebra elements>" );

end );

InstallMethod( ViewObj,
    "for a reduced set",
    true,
    [ IsReducedSetOfFAE ], 0,
    function( G )

    Print("<Reduced set of free algebra elements>" );

end );


InstallMethod( AsSSortedList,
    "for a reduced set",
    true,
    [ IsReducedSetOfFAE ], 0,
    function( G )

    return G!.elements;

end );

LRPrivateFunctions.search_factor:= function( m, lms )

     # here m is a monomial in ext rep; lms is a sorted list of monomial 
     # numbers of leading monomials. We search a leading monomial that is
     # a factor in m; if found then a list is returned with in the first
     # position the value true, in the second position, the position of the
     # factor in lms, and the third and fourth positions contain lists that
     # describe the correponding appliance (first the list of monomials, than
     # a list of 0,1; 0 means: mult on the left, 1 means mult on the right).
     # if no factor is found the list [false] is returned.

     local b, choices, points, pos, mns, lr, c, k;
    

     b:= m; 
     choices:= [ ];
     points:= [ b ];

     while true do

        pos:= PositionSorted( lms, b.no );       
        if pos <= Length(lms) and lms[pos] = b.no then
           mns:= [ ];
           lr:= [ ];
           c:= m;
           for k in choices do
               if k = 0 then
                  Add( lr, 1 ); Add( mns, c.right ); c:= c.left;
               else
                  Add( lr, 0 ); Add( mns, c.left ); c:= c.right;
               fi;
           od;
           return [ true, pos, Reversed(mns), Reversed(lr) ];
         fi;
         if IsBound(b.var) then
            # backtrack...
            k:= Length( choices );
            while k>=1 and choices[k] = 1 do k:= k-1; od;
            if k = 0 then return [ false ]; fi;
            choices:= choices{[1..k-1]}; points:= points{[1..k]};
           
            b:= points[k].right;
            Add( choices, 1 ); Add( points, b );
      
         else
            b:= b.left;
            Add( choices, 0 ); Add( points, b );
         fi;
     od;

end;


LRPrivateFunctions.ReduceElmFreeAlg:= function( fam, f, G, lms, minus )

     local ef, len, r, a, g, lg, mns, side, i, m, cf, cg, rem, q; 

     # Here f is an elem of a free algeb in ext rep,
     # fam is its family, G is a list of elements of
     # the same free alg, but in wrapped rep, lms is a list
     # of the numbers of the leading monomials of G, 
     # minus is a boolean, if true then the result is normalised
     # i.e., multiplied by an appropriate unit.

     if f=[] then return f; fi;
     if G = [ ] then
        if minus then
           f:= ShallowCopy(f);
           cf:= f[Length(f)]; 
           if fam!.isfield_basering then
              if not IsOne(cf) then
                 for i in [2,4..Length(f)] do
                     f[i]:= f[i]/cf;
                 od;
              fi;
           else
              if cf < 0 then
                 for i in [2,4..Length(f)] do
                     f[i]:= -f[i];
                 od;
              fi;
           fi;
        fi;
        return f; 
     fi;

     ef:= ShallowCopy( f );
     len:= Length(ef);

     r:= [ ];

     if fam!.isfield_basering then
        while len >0 do
           m:= ef[ len-1 ]; cf:= ef[len];
           ef:= ef{[1..len-2]};
           len:= len-2;
  
           # look for a factor...
           a:= LRPrivateFunctions.search_factor( m, lms );
 
           if a[1] then
              g:= ShallowCopy(G[a[2]]![1]);
              mns:= a[3];
              side:= a[4];
              lg:= Length(g);
              g:= g{[1..lg-2]};
  
              for i in [1..Length(mns)] do
                  if side[i] = 0 then 
                     g:= LRPrivateFunctions.dir_mult( fam, [mns[i],1], g );
                  else
                     g:= LRPrivateFunctions.dir_mult( fam, g, [mns[i],1] );
                  fi;
              od;
   
              # compute -cf*g:
              for i in [2,4..Length(g)] do
                  g[i]:= -cf*g[i];
              od;

              ef:= LRPrivateFunctions.direct_sum( fam, ef, g );            
              len:= Length( ef );
           else

              r:= LRPrivateFunctions.direct_sum( fam, r, [m,cf] );
# Better: add everything, then sort!
           fi;
        od;

        if r <> [ ] and minus then
           cf:= r[Length(r)];
           if not IsOne(cf) then
              for i in [2,4..Length(r)] do r[i]:= r[i]/cf; od; 
           fi;
        fi;

     else
        # so the base ring is the integers...
        while len >0 do
           m:= ef[ len-1 ]; cf:= ef[len];
           ef:= ef{[1..len-2]};
           len:= len-2;
  
           # look for a factor...
           a:= LRPrivateFunctions.search_factor( m, lms );
 
           if a[1] then
              g:= ShallowCopy(G[a[2]]![1]);
              lg:= Length(g);
              cg:= g[lg];
              rem:= cf mod cg;
              q:= (cf-rem)/cg;
              if q <> 0 then
                 mns:= a[3];
                 side:= a[4];
                 g:= g{[1..lg-2]};
  
                 for i in [1..Length(mns)] do
                     if side[i] = 0 then 
                        g:= LRPrivateFunctions.dir_mult( fam, [mns[i],1], g );
                     else
                        g:= LRPrivateFunctions.dir_mult( fam, g, [mns[i],1] );
                     fi;
                 od;

                 # compute -q*g:
                 for i in [2,4..Length(g)] do
                     g[i]:= -q*g[i];
                 od;

                 ef:= LRPrivateFunctions.direct_sum( fam, ef, g );            
                 len:= Length( ef );
              fi;

              if rem <> 0 then
                 r:= LRPrivateFunctions.direct_sum( fam, r, [m,rem] );

              fi;
           else

              r:= LRPrivateFunctions.direct_sum( fam, r, [m,cf] );
# Better: add everything, then sort!
           fi;
        od;

        if r <> [ ] and minus then
           cf:= r[Length(r)];
           if cf < 0 then
              for i in [2,4..Length(r)] do r[i]:= -r[i]; od;
           fi;
        fi;

     fi;

     return r;

end;

LRPrivateFunctions.AddElmRedSet:= function( fam, f, G, lms )

    local newelms, len, h, n, Gh, i, g, pos;

    newelms:= [ f ];
    len:= 1;
    while len>0 do
       h:= newelms[len];
       newelms:= newelms{[1..len-1]};
       len:= len-1;
       h:= LRPrivateFunctions.ReduceElmFreeAlg( fam, h, G, lms, true );
       if h <> [] then
          # we add it, but first we remove all elements of which the
          # leading monomial reduces mod h from G:
          n:= [ h[ Length(h)-1 ].no ];
          h:= ObjByExtRep( fam, h );
          Gh:= [ h ];
          for i in [1..Length(G)] do
              g:= LRPrivateFunctions.ReduceElmFreeAlg( fam, G[i]![1], Gh, n, true );
              if g <> [] and g[Length(g)-1].no <> lms[i] then
                 Add( newelms, g ); len:= len+1;
                 Unbind( G[i] ); Unbind( lms[i] );
              elif g=[ ] then
                 Unbind( G[i] ); Unbind( lms[i] );
              else
                 G[i]:= ObjByExtRep( fam, g );
              fi;
          od;
          G:= Filtered( G, x -> IsBound(x) );
          lms:= Filtered( lms, x -> IsBound(x) );
          pos:= PositionSorted( lms, n[1] );
          CopyListEntries(G,pos,1,G,pos+1,1,Length(G)-pos+1);
          G[pos]:= h;
          CopyListEntries(lms,pos,1,lms,pos+1,1,Length(lms)-pos+1);
          lms[pos]:= n[1];
       fi;
    od;

    return [ G, lms ];

end;

InstallMethod( ReducedSet, 
    "for a set of free alg elms",
    true,
    [ IsList ], 0,
    function( elms )

    local RS, G, lms, fam, g, a;

    RS:= Objectify( NewType( NewFamily( "ReducedSetFam", IsReducedSetOfFAE ), IsReducedSetOfFAE ), 
                    rec() );

    if elms = [ ] then
       RS!.elements:= [ ];
       RS!.leading_mns:= [ ];
       return RS;
    fi;

    G:= [ ]; lms:= [ ];
    fam:= FamilyObj( elms[1] );
    for g in elms do
        a:= LRPrivateFunctions.AddElmRedSet( fam, g![1], G, lms );
        G:= a[1]; lms:= a[2];
    od;
    RS!.elements:= G;
    RS!.leading_mns:= lms;
    return RS;

end );



InstallMethod( AddToReducedSet, 
    "for a reduced set of free alg elms, and a free alg elm",
    true,
    [ IsReducedSetOfFAE, IsFAlgElement ], 0,
    function( G, f )

    local elms, lms, ef, a;

    elms:= G!.elements;
    lms:= G!.leading_mns;
    ef:= f![1];
    if elms = [ ] and ef <> [ ] then
       G!.elements:= [ f ];
       G!.leading_mns:= [ ef[ Length(ef)-1 ].no ];
    elif elms <> [ ] then
       a:= LRPrivateFunctions.AddElmRedSet( FamilyObj( f ), ef, elms, lms );
       G!.elements:= a[1];
       G!.leading_mns:= a[2];
    fi;

end );

InstallMethod( NormalForm, 
    "for a reduced set of free alg elms, and a free alg elm",
    true,
    [ IsReducedSetOfFAE, IsFAlgElement ], 0,
    function( G, f )

     local h;

     h:= LRPrivateFunctions.ReduceElmFreeAlg( 
                            FamilyObj(f), f![1], G!.elements, G!.leading_mns, false );
     return ObjByExtRep( FamilyObj(f), h );

end );


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