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


Quelle  sqrt.gi   Sprache: unbekannt

 
#########################################################################
#
# this file contains the methods for defining the field SqrtField
# and for working with its elements, see sqrt.gd
#
#

###############################################
# Do deal with Flat for lists of matrices
#
corelg.myflat := function(L)
   return Concatenation(L);
end;


###############################################
# DUE TO A BUG IN BasisNC
InstallMethod( NiceBasisNC, 
               [IsBasisByNiceBasis and HasNiceBasis], NiceBasis );


#########################################################################

BindGlobal( "SqrtField_objectify", function( elm )
local u,isrt;
   isrt:= Length(elm) = 1 and Length(elm[1][2])=0;
   u:= Objectify( SqrtFieldType, [ Immutable(elm) ] );
   u![2]:= isrt;
   return u;
end ); 

#########################################################################

InstallMethod( \in,
   "for an object and a SqrtField",
   [ IsObject, IsSqrtField ], 1000000,
function( p, qf )
   return IsSqrtFieldElement(p);
end );

#########################################################################


InstallGlobalFunction(Sqroot, function(q)
local d, n, fc, cf, ps, i, m, sgn;

   if not IsRat(q) then 
      if IsSqrtFieldElement(q) and Length(q![1]) = 1 
         and IsRat(q![1][1][1]) and q![1][1][2] = [] then
         return Sqroot(q![1][1][1]);
      else
         Error("<q> must be a rational, or rational SqrtField elt"); 
      fi;
   fi;
   if q < 0 then sgn := E(4); q := -q; else sgn := 1; fi;
   if q in [0,1] then 
      return SqrtField_objectify([[sgn*q,[]]]); 
   fi;
   d  := DenominatorRat(q);
   n  := NumeratorRat(q);
   fc := FactorsInt(n);
   Append(fc,FactorsInt(d));
   fc := Collected(fc);
   cf := 1/d;
   ps := [];
   for i in [1..Length(fc)] do
      m  := fc[i][2] mod 2;
      cf := cf *(fc[i][1]^((fc[i][2]-m)/2));
      if m=1 then Add(ps,fc[i][1]); fi;
   od;
   if ps = [] then return 
      SqrtField_objectify([[sgn*cf,[]]]); 
   fi; 
   if ps[1] = 1 then ps := ps{[2..Length(ps)]}; fi;
   Sort(ps);
   MakeImmutable(ps);
   return SqrtField_objectify([[sgn*cf,ps]] );
end); 

#########################################################################

SetOne( SqrtField, Sqroot(1) );
SetZero( SqrtField, Sqroot(0) );
SetZero( SqrtFieldFam, Zero(SqrtField) );
SetOne( SqrtFieldFam, One(SqrtField) );
SetIsUFDFamily(SqrtFieldFam,true);

#########################################################################

InstallMethod( ViewObj, 
        "for SqrtField elements",
        [ IsSqrtFieldElement ],

function( sf )
local elt, l, i, printmon, printcf;
   elt := sf![1];
   l   := Length(elt);
   printmon := function(mon)
      if mon[1] = 1 then 
         Print( "Sqroot(",Product(mon[2]),")");
      elif mon[1]<0 or not (IsRat(mon[1]) or IsRat(E(4)*mon[1])) 
                    or (IsRat(E(4)*mon[1]) and E(4)*mon[1]>0) then
         Print( "(",mon[1],")*","Sqroot(",Product(mon[2]),")");
      else 
         Print( mon[1],"*","Sqroot(",Product(mon[2]),")");
      fi;
   end;
   if l=1 then
      if elt[1][2]=[] then Print(elt[1][1]); else printmon(elt[1]); fi;
   else
      if elt[1][2]=[] then 
         Print(elt[1][1]," + "); 
      else 
         printmon(elt[1]); 
         Print(" + "); 
      fi;
   fi;
   for i in [2..l-1] do printmon(elt[i]); Print(" + "); od;
   if l>1 then printmon(elt[l]); fi;  
end );

##########################################################################

