misc‎ > ‎

roots_of_unity

canonical := function(list)
  min,pos := Min(list);
  list := Rotate(list,-(pos-1));
  if list[#list] lt list[2] then
    list := [list[1]] cat [list[i] : i in [6..2 by -1]];
  end if;
  return list;
end function;
  

convert := function(zetas,n)
  Q := Pi(RealField())/n;
  Z := zetas cat [zetas[1]];
  int := [];
  for i in [1..#zetas] do
    z1 := Z[i];
    z2 := Z[i+1];
    x  := Modulus(z1+z2);
    c  := (2-x^2)/2;
    theta := Arccos(c);
    I  := Round(theta/Q-2) div 2;
    int := int cat [I];
  end for;
  return int;
end function;


six_cycle := function(n)
  z := RootOfUnity(2*n);
  R_even := [z^(2*i) : i in [0..n-1]];
  R_odd  := [z^(2*i+1) : i in [0..n-1]];
  R_odd2 := [z^(2*i+1) : i in [0..(n-1) div 2]];
  list := [];
  a := z^0;
  for b in R_odd2 do
    if Modulus(a+b) lt 1 then continue; end if;
    for c in R_even do
      if Modulus(b+c) lt 1 then continue; end if;
      if Modulus(a+b+c) lt 1 then continue; end if;
      for d in R_odd do
        if Modulus(c+d) lt 1 then continue; end if;
        if Modulus(b+c+d) lt 1 then continue; end if;
        if Modulus(a+b+c+d) lt 1 then continue; end if;
        for e in R_even do
          if Modulus(d+e) lt 1 then continue; end if;
          if Modulus(c+d+e) lt 1 then continue; end if;
          if Modulus(b+c+d+e) lt 1 then continue; end if;
          if Modulus(a+b+c+d+e) lt 1 then continue; end if;
            f := -(a+b+c+d+e);
            if f in R_odd then
              interiors := canonical(convert([a,b,c,d,e,f],n));
              if not(interiors in list) then
                print interiors;
                list := list cat [interiors];
              end if;
            end if;
        end for;
      end for;
    end for;
  end for;
  return "DONE!",#list;
end function;
  


six_cycle_sqrt := function(n)
  z := RootOfUnity(2*n);
  R_even := [z^(2*i) : i in [0..n-1]];
  R_odd  := [z^(2*i+1) : i in [0..n-1]];
  R := [z^i : i in [0..n-1]];

  // build sums of odd and even roots of unity.
  LR_sums := [];
  for z1 in R_odd do
    for z2 in R_even do
      z3 := z1+z2;
      if Modulus(z3) lt 1 then continue; end if;
      Append(~LR_sums,[z3,z1,z2]);
    end for;
  end for;

  list := [];
  cycles := [];
  for c1 in LR_sums do
    for c2 in LR_sums do
      if ((c1[1]-z^0-c2[1]) in R_odd) then
        zetas := [z^0,c2[2],c2[3],c1[1]-z^0-c2[1],-c1[2],-c1[3]];
        a,b,c,d,e,f := Explode(zetas);
        if Modulus(a+b) lt 1 then continue; end if;
        if Modulus(b+c) lt 1 then continue; end if;
        if Modulus(a+b+c) lt 1 then continue; end if;
        if Modulus(c+d) lt 1 then continue; end if;
        if Modulus(b+c+d) lt 1 then continue; end if;
        if Modulus(a+b+c+d) lt 1 then continue; end if;
        if Modulus(d+e) lt 1 then continue; end if;
        if Modulus(c+d+e) lt 1 then continue; end if;
        if Modulus(b+c+d+e) lt 1 then continue; end if;
        if Modulus(a+b+c+d+e) lt 1 then continue; end if;
        interiors := canonical(convert(zetas,n));
        if not(interiors in cycles) then
          Append(~cycles,interiors);
          print interiors;
        end if;
      end if;
    end for;
  end for;

  return "DONE!",#LR_sums,#list,#cycles;
end function;

for i in [i : i in [3..131]|IsOdd(i)] do
  print "n=",i;
  time six_cycle_sqrt(i);
end for;

Comments