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


Quelle  fpla.gi   Sprache: unbekannt

 
#####################################################################################
#
#  fpla.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. 

LRPrivateFunctions.make_basis_field:= function( fam, BB )

      # produce a basis of the subspace spanned by BB

      local o, mninds, b, i, mat, cc, bas, mns, n, t, s;

      o:= fam!.ordering;
      mninds:= [ ];
      for b in BB do
          for i in [1,3..Length(b)-1] do
              if not b[i].no in mninds then Add( mninds, b[i].no ); fi;
          od;
      od;

      Sort( mninds, function( a, b ) return o[a] > o[b]; end );
      mat:= [ ];
      for b in BB do
          cc:= List( mninds, x -> 0 );
          for i in [1,3..Length(b)-1] do
             cc[ Position( mninds, b[i].no ) ]:= b[i+1];
          od;
          Add( mat, cc );
      od;

      TriangulizeMat( mat );

      bas:= [ ];
      mns:= fam!.monomials;
      n:= Length( mninds );
      for cc in mat do
          if cc <> 0*cc then
             b:= [ ];
             for i in [n,n-1..1] do
                 if cc[i] <> 0 then
                    Add( b, mns[ o[mninds[i]] ] );
                    Add( b, cc[i] );
                 fi;
             od;
             Add( bas, b );
          fi;
       
      od;      

      return bas;

end;

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

     # Here we do assume G to be monic, but not that lms is sorted,
     # so a bit different from reduce.
 
     local lms0, ef, len, r, m, cf, a, g, mns, side, lg, i;

     if f=[] then return f; fi;
     if G = [ ] then return f; fi;

     lms0:= List( lms, x -> x.no );

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

     r:= [ ];

     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_factor0( m, lms0 );
 
        if a[1] then
           g:= ShallowCopy(G[a[2]]);
           lg:= Length(g);

           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 -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 <> [ ] 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;

     return r;

end;

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

     # Here we do assume G to be monic, and that lms is sorted
 
     local lms0, ef, len, r, m, cf, a, g, mns, side, lg, i;

     if f=[] then return f; fi;
     if G = [ ] then return f; fi;

     lms0:= List( lms, x -> x.no );

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

     r:= [ ];

     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, lms0 );
 
        if a[1] then
           g:= ShallowCopy(G[a[2]]);
           lg:= Length(g);

           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 -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 <> [ ] 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;

     return r;

end;

LRPrivateFunctions.addElm_RedSet_field:= 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.reduce_sorted( fam, h, G, lms );

       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 ] ];
          Gh:= [ h ];
          for i in [1..Length(G)] do

              g:= LRPrivateFunctions.reduce_sorted( fam, G[i], Gh, n );
              if g <> [] and g[Length(g)-1].no <> lms[i].no 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]:= g;
              fi;
          od;
          G:= Filtered( G, x -> IsBound(x) );

          lms:= Filtered( lms, x -> IsBound(x) );
          pos:= PositionSorted( List(lms,x->x.no), n[1].no );
          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;

LRPrivateFunctions.is_interred:= function( Fam, G )

   local i, j, h;

   for i in [1..Length(G)] do
       for j in [1..Length(G)] do
           if i <> j then
              h:= LRPrivateFunctions.reduce_sorted( Fam, G[i], [ G[j] ], [ G[j][Length(G[j])-1] ] );
              if h <> G[i] then
                 Print(i,"  ",j,"\n");
                 return false;
              fi;
           fi;
      od;
  od;
  return true;


end;

LRPrivateFunctions.interreduce_field:= function( fam, U )

   local G, lms, i, r, f, k, cf, lf;

   for i in [1..Length(U)] do
       if U[i] = [ ] then
          Unbind( U[i] );
       fi;
   od;
   U:= Filtered( U, x -> IsBound(x) );

   if U = [] then return U; fi;

   Sort( U, function(u,v) return u[Length(u)-1].deg < v[Length(v)-1].deg; end );

   for i in [1..Length(U)] do
       f:= ShallowCopy(U[i]); lf:= Length(f);
       cf:= f[lf];
       if not IsOne( cf ) then 
          for k in [2,4..lf] do f[k]:= f[k]/cf; od;
          U[i]:= f;
       fi;
   od;

   G:= [ U[1] ];
   lms:= [ U[1][ Length(U[1])-1 ] ];
   for i in [2..Length(U)] do
       r:= LRPrivateFunctions.addElm_RedSet_field( fam, U[i], G, lms );
       G:= r[1]; lms:= r[2];
   od;

   return G;