InstallMethod( PrintObj, 
        "for SqrtField elements",
        [ IsSqrtFieldElement ],
function( sf )
local elt, l, i, printmon;
   elt := sf![1];
   l   := Length(elt);
   printmon := function(mon)
      if mon[1] = 1 then 
         Print( "Sqroot(",Product(mon[2]),")");
      elif mon[1]<0  or not (IsRat(mon[1]) or IsRat(E(4)*mon[1]))  
                     or (IsRat(E(4)*mon[1]) and E(4)*mon[1]>0) then
         Print( "(",mon[1],")*","Sqroot(",Product(mon[2]),")");
      else 
         Print( mon[1],"*","Sqroot(",Product(mon[2]),")");
      fi;
   end;
   if l=1 then
      if elt[1][2]=[] then Print(elt[1][1]); else printmon(elt[1]); fi;
   else
      if elt[1][2]=[] then 
         Print(elt[1][1]," + "); 
      else 
         printmon(elt[1]); 
         Print(" + "); 
      fi;
   fi;
   for i in [2..l-1] do printmon(elt[i]); Print(" + "); od;
   if l>1 then printmon(elt[l]); fi;

end );

#########################################################################


InstallGlobalFunction( SqrtFieldIsGaussRat, function(el)
   return IsSqrtFieldElement(el) and el![2];
end); 

#########################################################################


InstallGlobalFunction( SqrtFieldMakeRational, function(el)
   if IsSqrtFieldElement(el) then
      if SqrtFieldIsGaussRat(el) then
         return el![1][1][1]; 
      else 
         return false; 
      fi;
   elif IsSqrtFieldElementCollection(el) then
      if ForAll(el,SqrtFieldIsGaussRat) then 
         return List(el,x->x![1][1][1]);
      else
         return false;
      fi;
   elif IsSqrtFieldElementCollColl(el) then
      if ForAll(Flat(el),SqrtFieldIsGaussRat) then
         return List(el,x->List(x,y->y![1][1][1]));
      else
         return false;
      fi; 
   fi;
   return false;
end); 

#########################################################################

InstallMethod( Determinant,
   "for SqrtField matrices",
   [ IsSqrtFieldElementCollColl], 1000,
function(x)
local a,b;
   a := SqrtFieldMakeRational(x);
   if not a = false then 
      return DeterminantMat(a)*One(SqrtField);
   fi;
   TryNextMethod();
end);

#########################################################################

InstallMethod( \*,
   "for SqrtField matrices",
   [ IsSqrtFieldElementCollColl, IsSqrtFieldElementCollColl],
function(x,y)
local a,b;
   a := SqrtFieldMakeRational(x);
   if not a = false then 
      b := SqrtFieldMakeRational(y);      
      if not b = false then
         return One(SqrtField)*(a*b);
      fi;
   fi;
  #Print("DONT USE MAKERAT\n");
  TryNextMethod();
end);


#########################################################################

InstallMethod( \+,
   "for SqrtField matrices",
   [ IsSqrtFieldElementCollColl, IsSqrtFieldElementCollColl],
function(x,y)
local a,b;
   a := SqrtFieldMakeRational(x);
   if not a = false then 
      b := SqrtFieldMakeRational(y);      
      if not b = false then
         return One(SqrtField)*(a+b);
      fi;
   fi;
  #Print("DONT USE MAKERAT\n");
   TryNextMethod();
end);


#########################################################################

InstallMethod( \*,
   "for rational and SqrtField elements",
   [IsCyclotomic, IsSqrtFieldElement], 
function(x,y)
local b,i;
      if not IsGaussRat(x) then
         Error("cyclotomic has to be Gaussian Rational");
      fi;
      if x = 0 then return Zero(SqrtField); fi;
      if x = 1 then return y; fi;
      b := List(y![1],ShallowCopy);
      for i in b do i[1] := x*i[1]; od;
      return SqrtField_objectify( b );          
end);

#########################################################################

InstallMethod( \*,
   "for SqrtField and rational elements",
   [IsSqrtFieldElement, IsCyclotomic], 
function(x,y)
   return y*x;      
end);

#########################################################################

InstallMethod( ZeroOp,
   "for SqrtField element",
   [IsSqrtFieldElement], 
function(x)
   return Zero(SqrtField);     
end);

#########################################################################

InstallMethod( OneOp,
   "for SqrtField element",
   [IsSqrtFieldElement], 
function(x)
   return One(SqrtField);   
end);

