newton_s_method_for_polynomials.sf 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #!/usr/bin/ruby
  2. # Newton's method for computing n-th roots of polynomials,
  3. # applied to the computation of "n-th roots" of p-adic numbers.
  4. # Inspired by:
  5. # https://yewtu.be/watch?v=3gyHKCDq1YA
  6. func newton_inverse_method(f, r, v) {
  7. var x = Poly(1)
  8. r.times {
  9. x = (x - (f(x).eval(v) / derivative(f(x)).eval(v)))
  10. }
  11. x.eval(v)
  12. }
  13. for n in (1..8) {
  14. say newton_inverse_method(func(x) { x**2 + 7 }, n, 1).as_rat
  15. }
  16. # Problem: find a value for x, such that x^2 + 7 is divisible by 2^50.
  17. # One such solution, is x = 206036503412917, which gives 42451040738620958589002448896.
  18. say ''
  19. var t = Mod(newton_inverse_method(func(x) { x**2 + 7 }, 6, 1), 2**50)
  20. say t #=> Mod(206036503412917, 1125899906842624)
  21. say (t**2 + 7) #=> Mod(0, 1125899906842624)
  22. say factor_exp(t.lift**2 + 7) #=> [[2, 51], [29, 1], [1789, 1], [363370967, 1]]
  23. __END__
  24. -3
  25. -1/3
  26. 31/3
  27. 449/93
  28. 70529/41757
  29. -3615594751/2945079453
  30. 23820962743960351231/10648213811544751203
  31. -113126467792729861089136567110653207551/253650704494531566925735633658389780893