end;


InstallMethod( FpLieAlgebra,
    "for free Lie algebra and list of its elements",
    true, [ IsFreeNAAlgebra, IsList ], 0,
    function( A, RR )

     # compute A/I, where I is the ideal gen by R along with Jacobi s

     local one, Fam, o, g, B, Bk, Bd, G, lms, lmspos, deg, bound, is_hom, r, eg, 
           dg, k, rels, i, f, c, j, lowdeg, lmsr, lmsposr, nonleadingr, a1, a2, a3, a4,
           m1, m2, m3, u, v, f1, f2, f3, lf, m, newB, T, cc, is_nilquot, nilquot, basinds,
           newrls, is_hom_elm, get_rid_of_hdeg, x, R, B0, d, diff_degree, K, cf, hom;

    is_hom_elm:= function( u )

       local e, dg, j;

       e:= u![1];
       dg:= e[1].deg;
       for j in [3,5..Length(e)-1] do
           if e[j].deg <> dg then return false; fi;
       od;
       return true;

     end;

     get_rid_of_hdeg:= function( f, dd )

       # all mons of degree > dd are zero...
       local h, i;

       h:= [ ];
       for i in [1,3..Length(f)-1] do
           if f[i].deg <= dd then
              Add( h, f[i] ); Add( h, f[i+1] );
           else
              break;
           fi;
       od;
       return h;

     end;

     R:= ShallowCopy( RR );
     R:= Filtered( R, x -> not IsZero(x) );
     one:= One( LeftActingDomain( A ) );

     Fam:= ElementsFamily( FamilyObj( A ) );
     o:= Fam!.ordering;

     g:= GeneratorsOfAlgebra( A );

     diff_degree:= Length( Set( List( g, Degree ) ) ) > 1;

# i.e., if the degrees of the generators are different, then we
# loop until the bound, and we do not care about homogeneous components
# that are zero.

     Bk:= [ ];
     Bd:= [ ];
    
     G:= [ ];
     lms:= [ ];
     lmspos:= [];

     deg:= 1;

     bound:= ValueOption( "maxdeg" );
     if bound = fail then 
        bound:= infinity; 
        is_nilquot:= false;
        nilquot:= bound;
     else
        is_nilquot:= true;
        nilquot:= bound;
     fi;

     # determine whether the relations are homogeneous.
     is_hom:= true;
     for r in RR do
         eg:= r![1];
         dg:= eg[1].deg;
         for k in [3,5..Length(eg)-1] do
             if eg[k].deg <> dg then 
                is_hom:= false; break;
             fi;
         od;
         if not is_hom and is_nilquot then bound:= 2*bound; break; fi;
     od;

     while deg <= bound do

       rels:= [ ];

       if is_nilquot and deg = nilquot+1 then  # ONLY in nonhom case!!!
          # we have to add all monomials of degree deg to the relations
          for i in [1..Length(Bd)] do
              for j in [i..Length(Bd)] do
                  if i+j = deg then
                     for m1 in Bd[i] do
                         for m2 in Bd[j] do
                             if  o[m1[1].no] < o[m2[1].no] then
                                 Add( rels, LRPrivateFunctions.dir_monmult( Fam, m1, m2 ) );
                             fi;
                         od;
                     od;
                  fi;
              od;
          od;

          # we add all monomials in the deg-th term of the lower central series
          # of the algebra that we got so far...

          B:= [ ];
          for i in [1..Length(Bd)] do Append( B, Bd[i] ); od;

          d:= 1;
          while d < deg do
              B0:= [ ];
              for m in Bd[1] do
                  for f in B do
                      Add( B0, get_rid_of_hdeg( LRPrivateFunctions.reduce_field( Fam, 
                        LRPrivateFunctions.dir_mult( Fam, m, f ), G, lms ), nilquot ));
                  od;
              od;
              B0:= Filtered( B0, x -> not x = [ ] );
              B:= LRPrivateFunctions.make_basis_field( Fam, B0 );
              d:= d+1;
          od;
         
          Append( rels, B );

       fi;

       for r in R do
           if Degree(r) = deg then
              if is_nilquot then
                 f:= get_rid_of_hdeg( r![1], nilquot );
              else
                 f:= r![1];
              fi;
              Add( rels, f );
           fi;
       od;

       rels:= LRPrivateFunctions.interreduce_field( Fam, rels );

       for i in [1..Length(rels)] do
           f:= ShallowCopy( LRPrivateFunctions.reduce_field( Fam, rels[i], G, lms ) );
           if f <> [ ] then
              c:= f[Length(f)];
              if not IsOne(c) then for j in [2,4..Length(f)] do f[j]:= f[j]/c; od; fi;
              rels[i]:= f;
           else
              Unbind( rels[i] );
           fi;
       od;

       rels:= Filtered( rels, x -> IsBound(x) );

       lowdeg:= not ForAll( rels, x -> x[ Length(x)-1 ].deg = deg );
       lmsr:= LRPrivateFunctions.leading_mns( rels );
       lmsposr:= [ ];
       for i in [1..Length(lmsr)] do
           lmsposr[ lmsr[i].no ]:= i;
           if lmsr[i].deg < deg then lowdeg:= true; fi;
       od;

       nonleadingr:= [ ];
       for r in rels do
           for k in [1,3..Length(r)-3] do
               AddSet( nonleadingr, r[k].no );
           od;
       od;

       if deg >= 3 then

          a1:= Length(g);
          a2:= Length(Bd);

          for i in [1..a1] do
              m1:= g[i]![1];
              for u in [1..a2] do
                  v:= deg-m1[1].deg-u;
                  if v > 0 and v <= a2 then
                     a3:= Length( Bd[u] );
                     a4:= Length( Bd[v] );
                     for j in [1..a3] do
                         m2:= Bd[u][j];
                         if o[m1[1].no] < o[m2[1].no] then
                            for k in [1..a4] do
                                m3:= Bd[v][k];
                                if o[m2[1].no] < o[m3[1].no] then

                                   f1:= LRPrivateFunctions.linalg_reduce_onemon( Fam, 
                          LRPrivateFunctions.dir_monmult( Fam, m2, m3 ), G, lmspos );
                                   f2:= LRPrivateFunctions.linalg_reduce_onemon( Fam, 
                          LRPrivateFunctions.dir_monmult( Fam, m1, m2 ), G, lmspos );
                                   f3:= LRPrivateFunctions.linalg_reduce_onemon( Fam, 
                          LRPrivateFunctions.dir_monmult( Fam, m3, m1 ), G, lmspos );

                                   f:= LRPrivateFunctions.special_mult( Fam, m1, f1, m3, f2, m2, f3 );

                                   if not is_hom then
                                      f:= LRPrivateFunctions.linalg_reduce( Fam, f, G, lmspos );
                                   fi;

                                   f:= LRPrivateFunctions.linalg_reduce( Fam, f, rels, lmsposr );

                                   if f <> [] then
                                      lf:= Length(f); 
                                      c:= f[ lf ];
                                      if not IsOne(c) then for i in [2,4..lf] do f[i]:= f[i]/c; od; fi;

                                      if f[ Length(f)-1 ].no in nonleadingr then
                                         rels:= LRPrivateFunctions.linalg_reduce_allbyone( Fam, f, rels );
                                      fi;

                                      Add( rels, f );
                                      for r in [1,3..lf-3] do
                                          AddSet( nonleadingr, f[r].no );
                                      od; 
                                      m:= f[ lf -1 ];
                                      lmsposr[ m.no ]:= Length( rels );
                                      if m.deg < deg then lowdeg:= true; fi; 
                                   fi;
                               fi;
                            od; 
                         fi; 
                     od;
                  fi;
              od;
          od;

       fi;

       if is_hom then         
          Append( G, rels );
       else 
          if lowdeg then
             SortParallel( lms, G, function( u,v) return u.no < v.no; end );
             for i in [1..Length(rels)] do
                 r:= LRPrivateFunctions.addElm_RedSet_field( Fam, rels[i], G, lms );
                 G:= r[1]; lms:= r[2];
             od;
          else
             Append( G, rels );   
          fi;
       fi;

       for i in [1..Length(G)] do
           c:= G[i][ Length( G[i] ) ];
           if not IsOne(c) then
              for j in [2,4..Length(G[i])] do G[i][j]:= G[i][j]/c; od;
           fi;
       od;

       lms:= LRPrivateFunctions.leading_mns( G );
       lmspos:= [ ];
       for i in [1..Length(lms)] do
           lmspos[ lms[i].no ]:= i;
       od;

       newB:= [ ];
       for f in g do
           m:= f![1];
           if m[1].deg = deg then
              if not IsBound( lmspos[m[1].no] ) then 
                 Add( newB, m );
              fi;
           fi;
       od;       

       if deg > 1 then
          
          for u in [1..Length(Bd)] do
              v:= deg-u;
              if v>=1 and v<=Length(Bd) then
                 for i in [1..Length(Bd[u])] do
                     m1:= Bd[u][i]; 
                     for k in [1..Length( Bd[v] )] do
                         m2:= Bd[v][k];
                         if o[m1[1].no] < o[m2[1].no] then
                            m:= LRPrivateFunctions.dir_monmult( Fam, m1, m2 );
                            if not IsBound( lmspos[m[1].no] ) then 
                               Add( newB, m );
                            fi;
                         fi;
                     od;
                 od;
              fi;
          od;

       fi;
       Add( Bd, newB );

       # maybe throw away some old basis elements (only in non-hom case!)
       if not is_hom and lowdeg then
          for i in [1..Length(Bd)] do
              for j in [1..Length(Bd[i])] do
                  m:= Bd[i][j][1];
                  for k in [1..Length(lms)] do
                      if LRPrivateFunctions.IsFactor_yn( lms[k], m ) then
                         Unbind( Bd[i][j] ); break;
                      fi;
                  od;
              od;
              Bd[i]:= Filtered( Bd[i], x -> IsBound(x) );
          od;
       fi;

       Bk:= Bd[ Length( Bd ) ];

       if Bk = [ ] and not diff_degree then
          c:= 1; 
          while Bd[c] <> [ ] do c:= c+1; od;
          bound:= 2*c-1;
          bound:= Maximum(bound,Maximum( List( R, x -> Degree(x) ) ) );
       fi;

       if is_hom and deg = nilquot then
          # we are done...
          deg:= bound+1;
       else
          deg:= deg+1;      
       fi;

     od;

     B:= [];
     for i in [1..Length(Bd)] do Append( B, Bd[i] ); od;

     basinds:= [ ];
     for i in [1..Length(B)] do
         basinds[ B[i][1].no ]:= i;
     od;

     T:= EmptySCTable( Length(B), Zero( LeftActingDomain(A) ), "antisymmetric" );

     for i in [1..Length(B)] do
         for j in [i+1..Length(B)] do
             if not( is_nilquot and B[i][1].deg + B[j][1].deg > nilquot ) then
                eg:= LRPrivateFunctions.linalg_reduce_onemon( Fam, 
                          LRPrivateFunctions.dir_monmult( Fam, B[i], B[j] ), G, lmspos );

                cc:= [ ];
                for k in [1,3..Length(eg)-1] do
                    Add( cc, eg[k+1] );
                    Add( cc, basinds[eg[k].no] );
                od;
                SetEntrySCTable( T, i, j, cc );
             fi;
         od;
     od; 

     K:= LieAlgebraByStructureConstants( LeftActingDomain(A), T );

     g:= [ ];
     for i in GeneratorsOfAlgebra(A) do
         eg:= LRPrivateFunctions.linalg_reduce_onemon( Fam, i![1], G, lmspos );
         cf:= List( [1..Dimension(K)], x -> Zero( LeftActingDomain(K) ) );
         for k in [1,3..Length(eg)-1] do
             cf[basinds[eg[k].no]]:= eg[k+1];
         od;    
         Add( g, cf*Basis(K) );
     od;
     SetGeneratorsImages( K, g );

     hom:= function( elm )

        local eval, e, len, res, i;

        eval:= function( expr )

            local a,b;
            if IsBound(expr.var) then
               return g[ expr.var ];
            else
               a:= eval( expr.left );
               b:= eval( expr.right );
               return a*b;
            fi;
        end;

        e:= elm![1];
        len:= Length( e );
        res:= Zero( K );
        for i in [ 1, 3 .. len - 1 ] do
            res:= res + e[i+1]*eval( e[i] );
        od;
        return res;

     end;

     SetCanonicalProjection( K, hom );

     return K;

end );



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