#########################################################################

InstallMethod( \+,
   "for SqrtField and SqrtField elements",
   [IsSqrtFieldElement, IsSqrtFieldElement], 10000,
function(x,y)
local a,b,i,j,e,len,pr;

   if x = Zero(SqrtField) then return y; fi;
   if y = Zero(SqrtField) then return x; fi;
   if x![2] then
      if y![2] then
         return SqrtField_objectify([[x![1][1][1]+y![1][1][1], []]]);
      else 
         return x![1][1][1] + y;
      fi;
   fi; 
   if y![2] then return y![1][1][1] + x; fi;


   if Length(x![1])<=Length(y![1]) then
      a := List(x![1],ShallowCopy);
      b := List(y![1],ShallowCopy);
   else
      a := List(y![1],ShallowCopy);
      b := List(x![1],ShallowCopy);
   fi;
   i := 1;
   for j in [1..Length(a)] do
      e  := a[j];
      pr := Product(e[2]);
      while i<= Length(b) and Product(b[i][2])<pr do i := i+1; od;
      if i>Length(b) then 
         Append(b,a{[j..Length(a)]});
         return SqrtField_objectify( b ); 
      fi;
      if e[2]=b[i][2] then
         b[i][1] := b[i][1] + e[1];
         if b[i][1] = 0 then
            #remove position i
             len := Length(b);
             CopyListEntries( b, i + 1, 1, b, i, 1, len - i );
             Unbind( b[len] );
         fi;
      else
        #add e at position i
         CopyListEntries(b,i,1,b,i+1,1,Length(b)-i+1);
         b[i] := e;
      fi;
   od;
   if b = [] then return Zero(SqrtField); fi;
   return SqrtField_objectify( b );          
end);

#########################################################################

InstallMethod( \+,
   "for Gaussian rational and SqrtField elements",
   [IsCyclotomic, IsSqrtFieldElement], 
function(x,y)
local t;
   if not IsGaussRat(x) then
      Error("cyclotomic has to be Gaussian rational");
   fi;
   if x=0 then return y; fi;
   t := List(y![1],ShallowCopy);
   if t[1][2] = [] then
      t[1][1] := t[1][1] + x;
      if t[1][1] = 0 then t := t{[2..Length(t)]}; fi;
      if t = [] then return Zero(SqrtField); fi;
   else
     #add [y,[]] at position 1
      CopyListEntries( t, 1, 1, t, 2, 1, Length(t) );
      t[1] := [x,[]];
   fi;
   return SqrtField_objectify( t );
end);

#########################################################################

InstallMethod( \+,
   "for SqrtField and rational elements",
   [IsSqrtFieldElement, IsCyclotomic], 
function(x,y)
   return y+x;
end);

#########################################################################

InstallMethod( AdditiveInverseSameMutability,
   "for SqrtField elements",
   [IsSqrtFieldElement], 
function(x)
local a, i;
   a := List(x![1],ShallowCopy);
   for i in a do i[1] := -i[1]; od;
   return SqrtField_objectify( a );   
end);

#########################################################################

InstallMethod( \=,
   "for SqrtField elements",
   [IsSqrtFieldElement, IsSqrtFieldElement], 
function(x,y)
   return x![1] = y![1];
end);
#########################################################################

InstallMethod( \=,
   "for SqrtField and rational elements",
   [IsSqrtFieldElement, IsRat], 
function(x,y)
   if not x![2] then return false; fi;
   return SqrtFieldMakeRational(x) = y;
end);

#########################################################################

InstallMethod( \=,
   "for rational and SqrtField element",
   [IsRat, IsSqrtFieldElement], 
function(x,y)
   if not y![2] then return false; fi;
   return SqrtFieldMakeRational(y) = x;
end);

#########################################################################


