Guest User

Untitled

a guest
Jul 21st, 2021
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.33 KB | None | 0 0
  1. # the code for the degree 5 polynomial takes FOREVER to run,
  2. # so I'm not sure if it works. This is definitely correct for
  3. # the degree 3 polynomial here, and terminates (with the incorrect answer :/)
  4. # for the degree 4 polynomial. I'm not sure if that's because of a bug
  5. # in my code or if it's because 4 is not prime...
  6.  
  7. f = x^5 + x^4 - 4*x^3 - 3*x^2 + 3*x + 1
  8. # f = x^4 -4*x^2 + 2
  9. # f = x^3 + x^2 - 2*x - 1
  10.  
  11. ###################################################
  12.  
  13. # the coefficients of f.
  14. # we reverse them to make upcoming code cleaner
  15. poly = f.coefficients(sparse=False)[::-1]
  16.  
  17. n = f.degree(x)
  18.  
  19. # make a number field where w is a nth root of 1
  20. K.<w> = CyclotomicField(n)
  21.  
  22. # make vars for the roots.
  23. # a[i] = alpha_i
  24. R = PolynomialRing(K, n, 'a')
  25. a = R.gens()
  26.  
  27. #v_1^n
  28. v = sum([w^k * a[k] for k in range(n)])^n
  29.  
  30. # build the conjugates of v.
  31. # it turns out we only need one from each conjugacy class,
  32. # which keeps the degree down.
  33.  
  34. Sn = SymmetricGroup(n)
  35.  
  36. print("start conjugates")
  37. conjugates = []
  38. for tau in Sn:
  39.   if v * tau not in conjugates:
  40.     conjugates += [v * tau]
  41. print("finish conjugates")
  42.  
  43. # It turns out to be WAY less efficient to have iterated polynomial rings
  44. S.<Y> = PolynomialRing(R)
  45. Sf = S.flattening_morphism().codomain()
  46.  
  47. print("start computing psi")
  48. psi = prod([Sf(Y - conj) for conj in conjugates])
  49. print("finish computing psi")
  50.  
  51. # the coefficients of psi are symmetric functions in the ai.
  52. # so let's write them as polynomials in the elementary
  53. # symmetric functions.
  54.  
  55. Sym = SymmetricFunctions(K)
  56. e = Sym.e()
  57.  
  58. # now, since each elementary symmetric function is one of the coefficients
  59. # of f (up to sign), we can convert the coefficients of psi into numbers!
  60.  
  61. def coeffToNumber(coeff):
  62.   """
  63.  Convert a sum of elementary terms into a number
  64.  """
  65.  
  66.   def elemToNumber(elem):
  67.     """
  68.    Convert an elementary term into a number
  69.  
  70.    the pair (ns = [n1,n2,...,nk], c) corresponds to c * e_{n1} * e_{n2} ... * e_{nk}
  71.    """
  72.     ns, c = elem
  73.  
  74.     out = c
  75.     for n in ns:
  76.       if n < len(poly):
  77.         # the elementary polys alternate in sign
  78.         # when you view them as the coefficients of
  79.         # a polynomial from the roots.
  80.         out *= (-1)^(n) * poly[n]
  81.       else:
  82.         out *= 0
  83.  
  84.     return out
  85.  
  86.  
  87.   return sum(elemToNumber(elem) for elem in coeff)
  88.  
  89.  
  90. print("start computing the coefficients of psi in Q")
  91. psiReduced = 0
  92. for j in range(n+1):
  93.   print(j)
  94.  
  95.   print("start converting to R")
  96.   coeff = R(psi.coefficient({Y:j})) # convert back to a ring without Y
  97.   print("finish converting to R")
  98.  
  99.   print("start converting to sym")
  100.   coeff = e(Sym.from_polynomial(coeff)) # convert into a symmetric polynomial
  101.   print("finish converting to sym")
  102.  
  103.   print("add to psi")
  104.   psiReduced += Y^j * coeffToNumber(list(coeff)) # convert into a member of K
  105.   print("finish adding to psi")
  106.  
  107. # v1,v2,...v(n-1) are exactly the roots of psi!
  108. # notice these are already in our underlying field,
  109. # so finding the roots isn't actually cheating.
  110. # We could do this by hand by factoring psi, which
  111. # must (by theory) factor into linear terms.
  112.  
  113. v0 = - poly[1] # v0 = a0 + a1 + ... + a(n-1) = e1
  114. vs = psiReduced.roots(multiplicities=False)
  115.  
  116. # Finally, we're done!
  117. r = (v0 + sum(v^(1/n) for v in vs))/n
  118.  
  119. print(f)
  120. print(r)
  121.  
  122. # and we can verify
  123. print(f(r.n()))
  124.  
  125.  
  126.  
  127.  
Advertisement
Add Comment
Please, Sign In to add comment