InstallMethod( \*,
   "for SqrtField and SqrtField elements",
   [IsSqrtFieldElement, IsSqrtFieldElement],
   function(x,y)
   local a,b,i,j,res,int,cf,v,w, mns, cfs, isSmaller, pos, k;

      if x=Zero(SqrtField) or y=Zero(SqrtField) then 
         return Zero(SqrtField); 
      fi;
      if x=One(SqrtField) then return y; fi;
      if y=One(SqrtField) then return x; fi;

      a   := x![1];
      b   := y![1];

      if x![2] and y![2] then
         return SqrtField_objectify([[a[1][1]*b[1][1],[]]]);
      fi; 

      mns := [ ];
      cfs := [ ];

      isSmaller := function(u,v) return Product(u)< Product(v); end;

      for i in a do
         for j in b do

            int := i[2]{[1..Length(i[2])]};
            INTER_SET( int, j[2] );

            cf  := i[1]*j[1];  #*Product(int);
            for k in int do cf:= cf*k; od;

            res := i[2]{[1..Length(i[2])]};
            APPEND_LIST( res, j[2] );
            v   := Filtered(res,x->not x in int);
            SORT_LIST(v);
            pos := POSITION_SORTED_LIST_COMP( mns, v, isSmaller );
            if IsBound(mns[pos] ) and mns[pos] = v then
               cfs[pos]:= cfs[pos]+cf;
            else
               Add( mns, v, pos );
               Add( cfs, cf, pos );
            fi;

         od;
      od;
      res:= [ ];
      for i in [1..Length(mns)] do
         if cfs[i] <> 0 then
            Add( res, [ cfs[i], mns[i] ] );
         fi;
      od;
      if res = [] then return Zero(SqrtField); fi;
      return SqrtField_objectify( res );
end);


##########################################################################

InstallMethod( InverseOp,
   "for SqrtField elements",
   [IsSqrtFieldElement], 
function(el)
local b, i, j, bas, mat, elts, a, cfs, l,cf, pos, ns, inv, res, v, nrp, want;
   if el=Zero(SqrtField) then Error("elt must be nonzero"); fi;
   a    := List(el![1],ShallowCopy);
   a    := SqrtField_objectify( a );
   i    := 1;
   elts := [One(SqrtField)];
   bas  := [[]];
   cfs  := [ [1] ];
   l    := Length(bas);
   nrp  := Length(Collected(Flat(List(a![1],x->x[2]))));
   want := 2^Minimum([nrp,Length(Filtered(a![1],x->not x[2]=[]))]);
   if want > 16 then
      Info(InfoSqrtField,2,"need ",want," powers for computing the inverse");
   fi;
   repeat
      i       := i+1;
      elts[i] := elts[i-1]*a; 
      cfs[i]  := ListWithIdenticalEntries(l,0);
      for j in elts[i]![1] do
         pos := Position(bas,j[2]);
         if pos=fail then 
            Add(bas,j[2]); 
            l   := l+1;  
            pos := l; 
            for v in cfs do v[l] := 0; od;
         fi;
         cfs[i][pos] := j[1];
      od;
      if i mod 10 = 0 then
         Info(InfoSqrtField,2,"  InfoSqrtField: (inverses) computed ",i," powers");
      fi;
   until i-1 = want;
   ns  := NullspaceMat(cfs);
   res := ns[1];
   inv := Sum(List([2..Length(res)],i->res[i]*elts[i-1]))/(-res[1]);
  #Info(InfoSqrtField,3,"test inverse");
  #if not el*inv = One(SqrtField) then Error("hmpf... inv wrong!"); fi;
   return inv;       
end);


#########################################################################

InstallMethod( AdditiveInverseMutable,
   "for SqrtField elements",
   [IsSqrtFieldElement],
   function(x)
   local a, i;
      a := List(x![1],ShallowCopy);
      for i in a do i[1] := -i[1]; od;
      return SqrtField_objectify( a );
end);

#########################################################################

InstallMethod( \<,
   "for SqrtField elements",
   [IsSqrtFieldElement, IsSqrtFieldElement],
   function(x,y)
      return x![1] < y![1];
end);

#########################################################################

InstallMethod( \<,
   "for SqrtField element and Rational",
   [IsSqrtFieldElement, IsRat],
   function(x,y)
      if not x![2] then TryNextMethod(); fi;
      return SqrtFieldMakeRational(x) < y;
end);

########################################################################

InstallMethod( \<,
   "for rational and SqrtField element",
   [IsRat, IsSqrtFieldElement],
   function(x,y)
      if not y![2] then TryNextMethod(); fi;
      return SqrtFieldMakeRational(y) > x;
end);


#########################################################################


InstallGlobalFunction(SqrtFieldMinimalPolynomial, function(el)
#returns polynomial f of min deg over GaussianRats such that f(el)=0; 
local b, i, j, bas, mat, elts, a, cfs, l,cf, pos, ns, inv, res, v, nrp, 
      want, pol, x;
   if not IsSqrtFieldElement(el) then
      Error("input has to be SqrtField elt");
   fi;
   if el=Zero(SqrtField) then Error("elt must be nonzero"); fi;
   a    := List(el![1],ShallowCopy);
   a    := SqrtField_objectify( a );
   i    := 1;
   elts := [One(SqrtField)];
   bas  := [[]];
   cfs  := [ [1] ];
   l    := Length(bas);
   nrp  := Length(Collected(Flat(List(a![1],x->x[2]))));
   want := 2^Minimum([nrp,Length(Filtered(a![1],x->not x[2]=[]))]);
   if want > 16 then
      Info(InfoSqrtField,1,"need ",want," powers for computing the inverse");
   fi;
   repeat
      i       := i+1;
      elts[i] := elts[i-1]*a; 
      cfs[i]  := ListWithIdenticalEntries(l,0);
      for j in elts[i]![1] do
         pos := Position(bas,j[2]);
         if pos=fail then 
            Add(bas,j[2]); 
            l   := l+1;  
            pos := l; 
            for v in cfs do v[l] := 0; od;
         fi;
         cfs[i][pos] := j[1];
      od;
      if i mod 10 = 0 then
         Info(InfoSqrtField,2,"  - computed ",i," elements");
      fi;
   until i-1 = want;
   ns   := NullspaceMat(cfs);
   res  := ns[1]*One(SqrtField);
   x    := Indeterminate(SqrtField);
   elts := [One(SqrtField)];
   Append(elts, List([2..Length(res)],i->x^(i-1)));
   pol  := Sum(List([1..Length(res)],i->res[i]*elts[i]));
   return pol;       
end);

#########################################################################


InstallGlobalFunction(SqrtFieldEltByRationalSqrt, function(e)
local sgn;
   if not IsRat(e^2) then Error("input has to be Sqroot of a rational"); fi;
   if not e-Sqrt(e^2) = 0 then sgn := -1; else sgn := 1; fi;
   return sgn*Sqroot(e^2);
end); 

##########################################################################


InstallGlobalFunction(SqrtFieldEltRealAndComplexPart, function(e)
local real, imag, i, makecf, cf, r;
   if not IsSqrtFieldElement(e) then 
      Error("input must be SqrtFieldElement"); 
   fi;
   makecf := function(cf)
      local cj;
      cj := ComplexConjugate(cf);
      return [1/2*(cf+cj),1/2*(cf-cj)];
   end;
   real := Zero(SqrtField);
   imag := Zero(SqrtField);
   for i in e![1] do
      r  := Sqroot(Product(i[2]));
      cf := makecf(i[1]);
      real := real+cf[1]*r;
      imag := imag+cf[2]*r;
   od;
   return [real,imag];
end); 
##########################################################################


InstallGlobalFunction(IsPosSqrtFieldElt, function(e)
local real, imag, i, makecf, cf, r;
   if not IsSqrtFieldElement(e) or not Length(e![1]) = 1 or
      not ForAll(e![1],i->IsRat(i[1])) then 
      Error("input must be a real SqrtFieldElement with one monom"); 
   fi;
   return e![1][1][1]>0;
end); 

##########################################################################


InstallGlobalFunction(CoefficientsOfSqrtFieldElt, function(e)
local cfs, i, x;
   if not IsSqrtFieldElement(e) then 
      Error("input must be SqrtFieldElement"); 
   fi;
   x := List(e![1],ShallowCopy);
   return List(x,i->[i[1],Product(i[2])]);
end); 

##########################################################################


InstallGlobalFunction(SqrtFieldEltByCoefficients, function(e)
local elt, i;
   elt := Zero(SqrtField);
   for i in e do
      if not IsGaussRat(i[1]) and IsRat(i[2]) then 
          Error("wrong format of coefficients vector"); 
      fi;
      elt := elt + i[1]*Sqroot(i[2]);
   od;
   return elt;
end); 

##########################################################################


InstallGlobalFunction(SqrtFieldEltToCyclotomic, function(e)
local makemon;
   if not IsSqrtFieldElement(e) then
      Error("input has to lie in SqrtField");
   fi;
   if Length(e![1])=1 and e![1][1][2]=[] then return e![1][1][1]; fi;
  #Info(InfoSqrtField,1,"Warning: might not work for large cyclotomics.");
   makemon := function(mon)
      if mon[2]=[] then return mon[1]; fi;
      return mon[1]*Sqrt(Product(mon[2]));
   end;
   return Sum(List(e![1],makemon));
end); 

##########################################################################

InstallMethod( DefaultFieldOfMatrix,
    "method for a matrix over SqrtField",
    [ IsMatrix and IsSqrtFieldElementCollColl ],
function( mat )
   return SqrtField;
end );

##########################################################################

InstallMethod( DefaultFieldByGenerators,
    "method for a list over SqrtField",
    [ IsList and IsSqrtFieldElementCollection ],
function( mat )
   return SqrtField;
end );

##########################################################################

InstallMethod( ComplexConjugate,
    "method for SqrtField elt",
    [ IsSqrtFieldElement ],
function( el )
local x, i;
   x := List(el![1], ShallowCopy);
   for i in x do i[1] := ComplexConjugate(i[1]); od;
   return SqrtField_objectify( x );
end );

##########################################################################

InstallMethod( Sqrt,
    "method for SqrtField elt",
    [ IsSqrtFieldElement ],
function( el )
local x, i;
   x := List(el![1],ShallowCopy);
   if not (Length(x) = 1 and x[1][2] = [] and IsRat(x[1][1])) then
      Error("input has to be rational SqrtFieldElt");
   fi;
   return  Sqroot(x[1][1]);
end );

##########################################################################

InstallMethodWithRandomSource( Random,
    "for a random source and an SqrtField ",
    [ IsRandomSource, IsSqrtField ],
function( rs, F )
   return Sum(List([1..15],x-> Random(rs,Rationals)*Sqroot(Random(rs,Rationals))));
   
end );

##########################################################################

InstallMethod( AbsoluteValue,
    "for SqrtField element",
    [ IsSqrtFieldElement ], 10000,
function( el )
local x,i;
   x := List(el![1],ShallowCopy);
   if not (Length(x)=1 and IsRat(x[1][1])) then
      Error("elt must be a real SqrtFieldElt with one summand");
   fi;
   for i in x do i[1] := AbsoluteValue(i[1]); od;
   return SqrtField_objectify( x );
end );

##########################################################################

InstallMethod( String,
    "for SqrtField element",
    [ IsSqrtFieldElement ],
function( el )
local elt, l, i, printmon, printcf, str;
   elt := List(el![1],ShallowCopy);
   str := "";
   l   := Length(elt);
   printmon := function(mon)
      if mon[1] = 1 then 
         Append(str, "Sqroot("); 
         Append(str,String(Product(mon[2])));
         Append(str,")");
      elif mon[1]<0 or not (IsRat(mon[1]) or IsRat(E(4)*mon[1])) 
                    or (IsRat(E(4)*mon[1]) and E(4)*mon[1]>0) then
         Append(str,"(");
         Append(str,String(mon[1]));
         Append(str,")*Sqroot(");
         Append(str,String(Product(mon[2])));
         Append(str,")");
      else 
         Append(str, String(mon[1]));
         Append(str,"*Sqroot(");
         Append(str,String(Product(mon[2])));
         Append(str,")");
      fi;
   end;
   if l=1 then
      if elt[1][2]=[] then Append(str,String(elt[1][1])); else printmon(elt[1]); fi;
   else
      if elt[1][2]=[] then 
         Append(str,String(elt[1][1]));
         Append(str," + "); 
      else 
         printmon(elt[1]); 
         Append(str," + ");
      fi;
   fi;
   for i in [2..l-1] do printmon(elt[i]); Append(str," + "); od;
   if l>1 then printmon(elt[l]); fi;  
   return str;
end );

##########################################################################

InstallMethod( String,
    "for SqrtField",
    [ IsSqrtField ],
function( el )
   return "SqrtField";
end );

##########################################################################


InstallGlobalFunction(SqrtFieldEltByCyclotomic, function(arg)
local e, cj, re, im, solvereal, res, r1, r2, 
      sqfree, whichSqfreeRootsInCF;
   e := arg[1];
   if e in SqrtField then return e; fi;
   if not IsCyclotomic(e) then 
      Error("input must be Cyclotomic"); 
   fi;
   if IsGaussRat(e) then return e*One(SqrtField); fi;

   whichSqfreeRootsInCF := function(n)
  #returns also one for technical reasons
   local sqfree, eeven, res;
      sqfree := x -> ForAll(Collected(FactorsInt(x)),i->i[2]=1);
      eeven  := x -> Length( Filtered(List(Collected(FactorsInt(x)), i->i[1]),
                             p -> p mod 4 = 3)) mod 2 = 0;
      res    := Filtered(DivisorsInt(n),x->sqfree(x));
      if IsOddInt(n) or (IsInt(n/2) and IsOddInt(n/2)) then
         return Filtered(res,x->IsOddInt(x) and eeven(x));
      fi;
      if n mod 4 = 0 and not n mod 8 =0 then
         return Filtered(res,IsOddInt);
      fi;
      return res;
   end;

  #check if input is sqrt of rational
  #test is expensive, e.g. for e=Sqrt(1231)+Sqrt(17);;
  #if IsRat(e^2) then return SqrtFieldEltByRationalSqrt(e); fi;

  #split into real and complex part
   cj    := ComplexConjugate(e);;
   re    := 1/2*(e+cj);;
   im    := 1/2*E(4)^3*(e-cj);;

  #the main function which requires a real input   
   solvereal := function( r )
   local n, pr, prsq, bas, mat, ns;  
      if IsRat(r) then return r*One(SqrtField); fi;
      n     := Conductor(r);
      pr    := whichSqfreeRootsInCF(n);
      prsq  := List(pr,Sqrt);
      bas   := Basis(CF(n));
      mat   := List(prsq,x->Coefficients(bas,x));
      ns    := SolutionMat(mat,Coefficients(bas,r));
      if ns = fail then return fail; fi;
      return Sum(List([1..Length(pr)],i->ns[i]*Sqroot(pr[i])));
   end;

  #try to solve real and complex part
   r1  := solvereal(re); if r1 = fail then return fail; fi;
   r2  := solvereal(im); if r2 = fail then return fail; fi;
   res := r1 + E(4)*r2;
 ###TEST
  #Info(InfoSqrtField,1,"test res");
  #if not e = SqrtFieldEltToCyclotomic(res) then
  #   Error("res wrong");
  #fi;
   return res;
end); 


#########################################################################


InstallGlobalFunction( SqrtFieldPolynomialToRationalPolynomial, function(e)
local x,i,j,cf;
   x  := Indeterminate(Rationals);
   cf := List(CoefficientsOfUnivariatePolynomial(e),SqrtFieldEltToCyclotomic);
   return Sum(List([1..Length(cf)],i-> cf[i]*x^(i-1)));
end); 


#########################################################################


InstallGlobalFunction( SqrtFieldRationalPolynomialToSqrtFieldPolynomial, function(e)
local x,i,j,cf;
   x  := Indeterminate(SqrtField);
   cf := List(CoefficientsOfUnivariatePolynomial(e),SqrtFieldEltByCyclotomic);
   return Sum(List([1..Length(cf)],i-> cf[i]*x^(i-1)));
end); 



##########################################################################

InstallOtherMethod( Factors,
    "for SqrtField",
    [ IsPolynomialRing, IsUnivariatePolynomial ],
function( R, f )
local rf;
if LeftActingDomain(R) = SqrtField and 
      IsSqrtFieldElementCollection(CoefficientsOfUnivariatePolynomial(f)) then
      rf := SqrtFieldPolynomialToRationalPolynomial(f);
      rf := Factors(rf);
      return List(rf,SqrtFieldRationalPolynomialToSqrtFieldPolynomial);
   else
      TryNextMethod();
   fi;
end );



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